Pages: [1]   Go Down
Author Topic: Setting fuses on ATMega328AU(32TQFP) bricks the microprocessor.  (Read 1550 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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 smiley-cool.
  • Decided to update all the fuses to bring them to the "Arduino FIO" state: efuse=0x05; hfuse=0xDA; lfuse=0xFF.
Code:
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:
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:
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
    « Last Edit: November 24, 2012, 02:48:22 pm by denyska » Logged

    vermont
    Offline Offline
    Sr. Member
    ****
    Karma: 8
    Posts: 298
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    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.
    Logged

    Offline Offline
    Newbie
    *
    Karma: 0
    Posts: 4
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    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.
    Logged

    vermont
    Offline Offline
    Sr. Member
    ****
    Karma: 8
    Posts: 298
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    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.
    Logged

    Offline Offline
    Newbie
    *
    Karma: 0
    Posts: 4
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    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.
    Logged

    vermont
    Offline Offline
    Sr. Member
    ****
    Karma: 8
    Posts: 298
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    dupity dup
    « Last Edit: November 24, 2012, 08:31:16 pm by john1993 » Logged

    vermont
    Offline Offline
    Sr. Member
    ****
    Karma: 8
    Posts: 298
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    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.

    Logged

    Offline Offline
    Newbie
    *
    Karma: 0
    Posts: 4
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    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
    Logged

    vermont
    Offline Offline
    Sr. Member
    ****
    Karma: 8
    Posts: 298
    View Profile
     Bigger Bigger  Smaller Smaller  Reset Reset

    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.
    Logged

    Pages: [1]   Go Up
    Jump to: