avrdude
avrdude copied to clipboard
Attiny85: increase delay
More details at https://forum.arduino.cc/t/usbtinyisp-from-ide/263885
Related conversation with @MCUdude https://github.com/umbynos/avrdude/commit/7c18d4bdfc69bb576bdee0e8e56da91ecaf361f4#commitcomment-73300758
Co-authored-by: Martino Facchin [email protected]
Well, all these proposed values look pretty arbitrary to me.
The values that are currently in avrdude.conf reflect the numbers from the datasheet (or .atdf file), and they are pretty much the same (4 ms / 4.5 ms) for almost all newer AVRs. The chiperasetime
value is documented to only affect HVSP programming, which is completely irrelevant to the USBtinyISP device. (In fact, it's always 0 for all entries anyway, and stk500v2.c is the only consumer of that value.)
The EEPROM "delay" value (6 in the original, 12 in the patch, 5 in the current .atdf file) is again only used in the stk500v2.c parameter block, not affecting USBtinyISP in any way.
Finally, the patch only affects the ATtiny85, but what about its smaller siblings (ATtiny45, ATtiny25)?
While I have no doubt that these changes might have cured the symptoms of the person once submitting them, I think the actual issue must be somewhere else.
For reference, delays similar to this PR are already present in the current avrdude.conf file.
Here's a few: ATmega324P ATmega644 ATmega1284 ATmega64RFR2 ATmega128RFA1
Maybe we can ask the users whether they also encounter issues with similar chips like ATtiny45 and ATtiny25, Probably they will have the same issue and it is just because ATtiny85 is much more popular than the other two.
Maybe we can ask the users
@mcuee Where should this action take place? If you mean here, that post is from 2014.
BTW here's another report https://learn.adafruit.com/introducing-trinket/programming-with-avrdude
@mcuee Where should this action take place? If you mean here, that post is from 2014.
I mean in the general Arduino forum -- probably a new post to ask about ATtiny45 and ATtiny25 to see if they have the same problem like the ATtiny85 or not.
Can anyone here even reproduce the problem with the ATtiny85?
I can't, even using the same version of AVRDUDE and avrdude.conf
bundled with the Arduino IDE 1.0.5-r2 installation, on Windows 7, using the drivers provided by Adafruit in that Trinket tutorial. I don't have a Trinket so I'm using a USBtinyISP connected to an ATtiny85 running on the 8 MHz internal oscillator (the clock configuration of the Trinket), as was done by the user at https://forum.arduino.cc/t/usbtinyisp-from-ide/263885.
For reference, delays similar to this PR are already present in the current avrdude.conf file.
These are different families, which have indeed different delays described in their datasheet.
As argued above, the delays in this proposal look completely arbitrary, and most of them don't even affect the programming tool used. That's why I question the complete proposal, unless someone can describe a scenario how to reproduce a problem with the ATtinyX5. Personally, I have been using these ATtinys quite a bit in the past, and never encountered problems with them.
@ladyada would you or someone else from Adafruit mind checking whether this patch is still needed with the latest AVRDUDE from this repository to reliably upload to the Trinket and Gemma?
This patch originated from Adafruit: https://github.com/arduino/toolchain-avr/pull/21
Can anyone here even reproduce the problem with the ATtiny85?
I haven't used the ATtiny85 that much, but I've used the USBtinyISP programmer a lot with the ATtiny13, which was reported to have similar issues. I've never had any issues with the USBtinyISP when using the ATtiny13, and that's with "sensible" delay values.
It may be that @ladyada knows why the original ATtiny85-based Adafruit Trinket needs such large delays, and if this somehow has later been fixed. BTW does anyone know where I can find the source code for the Trinket bootloader?
does anyone know where I can find the source code for the Trinket bootloader?
Here it is: https://github.com/adafruit/Adafruit-Trinket-Gemma-Bootloader
our notes say
Because the USB bootloader is a little different than an off-the-shelf programmer, we have to update the configuration file to have a longer erase delay. This does not affect programming bare Attiny85 chips, so you can use this configuration file with Trinkets or raw chips without any problems.
probably this is due to USB transmission delays, we had timeout errors otherwise
But see my analysis above:
https://github.com/avrdudes/avrdude/pull/983#issuecomment-1156876317
Hi @dl8dtl, sorry for the delay, finally I had some time to carry on some tests.
I tried uploading to an Arduino Gemma with our patched version of the avrdude.conf
(which includes the patch we are trying to upstream with this PR). This is the result:
"/home/umberto/.arduino15/packages/arduino/tools/avrdude/7.0-arduino.3/bin/avrdude" "-C/home/umberto/.arduino15/packages/arduino/hardware/avr/1.8.99/bootloaders/gemma/avrdude.conf" -v -V -pattiny85 -carduinogemma "-Uflash:w:/tmp/arduino-sketch-61D4583461DF5011988F3D93F494BD0B/Blink.ino.hex:i"
avrdude: Version 7.0-arduino.3
Copyright (c) Brian Dean, http://www.bdmicro.com/
Copyright (c) Joerg Wunsch
System wide configuration file is "/home/umberto/.arduino15/packages/arduino/hardware/avr/1.8.99/bootloaders/gemma/avrdude.conf"
User configuration file is "/home/umberto/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : usb
Using Programmer : arduinogemma
avrdude: usbdev_open(): Found USBtinyISP, bus:device: 001:019
AVR Part : ATtiny85
Chip Erase delay : 400000 us
RESET disposition : possible i/o
RETRY pulse : SCK
Serial program mode : yes
Parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 12 4 0 no 512 4 0 4000 4500 0xff 0xff
flash 65 6 32 0 yes 8192 64 128 30000 30000 0xff 0xff
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
lock 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
lfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
efuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
calibration 0 0 0 0 no 2 0 0 0 0 0x00 0x00
Programmer Type : USBtiny
Description : Arduino Gemma. Based on USBtiny
avrdude: programmer operation not supported
avrdude: Using SCK period of 10 usec
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e930b (probably t85)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: 7 retries during SPI command
avrdude: Using SCK period of 10 usec
avrdude: reading input file "/tmp/arduino-sketch-61D4583461DF5011988F3D93F494BD0B/Blink.ino.hex"
avrdude: writing flash (682 bytes):
Writing | ##### | 9% 0.03savrdude: 8 retries during SPI command
Writing | ######### | 18% 0.07savrdude: 7 retries during SPI command
Writing | ############## | 27% 0.11savrdude: 8 retries during SPI command
Writing | ################## | 36% 0.14savrdude: 8 retries during SPI command
Writing | ####################### | 45% 0.18savrdude: 8 retries during SPI command
Writing | ################################ | 63% 0.25savrdude: 8 retries during SPI command
Writing | #################################### | 72% 0.29savrdude: 8 retries during SPI command
Writing | ######################################### | 81% 0.33savrdude: 8 retries during SPI command
Writing | ############################################# | 90% 0.36savrdude: 8 retries during SPI command
Writing | ################################################## | 100% 0.40s
avrdude: 682 bytes of flash written
avrdude done. Thank you.
And the uploaded code seems to work just fine on the board.
By only setting chip_erase_delay
back to 4500
, just like in the avrdude.conf
file in this repo, I get this:
"/home/umberto/.arduino15/packages/arduino/tools/avrdude/7.0-arduino.3/bin/avrdude" "-C/home/umberto/.arduino15/packages/arduino/hardware/avr/1.8.99/bootloaders/gemma/avrdude.conf" -v -V -pattiny85 -carduinogemma "-Uflash:w:/tmp/arduino-sketch-61D4583461DF5011988F3D93F494BD0B/Blink.ino.hex:i"
avrdude: Version 7.0-arduino.3
Copyright (c) Brian Dean, http://www.bdmicro.com/
Copyright (c) Joerg Wunsch
System wide configuration file is "/home/umberto/.arduino15/packages/arduino/hardware/avr/1.8.99/bootloaders/gemma/avrdude.conf"
User configuration file is "/home/umberto/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : usb
Using Programmer : arduinogemma
avrdude: usbdev_open(): Found USBtinyISP, bus:device: 001:017
AVR Part : ATtiny85
Chip Erase delay : 4500 us
RESET disposition : possible i/o
RETRY pulse : SCK
Serial program mode : yes
Parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 12 4 0 no 512 4 0 4000 4500 0xff 0xff
flash 65 6 32 0 yes 8192 64 128 30000 30000 0xff 0xff
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
lock 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
lfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
efuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
calibration 0 0 0 0 no 2 0 0 0 0 0x00 0x00
Programmer Type : USBtiny
Description : Arduino Gemma. Based on USBtiny
avrdude: programmer operation not supported
avrdude: Using SCK period of 10 usec
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e930b (probably t85)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: Using SCK period of 10 usec
avrdude: error: usbtiny_transmit: Broken pipe
avrdude: reading input file "/tmp/arduino-sketch-61D4583461DF5011988F3D93F494BD0B/Blink.ino.hex"
avrdude: writing flash (682 bytes):
Writing | | 0% 0.00s
avrdude: error: usbtiny_send: Broken pipe (expected 64, got -32)
Writing | ##### | 9% 0.00s
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 11 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 34 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 26 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 16 retries during SPI command
avrdude: 9 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 9 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 34 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 27 retries during SPI command
avrdude: 9 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 17 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 9 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 27 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 17 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 17 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 16 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 25 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 14 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 16 retries during SPI command
Writing | ##### | 10% 0.33savrdude: 8 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: 17 retries during SPI command
avrdude: 9 retries during SPI command
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
avrdude: error: usbtiny_receive: Broken pipe (expected 4, got -32)
Writing | ###### | 11% 0.36savrdude: 35 retries during SPI command
avrdude: 8 retries during SPI command
avrdude: 9 retries during SPI command
Writing | ################################################## | 100% 1.04s
avrdude: 682 bytes of flash written
avrdude done. Thank you.
and the board does not seems to work.
The interesting part is this one:
If I try to use the default avrdude.conf
present on this repo, with only this small addition:
programmer
id = "arduinogemma";
desc = "Arduino Gemma. Based on USBtiny";
type = "usbtiny";
connection_type = usb;
usbvid = 0x2341;
usbpid = 0x0c9f;
;
I get the exact same error.
This experiment led me to think that indeed we need that delay.
As @ladyada explained this is because that board do not use a programmer but instead when the mcu is powered on acts as a programmer itself for a few seconds using bit banging, after that runs the user program.
Infact the avrdude: 8 retries during SPI command
could be caused by this. I'm not knowledged enough about this topic. But at this point I think that that delay is required for that board to work properly.
Well, all these proposed values look pretty arbitrary to me.
Probably you are right about this, and I don't know all the back-story since I was not part of Arduino at that point.
Finally, the patch only affects the ATtiny85, but what about its smaller siblings (ATtiny45, ATtiny25)?
Probably yes, if they use the same kind of bootloader. Unfortunately I do not have these MCU to test things out.
Maybe a viable solution would be to add another entry in the avrdude.conf
to cover this use-case? Just like the guys from adafruit suggests: https://github.com/adafruit/Adafruit-Trinket-Gemma-Bootloader/blob/master/avrdude.conf.addition.txt
Of course I don't know if such thing would be accepted.
Thanks for the feedback, it's welcome.
My problem with changing any of that: these parameters are obtained from the Atmel definitions, and they are meant to apply to certain (Atmel-origin) programmers.
If any particular implementation cloning that protocol needs more time, in my opinion, it's the responsibility of that implementation to adapt the timing accordingly. So if a bootloader needs 200 ms instead of the 4.5 ms defined by the datasheet, they are free to simply implement a longer timeout (and/or completely ignoring the incoming parameter). If you attach it to an Atmel/Microchip Studio, and declare it being an STK500, they are passing the exact same values down *) as AVRDUDE does.
*) If not, it's indeed a bug in AVRDUDE. They are supposed to be the same.
It seems to me the right solution is to create a new programmer type called arduino-gemma
or (adafruti-gemma
) and then deal with it in usbtiny code as usbtiny is the parent. Hopefully it is possible to differentiate usbtiny with the gemma bootloader.
Ref: https://github.com/adafruit/Adafruit-Trinket-Gemma-Bootloader/blob/master/avrdude.conf.addition.txt
Or just have the USBtiny code not use STK500 values at all, instead use fixed values inside. It seems the critical value is the chip erase delay here.
Or just have the USBtiny code not use STK500 values at all, instead use fixed values inside. It seems the critical value is the chip erase delay here.
Good idea.
usbtiny_chip_erase()
has:
usleep( p->chip_erase_delay );
Just use any larger value there. @umbynos can you give it a try whether 100000 (µs) is already sufficient, or does it really have to wait for 400 ms?
Nope, with hip_erase_delay = 100000;
won't work, it seems to be the same error as with the default unpatched avrdude config:
out.txt
OK, then I suggest we simply change the wait time in the USBtiny implementation to 400 ms. There's no point for it to reuse the STK500 value if it just doesn't work for some implementations.
@umbynos Do you want to change your PR that way, or do you want me to suggest a new one instead?
@ladyada Is there any way to tell this bootloader apart from a real USBtiny programmer?
If so, the extension of the wait time could be made dependant on that.
@umbynos Do you want to change your PR that way, or do you want me to suggest a new one instead?
Since I don't know the codebase that well, maybe it would be better if you could suggest a new one instead.
So, the affected boards' bootloaders latch on to the -c usbtiny
protocol, which I believe has no handshake. For this to work, AVRDUDE would need to wait for the requests to have been processed on the board. A reasonable estimate for the time that a bootloader needs to emulate chip erase will probably be flash->num_pages * part->chip_erase_delay
. This assumes that an SPM page erase does not take longer than an SPI programming chip erase. BTW (as a side note) I wonder why the -c usbtiny
programmer gets initialised after the chip erase. Is that really necessary?
https://github.com/avrdudes/avrdude/blob/a5552f64cf0bea2a4f72e3a0dc90672d1bc2a18a/src/usbtiny.c#L636-L639
Going down the route of a computed chip erase time penalises large parts, eg, ATmega2560, when programmed with a proper usbtiny physical programmer, as the chip erase time would then be 10 s rather than the necessary 10 ms (or so). Maybe best to estimate needed delays with the target parts/boards, try them out and then use one fixed value that suits all target boards.
And also, have a look at the proposed urprotocol https://github.com/avrdudes/avrdude/discussions/940#discussioncomment-3017328, which is meant to help establish exactly what the bootloader is capable of. This should, if/once implemented into future AVRDUDE releases, enable boards like trinket to carry out happy bootloading with small resources (the corresponding prototype ATmega85 bootloader is 256 bytes albeit without EEPROM support).
flash->num_pages * part->chip_erase_delay
We now know that the ATtiny85 works with 400 ms delay, while it fails with 100 ms. Does that somewhat fit into this formula?
flash->num_pages * part->chip_erase_delay
We now know that the ATtiny85 works with 400 ms delay, while it fails with 100 ms. Does that somewhat fit into this formula?
128*4500 µs, so 576 ms. Considering it's an upper estimate and that the subsequent pgm->initialize(pgm, p)
will burn through one or more(?) 50 ms periods, the 400 ms look like it fits with the formula.
Future release fun: expr $(avrdude -p ATtiny85/st | grep num_pages | cut -f5 ) \* $(avrdude -p ATtiny85/st | grep chip_erase_delay | cut -f4 )
(this is how I actually found out)
But I wouldn't just use the formula. I would cap it somehow. For an ATmega2560 this results in a 9.2 s pause that is hard to explain to users that use an actual (physical) programmer that can do the job in that many ms.
I wish there were a method to tell a real USBtinyISP apart from a bootloader.
I suggest a solution that uses extended arguments (-x
) for larger delays than 400 ms, so any user who does use such a bootloader on a large device has a way to override it appropriately.
I wish there were a method to tell a real USBtinyISP apart from a bootloader.
@dl8dtl and @umbynos
If we just need to differentiate USBtinyISP and the Arduino Gemma bootloader, then there is a simple way -- to use different USB VID/PID.
USBtinyISP: https://github.com/avrdudes/avrdude/blob/main/src/usbdevs.h#L51-L55
// these are specifically assigned to USBtiny,
// if you need your own VID and PIDs you can get them for cheap from
// www.mecanique.co.uk so please don't reuse these. Thanks!
#define USBTINY_VENDOR_DEFAULT 0x1781
#define USBTINY_PRODUCT_DEFAULT 0x0C9F
Arduino Gemma Bootloader
programmer
id = "arduinogemma";
desc = "Arduino Gemma. Based on USBtiny";
type = "usbtiny";
connection_type = usb;
usbvid = 0x2341;
usbpid = 0x0c9f;
;