@westfw:
This is actually a bug in the bootloader.
I can't say how happy I am that you found it! I (probably) never would have figured out that r1 is zeroed out on power-up but not by a hardware reset. (I feel that it must be documented somewhere, but I haven't seen any Atmel AVR chip references other than doc8271.)
Anyhow, here's what I did:
I downloaded the optiboot source from
http://code.google.com/p/optiboot/. At the very beginning of main() in optiboot.c there are these lines:
// After the zero init loop, this is the first code to run.
//
// This code makes the following assumptions:
// No interrupts will execute
// SP points to RAMEND
// r1 contains zero
//
// If not, uncomment the following instructions:
// cli();
#ifdef __AVR_ATmega8__
SP=RAMEND; // This is done by hardware reset
#endif
// asm volatile ("clr __zero_reg__");
I uncommented the
cli() line and the
asm line. Since cli() is defined in the avr interrupt.h header, I added the following right after the #include
<avr/pgmspace.h> line:
#include <avr/interrupt.h>
Did "make atmega328" and burned the loader into UNO and other boards.
Now I observe that none of the "UNO breaker" programs in this thread seen ti be causing problems. (Whew.)
Tested with UNO as well as with Duemilanove and other FTDI-interface '328P boards on Centos 5.5 Linux and Windows XP workstations.
Regards,
Dave
Footnote:Get the source tree from
http://code.google.com/p/optiboot/source/checkout,
not the zip file. This is important!
Then...
With avr-gcc Version 4.3.4, the code size was too large until I modified the LDFLAGS line in the Makefile as follows:
# Original LDFLAGs resulted in code size greater than 512 bytes
# with avr-gcc version 4.3.4
# Added -nostdlib to make it fit
# davekw7x
#override LDFLAGS = -Wl,$(LDSECTION) -Wl,--relax -nostartfiles -Wl,--gc-sections
override LDFLAGS = -Wl,$(LDSECTION) -Wl,--relax -nostartfiles -Wl,--gc-sections -nostdlib