Go Down

Topic: Setting fuses on ATMega328AU(32TQFP) bricks the microprocessor. (Read 1 time) previous topic - next topic

denyska

Nov 24, 2012, 08:15 pm Last Edit: Nov 24, 2012, 08:48 pm by denyska Reason: 1
Hi all,

I have custom built board on ATMega328AU that I am trying to upload bootloader with AVRISPmkII. It powered with 3v3 and has 8Mhz external crystal. It is similar to the "Arduino Fio" board except it uses ATMega328AU instead of ATMega328P that I believe differs only in pico-power and signature. I went ahead and created record in avrdude.conf for "atmega328au" by copying completely ATmega328P section and changing signature "0x1e 0x95 0x0F" => "0x1e 0x95 0x14" and id to "atmega328au".

Steps:

  • Verified with avrdude that default fuses per datasheet are set. efuse = 7; hfuse = D9; lfuse = 62;  

  • Set unlock bits and wrote efuse.
Code: [Select]
avrdude -v -v -v -v -patmega328au -cavrispmkII -Pusb  -e -Ulock:w:0x3F:m -Uefuse:w:0x05:m
........
avrdude: safemode: efuse reads as 5
avrdude: safemode: Fuses OK
avrdude: Sent: . [11] . [01] . [01]
avrdude: Recv: . [11] . [00]

avrdude done.  Thank you.

  • Played with device by uploading various sketches directly with programmer. Everything worked just fine. Except the fact that timing was wrong (attributed to CKDIV8 fuse that divided internal RC Oscillator @ 8MHz by 8).

  • Decided to update all the fuses to bring them to the "Arduino FIO" state: efuse=0x05; hfuse=0xDA; lfuse=0xFF.

Code: [Select]
avrdude -v -v -v -v -patmega328au -cstk500v2 -Pusb -t -U efuse:w:0x05:m -U hfuse:w:0xDA:m -U lfuse:w:0xFF:m
………

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0x05:
……..
avrdude: 1 bytes of efuse verified


avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xDA:
………..
avrdude: 1 bytes of hfuse verified


avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
……………
avrdude: 1 bytes of lfuse verified


avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [00] ? [ff] . [00]
avrdude: safemode read 1, lfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [00] ? [ff] . [00]
avrdude: safemode read 2, lfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [00] ? [ff] . [00]
avrdude: safemode read 3, lfuse value: ff
avrdude: safemode: lfuse reads as FF
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [ff] . [00]
avrdude: safemode read 1, hfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [ff] . [00]
avrdude: safemode read 2, hfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [da] . [00]
avrdude: safemode read 3, hfuse value: da
avrdude: safemode: Verify error - unable to read hfuse properly. Programmer may not be reliable.
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [00] ? [ff] . [00]
avrdude: safemode read 1, lfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [00] ? [ff] . [00]
avrdude: safemode read 2, lfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [00] ? [ff] . [00]
avrdude: safemode read 3, lfuse value: ff
avrdude: safemode: lfuse reads as FF
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [da] . [00]
avrdude: safemode read 1, hfuse value: da
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [da] . [00]
avrdude: safemode read 2, hfuse value: da
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [da] . [00]
avrdude: safemode read 3, hfuse value: da
avrdude: safemode: hfuse reads as DA
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [08] ? [fd] . [00]
avrdude: safemode read 1, efuse value: 5
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [08] ? [fd] . [00]
avrdude: safemode read 2, efuse value: 5
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] P [50] . [08] ? [fd] . [00]
avrdude: safemode read 3, efuse value: 5
avrdude: safemode: efuse reads as 5
avrdude: safemode: Fuses OK
avrdude: Sent: . [11] . [01] . [01]
avrdude: Recv: . [11] . [00]

avrdude done.  Thank you.


Command executed successfully. However this output makes me suspicious.

avrdude: safemode read 1, hfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [ff] . [00]
avrdude: safemode read 2, hfuse value: ff
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] . [00] X [58] . [08] ? [da] . [00]
avrdude: safemode read 3, hfuse value: da
avrdude: safemode: Verify error - unable to read hfuse properly. Programmer may not be reliable.




  • However, when I run avrdude again it bombs

Code: [Select]

avrdude: Sent: . [10] . [c8] d [64] . [19]   [20] . [00] S [53] . [03] . [ac] S [53] . [00] . [00]
avrdude: Recv: . [10] . [c0]
avrdude: stk500v2_command(): command failed
avrdude: Sent: . [03] . [a1]
avrdude: Recv: . [03] . [00] . [00]
avrdude: stk500v2_program_enable(): bad AVRISPmkII connection status: Unknown status 0x00
avrdude: initialization failed, rc=-1
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
avrdude: Expected signature for ATMEGA328AU is 1E 95 14

I am able to read fuses and lock bits only in terminal mode with -F flag. Fuses suddenly became :
efuse=0x05; hfuse=0xFF; lfuse=0xFF and disabled SPIEN fuse bit. Write operations on fuses and lock bits fail now.

Code: [Select]

avrdude -v -v -v -v -patmega328au -cavrispmkII -Pusb -tF
..........

>>> d lock
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] ? [ff] ? [ff] ? [ff] ? [ff] . [00]
0000  3f                                                |?               |

avrdude> d efuse
>>> d efuse
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] ? [ff] ? [ff] ? [ff] ? [ff] . [00]
0000  07                                                |.               |

avrdude> d hfuse
>>> d hfuse
avrdude: Sent: . [1d] . [04] . [04] . [00] X [58] . [08] . [00] . [00]
avrdude: Recv: . [1d] . [00] ? [ff] ? [ff] ? [ff] ? [ff] . [00]
0000  ff                                                |.               |

avrdude> d lfuse
>>> d lfuse
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] ? [ff] ? [ff] ? [ff] ? [ff] . [00]
0000  ff    


avrdude> w lfuse 0 0x62
>>> w lfuse 0 0x62
......
avrdude (write): error writing 0x62 at 0x00000, rc=-6
avrdude: Sent: . [1d] . [04] . [04] . [00] P [50] . [00] . [00] . [00]
avrdude: Recv: . [1d] . [00] ? [ff] ? [ff] ? [ff] ? [ff] . [00]
avrdude (write): error writing 0x62 at 0x00000 cell=0xff






Is there anything obvious that I am doing wrong? I already locked several microprocessors this way.
Any suggestions and recommendations are helpful.

Regards, Denys

john1993

what i see missing in your command line is the "-u" option wich tells avrdude not to put the fuses back the way they were (aka safemode). if im not mistaken w/o this the fuses are not programmed. this dont really explain things from your description but double check this in the manual.

afaik the only two things that can brick a 328 are reset disable bit and a wrong clock bits. reset disable can only be fixed with 12v programming (dragon, stk500, etc) or jtag on chip that have that. bad clock bits can usually be fixed by suppying an external signal to the crystal input pin. you can use a 555 chip, a crystal oscillator, or, like i did, the 1khz calibration output on my scope. if its a really slow signal like that you must tell the programmer to slow way down but it works.

denyska

Hi John,

thank you for the reply.


what i see missing in your command line is the "-u" option wich tells avrdude not to put the fuses back the way they were (aka safemode). if im not mistaken w/o this the fuses are not programmed. this dont really explain things from your description but double check this in the manual.



I was running the same avrdude command against "Arduino Fio" and it worked just fine.


afaik the only two things that can brick a 328 are reset disable bit and a wrong clock bits. reset disable can only be fixed with 12v programming (dragon, stk500, etc) or jtag on chip that have that. bad clock bits can usually be fixed by suppying an external signal to the crystal input pin. you can use a 555 chip, a crystal oscillator, or, like i did, the 1khz calibration output on my scope. if its a really slow signal like that you must tell the programmer to slow way down but it works.

I was under impression that  SPIEN(2) can lock it as well.

john1993

the manual and my own experience indicate -u must be used to change fuses (or else its a fuse in my brain that blew. lol). it might be a good idea to look that up in the manual and tell us what you found as others might be confused on this.

spien cannot be changed with your type programmer. only 12v will do it. and it has no effect on the ability to download via the bootloader. so it cant brick your chip.

denyska

John,

avrdude works just fine with "Fio" with and w/o "-u" parameter.

I checked the source code of avrdude (https://github.com/arduino/avrdude/blob/master/main.c) and  -u aka "safemode" is all about checking on every step before proceeding to the next  that fuses/lock bits/memory is what it intended to be.

john1993

#5
Nov 25, 2012, 02:29 am Last Edit: Nov 25, 2012, 02:31 am by john1993 Reason: 1
dupity dup

john1993

i finally got home and checked docs from the last few downloads (savana, sourceforge, github, etc) which all said:

Quote
-u
Disables the default behaviour of reading out the fuses three times before
programming, then verifying at the end of programming that the fuses have
not changed.  If you want to change fuses you will need to specify this
option, as avrdude will see the fuses have changed (even though you wanted
to) and will change them back for your "saftey".  This option was designed
to prevent cases of fuse bits magically changing (usually called safemode).


just for yucks i tried no -u with current installation and no fuse change. obviously you have a different version than mine. apparently there are some VERY queer distibutions floating around as i found out the hard way in a recent thread (http://arduino.cc/forum/index.php/topic,133005.0.html). in fact ive now collected 3 variations that clearly function differenty but all labeled 5.11.1. looks like you got one that was "customized" with oddball safemode code. in any case this is definitely unrelated to your problem which, if your description is accurate, indicates a really deviant copy of avrdude or seriously defective avr chip. my suggestion at this point is get a new 328 and download a more "official" copy of avrdude. ie one that complies with the docs. it will probably get you back on track. lets hope anyway.


denyska

John,

I tried AVRStudio on the Windows machine and by the cost of one more microprocessor I found the problem: lfuse (responsible for the clock) doesn't work properly with external 8Mhz crystal (0xFF for the lfuse). Will try to restore it with scope/oscillator on 8Mhz.


Good lesson learned: play with fuses bit by bit, don't set them in the batches.

thanks for the help

john1993

aha... mystery solved. i have a box of dead avr chips and every few months i dig them out and restore. almost always they come back to life with the ext clock trick. for the rare case where i goofed up rstdisbl i may have to pull out the 12v programmer. if you dont have one and no spares it pays to be careful w/fuses. i find it better to use a couple hex bytes to designate fuses rather than those gui menues with checked boxes but it depends on the dev environment i guess. good luck.

Go Up