High-Voltage FLASH Programming on ATTINY85

The Bubblegum Chip, Now With Steroids!

The Atmel ATTINY85 is a great chip (cheap, easy to use, supported in the Arduino IDE).  Unfortunately it only has 5 IO pins, which limits its usability.  There are guides on using a High-Voltage Programmer (HVP) to change the Reset pin into an IO pin.  However, that prevents you from programming the Flash (Program Memory) until you re-enable the Reset pin.

Thankfully the Flash can be programmed with an HVP, but the commands and protocol are different.  My USBtinyISP simply cannot be modified to be an HVP.  Using an Arduino as ISP (In-Service Programmer) on an ATTINY85 is fairly simple but doesn’t work if the Reset pin is disabled.

Datasheet To The Rescue!

The datasheet describes the protocol for high-voltage programming (pp. 158 – 160).  Sadly, not everything about the protocol is clear and there is at least one error!

I decided to use the ArduinoISP sketch as a starting point.  The sketch is included with the Arduino IDE (File -> Examples -> Arduino as ISP).  Then I edited the protocol to use the HVP protocol described in the datasheet.  Bingo!

Step 1 – Hardware

There are already several guides on building an HVP.  I’ll leave a link here to Paul Willoughby’s page on the topic (who, in turn, credits Jeff Keyzer).  He describes how to set the fuses on an ATTINY85 using an HVP.  Thanks Paul!

Paul Willoughby's HVP Circuit
Paul Willoughby’s HVP Circuit

The same HVP circuit is shown on several websites.  What doesn’t seem to be common is using the HVP to program the Flash.  I built an HVP on perfboard using 6x 1K resistors, a PN2222A transistor, and a 5V- 12V boost converter from eBay (you can use any voltage source 11.5 – 12.5 V).  Below is an example HVP setup with an Arduino Uno.

If you don’t want to wire up the HVP on a breadboard or perfboard, look at Jeff Keyzer’s HV Rescue Shield.

Step 2 – Uploading A Sketch (Programming Flash)

My modified sketch is available at https://github.com/td0g/ArduinoHVP.  Simply upload it to the Arduino Uno / Nano that you are using in the HVP.  Now you can upload sketches to the ATTINY85 with the HVP by selecting Tools -> Programmer -> Arduino As ISP.

Step 3 – Setting The Fuses (Disable Reset, etc.)

The fuses in the ATTINY85 affect several areas of functionality (Datasheet pp. 148,149).  The most useful settings are:

  • Reset pin functionality (the whole purpose of the high-voltage flash programmer!)
  • Clock rate (1MHz vs 8MHz)
  • EEPROM preserve during Flash programming (by default the EEPROM is erased when Flash is programmed)

Paul already described how to set the fuses in his page.  I included a tool to set the fuses in my program as well.  To use it, simply open a Serial console (19200 Baud) and type ‘Z’.  Finally, enter your desired fuse settings.  Done!

My Programmer

Here’s a few photos of my programmer.  It’s a fairly useful board that straps onto an Arduino Nano.

Arduino As ISP For ATTINY85 ATMEGA328P

It can be used to program an ATMEGA328P and ATTINY85 (standard AND high-voltage programming).  I use a few different sketches on the Nano depending on what’s needed:

  • ArduinoISP – This sketch is useful for programming an ATMEGA328P or ATTINY85 without burning a bootloader.  It’s also come in handy to program a stubborn ATTINY85 when my USBtinyISP fails.
  • Nick Gammon’s ATMEGA toolkit – If you use ATMEGA328P microcontrollers in your projects, go get Nick’s board programming tools NOW!  I use them to burn bootloaders on my microcontrollers.
  • ArduinoHVP – What this whole post was about.

ATTINY85 High-Voltage Programmer

Thanks for reading!

7 thoughts on “High-Voltage FLASH Programming on ATTINY85”

  1. This would work with a Attiny84A? I want to enable/disable reset which needs a HVP ony for that. But everyone talks about using ISP, and then change fuses… That means i have to use 2 different programmers to do the job, one for ISP and the other for the fuses. While if i have a HVP i can do everything from the same place 🙂

    • Hi, sorry for the delay… I’m not really sure, one would need to review the datasheets to see. I have no experience with the 84A to give a quick answer. Sorry!

  2. Hi, thanks for sharing your good work. Exactly what I was looking for 😉
    Using a poor man’s charge pump circuit to generate the 12V from USB 5V, with only 3 signal diodes, 3 caps, 1 zener diode, and a few more instructions in ISR sketch, I managed to program a Attiny13 through HVSP with a simple arduino nano.
    My goal was to gain 1 more pin (+20%), but fuses are different on Attiny13. Working on that

    My changes to fuses.ino weren’t even necessary. Modifying boards.txt of Microcore-master (I use this one for ATtiny13), I realized the fuses can be set by HVSP from Arduino IDE. Really, it works! (still don’t understand fully why 🙁
    – A dozen lines more in your code, _fuse.ino is’nt even necessary with the changes in boards.txt
    – Nano board + 3*100n caps, 3*1N4148 , 12V zener (tested on breadboard)
    and you have a fully working HVSP programmer (at least for ATtiny13 I’m using: one I/O pin -20%- more, that’ just what I wanted)

  4. Hey, great job.
    This helps me with programming an ATtiny with external LF crystal and difference ADC on RES pin.
    I spent some time, since my avrdude sends commands which are not prepared in your universal().
    Maybe because I use a quite old version (5.10)?
    It always (if I tried to prgramm flash or reading fuses) ended with
    avrdude: stk500_cmd(): programmer is out of sync.
    The last message from avrdude to the HVPROG was “56 A0 01 FC 00 20” what looks like EEPROM read command. I couldn’t even find the particular command in the data sheet (it’s only mentioned with A0 00 .. ..).
    Anyway, adding another elseif did the job:

    else if (buff[0] == 0xA0){
    writeHV(buff[2], 0x0C);
    writeHV(buff[1], 0x1C);
    writeHV(0x00, 0x68);
    breply(writeHV(0x00, 0x6C));

    Since I use a Digispark instead of plain ICs, I needed to add some more delay after turning VCC on (I guess because of some capacitors on the PCB).
    So, in start_pmode() I have in total 400 us between
    digitalWrite(VCC, 1);
    digitalWrite(RST, 0);

    One issue is still left, first time after connecting the HVPROG, I get a
    avrdude: stk500_getsync(): not in sync: resp=0x15

    Checking the details, avrdude sends “30 20” but the HVPROG answers “15 15”, maybe a timing issue and the HVPROG cannot manage to receive the “30” but only the “20”?. But after the second try it works always flawlessly.



Leave a Comment