# ATtiny2313 refuses to be programmed after setting CPU clock to 500kHz

The other day I was writing a program for an ATtiny2313. Once it worked I decided to test it at the various clock speeds that are available and programmed through setting the LFUSE as described on page 159.

• The default clock speed is 1MHz;
• so I tried 8MHz next and all worked fine;
• Then I set the clock speed for 4MHz with the /8-prescaler resulting in 500kHz clock.

Although the controller runs the program at the expected speed, my programmer refuses to reprogram the controller since. avrdude (5.11.1) just throws the well known: 'Yikes!':

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
Double check connections and try again, or use -F to override
this check.


I tried adding the -F flag, but of course that didn't either.

Here are some code sniplets I used and changed the clock speed as expected:

// 0.5MHz
FUSES = { .low = 0x62   , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };

// 1MHz (default)
FUSES = { .low = 0x64   , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };

// 8MHz
FUSES = { .low = 0xe4   , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };


For programming, I use an Arduino with the ArduinoISP (version 04m3) sketch that came with Arduino IDE 1.0.1.

This is the command to program flash:

avrType=attiny2313
avrFreq=1000000
programmerDev=/dev/ttyUSB003
programmerType=arduino
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U flash:w:$(src).flash.hex  This is the command to program the fuses: avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U lfuse:w:$(src).lfuse.hex


My question is twofold:

1. What is the reason I cannot program the controller after setting it to 500kHz clock (while the program in the controller seems to run just fine);
2. What are my options for reprogramming the fuses without using a HV-programmer? Did I perhaps miss any useful flags to avrdude?

BTW: Had the same issue once with an ATtiny45 @ 128kHz. HV-programming solves it, but I want to prevent the HV situation.

• At which frequency does the programmer try to program? I remember that I had similar problems when I tried to program AVRs with SPI frequency which is too high compared to main clock. Lowering the SPI frequency solved the problem for me. – AndrejaKo Apr 9 '13 at 6:40
• I was thinking about that, but I have no idea. Arduino runs on 16MHz, but I don't know about the programming pins. It all happens too quick to measure the clock line for example. I could give it a try later today, after work. Nor do I have an idea how to scale down the programmer frequency. – jippie Apr 9 '13 at 6:53
• I can't help you much there. I haven't used Arduino, so I don't know how exactly the sketch looks. The programmer I used, had special setting just for this case. Some initial searches gave me these results: arduino.cc/forum/index.php?topic=71973.0 github.com/rsbohn/ArduinoISP/pull/2 Unfortunately, I don't have time right now to do any more research on this topic. Good luck! – AndrejaKo Apr 9 '13 at 7:08
• I don't use Arduino, so I don't know much about it, but sometimes I've had to alter the SPI speed when trying to program an AVR device that has a slower clock. There is a -B option to control the speed that works with the USBtiny programmer, but it doesn't sound like you are using that. It is mentioned here: tom-itx.dyndns.org:81/~webpage/usbtiny_programmer/… As well as in the links from the previous comment. – Kurt E. Clothier Apr 9 '13 at 7:11

The issue, as explained, too high SPI clock frequency. There exists a fixed version of ArduinoISP that can program at lower frequency available here. Some discussion on topic is available here.

• I checked the github link and I was able to flash the controller again on first try. As a matter of fact it allows for changing between SPI (too fast as explained in electronics.stackexchange.com/a/65019/8627 for some fuse settings) and bit banging (which just seems to work). Although I managed the reprogram the controller, the original ArduinoISP version is more stable. The new one sometimes fails and then works on a second try. – jippie Apr 10 '13 at 19:52

As a rule of thumb, you may not choose any ISP speed more than quarter of your target MCU's speed. In your case, 500 / 4 = 125KHz should be the maximum ISP speed. If you can't change your Arduino's SPI speed as angelatlarge described, you may need an external programmer.

If you can't manage decreasing SPI speed of ArduinoISP, another solution may be a custom programmer code. You may change ArduinoISP to use a software SPI and calculate proper delays to decrease to 100KHz or maybe custom speeds. Take a look at http://little-scale.blogspot.com/2007/07/spi-by-hand.html for software implementation of SPI.

I am going to go for the Captain Obvious badge here and suggest that the ATtiny2313 speed is too low to be programmed by the ArduinoISP now. From the ATtiny2313 datasheet:

The minimum low and high periods for the serial clock (SCK) input are defined as follows: Low:> 2 CPU clock cycles for f$_{ck}$ < 12 MHz, 3 CPU clock cycles for f$_{ck}$ >= 12 MHz High:> 2 CPU clock cycles for f$_{ck}$ < 12 MHz, 3 CPU clock cycles for f$_{ck}$ >= 12 MHz

Your arduino probably runs at at least 16Mhz. Here's the relevant line from ArduinoISP.ino:

SPCR = 0x53;


This sets the Arduino SPI speed at f$_{OSC}$/64, or 250Khz if the SPI2X bit is programmed in the SPSR register. If this is correct At 500kHz clock, this is not more than 2 CPU clock cycles as the datasheet recommends. If this hypothesis is correct, the solution is to set the SPI clock divider to 128 by ensuring that SPI2X is off in spi_init() function in ArduinoISP.ino:

SPSR &= ~(1<<SPI2X);

• unfortunately my version of ArduinoISP is already at /256 :( – jippie Apr 10 '13 at 19:50

I’m currently working on ScratchMonkey, an Arduino-as-programmer sketch that implements a software fallback for SPI, gradually backing off to speeds as low as 1kHz.

It’s still a work in progress, but you can get it from github