I have been contemplating reprogramming the UNO 16U2 in order to reconfigure the board as a joystick (according to posts elsewhere in the Forum). I would like to make sure I can restore the 16U2 to its previous state to reuse the board or in case something goes wrong. How can I locate and save the existing 16U2 firmware before I reprogram it?
kstjohn:
I have been contemplating reprogramming the UNO 16U2 in order to reconfigure the board as a joystick (according to posts elsewhere in the Forum). I would like to make sure I can restore the 16U2 to its previous state to reuse the board or in case something goes wrong. How can I locate and save the existing 16U2 firmware before I reprogram it?
Just download the original code from the chip:
avrdude -c avrispmkii -p m16u2 -P usb -b 115200 -v -U flash:r:firmware.hex:i -U eeprom:r:firmware.eep:i -U hfuse:r:firmware.hfu:i -U lfuse:r:firmware.lfu:i -U efuse:r:firmware.efu:i -U lock:r:firmware.lck:i
Note: You may need to change the -c option (type of programmer), the -P option (the programmer port) and the -b option (programmer baud rate).
The command will produce files named "firmware.xxx" where "xxx" is "hex" (the main code), "eep" (eeprom contents), "hfu, lfu and efu" (fuse settings) and "lck" (lock settings).
If necessary, just burn these same files back into the chip and it should be restored to the exact state it started with.
Good luck.
(edit to add): Here's a Linux script that I use to read AVR chips. If you don't use Linux, you may be able to convert it to a Windows batch file - I don't know - but here it is:
#!/bin/bash
## case insensitive
shopt -s nocasematch
## $0 is the filename of the script (same as argv[0] in C)
if [[ ! $2 ]]; then {
echo
echo "usage: ${0##*/} filename chipname"
echo
exit 1
} fi
CHIP="$2" ## second command line parameter
PGMR="avrispmkii" ## programmer type
PORT="usb" ## programmer port
BAUD=115200 ## programmer baud rate
VERBOSE=1 ## higher=more info
BITCLOCK=3 ## make this larger or remove it if you get avrdude errors
FNAME=$1 ## first command line parameter
FNAME=${FNAME%%.*} # isolate filename w/o extension
ANS="N"
CMD="avrdude"
test -e $FNAME.hex
if [[ ${?} -eq 0 ]]; then {
echo
echo -n "$FNAME.hex already exists - overwrite? (yes/N) "
read ANS
} else {
ANS="yes"
} fi
if [[ "$ANS" == "y" ]]; then {
echo
echo "Type the full word \"yes\" to overwrite $FNAME.hex"
echo
exit 0
} fi
if [[ "$ANS" == "yes" ]]; then {
## uncomment this for a bit more info
## echo
## echo "${0##*/} set for $PGMR programmer and $CHIP on port $PORT"
## echo
test -e $FNAME.hex && rm $FNAME.hex
test -e $FNAME.eep && rm $FNAME.eep
test -e $FNAME.hfu && rm $FNAME.hfu
test -e $FNAME.lfu && rm $FNAME.lfu
test -e $FNAME.efu && rm $FNAME.efu
test -e $FNAME.lck && rm $FNAME.lck
CMD+=" -c $PGMR"
CMD+=" -p $CHIP"
CMD+=" -P $PORT$NUM"
CMD+=" -b $BAUD"
## avrdude verbose mode?
if [[ $VERBOSE -gt 0 ]]; then {
CMD+=" -"
while [[ $VERBOSE -gt 0 ]]
do
CMD+="v"
VERBOSE=$[ VERBOSE-1 ]
done
} else {
CMD+=" -qqq"
} fi
## bitclock defined?
if [[ $BITCLOCK ]]; then {
CMD+=" -B $BITCLOCK"
} fi
CMD+=" -U flash:r:$FNAME.hex:i"
CMD+=" -U eeprom:r:$FNAME.eep:i"
CMD+=" -U hfuse:r:$FNAME.hfu:i"
CMD+=" -U lfuse:r:$FNAME.lfu:i"
CMD+=" -U efuse:r:$FNAME.efu:i"
CMD+=" -U lock:r:$FNAME.lck:i"
## echo "$CMD"
$CMD
if [[ ${?} -eq 0 ]]; then {
echo
echo "+-----------------+"
echo "| === SUCCESS === |"
echo "+-----------------+"
echo
beep -f 880 -l 100;
beep -f 770 -l 100;
beep -f 660 -l 100;
beep -f 550 -l 100;
beep -f 440 -l 100;
beep -f 330 -l 100;
beep -f 220 -l 100;
exit 0
} else {
echo
echo "+-----------------+"
echo "| === FAILURE === |"
echo "+-----------------+"
echo
beep -f 440 -l 500;
beep -f 220 -l 500;
exit 1
} fi
} else {
echo
echo "Cancelled"
echo
exit 0
} fi
Thanks Krupski for the quick and detailed reply. Although I would classify myself as an experienced C programmer, I haven't quite figured out everything with the Arduino or AVR tools yet. I'll have to go find an AVR tool to use for the programmer - I use a Win7 platform. I was hoping there was a function built into the Arduino IDE that I was missing but guess not. Thanks again.
kstjohn:
Thanks Krupski for the quick and detailed reply. Although I would classify myself as an experienced C programmer, I haven't quite figured out everything with the Arduino or AVR tools yet. I'll have to go find an AVR tool to use for the programmer - I use a Win7 platform. I was hoping there was a function built into the Arduino IDE that I was missing but guess not. Thanks again.
The command line I posted was generated by my script. That command line (an AVRDUDE command) will work equally well in Windows. The script, however, will not.
All you have to do is click Start, then Run, then type "cmd". A black screen with white letters will open. That's a command line interface.
Then just copy and paste the command I posted into the window and press enter.
Of course as I said, edit the command line accordingly to match your hardware (for example, your COM port will be something like "COM3" rather than "usb").
That command line should run AVRDUDE, read the 16u2 chip and record all the stuff in the filenames I mentioned previously.
If you get a "Command or path not found" error message, that's because AVRDUDE.EXE isn't in your path. You'll have to find where it is and then type in the whole path.
For example, instead of just "avrdude" you may need something like "C:\Program Files\Arduino_105\hardware\tools\avrdude.exe" (wherever your AVRDUDE is - you'll have to find it).
When you're done, type "exit" and hit enter to close the command window.
Hope this helps.
AVRDude is what threw me. We use the console for a lot of background loaders and such but I wasn't familiar with AVRDude. I see the directory - I'll have to get into it now to see what it's doing. I really appreciate you're taking the time to point me in the right direction - thanks again!
I would like to revive this thread to gain some understanding and learn something, if somebody could please help.
In an earlier post Krupski said about making a backup of the original 16u2 code in preparation for doing some temporary play:
Just download the original code from the chip:
avrdude -c avrispmkii -p m16u2 -P usb -b 115200 -v -U flash:r:firmware.hex:i -U eeprom:r:firmware.eep:i -U hfuse:r:firmware.hfu:i -U lfuse:r:firmware.lfu:i -U efuse:r:firmware.efu:i -U lock:r:firmware.lck:i
Note: You may need to change the -c option...
My main question is: once I have done this and now have a hex and some fuse files, can you explain how to interpret the contents of the fuse files and form a correct avrdude command line to re-upload the hex file and restore the fuses?
Here is an example of what is in the fuse files as read from the UNO by avrdude using Krupski's example command:
$ cat firmware.lfu
:01000000FF00
:00000001FF
$ cat firmware.hfu
:01000000D926
:00000001FF
$ cat firmware.efu
:01000000F40B
:00000001FF
$ cat firmware.lck
:010000003FC0
:00000001FF
You could use:
objdump -s firmware.lfu
Output:
Contents of section .sec1:
0000 ff
That is, the low fuse is 0xFF.
Thanks, that is just what I needed.