Wednesday, July 18, 2018
Reading extended signature bytes with AVRdude
AVR MCUs like the ATtiny85 and the ATtiny13 store their signature and RC oscillator data in a special page of flash. Just like the flash for program storage, this special page of flash can be erased and reprogrammed. If you are not careful with your ICSP connections, it's not hard to accidentally erase this special page of flash. I have 2 ATtiny13 chips that had their signature erased when I forgot to connect the power wire from a USBasp. The voltage on the MOSI and SCK lines was enough to power up the ATtiny13, but without a stable Vcc, the serial programming instructions were scrambled in such a way that the chips interpreted them as an undocumented command to erase the signature page.
Official documentation for the signature table is rather terse, but forum and blog posts about this special page of flash date back for more than a decade. Here is an example of the official documentation from the ATtiny85 datasheet:
The last row in the table has an error, since the page size of the t85 is 64 bytes, the signature table addresses go up to 0x3F, not 0x2A. For devices like the ATtiny25 and ATtiny13 with a 32-byte page size, the signature table addresses only go up to 0x1F. Most AVRs have the ability to read the signature table in software using the SPM instruction and the RSIG bit in SPMCSR. The ATtiny13 does not not support reading the signature in software, so the only way to read it is through the serial programming interfaces. I even tried setting the reserved bits in SPMCSR on the t13 in case reading the signature through software is an undocumented feature, but that did not work.
For most users, the ability to read the extended signature bytes is likely academic. Since each chip seems to have slightly different data in the reserved signature area, it could be used for a sort of serial number to keep track of different chips. The practical use for reading the signature page is when you can also reprogram it. Since the default OSCCAL value is stored in the signature table, it would be possible to tune the frequency to a different default value. One of my goals for reprogramming the signature page is to have a UART-friendly clock rate for debugWire. Having the default OSCCAL value correspond to a clock speed close to 7372.8Mhz means debugWire will run at a baud rate of 7372.8/128 = 57.6 kbps. It would also be possible to store other calibration data such as a more precise measurement of the internal voltage reference than what is specified in the datasheet.
While my ultimate goal is to create an AVR programmer that will read and write the signature table, a simple first step is to have AVRdude read the signature. Fortunately, the programming sequences used by AVRdude are not hard-coded in the source. The avrdude.conf file contains information on the command sequences to use for different protocols such as standard serial and high-voltage programming. To get AVRdude to read 32 bytes of signature data instead of just 3, make the following changes to the ATtiny85 section of the avrdude.conf file:
size = 32;
read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
"x x x a4 a3 a2 a1 a0 o o o o o o o o";
To read the 32 bytes of calibration data (which is just the odd bytes of the signature page), make the equivalent change for memory "calibration".
The next step in my plan is to write a program that tests undocumented serial programming instructions in order to discover the correct command for writing the signature page. Since there are likely other secret serial programming instructions that do unknown things to the AVR, I could end up bricking a chip or two in the process. If anyone already knows the program signature page opcode, please let me know.