ATtiny85 Bricked? No problem!

Messing with fuses may brick ATtiny85!

On Attiny85 (also on other Attiny__) chips from Atmel, I recently made mistake, not knowing exact ‘truth’ about how to set fuses properly, so that it work as expected. The problem is in online documentation and implementation in some of available programmers as is “Khazama AVR programmer”. Even online calculator is wrong – if for example you want to use 8 MHz and above external quartz crystal oscillator, then you should select CSEL = 1110, but calculator showing that three boxes should be unchecked (CSEL[3:1]), while last box (CSEL0) should be checked. THIS IS NOT TRUE!!! If you look in datasheet about Attiny85, then it is exactly 1110, but online calculators, and programmer showing confusing and contradictory messages about what enables or disables what. So, I made (not so short) video about this issue + how to ‘un-brick’ Bricked Attiny__ (in my case Attiny85).

Is there hope for bricked chip?

YES! Bricked Attiny85 simply does not accept ISP programmer, but it can be ‘rescued’ by so called “HV programming”, where high voltage is actually 12V to the reset pin (pin number 1 on Attiny85), then some weird commutation of +5V and +12V on the chip brings it into programming mode. Down below is diagram and sketch, which is not my idea, but rather I with to thanks and give credit to those people who designed it and modified so that we can rescue our favorite chips.

Attiny85

On the image above, there is credit to someone who made it possible, but someone else changed sketch slightly, so that it now works as is expected.

The sketch for Arduino nano:

Be careful about the “Fuse calc”!!!

You may notice that “Fuse calc” gives (for example) result of 1110 for external quartz oscillator, but boxes below are incorrectly checked! Pay attention to that. Here is my video and some conclusions about that:

Instead ugly 12V lead acid battery, consider buying this 5V to 12V step-up converter.

2 thoughts on “ATtiny85 Bricked? No problem!”

  1. Thanks built the circuit into a shield using perf board, I will try it tomorrow.
    I needed to modify the code somewhat: (works in v1.8.13)

    /*
    AVR High-voltage Serial Fuse Reprogrammer by Paul Willoughby (03/20/2010) and modified by William Andersen
    06/28/2020. http://www.rickety.us./2010/10/arduino-avr-hich-voltage-serial-programmer/
    Fuse Calc:
    http://www.engbedded.com/fusecalc/
    */

    #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);
    Serial.println(“Code is modified by Rik. Visit riktronics.wordpress.com and electronics-lab.com for more projects”);
    Serial.println(“————————————————————————————————-“);
    Serial.println(“Enter any character to start process..”);

    if (Serial.available() > -1 ) {
    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);
    unsigned int sig = readSignature();
    Serial.println(“Reading signature from connected ATtiny……”);
    Serial.println(“Reading complete..”);
    Serial.print(“Signature is: “);
    Serial.println(sig, HEX);
    readFuses();
    if (sig == ATTINY13) {
    Serial.println(“The ATtiny is detected as ATtiny13/ATtiny13A..”);
    Serial.print(“LFUSE: “);
    writeFuse(LFUSE, 0x6A);
    Serial.print(“HFUSE: “);
    writeFuse(HFUSE, 0xFF);
    Serial.println(“”);
    } else if (sig == ATTINY24 || sig == ATTINY44 || sig == ATTINY84 || sig == ATTINY25 || sig == ATTINY45 || sig == ATTINY85) {
    Serial.println(“The ATtiny is detected as “);
    if(sig == ATTINY24) Serial.println(“ATTINY24..”);
    else if(sig == ATTINY44) Serial.println(“ATTINY44..”);
    else if(sig == ATTINY84) Serial.println(“ATTINY84..”);
    else if(sig == ATTINY25) Serial.println(“ATTINY25..”);
    else if(sig == ATTINY45) Serial.println(“ATTINY45..”);
    else if(sig == ATTINY85) Serial.println(“ATTINY85..”);
    writeFuse(LFUSE, 0x62);
    writeFuse(HFUSE, 0xDF);
    writeFuse(EFUSE, 0xFF);

    }
    Serial.println(“Fuses will be read again to check if it’s changed successfully..”);
    readFuses();
    digitalWrite(SCI, LOW);
    digitalWrite(VCC, LOW); // Vcc Off
    digitalWrite(RST, HIGH); // 12v Off

    Serial.println(“”);
    Serial.println(“”);
    Serial.println(“”);
    Serial.println(“”);
    }
    }

    void loop() {
    }

    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 <= 0; ii–) {
    digitalWrite(SDI, !!(dout & (1 << ii)));
    digitalWrite(SII, !!(iout & (1 << ii)));
    inBits <> 2;
    }

    void writeFuse (unsigned int fuse, byte val) {
    Serial.println(“Writing correct fuse settings to ATtiny…….”);
    shiftOut(0x40, 0x4C);
    shiftOut( val, 0x2C);
    shiftOut(0x00, (byte) (fuse >> 8));
    shiftOut(0x00, (byte) fuse);
    Serial.println(“Writing complete..”);
    }

    void readFuses () {
    Serial.println(“Reading fuse settings from connected ATtiny…….”);

    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);
    Serial.println(“Reading complete..”);
    }

    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;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.