I posted Q&A on Arduino.cc.
To read fuses of an AVR chip (AtTiny85 in my case), you need an ISP. For that I used a spare Arduino Uno that I programmed to be an ISP, just by loading on it this example: file/Examples/ArduinoISP.
I had to wire the AtTiny85 as slave to the Arduino Uno board. I followed this:
- 5 Volt: AtTiny 8 (VCC) <- Power 5V
- SCK: AtTiny 7 (SD2) <- Uno 13 (AtMega 19, PB5)
- MISO: AtTiny 6 (SD1) -> Uno 12 (AtMega 18, PB4)
- MOSI: AtTiny 5 (SD0) <- Uno 11 (AtMega 17, PB3)
- 0 Volt: AtTiny 4 (GND) <- Power GND
- RESET: AtTiny 1 (reset) <- Uno 10 (AtMega 16, PB2)
Put a 10 microFarad or more capacitor between the Uno reset pin and ground, to prevent it from resetting when receiving a program from USB. Also put ground and power wire on AtTiny85.
AVRdude to read fuses
AVRdude is part of the Arduino IDE package, but is a command line tool invoked during programming of boards. When you run load program, some of the output comes from it.
cd "C:\Program Files (x86)\Arduino\hardware\tools\avr\bin" ./avrdude.exe -c stk500v1 -p attiny85 -P com4 -U lfuse:r:-:i -v -C ..\etc\avrdude.conf -b 19200
To use AVRdude, on Windows 8, I had to use powershell (run powershell), and cut and paste, use quotes for the path. It turns out the UNO ISP behaves like a stk500v1 programmer, and that the AtTiny85’s device name is attiny85, not t85 or anything. To figure these things out, run the compiler to compile code for the AtTiny85, and also try to use the Uno as ISP. In the output there’s hints of these infos. The com port is the Uno’s (or ISP’s) port. That’s how I figured it out. I also had much difficulty finding avrdude.conf.
The above command -U lfuse:r:-:i means read the fuses.
The default AtTiny85 reports:
avrdude.exe: Device signature = 0x1e930b
avrdude.exe: safemode: lfuse reads as 62
avrdude.exe: safemode: hfuse reads as DF
avrdude.exe: safemode: efuse reads as FF
AVRdude to write fuses
Fuses will be reported as 3 hexadecimal values specific to each CPU model. Use this calculator to figure out the meaning. Be careful when setting the frequencies to not pick any external clock option unless you have a 16MHz crystal and capacitors available and wired to your chip. Also don’t mess with the disable reset option which prevents future programming of the chip.
I wanted a 16MHz AtTiny85, with internal clock to avoid wiring anything more, similar config as digispark boards, so I ran this:
./avrdude.exe -c stk500v1 -p attiny85 -P com4 -U lfuse:w:0xf1:m -U hfuse:w:0xdd:m -U efuse:w:0xfe:m -v -C ..\etc\avrdude.conf -b 19200
- lfuse F1 (CKSEL 001, SUT 11 i.e. 16MHz PLL clock, 16CK/14CK + 64ms)
- hfuse DD (Brownout detection level1 2.8V)
- efuse FE (self programming enable)
Programming the AtTiny85 with an Arduino Uno ISP
The best in 2017 is to install the definition files Damelis posted on GitHUB using this tutorial, i.e. by adding https://…/package_damellis_attiny_index.json to the board definitions and loading the AtTiny definitions. I asked him to add support for 16MHz boards so this is fully functional now.
Note that this means you can flash the fuses directly from the Arduino IDE by running Tools/Burn bootloader (AtTiny85 has no bootloader, but fuses get set). His fuse choices are different from mine but will get you at 16MHz. Before burning the bootloader or pushing a program, in the Arduino IDE, select Tools/Board/AtTiny. Then more menus appear. use them to set your board specs (unfortunately Damellis decided default should be what the chip ships at aka 1MHz ):
- Tools/Prot/Com 4 (Arduino Uno)
- Tools/Programmer/Arduino as ISP (not ArduinoISP)
Compile and upload the program.
Note: To debug if the frequency was correct, I had to use the delay() routine to pulse a visible event. If the pulse is X times slower than what you programmed, the chip speed is 16MHz/X. Simple… A good thing to verify at least once! Since I use bit-banged ws2812b LED protocols, any error is CPU clock prevents any programmable LED from working.