How to recover incorrectly exposed fuses in ATtiny

  • Tutorial
image

Hello to all the habrayuzers. I think many who are involved in microcontrollers have little experience in "blocking" the microcontroller with incorrectly set fuse bits, for example, incorrect clock settings, in particular, a very low frequency, for example 16 kHz.

Also, this method must be suitable for the cases when they were accidentally changed Fyuz bits RSTDISBL , and more specifically - RESET port is used as an I / O port or a careless attitude towards Fyuz-bit SPIEN (permit sequential programming), all it eliminates the firmware classic method according to the protocol SPI (In-System Programming).



In this video, I will tell and show how you can unlock microcontrollers from the ATtiny series that have incorrectly set fuse bits.

This method is not suitable for all ATtiny, but is suitable for most popular ones, here is a list of them:

  • ATtiny13;
  • ATtiny24;
  • ATtiny25;
  • ATtiny44;
  • ATtiny45;
  • ATtiny84;
  • ATtiny85.

In the video I showed how you can restore factory fuse bits using Arduino, in fact, the information presented below is duplicated in video format.


I have to say right away that the project of Comrade Wayne Holder is taken as a basis , for which many thanks to him, here is a link to his article .
So, let's start, here is the connection diagram using the example of ATtiny13:

image

And this is how this diagram looks like in my version:

image

About connecting to ATtiny25 / 45/85/24/44/84 it will be lower.

As you can see, the circuit consists of 6 resistors with a nominal value of 1 KOhm, 1 NPN transistor 2n3904, here is its pinout:

image

You can take the Soviet KT315, or its analogues, well, actually a voltage source of 11.5-12.5 V, as ATmel engineers recommend in the documentation for those microcontrollers that are mentioned above. I don’t think it’s worth overstating or underestimating the voltage, so I advise you to check the voltage at the power source with a voltmeter or multimeter before restoration. At the time of shooting the video, the voltage on my battery was 12.4 V.

A couple of words where you can get 12 V are different kinds of power supplies for routers or modems, for example, my DSL modem ASUS DSL-N10E just has a 12 V power supply, like As a rule, voltage is indicated on each power supply.
Also, 12 V can be taken from the computer’s MOLEX connector :

image

And more precisely - yellow and black.

It is worth mentioning that you need to be very careful when connecting a 12 V part , because this voltage easily burns out both microcontrollers and other Arduino peripherals, for example, a USB-TTL converter, I refer to personal experience. Therefore, we follow the algorithm:

  • Putting together a circuit;
  • We supply power to the Arduino by connecting to usb;
  • We supply + 12V to the transistor;
  • We restore the microcontroller;
  • Turn off + 12V.

This is how I reset ATtiny13 fuse bits (I used the Reset port as an input / output port), already 10-15 times when debugging one of my projects, here is a short video preview of it:

LCD (HD44780) multimeter on ATtiny13


We connect to other microcontrollers our "fuse-bit reducer" as follows:

image

  • The RST ATtiny port is connected between a 1 KΩ resistor, the one that connects to + 12V, and the collector of the VT1 transistor;
  • The 13th pin of Arduino, aka PB5, is connected through a 1 kΩ resistor to the base of the VT1 transistor;
  • The 12th pin of Arduino, aka PB4, is connected via a 1 kΩ resistor to the ATtiny SCI (Target Clock Input);
  • The 11th pin of Arduino, aka PB3, is connected via a 1 kΩ resistor to the ATtiny SDO (Target Data Output);
  • The 10th pin of Arduino, aka PB2, is connected via a 1 kΩ resistor to the SII (Target Instruction Input) ATtiny;
  • 9th pin of Arduino, aka PB1, is connected via a 1 kΩ resistor to the ATtiny SDI (Target Data Input);
  • The 8th pin of Arduino, aka PB0, it is advisable to connect through a 100-330 ohm resistor to the VCC ATtiny, just in case.
  • GND is, of course, a common wire or, in other words, "ground."


All this is reassigned to the code, no problem.

Here is the code from the author’s page
// AVR High-voltage Serial Fuse Reprogrammer
// Adapted from code and design by Paul Willoughby 03/20/2010
//   http://www.rickety.us/2010/03/arduino-avr-high-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);
}
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);
    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;
}


As you see, nothing intricate, they sent any character to Arduino via UART and voila, the fuse bits were restored to the factory ones, and we see what they were before unlocking and which ones became.

My previous article is about how to turn Arduino into a full-fledged AVRISP programmer . There you can read about the software mentioned in the video on the firmware of the microcontroller.

I also recommend visiting a slightly different project of Comrade Wayne Holder :

ATTiny Fuse Reset with 12 Volt Charge Pump

The essence is the same, but you do not need to look for the source of 12 V.

All my publications .

PS Serial.begin (19200);

Also popular now: