Simple and Cheap Fuse Doctor for Attiny

Published

Introduction: Simple and Cheap Fuse Doctor for Attiny

About: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I like. Other than my hobbies that involves grassroots medicine in S.E.&P Asia. I have bu...

When you are working with Attiny's like the Attiny 85 or the Attiny13, it is bound to happen sooner or later: you brick your Attiny.
I got faced with it while trying to burn a bootlaoder (i.e. setting the correct fuses), that I suddenly got the dreaded 'Yikes! Invalid device signature' error message. As I had just succesfully burned it on IDE1.06 and now was trying on IDE1.6.3, just to see if I installed everything OK, I knew the chip was OK and that my programmer was OK. Also, a new chip did well, so something ominous must have happened to my chip.

Could it be because my computer had some memory problems during the burning???
Well, not much choice but to try and reset my Attiny85.
For that you need a Serial High Voltage Programmer. Plenty of circuits to find, so no way I claim to be original here, but I am writing this ibble to take away any hesitation that people might have by showing how quick and easy it is.

All it takes are 6 resistors, a transistor, a DIL foot, a 9x20 piece of stripboard and a 7-pins male header and of course a 12 Volt supply. And yes, A UNO to stick it in.

As I didnt expect to use the programmer very often, I planned to use a battery, but as I couldnt find my 12 Volt battery, I ended up using a 0.75 USD (so 75 dollarcents) 5 to 12 Volt converter from aliexpress, that i had for another project.

I used the program below. The program starts when you send a random character to teh serial port. As it turns out, it was a fuse problem in my chip as the fuse bits were E4 DF which means it was set for 128 kHz oscillator. Not sure how that could happen as I removed that choice from my menu in the boards.txt file.
Anyway, it reset the fuses to factory setting and after that I could use my Attiny85 again.
Sadly, in order to build this unbricker, I had to use the 1k resistors I wanted to use for the very project I was programming the Attiny for :-) Oh well!!
All in all took me less than an hour to put it together So if you are having problems with your Attiny13/25/45/85 build one of these.
If you want to unbrick the 24/44/84 series, you need a bigger DIL Foot.
If you are trying to unbrick an Attiny15.. then remember that that has PB3 and PB4 switched compared to the 13/25/45/85 series, so you probably need a software or hardware change (Tar and feathers for the Atmel designer who did this)

// AVR High-voltage Serial Fuse Reprogrammer<br>    // Adapted from code and design by Paul Willoughby 03/20/2010
    //   <a href="http://www.rickety.us/2010/03/arduino-avr-high-voltage-serial-programmer/" rel="nofollow"> http://www.rickety.us/2010/03/arduino-avr-high-vo...</a><br>    //
    // Fuse Calc:
    //   <a rel="nofollow">http://www.rickety.us/2010/03/arduino-avr-high-vo....</a>
    #define  RST     13    // Output to level shifter for !RESET from transistor
    #define  SCI     12    // Target Clock Input
    #define  SDO     11    // Target Data Output
    #define  SII     10    // Target Instruction Input
    #define  SDI      9    // Target Data Input
    #define  VCC      8    // Target VCC
    #define  HFUSE  0x747C
    #define  LFUSE  0x646C
    #define  EFUSE  0x666E
    // Define ATTiny series signatures
    #define  ATTINY13   0x9007  // L: 0x6A, H: 0xFF             8 pin
    #define  ATTINY24   0x910B  // L: 0x62, H: 0xDF, E: 0xFF   14 pin
    #define  ATTINY25   0x9108  // L: 0x62, H: 0xDF, E: 0xFF    8 pin
    #define  ATTINY44   0x9207  // L: 0x62, H: 0xDF, E: 0xFFF  14 pin
    #define  ATTINY45   0x9206  // L: 0x62, H: 0xDF, E: 0xFF    8 pin
    #define  ATTINY84   0x930C  // L: 0x62, H: 0xDF, E: 0xFFF  14 pin
    #define  ATTINY85   0x930B  // L: 0x62, H: 0xDF, E: 0xFF    8 pin
    void setup() {
      pinMode(VCC, OUTPUT);
      pinMode(RST, OUTPUT);
      pinMode(SDI, OUTPUT);
      pinMode(SII, OUTPUT);
      pinMode(SCI, OUTPUT);
      pinMode(SDO, OUTPUT);     // Configured as input when in programming mode
      digitalWrite(RST, HIGH);  // Level shifter is inverting, this shuts off 12V
      Serial.begin(19200);
    }
    void loop() {
       if (Serial.available() > 0) {
        Serial.read();
        pinMode(SDO, OUTPUT);     // Set SDO to output
        digitalWrite(SDI, LOW);
        digitalWrite(SII, LOW);
        digitalWrite(SDO, LOW);
        digitalWrite(RST, HIGH);  // 12v Off
        digitalWrite(VCC, HIGH);  // Vcc On
        delayMicroseconds(20);
        digitalWrite(RST, LOW);   // 12v On
        delayMicroseconds(10);
        pinMode(SDO, INPUT);      // Set SDO to input
        delayMicroseconds(300);
        Serial.println("Reading: ");
        unsigned int sig = readSignature();
        Serial.print("Signature is: ");
        Serial.println(sig, HEX);
        readFuses();
        if (sig == ATTINY13) {
          writeFuse(LFUSE, 0x6A);
          writeFuse(HFUSE, 0xFF);
        } else if (sig == ATTINY24 || sig == ATTINY44 || sig == ATTINY84 ||
                   sig == ATTINY25 || sig == ATTINY45 || sig == ATTINY85) {
          writeFuse(LFUSE, 0x62);
          writeFuse(HFUSE, 0xDF);
          writeFuse(EFUSE, 0xFF);
        }
        readFuses();
        digitalWrite(SCI, LOW);
        digitalWrite(VCC, LOW);    // Vcc Off
        digitalWrite(RST, HIGH);   // 12v Off
      }
    }
    byte shiftOut (byte val1, byte val2) {
      int inBits = 0;
      //Wait until SDO goes high
      while (!digitalRead(SDO))
        ;
      unsigned int dout = (unsigned int) val1 << 2;
      unsigned int iout = (unsigned int) val2 << 2;
      for (int ii = 10; ii >= 0; ii--)  {
        digitalWrite(SDI, !!(dout & (1 << ii)));
        digitalWrite(SII, !!(iout & (1 << ii)));
        inBits <<= 1;
        inBits |= digitalRead(SDO);
        digitalWrite(SCI, HIGH);
        digitalWrite(SCI, LOW);
      }
      return inBits >> 2;
    }
    void writeFuse (unsigned int fuse, byte val) {
      shiftOut(0x40, 0x4C);
      shiftOut( val, 0x2C);
      shiftOut(0x00, (byte) (fuse >> 8));
      shiftOut(0x00, (byte) fuse);
    }
    void readFuses () {
      byte val;
            shiftOut(0x04, 0x4C);  // LFuse
            shiftOut(0x00, 0x68);
      val = shiftOut(0x00, 0x6C);
      Serial.print("LFuse: ");
      Serial.print(val, HEX);
            shiftOut(0x04, 0x4C);  // HFuse
            shiftOut(0x00, 0x7A);
      val = shiftOut(0x00, 0x7E);
      Serial.print(", HFuse: ");
      Serial.print(val, HEX);
            shiftOut(0x04, 0x4C);  // EFuse
            shiftOut(0x00, 0x6A);
      val = shiftOut(0x00, 0x6E);
      Serial.print(", EFuse: ");
      Serial.println(val, HEX);
    }
    unsigned int readSignature () {
      unsigned int sig = 0;
      byte val;
      for (int ii = 1; ii < 3; ii++) {
              shiftOut(0x08, 0x4C);
              shiftOut(  ii, 0x0C);
              shiftOut(0x00, 0x68);
        val = shiftOut(0x00, 0x6C);
        sig = (sig << 8) + val;
      }
      return sig;
    }

2 People Made This Project!

Recommendations

  • Woodworking Contest

    Woodworking Contest
  • Casting Contest

    Casting Contest
  • Clocks Contest

    Clocks Contest
user

We have a be nice policy.
Please be positive and constructive.

Tips

Questions

40 Comments

Hi, Diy-BlokHi DIY-Bloke, I have 15 Attiny13 (smd) as many as 15 pieces that can not be filled programmed while still sealed from the factory, I've tried it by soldered directly to IC foot with wire (worried socket IC dip to SSU problem) but the effort was not successful with the description of Chip not found) whether it can be cured with Attiny Doctor? thanks.

1 reply

interesting, you are in fact the 2nd one to approach me about chips not working straight from the factory. Asian Webstore??

Not sure if the attiny doctor can help as the chip apparently isn't found but with 15 it might be worth a try

I am not too familiar with the 84a. but it seems indeed yours is bricked

Perfect, thank you. Nearly perfect anyway, - it correctly reads the fuses and signature for my smd tiny85 but doesn't actually change the fuses. At least I now know that reset is disabled (which is why ISP reports that the signature is 000000 using avrdude). I'll update here if I ever get to the bottom of this ;)

1 reply

Solved. tl;dr I needed to do a chip erase, then the fuses reset as expected.

Using the code and hardware here I worked out with the help of the datasheet how HV programming works. From that I was able to add some code to read the lock bits back. I was expecting the ATtiny85 to be locked as that should prevent the fuses being changed, but it wasn't. So, with nothing to lose, I tried erasing the whole chip...

void chipErase () {
Serial.print ("Erasing chip....");
shiftOut(0x80, 0x4C);
shiftOut(0x00, 0x64);
shiftOut(0x00, 0x6C);
Serial.println ("done");
}

I added the above routine to the code and called it after it reads the signature and fuses, but before it writes/re-reads the fuses. It worked perfectly first time.

Hello and thank you for this simple but very useful circuit, I added some cosmetic printings to your code, to help my failing memory :-) !

<a href="https://github.com/jeanrocco/cheap-fuse-doctor/blob/master/Attiny85_fuse_doctor.ino">cheap-fuse-doctor</a>

1 reply

hem ! markdown not working here !

https://github.com/jeanrocco/cheap-fuse-doctor/blob/master/Attiny85_fuse_doctor.ino

Thank you SO much! It took me hours to figure out why this damned attiny wouldn't flash. Now I can just reset it and everything works nicely.

2 replies

Let me add that I built it also for an attiny that wouldnt flash without me having the foggiest why. Turned out to be a fuse i had no idea I had set

Happy I/my instructable could be of help :-)

How to use it? Is it enough to burn it or upload it on arduino? I have not understood the use on arduino because there is no video tutorial that I can see. thank you for your answer

1 reply

put the attiny in the board an insert in the arduino.

upload the program to the arduino,

I wonder why SCK, MISO and MOSI from the Arduino Uno are not used?

Erik$

4 replies

You mean pins 11, 12 and 13? They are used.
Happy Newyear

Hi, thks for your quick reply! I am confused: Arduino Uno SCK is on pin 13 (PB5), MISO is on pin 12 (PB4) and MOSI is on pin 11 (PB3).

In your drawing ATtiny pin 5 (PB0, MOSI) goes to Arduino D9 (pin 9?), ATtiny pin 6 (PB1, MISO) goes to Arduino D10, ATtiny pin 7 (SCK, PB2) goes to Arduino D11 (MOSI), ATtiny pin 2 (PB3) goes to Arduino D12 (MISO).

And in the sketch pin 5, 6, 7, 2 and 1 are respectively configured as SDI, SII, SDO, SCI and Reset.

So my question:

1. MISO, MOSI and SCK are not on the corresponding pins on the Arduino Uno: what do I miss?

2. In high voltage programming it seems as if rather SDI, SII, SDO , SCI and Reset are used as variables: what is the difference with MISO and MOSI?

Thks,

have a great New Year!

Erik

OK, now I get your point. Well this is not SPI programming, it is High voltage serial programming, that you still can use if for instance SPI (ICSP) is disabled. One of the pins is SCI (serial clock input), one is SDI (data in to the chip), one is SII (instruction in to the chip), and one is SDO (data out from the chip).
So it is totally different from SPI programming

Ah ok!! Now next question.

I am in process of making a pcb to do both ISP and HV programming for all ATtiny MCU's, based on initial work by Kai Bader:

https://github.com/kaibader/ISP-HVP-Shield/tree/ma...

We agreed I could develop his unfinished project. But I am in need of someone to help me program this project.

Goal: use HV serial programming on one pcb for ATtiny85/45/25/15/13, ATtiny84/44/24, ATtiny26/261/461/861, ATtiny2313/4313 and ATmega328/168.

Question: is HV programming for all these MCU's possible, and what changes to my pcb would be needed to get this programmed (see attachment)

Thks!!

Erik

Hello ! can you modify it (or the whole code) for Attiny2313 ?
I tried my self a bit gone this far :

#define t2313 0x1e910a // Signature of device (found while burning bootloader to a functional chip)

#define HFUSE 0xDF

#define LFUSE 0x64
#define EFUSE 0xFF

//calculated from :

// http://eleccelerator.com/fusecalc/fusecalc.php?ch...

...

...

...

else if (sig == t2313) {
writeFuse(LFUSE, 0x62); // i dont know what 0x62 is. some sort of memory location? because I have defined LFUSE above
writeFuse(HFUSE, 0xDF);// same goes for this.
writeFuse(EFUSE, 0xFF);// if that is memory location. than I may read its data sheet to search for it.I did read it but just for calculating the fuses. which I later found that these were already written in my board.txt.
}


and MY Serial Console is printing this :

Reading:
Signature is: FFFF
LFuse: FF, HFuse: FF, EFuse: FF
LFuse: FF, HFuse: FF, EFuse: FF


Thanks Again :) !