Thursday, September 17, 2020

Recording the Reset Pin


The AVR reset pin has many functions.  In addition to being used as an external reset signal, it can be used for debugWire, and it is used for SPI and for high-voltage programming. Other than for when it is used as an external reset signal, the datasheet specifications are somewhat ambiguous.  I recently started working on an updated firmware for the USBasp, and wanted to find out more details about the SPI programming mode.  The image above is one of many recordings I made from programming tests of AVR MCUs.

When I first started capturing the programming signals, I observed seemingly random patterns on the MISO line before programming was enabled.  Although the datasheet lists the target MISO line as being an output, it only switches to output mode after the first two bytes of the "Programming Enable" instruction, 0xAC 0x53, are received and recognized.  Prior to that the pin floats, and the seemingly random patterns I observed were caused by the signals on the MOSI and SCK lines inducing a voltage on the MISO line.  I enabled the pullup resistor on the programmer side in order to keep the MISO line high until the PE instruction was recognized by the target.

One of the steps in the datasheet's serial programming alorithm that doesn't make sense to me is step 2, which says, "Wait for at least 20 ms and enable Serial Programming by sending the Programming Enable serial instruction to pin MOSI."  It's clear from the capture image above that a wait time of less than 100 us worked in this case.  I did a number of experiments with different targets (t13, t85, m8a) with and without the CKDIV8 fuse set, and found a delay of 64 us was always sufficient.  Nevertheless, I still used a 20 ms delay in the USBasp firmware.

Another observation I made was of a repeatable delay between the 8th rising edge of the SCK signal on the second byte and MISO going low.  After multiple tests, I found that delay is between 2 and 3 of the target clock cyles.  A close-up of the 0x53 byte shows this clearly:

The 2-3 clock ccyle delay seems to correspond with the datasheet's specification of the minimum low and high periods for the SCK signal of 2 clock cycles when the target is running at less than 12Mhz.  However I found I couldn't consistently get a target running at 8MHz to enter programming mode with a SCK clock of 1.5MHz.  Additional logs of the programming sequence revealed something interesting when multiple PE instructions are sent at less than 1/8th of the target clock rate, with a positive pulse on RST for synchronization.  In those sequences, the delay was smaller between the 8th rising edge of the SCK signal on the second byte and MISO going low for the second and subsequent times the PE instruction is sent.  It seems you need to use a slower SCK frequency to get the target into programming mode, but after that, the frequency can be increased to 1/4 of the target clock.

Using what I learned, I have implemented automatic SCK speed negotiation and a higher default SCK clock speed.  The speed negotiation starts with 1.5MHz for SCK, and makes 3 attempts to enter programming mode.  If that fails, the next slower speed (750kHz) is tried three times, and so on until a speed is found where the target responds.  For subsequent communications with the target, the speed is doubled, since the slowest speed is only needed the first time the PE command is received after power-up.  The firmware also supports a maximum SCK frequency of 3MHz, vs 1.5MHz for the original firmware.

The higher speeds don't make a large difference in flash/verify times since the overhead of the vUSB code tends to dominate beyond a SCK frequency of 750kHz or so.  Reading the 8kB of flash on an ATtiny85 takes around 3 seconds.  By optimizing the low-speed USB code, such as was done by Tim with u-wire, it should be possible to double that speed.

Sunday, September 6, 2020

Flashing AVRs at high speed


I've written a few bootloaders for AVR MCUs, which necessarily need to modify the flash while running.  The typical 4ms to write or erase a page depends on the speed of the internal RC oscillator.  Here's a quote from section 6.6.1 of the ATtiny88 datasheet:

Note that this oscillator is used to time EEPROM and Flash write accesses, and the write times will be affected accordingly. If the EEPROM or Flash are written, do not calibrate to more than 8.8 MHz. Otherwise, the EEPROM or Flash write may fail.

I wondered how running the RC oscillator well above 8.8MHz would impact erasing and writing flash  In the past I read about tests showing the endurance of AVR flash and EEPROM is many times more than the spec, but I couldn't find any tests done while running the AVR at high speed.  I did come across a post from an old grouch on AVRfreaks warning not to do it, so now I had to try.

The result is a program I called flashabuse, which you'll see later is a bit of a misnomer.  What the program does is set OSCCAL to 255, then repeatedly erase, verify, write, and verify a page of flash.  I chose to test just one page of flash for a couple reasons.  First, testing all 128 pages of flash on an ATtiny88 would take much more time.  The second is that I would only risk damaging one page, and an ATtiny88 with 127 good pages of flash is still useful.

The results were very positive.  My little program was completing about 192 cycles per second, taking 2.6ms for each page erase or page write.  I let it run for an hour and a half, so it successfully completed 1 million cycles.  Not bad considering Atmel's design specification is a minimum of 10,000 cycles.

So why does the flash work fine at high speed?  I think it has to do with how floating-gate flash memory works.  Erasing and writing the flash requires removing and adding a charge to the floating gate using high voltages.  Atmel likely uses timing margins well in excess of the 10% indicated in the datasheet, so even half the typical 4ms is more than enough to ensure error-free operation.  I even think writing at high speed puts less wear on the flash because it exposes the gate to high voltages for a shorter period of time.


I received some feedback questioning whether the faster write time may reduce retention due to reduced charge on the floating gate.  As I mentioned above, Atmel likely used a very large timing margin when designing the flash memory.  Chris Lamont, who tested flash retention on a PIC32, stated that retention failure is "extremely unlikely".

The retention specs for the ATtiny88 are, "20 years at 85°C / 100 years at 25°C".  As this Micron technical note (PDF) shows, retention specs are based on models, not actual testing.  Micron's JESD47I PCHTDR testing is done at 125C for 1000 hours, and requires 0 failures.  TEKMOS states, "As a very rough rule of thumb, the data retention time halves for every 10C rise in temperature."  Extrapolating from a 100-year retention at 25C, retention at 255C, a typical reflow soldering peak temperature, would be only 6 minutes.

In an attempt to show that retention is not impacted by repeated fast flashing, I performed two additional tests.  For the first test, I baked the subject MCU for 12 hours at 150C, then performed 100,000 fast write/erase cycles.  Next, 0x55 was written to the test page, and repeatedly verified for 2 hours.  This test passed with no errors.  For the second test, I filled the 8kB of flash with zeros to put a charge on the floating gate for every bit.  I then baked the subject MCU for 12 hours at 150C, then verified that all bits remained at zero.  This test passed with all 65,536 bits reading zero.  I did, however have a failure of one solder joint, likely due to the stress of thermal cycling.

For those who are particularly concerned paranoid about flash retention, one solution is refereshing the flash.  For an AVR MCU, it would be simple to refesh the flash on every bootup with a small segment of code in .init1.  The code would copy each page into the page buffer, then perform a write on the page.  This would refresh all the 0 bits, and extend the retention life for another 20 to 100 years.