# AVR program behavior incorrect after disabling reset fuse

I am using an ATtiny13 to drive 15 LEDs from five I/O pins (Charlieplexed). I am using ADC0 (pin1) as input from a voltage divider to provide a speed control. In order use ADC0 properly, I need to disable the reset fuse when I write the program.

The problem is, the program behaves differently when the reset fuse is disabled. Instead of all 15 LED's lighting, only 9 are. The 9 LEDs that light involve all 5 I/O pins, in both polarities, so I don't believe I've accidentally changed any configuration to those pins.

Here is the command line I use to flash the AVR (using avrdude on wintel) and set the fuses:

avrdude -c usbtiny -p attiny13 -U flash:w:program.hex -U lfuse:w:0x6a:m -U hfuse:w:0xfe:m


And the schematic:

Before setting the fuses, the program works perfectly, lighting the 15 LEDs as expected. The input on ADC0 will reset the micro when the voltage drops low enough, as expected, but otherwise speed control works. Here is a chart to show how the LEDs are connected:

LED #    AVR PINs    I/O PINs
1       5-6         1-2
2       6-5         2-1
3       5-7         1-3
4       7-5         3-1
5       5-2         1-4
6       2-5         4-1
7       5-3         1-5
8       3-5         5-1
9       6-7         2-3
10       7-6         3-2
11       6-2         2-4
12       2-6         4-2
13       6-3         2-5
14       3-6         5-2
15       7-2         3-4


After disabling the reset fuse, LEDs 1 through 9 work, 10 through 15 do not. There is a slight flicker detectable on LED 13. ADC0 speed control works through the full range, without resetting the micro.

I am thoroughly confused. Can anyone advise?

Edit:

In case it matters, this is using an SOIC-8 package. Previously I've used a DIP-8 and not had this problem.

I discovered the solution to this problem!

I wrote a batch file to compile the code, convert to hex, and write to the microcontroller in one go. To avoid accidentally disabling the reset fuse, I wrote a second batch file.

At some point, I was experimenting with different optimization levels with avr-gcc. My command line parameters for avr-gcc included -O3 in both files. I discovered that this level of optimization was unreliable and caused some issues. I changed it back to -Os but only in the first batch file, not the second.

So, the code behavior change was a result of an incorrect optimization, which was used only in the script I used to also disable the reset fuse. It was finally caught by an astute coworker who noticed the difference in the two scripts.

You have no bypass caps between VCC and GND. Power supply noise is likely your problem.

• I should have included that in the schematic; there is a 100uF electrolytic near the power supply and a smaller 0.1uF ceramic cap near the microcontroller. It still exhibits the problem. – JYelton Oct 30 '12 at 15:28

This is a bit of a wild guess, but the following snippet from page 103 of the datasheet may be relevant.

See “Alternate Functions of Port B” on page 54 for description of RSTDISBL and DWEN fuses. When programming the RSTDISBL fuse, High-voltage Serial programming has to be used to change fuses to perform further programming.

Once you've programmed the RSTDISBL fuse, you'll need to use high voltage programming to do any further programming of the device. It appears you're using the USBTiny which cannot do high voltage programming.

What may be happening is that the first programming cycle has worked as expected because the RSTDISBL fuse was programmed last in the avrdude invocation, but subsequent attempts are failing due to the RSTDISBL being programmed and preventing the part from going into serial programming mode.

• I'm aware that I cannot program the device after RSTDISBL unless I use high voltage programming. The intention is twofold: to use pin 1 as I/O (for ADC0); and to prevent accidental resets. The problem is not with programming attempts, but that the program already on the micro is no longer working as expected. – JYelton Oct 30 '12 at 15:27
• @JYelton Write some simple code to put each of the pins into high/low/tristate for 1 second in sequence. With equal pullup/pulldown on each port pin you should be able to verify that your port logic is correct with a scope. There's nothing obvious to me that may be wrong. I suggest bringing everything back to its most basic form and build up from there. – Austin Phillips Oct 31 '12 at 2:37