Springuin.nl

Electronics engineer, open source enthousiast, random maker, occasional hacker, careful motorcyclist, amateur artist, incidental hat-wearer, right-winged socialist, basic bass player, awful believer, skeptical dreamer. You can stay right here.

ATtiny43u with avrdude

... or how to add a new device to your avrdude.conf file.

This article is about how I added a section for the ATtiny43u to the avrdude config file. If you are looking for a quick solution, scroll all the way down and copy-paste the text to your config file. If you want to know how I did it and which assumptions I made during the process, or want to add a section for a different type, read the full article.

Introduction

The ATtiny43u is just a regular AVR with a special feature: it has a built-in step-up converter so that it can run from a single 1.5 volts battery.

"That's nice," I tought, "let's use that for a new project". And so I ordered the ATtiny43u and some supporting parts, drew a schematic and soldered a prototype. "Let's see if this works!" I connected the AVR Dragon and fired-up avrdude:

$ avrdude -p attiny43u -B 125 -c dragon_isp -P usb
avrdude: AVR Part "attiny43u" not found.

Valid parts are:
...list of supported AVRs...
Okay, that's not working. And there is nothing in the list that looks like the ATtiny43u either.

To check if my circuit was correct I forced avrdude to believe that this was a ATtiny44:
$ avrdude -p attiny44 -B 125 -c dragon_isp -P usb

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.17s

avrdude: Device signature = 0x1e920c
avrdude: Expected signature for ATtiny44 is 1E 92 07
         Double check chip, or use -F to override this check.

avrdude done.  Thank you.

Ok, so the circuit works, the part is just not supported by avrdude. Well, I was not the first person, some other people found out the same thing.

One quick-and-dirty solution is to choose a very similar part and force avrdude to believe it's something else that is supported, like I did above with the ATtiny44. This may not work as the devices are different and may need different instructions and such. The another solution, as suggested in this topic, is to add something useful to the avrdude config file.

The avrdude config file consists of a number of definitions for programmers followed by a number of part definitions.

The part definition describes how a programmer should handle the specific chip. The best source of this information is the manufacturer, Atmel. When you install AVR studio on Windows, it comes with a set of XML files that have the same function as the part descriptions in the avrdude config file.

Getting my hands dirty

To get the structure right I copied the definition for the ATtiny45 and started to change it to fit the ATtiny43U.

First there is de id and desc fields: I used "t43u" and "ATtiny43u". The device has debugWire, so has_debugwire should have the value "yes". The flash_instr comes from the ucFlashInst field in the XML file. The eeprom_instr is called ucEepromInst in the XML file. The ATtiny43u XML file does not mention a STK500 device id, so I used 0x14 from the ATtiny45 definition. The same goes for the avr910_devcode. The signature is 0x1e 0x92 0x0C.

reset could be dedicated or io. The ATtiny43u has a reset pin that could also be used for io, therefore I chose io. The chip_erase_delay for the ATtiny45 was 4500. In the ATtiny45's XML file was a field called eraseDelay with a value of 45. The ATtiny43u has 10 there, so I filled 1000 in as chip_erase_delay.

For pgm_enable and chip_erase I consulted chapter 19 of the ATtiny43u datasheet and chapter 20 of the ATtiny45 datasheet. The values in the serial programming instruction set were the same and matched the values of pgm_enable and chip_erase, so I left them unchanged.

Then there is a section starting with timeout and anding with pollmethod. These values can be found in the XML under STK500_2 -> IspEnterProgMode. All required values are there and in the next few lines. The ATtiny43u does not have high voltage serial programming but does have parallel programming. I removed the hv_controlstack parameter and added the pp_controlstack parameter.

Following the timing parameters in the following lines of the XML files I adjusted the timing values and added chiperasepulsewidth, programfusepulsewidth and programlockpulsewidth.

The information about the eeprom and flash memory sizes, pages and pagesizes comes from paragraph 19.4. The ATtiny43U's eeprom has 16 pages of 4 bytes; a total of 64 bytes. The write delays are in table 19-15 of the datasheet. The eeprom minimum wait delay is 4.0ms, so min_wait_delay becomes 4000 (microseconds). There is nothing about the maximum wait delay, so I assumed that the 4500 from the ATtiny45 would be ok. I could not find anything about the readback_p1 and readback_p2, so I kept them the same.

The commands for reading, writing, loadpage_lo and writepage were the same, the difference with the ATtiny45 is that the 45 has 265 bytes where the 43u has only 64. The pagesize is the same: 4 bytes. Therefore I adjusted the lengths of the address parts of the commands to 6 instead of 8 bits. The mode, delay and blocksize values come from the XML file, section IspProgramEeprom. I assumed that readsize was the blocksize value in the IspReadEeprom section.

When the eeprom memory is done, the same trick works for the flash memory. One thing to watch out for: the datasheet mentions the pagesize in words instead of bytes, so 32 words becomes 64 bytes in the avrdude config file. The mode, delay, blocksize and readsize come from the IspProgramFlash and IspReadFlash sections of the XML file.

For the fuses and lock bits: the wait delay is 4.5ms instead of 9.0ms so I changed the min_write_delay and max_write_delay values. The rest is the same as the ATtiny45.

Now it's time to test the config:
avrdude -e -p attiny43u -P usb -c dragon_isp -b 19200 -D -C<path to modified>avrdude.conf -u -U flash:w:obj/main.hex
If you made a typo you get:
syntax error at <path to modified>avrdude.conf:10066
avrdude is actually quite helpful when you did something wrong.

final result

This is how my ATtiny43u section looked like when I was finished. When you copy this to your avrdude config file it should work.

#------------------------------------------------------------
# ATtiny43U
#------------------------------------------------------------

part
	id            = "t43u";
    desc          = "ATtiny43u";
    has_debugwire = yes;
    flash_instr   = 0xB4, 0x07, 0x17;
    eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
     			 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, 
     			 0x99, 0xE1, 0xBB, 0xAC;
    stk500_devcode   = 0x14;
##  avr910_devcode   = ?;
##  Try the AT90S2313 devcode:
    avr910_devcode   = 0x20;
    signature        = 0x1e 0x92 0x0C;
    reset            = io;
    chip_erase_delay = 1000;

    pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
                        "x x x x  x x x x    x x x x  x x x x";

    chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x",
                        "x x x x  x x x x    x x x x  x x x x";

    timeout			= 200;
    stabdelay		= 100;
    cmdexedelay		= 25;
    synchloops		= 32;
    bytedelay		= 0;
    pollindex		= 3;
    pollvalue		= 0x53;
    predelay		= 1;
    postdelay		= 1;
    pollmethod		= 1;
    pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E,
                     0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56,
                     0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00,
                     0x00, 0x00;
    hventerstabdelay    = 100;
    progmodedelay       = 0;
    hvspcmdexedelay     = 0;
    latchcycles         = 5;
    togglevtg           = 1;
    poweroffdelay       = 20;
    resetdelayms        = 1;
    resetdelayus        = 0;
    hvleavestabdelay    = 15;
    resetdelay          = 15;
    chiperasepulsewidth = 0;
    chiperasepolltimeout = 10;
    programfusepulsewidth = 0;    
    programfusepolltimeout = 5;
    programlockpulsewidth = 0;
    programlockpolltimeout = 5;
    memory "eeprom"
		size            = 64;
		paged 			= yes;
		page_size       = 4;
		num_pages 		= 16;
		min_write_delay = 4000;
		max_write_delay = 4500;
		readback_p1     = 0xff;
		readback_p2     = 0xff;
		read            = "1  0  1  0   0  0  0  0    0 0 0 x  x x x x",
		                   "0  0 a4  a3 a2 a1 a0   o o o o  o o o o";
		
		write           = "1  1  0  0   0  0  0  0    0 0 0 x  x x x x",
		                   "0  0 a5 a4  a3 a2 a1 a0   i i i i  i i i i";

		loadpage_lo	= "  1   1   0   0      0   0   0   1",
				  "  0   0   0   0      0   0   0   0",
				  "  0   0   0   0      0   0  a1  a0",
				  "  i   i   i   i      i   i   i   i";
	
		writepage	= "  1   1   0   0      0   0   1   0",
				  "  0   0   x   x      x   x   x   x",
				  "  0   0  a5  a4     a3  a2   0   0",
				  "  x   x   x   x      x   x   x   x";
	
		mode		= 0x41;
		delay		= 5;
		blocksize	= 4;
		readsize	= 256;
	;
    memory "flash"
    	paged           = yes;
        size            = 4096;
        page_size       = 64;
        num_pages       = 64;
        min_write_delay = 4500;
        max_write_delay = 4500;
        readback_p1     = 0xff;
        readback_p2     = 0xff;

        read_lo         = "  0   0   1   0    0   0   0   0",
                          "  0   0   0   0    0  a10 a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  o   o   o   o    o   o   o   o";

        read_hi         = "  0   0   1   0    1   0   0   0",
                          "  0   0   0   0    0  a10 a9  a8",
                          " a7  a6  a5  a4   a3  a2  a1  a0",
                          "  o   o   o   o    o   o   o   o";

        loadpage_lo     = "  0   1   0   0    0   0   0   0",
                          "  0   0   0   x    x   x   x   x",
                          "  x   x   x  a4   a3  a2  a1  a0",
                          "  i   i   i   i    i   i   i   i";

        loadpage_hi     = "  0   1   0   0    1   0   0   0",
                          "  0   0   0   x    x   x   x   x",
                          "  x   x   x  a4   a3  a2  a1  a0",
                          "  i   i   i   i    i   i   i   i";

        writepage       = "  0  1  0  0   1  1  0  0",
                          "  0  0  0  0   0 a10 a9 a8",
                          " a7 a6 a5  x   x  x  x  x",
                          "  x  x  x  x   x  x  x  x";

		mode		= 0x41;
		delay		= 10;
		blocksize	= 64;
		readsize	= 256;
       ;
#   ATtiny44u has Signature Bytes: 0x1E 0x92 0x0c.
    memory "signature"
    	size            = 3;
        read            = "0  0  1  1   0  0  0  0   0  0  0  x   x  x  x  x",
                          "x  x  x  x   x  x a1 a0   o  o  o  o   o  o  o  o";
    ;
    memory "lock"
        size            = 1;
        write           = "1 0 1 0  1 1 0 0  1 1 1 x  x x x x",
                          "x x x x  x x x x  1 1 i i  i i i i";
        min_write_delay = 4500;
        max_write_delay = 4500;
    ;

    memory "lfuse"
    	size            = 1;
        write           = "1 0 1 0  1 1 0 0  1 0 1 0  0 0 0 0",
                          "x x x x  x x x x  i i i i  i i i i";

        read            = "0 1 0 1  0 0 0 0  0 0 0 0  0 0 0 0",
                          "x x x x  x x x x  o o o o  o o o o";
        min_write_delay = 4500;
        max_write_delay = 4500;
	;

    memory "hfuse"
        size            = 1;
        write           = "1 0 1 0  1 1 0 0  1 0 1 0  1 0 0 0",
                          "x x x x  x x x x  i i i i  i i i i";

        read            = "0 1 0 1  1 0 0 0  0 0 0 0  1 0 0 0",
                          "x x x x  x x x x  o o o o  o o o o";
    	min_write_delay = 4500;
        max_write_delay = 4500;
	;

    memory "efuse"
        size            = 1;
        write           = "1 0 1 0  1 1 0 0  1 0 1 0  0 1 0 0",
                          "x x x x  x x x x  x x x x  x x x i";

        read            = "0 1 0 1  0 0 0 0  0 0 0 0  1 0 0 0",
                          "x x x x  x x x x  o o o o  o o o o";
        min_write_delay = 4500;
        max_write_delay = 4500;
    ;

    memory "calibration"
        size            = 2;
        read            = "0  0  1  1   1  0  0  0    0 0 0 x  x x x x",
                          "0  0  0  0   0  0  0  a0   o o o o  o o o o";
    ;
;

Conclusion

Well, thats done. Now I can program my ATtiny43u. If you have any comments or found a mistake or wrong assumption, drop me a line! See the contact page for details. The text and pictures in this tutorial are licensed under the terms of the Creative Commons Attribution-ShareAlike 3.0 Unported license.
 

© Springuin.nl 2012 - SDG