Attiny Programming Notes

[At the time of this writing, the Arduino SDE version was 1.6.11]

Using the Arduino Uno R3 as the ISP (Following HighLowTech instructions at http://highlowtech.org/?p=1706)

  • Load the ArduinoISP sketch into the SDE

    • File -> Examples -> 11. ArduinoISP -> ArduinoISP

  • Set Board to Uno

    • Tools -> Board -> Arduino/Genuino Uno

  • Set Programmer

    • Tools -> Programmer -> AVRISP mkII

  • Set Port appropriately

  • Upload sketch to Uno

    • Edit -> Upload

Programming the Attiny85 under the Arduino SDE

  • Wire up Attiny85 to Uno per HighLowTech's instructions)

  • Program the Attiny85 per HighLowTech's instructions (http://highlowtech.org/?p=1695)

    • Tools -> Board -> ATtiny25/45/85

    • Tools -> Processor ATtiny85

    • Tools -> Clock -> Internal 1 MHz (unless you changed it in previous instructions)

    • Tools -> Programmer -> Arduino as ISP

    • Sketch -> Upload

Note: If you received an error regarding a device signature other than 0x1e930b (an Attiny85), it may be because the Uno is in bootloader mode. The 10 microfarad capacitor across Reset and GND is supposed to prevent that. If the problem persists, try:

  1. Unplugging the Uno from the computer

  2. Removing the capacitor

  3. Plugging the Uno into the computer

  4. Inserting the capacitor across Reset and GND

For my application, I needed to set fuses in the Attiny85 to make the Reset pin an output. I did it from the command line with this command (replace the path and port with the appropriate ones):

C:\arduino-1.6.11\hardware\tools\avr\bin>avrdude.exe -C C:\arduino-1.6.11\hardware\tools\avr\etc\avrdude.conf -c arduino -P com3 -p t85 -U lfuse:w:0x62:m -U hfuse:w:0x5f:m -U efuse:w:0xff:m -b 19200

Setting these fuses results in being unable to reprogram the attiny. I decided to build a high voltage programmer to reset the fuses when necessary. I followed the instructions at https://arduinodiy.wordpress.com/2015/05/16/high-voltage-programmingunbricking-for-attiny/

  • Build the circuit

Circuit
  • Upload one of the two listed sketches to the Uno. I picked the second one

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

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;

}

  • Unplug the Uno from the computer

  • Connect the HV programmer to the Uno

  • Connect the Uno to the computer

  • Open up a serial monitor (easiest is the Arduino SDE's Serial Monitor set to 19200 baud with no line ending)

  • Apply 12v to the HV programmer

  • Send a character to the Uno.

  • The output will be the initial settings of the fuses followed by the reset settings of the fuses

  • Remove the 12v supply

  • Unplug the Uno from the computer

  • Unplug the HV programmer from the Uno