Tag Archives: fuses

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.

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.

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("");

}

}

byteshiftOut(byteval1,byteval2){

intinBits=0;

//Wait until SDO goes high

while(!digitalRead(SDO))

;

unsignedintdout=(unsignedint)val1<<2;

unsignedintiout=(unsignedint)val2<<2;

for(intii=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);

}

returninBits>>2;

}

voidwriteFuse(unsignedintfuse,byteval){

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..");

}

voidreadFuses(){

Serial.println("Reading fuse settings from connected ATtiny.......");

byteval;

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..");

}

unsignedintreadSignature(){

unsignedintsig=0;

byteval;

for(intii=1;ii<3;ii++){

shiftOut(0x08,0x4C);

shiftOut(ii,0x0C);

shiftOut(0x00,0x68);

val=shiftOut(0x00,0x6C);

sig=(sig<<8)+val;

}

returnsig;

}

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: