Arduino AVR High-Voltage Serial Programmer

My son Paul is the author of this guest post.

This Arduino sketch is useful for rescuing ATtiny microcontrollers rendered useless by incorrect fuse settings. It does this by putting the bricked tiny into high-voltage serial programming mode and writing the fuses to safe values.

Connection Diagram

Diagram

Click to enlarge

The Arduino is connected to the tiny though 1k resistors and a 2N3904 transistor is used to switch 12 volts applied to the tiny’s reset pin. After uploading the sketch the Arduino sends “Enter a character to continue.” repeatedly until communications are established by sending a byte through the serial monitor. The Arduino then programs the fuses.

Serial Monitor log

Enter a character to continue.

Enter a character to continue.

Enter a character to continue.

1

Entering programming Mode

lfuse reads as 62

hfuse reads as 5F

efuse reads as FF

Writing hfuse

Writing lfuse

lfuse reads as 62

hfuse reads as DF

efuse reads as FF

Exiting programming Mode

Download the program: hv_serial_prog.pde

Based on work by Jeff Keyzer.

Let me know if it works for you.

Comments

  1. R1-R5 = x Ohm ?

  2. If you need a 5 to 12V converter then you can design your own at:

    http://www.nomad.ee/micros/mc34063a/index.shtml

    with the standard MC34063A controller.

  3. Adding support for more Attinys ?

    // Defaults for ATtiny13

    HFUSE 0xFF
    LFUSE 0x6A

  4. André Delgado says:

    Excelent AVR Programer

  5. It works fine for me on a AtTiny45 ! Thank you so much.
    I’ve tried on an AtTiny15 (default fuse value = 0x50) with some tweaks in the ARduino sketch but it keeps sending back 0xFF. Then I remembered that RB3 and RB4 pins on AtTiny15 are swapped compared to ATTiny25 (hell, the Atmel guy who did it deserves tar & feather).
    So I rewired for Tiny15 and then… it doesn’t work either (the bricked AtTiny15 remains bricked).

    • Hobby it looks like the algorithm to enter the High-voltage programming mode is different on the AtTiny15 but the instructions to read and write the fuse bits are similar. I would first try commenting out read hfuse, read efuse, and write hfuse. Then try writing 0x5C instead of 0x50 as the fuse value. It appears the third and forth bits are part of the write instruction and need to be 1s. If that does not work try changing the sequence to enter programming mode to match the datasheet (page 56).

  6. So i’ve build this thing and testet it with a bricked ATTiny13 : I works at the first time.

  7. Use MAX662 to convert 5V into 12V. Needs only 2 capicators and no justage. DIL8 package.

    http://datasheets.maximintegrated.com/en/ds/MAX662A.pdf

    • Is that the other chip on your shield? That’s pretty neat Michael.

      • For my shield i have use the usual and cheap MC34063. But you need an bunch of other components to build this.

        I you don’t want to solder much the MAX 662 is a better solution although it is harder to get and much more expensive as the MC34063.

        • And:

          If you use the MAX662 you don’t need T1 and R6 anymore. You can connect R5 to the shutdown input of this ic. (No need to modify the code.)

          And the RESET input of the Attiny connects directly to the 12V output of the MAX662.

          • OK. You need a delay for minimal 400us after activating the programming voltage by your program to stabilize the 12V output of the MAX 662. (see data sheet).

  8. studioeng says:

    Hi, I’ve recently done the stupid thing of setting the wrong fuses on my Attiny85. I only have a Teensy++2.0 to work with and I’m having a job trying to ‘convert’ the pins to work with this. Any help would be much appreciated. Thank you.

    • Here is my best guess studio,
      Match up the green pin numbers on my connection diagram to the white silk screen numbers on your Teensy board as follows:
      Arduino – Teensy++ 2.0
      GND – GND
      13 – C3
      12 – C2
      11 – C1
      10 – C0
      9 – E1
      8 – +5v

      • studioeng says:

        Thank you for your reply.

        In the meantime while I was waiting for my post to be moderated I jumped in the deep end and wired it up. It all worked perfectly. If it helps anyone else, I used a 2N2222A transistor and a 12v power pack from a cheap USB->SATA/IDE converter and connected it following the pin numbers in the schematic. I have saved my first tiny85 :D happy days.

        I must admit I didn’t quite follow your post, are you indicating the connection pins between the Arduino and Teensy++ 2.0 or the equivalents between them? In my case I simply connected using the same Arduino pin numbers as the schematic and it worked perfectly.

        • Once you have a comment that contains your email that is approved, all subsequent comments that contain the same email will be posted immediately. See Comments Policy.

          Thanks for helping others by posting of your experiences.

        • Glad to hear you got things working studio. I am indicating the equivalency between the Arduino pins on the schematic and the Teensy++ 2.0.

          To be a little more clear:
          Attiny85 pin 2 connects to Arduino pin 12 or in your case Teensy++ 2.0 pin C2.
          Attiny85 pin 7 connects to Arduino pin 11 or in your case Teensy++ 2.0 pin C1.
          etc.

          Is this the way you wired it up? If not maybe a picture of the correct setup could help clear things up.

          I am getting these pin mappings from this picture, http://www.pjrc.com/teensy/teensyduino.html and a table http://www.pjrc.com/teensy/td_digital.html

  9. Hi,

    I wanted to thank you for this excellent work and programmer, which I used successfully to revitalize two “broken” attiny45. For the 12 V source, I used directly (without regulation) a wall plug adapter which provided ~ 12.5 V. I also used a BC337 as a switch transistor instead of the 2N3904. Thanks again for sharing your work like this !

    • Glad to hear it worked for you Thierry. It looks like the absolute maximum rating for the reset pin is 13 volts if someone has an odd value transformer.

  10. Thanks, this saved my butt

  11. hey , would this work on other atmel chips like atmega specially atmega8 ?
    thanks

  12. ATtiny84 wiring require more pins to be connected to GND:
    http://www.instructables.com/id/AVR-Attiny-fusebit-doctor-HVSP/step2/How-it-works/

    • I did it with an Attiny84 and it worked very well. I also read about the missing GND connections in the Datasheet.

      But at first it didn’t work, simply because of some loose pin connection.
      While I was searching for the Error I compared the Datasheets and it seems that the instruction sets for reading/writing the HIGH Fuse is different (The Attiny84 has some more fusebit settings), but luckily the Software isn’t depending on this and so I think almost every AVR with the High Voltage Programming feature should be programmable with this.

    • Paul Allsopp says:

      Thank you, I knew I was missing something.

  13. Works like a dream.

    An AVR is easily bricked while experimenting with the fuses. I fixed my ATtiny45 with your sketch. There is one gotcha though: the ‘Hello?’ is actually an invitation to the user to enter some key strokes, it is not the programmer being unable to see the ATtiny. I changed the text in my copy to ‘Enter a single character to continue …’.

    BTW: to give other visitors an idea what components to select, here is what I used:
    – 330E resistors for R1-R4 (limiting Arduino’s I/O-pin current to a safe 15mA)
    – 4k7 for R5 (limiting base current to little under a safe 1mA)
    – BC547B for T1 (most general purpose NPN will do)
    – An old 12V laptop power supply (check output voltage before use)

    Thnx for sharing unbricking tool :o)

  14. Bricked a tiny45 and tiny13 by setting /RESET to IO today.
    Thankfully I found your post and with the help of an Arduino Nano I easily could resurrect them again.
    Just had to change the default FUSE values.
    Thanks a lot!

  15. After bricking by ATTiny85 by setting it to 128KHz, I finally solved the problem by using a modified version of the ArduinoISP example sketch that uses slow software SPI. Was able to get it all the way down to 16KHz.

    I rewrote the sketch to be a bit slicker, now it gives boot time and serial configuration of your Arduino-as-ISP (hardware SPI @ 125KHz, or fully configurable software SPI). Modified sketch can be found here:
    http://pastebin.com/60xYhyq0

    Not to be deterred by success, the next day I went on to brick the same ’85 by disabling the RESET pin.

    Saved my butt. Thanks!

    jj

  16. Could you give me some insight to use your solution for microcontroleur programming (ATTiny85) not only rescuing. I whant to use RESET_PIN as IO_pin and download a sketch with high-voltage programming method.

    • High-voltage programming is not necessary in order to use the reset pin as an i/o pin. You can download a sketch and set the reset pin to i/o pin fuse using the normal programming method. If you need to make changes later on, then high-voltage programming is used to reset the fuses so the regular programmer can download the sketch again.

      If you really want to use high-voltage serial programming to download a sketch then the instructions to implement a full blown programmer are documented in section 20.6 in the ATtiny85 datasheet. They could be implemented in a similar fashion to read and write fuse bit instructions in my sketch.

  17. Very fine!

    Thank you very, very much!

    I built it as a shield. It works very good!

    Frank

  18. Hi!

    Really great work! I have juste save my ATtiny13A!

    But my problem wasn’t a fuse problem. I programmed a wrong clock prescaler so my programer won’t recognize the ATtiny cause of the too slow clock.
    So I modified your sketch, I just add few lines to make an Chip Erase, and wait for SDO goes to high:

    [...]
    //Write lfuse
    Serial.println(“Writing lfuse\n”);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x40, 0x4C);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, LFUSE, 0x2C);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x64);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6C);

    //Erase device
    Serial.println(“Erase device\n”);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x80, 0x4C);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x64);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6C);
    while (!digitalRead(DATAIN));

    readFuses();
    [...]

    Thanks a lot!

    • Mark Moran says:

      Thank you, Moot! The extra erase cycles just saved an ATtiny13A that I had given up on. I had previously used this tool successfully with that chip, but then I accidentally flipped the high and low fuses and got into a cycle where every read and write was inconsistent, so I assume I too ended up setting the clock speed to zero and not being able to recover without the erase.

  19. Thank you, Paul, for this useful post! I managed to salvage a bricked t45 from this;)

    I was however wondering if it would be possible to apply this to an m328p chip? I have used the fuse bit calculator http://www.engbedded.com/fusecalc/ to get the default values as:

    lfuse:0x62
    hfuse:0xD9
    efuse:0xFF

    my question is this; “How do I implement this into your program?”

    Thank you in advance

    Jesper

  20. where is the code?

  21. Thanks for this post!
    I accidentally programmed the RSTDISBL fuse on my ATtiny85. Your schematic + sketch worked great. Unlocked it in a second.

    As a note, the resistors for the pins are only needed to protect your Arduino\ATiny against incorrectly wired pins. I didn’t use them and it worked fine. But you still need the resistors for the transistor base and collector rails! Don’t forget them.

  22. Thomas Wang says:

    IT WORKED!!!!!
    I love you! you saved me a couple dollars. This is brilliant.
    Thanks.

  23. christophe says:

    Bonjour,
    Réalisation du montage suivant le schéma puis essai de programmation des fusibles sur un ATtiny85.
    Cela a parfaitement fonctionné.
    Merci

    Hello,
    Completion of installation and testing according to the scheme programming fuses on ATTINY85.
    It worked perfectly.
    Thank you

  24. The serial monitor isn’t outputting anything after “Entering Programming Mode”, I don’t believe it is reading the fuses on my ATtiny85 properly. Any ideas? I checked the circuit multiple times, everything seems to be in order.

  25. wonderful thank-you – worked first time

  26. You will be happy to note that the process is still a great success here in late 2013.

    Upgrading Windows to 8.1 provided some surprises when my USBASP programmer went astray. It hadn’t occurred to me sooner, but after several hours of trying to fix the ATTiny85, I dropped in a fresh one. It programmed, but on second upload, it also bricked. Then number 3 and 4 (while I was trying to get the programmer working right. ) I figured out what was happening, but exhausted my stock until your procedure came to the rescue.

    Thanks.

    Steve

  27. Sorry without luck on ATTINY85 and original Arduino Uno R3:
    Entering programming Mode

    lfuse reads as FF
    hfuse reads as FF
    efuse reads as FF

    Writing hfuse
    Writing lfuse

    lfuse reads as FF
    hfuse reads as FF
    efuse reads as FF

    Exiting programming Mode

  28. Paul Allsopp says:

    I would love to hear suggestions for both Alex’s and Radius’ questions as I have been experiencing both of these issues.

    • Paul Allsopp says:

      Sorry, adding email notify

    • In both case, (all fuses being read as FF, or no activity after “Entering Programming mode) seems to me to suggest a problem with the wiring to DATAIN (pin 11 on the Arduino, pin 7 on the target).

    • Hi Paul,
      Do the arduino serial examples work for you?

      • If you mean the hv_serial_prog.pde sketch linked above, yes. It has been a while though, I can’t say with 100% certainty whether or not I needed to modify the sketch in any way.

      • Paul Allsopp says:

        They certainly seem to, but always return before and after fuses of FF on all fuses. I have some new parts coming this week so I will try them. I used old parts and some were alternate parts, so I’ll wait on building a new one. Thanks for the awesome solution, regardless.

        Paul

        • Ah! I was confused by the two Pauls! ;)

          Paul A,

          If you’re seeing FF for all fuses, it means that pin 11 on your Arduino is always reading high. This probably means that pin 11 on your Arduino is not properly connected to pin 7 on the target, although that is not the only explanation. Bottom line though is that it has to be a circuit problem, or a completely dead AVR (which I have never actually seen… they are pretty tough little chips).

          – Double-check all the connections (are you doing this on a breadboard?)
          – Make sure you’ve got the right kind of transistor (almost any NPN will do, 2N2222, etc.)
          – Confirm all of the resistors are the correct value, although the only critical one is the one between the transistor and the 12V source.
          – Confirm that your 12V source is in fact 12V. This really has to be either a 12V regulated supply, or a 12V battery.

          The voltage MUST be between 11.5V and 12.5V, and be ‘clean’ i.e. no ripple. Do you have an oscilloscope to check it? You should know that most cheap 12V ‘wall-warts’ will likely deliver more like 16V when idling. Many don’t even have filtering of any kind, so will cycle between 0V and 17V, 60 or 120 times per second. These won’t do.

          • Paul Allsopp says:

            Thanks for the advice. I am using a wall wart, but have it running through a 12v regulator and a 100uF cap to clean it up and it seems smooth at 11.7v.

            I am trying to unbrick an attiny84 though, not a 25, so I may need to take another look at the datasheet for that and make sure my connections are good.

            Paul A.

            • Paul Allsopp says:

              [EDIT]

              OK, got it. CLOCK on ATT25 is PORTB3 but on ATT84 it is PB0. Once I moved the jumper wire to the correct pin I got:

              Entering programming Mode

              lfuse reads as C1
              hfuse reads as DF
              efuse reads as FF

              Writing hfuse
              Writing lfuse

              lfuse reads as 62
              hfuse reads as DF
              efuse reads as FF

              Exiting programming Mode

              …and I know I should be getting 62/FF for lf/hf so I know I’m good now.

              Thanks for the help guys!

  29. Thanks a lot! Worked like a charm.

    As an Attiny-starter I already bricked few Attiny85’s in attempt to set them to 128kHz-mode, which seems to make them un-programmable with Olimex AVR-ISP-mk2, I got them revived with this!

    https://www.dropbox.com/s/bs5bx47p6p5fwxh/_20140323_213113.JPG

    Although I used B547 because I didn’t have anything else at hand, but it seemed to work just fine.

    • HVSP is always an option, but be aware that your specific issue could have been solved by using a slower programming clock speed.

      ISP on an AVR requires that SCK (the programming clock) be < 1/4 of the target's clock speed. If you fused your '85 for 128 kHz, then you need a programming clock of < 32 kHz. If you left CKDIV8 programmed, you'd need < 4 kHz.

      I guess you're using avrdude with your Olimex AVR-ISP-mk2. You can reduce the programming clock speed by using the -B option. The default is a 1 microsecond bit-time, giving a 1 MHz clock.

      To set a < 32 kHz clock, you need about a 32 microsecond bit-time. Try -B 35

      To set a < 4 kHz clock, you need a bout a 250 microsecond bit-time. Try -B 300

      I've not used the Olimex AVR-ISP-mk2, it may not support use of -B. You could try -i instead with the same bit-time.

      • Thanks, you’re correct, it seems that -B 35 and -B 300 also work.

        Although, I still had use for HVSP because in one project I accidentally exchanged lfuse and hfuse and tried with few Attinys before realising :)

        Fortunately I was saved with this again!

  30. Please add into your schetch, before writing Hfuse

    //Chip erase
    Serial.println(“Erasing chip”);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x80, 0x4C);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x64);
    shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6C);

    If the lock fuses are enabled you cannot write fusebits without chip erase

  31. Thanks for the resource, I am new to electronics, so am I correct in assuming that the 12v source’s GND is common to the Arduino too?

  32. Paul Allsopp says:

    Can I ask what you guys are using to program your chips? I’m building some micro-drones as part of a wireless mobile sensor network, but cannot get anything onto the chips, using an Arduino as programmer. Has anyone successfully used an Arduino, and if so can you post your setup? Thanks to this blog I have learnt so much about these tiny monsters. :0)

    • The ArduinoISP sketch should work just fine. What are the symptoms you’re seeing?

      • Paul Allsopp says:

        After reading a bunch of related posts, I bought a programmer from MikroElectronica and that does the job just fine.

        I cannot connect it directly to the Arduino IDE, but I can use AVRFlash to push the hex to the chip once written from Arduino.

        One oddity I did notice though was that if I put the blink script on the chip, the delay time is increased by a factor of 10.

        Clock settings?

        • I’d guess more like a factor of 8. Maybe 16.

          New AVR ship configured to run at 1 MHz from the 8 MHz internal oscillator via the CKDIV8 fuse. I’d guess that you’ve got your Arduino IDE expecting a ‘board’ running at 8 MHz or 16 MHz. Check ‘Board’ under ‘Tools’.

  33. Is it working on a Attiny861 ?
    Has someone tested ?

    • Unfortunately, the ATtiny861 doesn’t support HVSP (high voltage serial programming). If you’ve programmed the wrong fuses and are no longer able to reach your ‘861 with a normal ISP programmer, then you’ll need a programmer capable of HVPP (high voltage parallel programming).

      This is possible with with an Arduino, but it is somewhat more complicated. Do a Google search for Arduino HVPP. The author Paul mentions one of the resulting links earlier in this page of comments. That link is:
      http://mightyohm.com/blog/2008/09/arduino-based-avr-high-voltage-programmer/

      You may not need HVPP. Depending on which fuses you’ve programmed into the ‘861, there may be much simpler ways to recover. Really the only ‘killer’ fuse is RSTDISBL. If you’ve programmed that, there is no alternative but HVPP. DWEN is also troublesome, but there are recovery methods which don’t require HVPP.

      If you’ve fused for an external clock source, or a low-frequency clock source, recovery may only require that you provide such a clock.

      You can find a version of ArduinoISP modified to provide an external clock here:
      http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=1035693#1035693

      An excellent tutorial on recovering from ‘fuse accidents’ is here:
      http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=106325&start=all&postdays=0&postorder=asc

      • Thank you very much for your quickest answer.
        I don’t know what happend with my Attiny861.
        After programming with PonyProg2000, i can’t recognize it, and i don’t know what to do.

        I tried with this method (arduino HVSP), but with no success.

        Thank you!

  34. Hi there

    Could someone please explain where I messed up here and provide a solution for me ?
    All worked like a charm regarding programming …Thanks Joey!
    Initially i used this line to make use of my reset pin on an ATTINY85
    avrdude -P COM15 -b 19200 -c avrisp -p attiny85 -v -e -U lfuse:w:0xE2:m -U hfuse:w:0x5F:m -U efuse:w:0xFF:m -U flash:w:85v1.cpp.hex
    THEN to recover the RESET pin I used the solution mentioned on this page..which worked as I can now re-program my ATTINY85.
    The only problem is I now have things working 8X (8 TIMES) SLOWER.
    So a delay(1000); actually ends up being 8 seconds long …eeeek!
    How do I solve this issue ?
    Please help
    Joe44

    • Anonymous says:

      Set the correct fusebits value. You compiled the hex for internat 8 MHz clock, but you set the fusebits at internal 1 Mhz Clock http://www.engbedded.com/fusecalc

    • (The avatar is of Rickety, not Joey)

      You’ve fused your ATtiny85 with the default fuse settings, which includes the fuse CKDIV8. This fuse causes the device to run with a system clock prescaler of 8 by preloading the CLKPR register after a reset.

      You can either unprogram CKDKIV8, or load the CLKPR register with the correct sequence to restore to a prescaler of 1.

      The default low fuse is 0x62. To unprogram CKDIV8 without changing anything else, write the low fuse as 0xE2.

      If instead you want to change CLKPR from your program, include the following code early in your program:

      CLKPR = (1<<CLKPCE);
      CLKPR = 0;

      The first line enables a change to the prescaler, while the second line changes the prescaler to 1.

      Make sure interrupts are disabled during those two lines.

  35. I used your code and instructions to get back a bricked Tiny85 the other day. I simplified things a bit, though, since I just had a one-off to do.

    I wired pins 2, 5, 6, and 7 to the same Uno pins (without the series resistors), wired 4 and 8 to ground and +5 from the Uno, and then took 12 volts from my bench supply and just applied that to pin 1 – no switching.

    From reading the other comments it appears that perhaps there is a more sophisticated dance involving the +12 required for some parts. But in my case, it just worked. I did make sure that the +5 supply was active both before and after the +12 volts.

  36. Hi, I want to thank you, yesterday I bricked 3 attiny85’s (playing with V-usb and bootloaders) and thanks to you, they are all working again! First it didn’t want to work, but then I noticed that I used 10k resistor as R6 instead of 1k (bad light, orange and red colour). When I replaced it, it worked as a charm. And I don’t have 2N3904 so I used BC548 without problems.

Trackbacks

  1. AlferSoft Blog » Revenge of the Tiny Pong VGA, now controlled with a single button says:

    [...] need to flash another firmware, you will need to reset the fuses using a High Voltage programmer; this one worked fine for me. AVR GNU toolchain is used for this project, so the code is written in GNU [...]

  2. Arduino rettet verfuste ATtinyss | www.franzis-arduino.de says:

    [...] Das Programm lässt sich Hier runterladen. [...]

  3. [...] High Voltage Programming circuit and software to fix the fuses. You can find a good write up this here.  So seeing that this must be a problem out here I made a Arduino shield up for this [...]

  4. Revenge of the Tiny Pong VGA, now controlled with a single button says:

    [...] need to flash another firmware, you will need to reset the fuses using a High Voltage programmer; this one worked fine for me. AVR GNU toolchain is used for this project, so the code is written in AN A [...]

Speak Your Mind