It isn't a timing issue and adding/modifying delays is the wrong way to address this issue.
This is a an outstanding bug in avrdude.
It is due to the way avrdude and libusb handle the USB bus.
I reported this a long time ago - back in 2011, but am unable to get the avrdude author to fix it.
He doesn't like the 6 line patch.
See these bug reports for more details:
Here is the savanah bug report for avrdude:
While I reported this for the AVR dragon, it also applies to other Atmel devices.
Here is the bug reported to the Arduino bug list:
https://code.google.com/p/arduino/issues/detail?id=650&q=AVR%20dragon
And here it is on the new github issues list:
opened 06:43PM - 15 Nov 12 UTC
This is [Issue 650](http://code.google.com/p/arduino/issues/detail?id=650) moved… from a Google Code project.
Added by 2011-09-22T20:33:15.000Z by [bperry...@gmail.com](http://code.google.com/u/107476669756743351267/).
Please review that bug for more context and additional comments, but update this bug.
Original labels: Type-Defect, Priority-Medium
### Original description
When attempting to burn a bootloader using either the IDE Burn Bootloader option
or any of the Makefiles down in the hardware/arduino/bootloaders/xxx
the fuses will be burned and the flash erased but the bootloader is not burned
resulting in a non operational chip.
This behavior is easily reproducible on both windows and Ubuntu linux.
It is probably an issue other OSs and
potentially an issue with other USB ISP programmers.
This is not a permissions issue or a libusb installation/configuration issue.
This is due to an interaction between how the burning tool
(IDE or Makefile) is using avrdude, avrdude itself, libusb and the OS.
The crux of the problem is that two avrdude commands are being used to burn
a bootloader. One command to set the fuses and erase the flash and another
to burn the bootloader to the flash.
The 2nd avrdude command is failing because it can't locate the USB device.
Digging deeper, the problem is that when the avrdude command finishes
using the USB device, it resets the USB device.
This reset cause the USB device to have to go
through enumeration again. This enumeration takes time. If another avrdude
command runs before the enumeration is complete, it will not see the USB
device on the USB bus.
The reset cannot be removed because for some reason if the USB device is
not reset, it will fail to communicate properly. There is probably some
other issue either in the OS or libusb itself that is causing this issue.
In my view this really is an avrdude command issue or at least an
issue that avrdude could resolve.
I went so far as to enter a bug for it on savannah:
https://savannah.nongnu.org/bugs/?34339
So far, it was not well received as the avrdude maintainer
considers this to be an OS issue rather than an avrdude issue.
There are some options to work around this.
1. add a blind delay between the two avrdude commands (in IDE and Makefiles)
2. Update the avrdude code to poll for the devices for a few seconds
rather than just look one time.
3. Alter the IDE and Makefiles to use a single avrdude command rather than two.
arduino/Arduino#1)
Currently, it looks like there already is a 1 second blind delay in the IDE
code down in AvrdudeUploader.java in the burnBootloader() function.
The problem is that 1 second is not long enough.
From my experimentation on some of my machines, on Ubuntu 10.10
2 seconds seems to work. While I didn't fully test this
on Windows to find the exact time needed,
I can say that on my older 1.6Ghz Dell, it takes longer
than 2 seconds for the enumeration to complete.
The problem with these blind delays is that it slows down things for everyone
since the full wait is always done and there is no way to really know what
the best value to pick is.
arduino/Arduino#2)
It is possible to modify the avrdude code to be smarter to try to
poll "a while" looking for USB devices rather than just look one time.
I modified the code in usb_libusb.c to do this (it is only 7 lines of code)
and placed a patch for it in the savannah bug noted above.
This update works great, it polls the USB every 1/10 of second until
it finds the desired USB device - using a maximum delay of 3 seconds
(Probably should up this to 5 seconds.)
The nice thing is it will now only delay as long
as needed and only the full time if truely there is a problem. On my Ubuntu 10.10
machine the delay is just over 1 second.
But given the initial reception for updating avrdude to compensate
for the USB device behavior, this type of change probabaly will not be
accepted or at least may be well beyond the uno 1.0 release timeframe.
arduino/Arduino#3)
Perhaps the best way to deal with the issue is to avoid it
completely by changing things to burn the fuses and the bootloader
in a single avrdude command.
It is a vary small change to modify the java code and the Makefiles
to use a single avrdude comman rather than two.
Not only will doing this avoid the issue, but it will speed up
the bootloader burning process by avoiding the overhead of a blind
delay and the overhead of a second avrdude command.
It may also help in some cases with AutoReset issues on non USB
devices as there will no longer be a port close and re-open between
setting the fuses and burning the bootloade since it would all
now be done with a single call to avrdude.
I modified the optiboot Makefile in westfw's latest optiboot working tree
to do this as an example.
(See attachment). It was a very small change and this change
can and probably should be propagated through all the other Makefiles as well.
It is very simple and impacts no other code.
The JAVA code can easily do the same.
So down in burnBootLoader() rather than call avrdude() and then
Thread.sleep(1000)
Just build up a single List for both the fuses and the bootloader
I've attached an untested attempt at what that could look like.
It is such a small easy to fix thing, yet I was unable to get the fix in the main line code.
I patch the avrdude code and build my own version.
It would be nice if the Arduino team could patch it in their release since Joerg won't fix it in the mainline code.
As an alternative the IDE could do its programming in a single avrdude command rather than 2. This also solves the issue since it avoids the avrdude bug.
Every few years I bring it up, but can't seem to get it fixed.
The irony is that it primarily affects Atmel products like the AVR dragon, and MK series programmers/debuggers.
So sad.....
I guess I'll poke Arduino team again to see if we can get this fixed.
--- bill