Open jwillikers opened 2 years ago
The programmer is specified per board in ravedude, and there's already two boards that use the usbtiny programmer; the Trinket and Trinket Pro.
If you're using some other board you might have to add a definition for it in ravedude/src/board.rs, and specify that the usbtiny programmer should be used in the avrdude_options method.
Thanks! I'm using an atmega328p on a breadboard, so I'd have to add a board definition for it.
Oh, in that case I misunderstood what you were trying to accomplish.
Adding a "bare atmega328p" board definition might work, but it's probably not the right way to go about this.
If programming bare microcontrollers is something that's within the intended scope of ravedude it should probably be implemented in another way; maybe by adding a bunch of new arguments (in main.rs) where all the required parameters can be specified(?).
Let's see if Rahix can chime in on this.
Honestly the architecture of ravedude
is not well thought out - I just hacked something together quickly so people using the well known AVR boards have something to run their programs with. Before ravedude
was a thing, we were all just using a shell-script which did the same thing: Call avrdude to flash the program and then some console emulator like picocom
to interact with the serial console.
Of course in the long run it would be nice to make ravedude
a generic tool for running rust programs on any AVR board, not just the "well known" ones. One step in that direction would be to drop board.rs
and instead add all its contents into a configuration file. ravedude
would then ship with a default config and people like you, @jwillikers, could use their own config file instead... I even started working on that but didn't finish it yet unfortunately :/
Here is a mock-up of what I was thinking the config file could look like:
[uno]
name = "Arduino Uno"
[uno.reset]
automatic = true
[uno.avrdude]
programmer = "arduino"
partno = "atmega328p"
baudrate = -1
do_chip_erase = true
[uno.usb-info]
port-ids = [
{ vid = 0x2341, pid = 0x0043 },
{ vid = 0x2341, pid = 0x0001 },
{ vid = 0x2A03, pid = 0x0043 },
{ vid = 0x2341, pid = 0x0243 },
]
[micro]
name = "Arduino Micro"
[micro.reset]
automatic = false
message = "Reset the board by pressing the reset button once."
[micro.avrdude]
programmer = "avr109"
partno = "atmega32u4"
baudrate = 115200
do_chip_erase = true
[micro.usb-info]
port-ids = [
{ vid = 0x2341, pid = 0x0037 },
{ vid = 0x2341, pid = 0x8037 },
{ vid = 0x2A03, pid = 0x0037 },
{ vid = 0x2A03, pid = 0x8037 },
{ vid = 0x2341, pid = 0x0237 },
{ vid = 0x2341, pid = 0x8237 },
]
[nano]
name = "Arduino Nano"
[nano.reset]
automatic = true
[nano.avrdude]
programmer = "arduino"
partno = "atmega328p"
baudrate = 57600
do_chip_erase = true
[nano.usb-info]
# No IDs here because the Nano uses a generic USB-Serial chip.
[leonardo]
name = "Arduino Leonardo"
[leonardo.reset]
automatic = false
message = "Reset the board by pressing the reset button once."
[leonardo.avrdude]
programmer = "avr109"
partno = "atmega32u4"
baudrate = -1
do_chip_erase = true
[leonardo.usb-info]
port-ids = [
{ vid = 0x2341, pid = 0x0036 },
{ vid = 0x2341, pid = 0x8036 },
{ vid = 0x2A03, pid = 0x0036 },
{ vid = 0x2A03, pid = 0x8036 },
]
[mega2560]
name = "Arduino Mega 2560"
[mega2560.reset]
automatic = true
[mega2560.avrdude]
programmer = "wiring"
partno = "atmega2560"
baudrate = 115200
do_chip_erase = false
[mega2560.usb-info]
port-ids = [
{ vid = 0x2341, pid = 0x0010 },
{ vid = 0x2341, pid = 0x0042 },
{ vid = 0x2A03, pid = 0x0010 },
{ vid = 0x2A03, pid = 0x0042 },
{ vid = 0x2341, pid = 0x0210 },
{ vid = 0x2341, pid = 0x0242 },
]
[diecimila]
name = "Arduino Diecimila"
[diecimila.reset]
automatic = true
[diecimila.avrdude]
programmer = "arduino"
partno = "atmega168"
baudrate = 19200
do_chip_erase = false
[diecimila.usb-info]
# No IDs known.
[promicro]
name = "SparkFun Pro Micro"
[promicro.reset]
automatic = false
message = "Reset the board by quickly pressing the reset button **twice**."
[promicro.avrdude]
programmer = "avr109"
partno = "atmega32u4"
baudrate = -1
do_chip_erase = true
[promicro.usb-info]
port-ids = [
{ vid = 0x1B4F, pid = 0x9205 }, # 5V
{ vid = 0x1B4F, pid = 0x9206 }, # 5V
{ vid = 0x1B4F, pid = 0x9203 }, # 3.3V
{ vid = 0x1B4F, pid = 0x9204 }, # 3.3V
]
[trinket-pro]
name = "Trinket Pro"
[trinket-pro.reset]
automatic = false
message = "Reset the board by pressing the reset button once."
[trinket-pro.avrdude]
programmer = "usbtiny"
partno = "atmega328p"
baudrate = -1
do_chip_erase = false
[trinket-pro.usb-info]
# The Trinket Pro does not have USB-Serial, thus no port is known or needed.
[nano168]
name = "Nano Clone (ATmega168)"
[nano168.reset]
automatic = true
[nano168.avrdude]
programmer = "arduino"
partno = "atmega168"
baudrate = 19200
do_chip_erase = false
[nano168.usb-info]
# No IDs here because the Nano 168 uses a generic USB-Serial chip.
Any word on this? I would say adding this -c usbtiny
syntax as a small patch is a good solution until a proper refactor can be made for the entire board.rs
re-write.
My situation is that using a M1 Mac (Studio) I am unable to connect to the Arduino Nano directly. I get a constant avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
error with a direct connection. I have tried everything imaginable to remedy this but... it simply does not want to allow me to upload directly either in Arduino IDE 2.x or avrdude
directly.
So, I started using an ISP from Spark Fun. With that, I am able to program the Arduino Nano using the same exact cable. I don't know why this works and why the other method does not, but it does. My suspicion is Apple Silicon and the UART driver has some wonky behavior together (/dev/cu.usbserial-AB0JQVPN
).
Using the Rust template project, I have the following .cargo/config.toml
:
[target.'cfg(target_arch = "avr")']
runner = "./flash.sh"
Then in my flash.sh
script I use this:
#!/bin/zsh
avrdude -c usbtiny -p atmega328p -b 57600 -U "flash:w:$1"
Works beautifully with cargo run
. I'd just love to remove the hacky shell script and be able to specify this directly in ravedude
.
I would say adding this
-c usbtiny
syntax as a small patch is a good solution until a proper refactor can be made for the entire board.rs re-write.
I'm not quite following... What would you suggest to do as a "quickfix" for now?
What I would like to be able to do is pass the -c usbtiny
flag to ravedude
and it would then be passed to the avrdude
command as a passthrough and allow the omission of the -P <port>
.
I see. I'm not a fan of adding such specific options here because supporting them in the long run will be painful... I think what I'd prefer would be adding a mode to ravedude where all avrdude options are explicitly passed on the commandline. A sort of "custom" board for people like you. But this will also become superfluous as soon as there is a proper config file...
Maybe we can just add a fake "board" for your configuration for now which just uses the right settings? Or, from looking at the boards we have, maybe the existing trinket-pro
already has the configuration you need? Can you try whether it works for your setup? Otherwise I'd be fine with adding a custom board just for your environment for now.
Sorry, I'm not the original reporter so maybe this seemed confusing between me and them. I just added on to this discussion because of the title and I figured it was better than creating a separate issue for my need.
I see two separate issues here:
I can understand that the second point is complicated and not the scope of this. My point is that using an ISP to flash an already supported board seems like a possible use case and only requires a simple pass through of the -c
param to avrdude
.
For example, I am using an Arduino Nano. This is something that is already supported and defined in the 328p family of boards. I just want to deploy my code using an ISP instead of direct upload to the device. There should not be any additional configuration required since it is eventually running on the same device, it's a matter of how it gets sent via avrdude
.
Ex: PC -> Arduino
vs PC -> ISP -> Arduino
should not require any board config changes, and avrdude
already supports this via -c usbtiny
.
Consider this use case: I am using a Nano or Uno R3 as a development board for my Rust embedded project. I get my prototype working and finalized, so then I develop a custom PCB that will use the Atmega 328p IC and no USB or UART (as it is a 'production' board). I still need a way to upload my code to the microcontroller, so a ISP of some kind will be necessary. And it seems I cannot do this with ravedude
today.
Of course I can use my shell script and use avrdude
directly but I think this is something that should be supported for production builds and deployments to real hardware.
@ewrogers Your discussing your issue on the right thread. I believe @Rahix has proposed an adequate solution via a new configuration file to solve both your problems, though not how you'd like, right? It sounds like you'd still prefer the command-line option or perhaps a config file section separate from the board which describes the programmer to use?
Yes, I think it can be useful for people who are in this situation and using an already supported board. It seems like it should be doable via a simple passthrough.
I like to avoid additional files when possible and not overly complex.
The config file Ravedude.toml
has now been implemented as of #522. Usbtiny support can now be added ontop I assume.
Would it be possible to add support for flashing via a USBtiny programmer? There's built-in support in avrdude, but it requires using the
-c usbtiny
command-line flag instead of specifying a serial port.