I used the AVR Dragon to extract the contents of the flash memory (
avrdude -P usb -c dragon_jtag -p atmega1284p -U flash:r:flash.img:r
) and compared it against the saved raw image file using the linux split
and cmp
commands. Sure enough, three pages of flash memory were set to 0xFF
, probably from some erroneous page clear operation. Brown-out detection was disabled by the fuse settings to save power. Big mistake! What I think happened was as the voltage dipped below its valid range the microcontroller started executing random commands, including 3 SPM page clears, one of which was the first page of flash which holds the interrupt vector table. Valid execution was doomed.What I should have done was to enable brown-out detection in the fuses, 2.7V seems the most appropriate setting for an 8MHz clock and 3.3V operation. To save power during sleeping the brown-out detection can be disabled with a call to
sleep_bod_disable()
. Lesson learned!
Good post.
ReplyDelete