Building for new ATtiny 1-series chips on Debian

In 2018, Microchip released a new range of ATtiny microcontroller chips, called the "ATtiny 1-series" - presumably named from the naming pattern of the part numbers. In usual Atmel (now bought by Microchip) style, the first digit(s) of the part number give the size of the flash memory; the remaining give an indication of the size and featureset of the chip.

ATtinyX128 pin package, 5/6 IO pinsATtiny212, ATtiny412
ATtinyX1414 pin package, 11/12 IO pinsATtiny214, ATtiny414, ATtiny814, ATtiny1614
ATtinyX1620 pin package, 17/18 IO pinsATtiny416, ATtiny816, ATtiny1616, ATtiny3216
ATtinyX1724 pin package, 21/22 IO pinsATtiny417, ATtiny817, ATtiny1617, ATtiny3217

I'll write more about these new chips in another post - there's much change from the older style of ATtiny chips you may be familiar with. Many new things added, things improved, as well as a couple of - in my opinion - backward steps.

This post is largely a reminder to myself, and a help to anyone else, on how to build code for these new chips. The trouble is that they're newer than the avr-libc support package in Debian, meaning that you can't actually build code for these yet. Such an attempt will fail:

$ avr-gcc -std=gnu99 -Wall -Os -DF_CPU=20000000 -mmcu=attiny814 -flto -ffunction-sections -fshort-enums -o .build/firmware.elf src/main.c
/usr/lib/avr/include/avr/io.h:625:6: warning: #warning "device type not defined" [-Wcpp]
 #    warning "device type not defined"
In file included from src/main.c:4:0:
src/main.c: In function ‘RTC_PIT_vect’:
src/main.c:33:5: warning: ‘RTC_PIT_vect’ appears to be a misspelled signal handler, missing __vector prefix [-Wmisspelled-isr]
src/main.c:35:3: error: ‘RTC’ undeclared (first use in this function)

This is caused by the fact that, while avr-gcc has support for the chips, the various support files that should be provided by avr-libc are missing. I've reported a Debian bug about this. Until it's fixed, however, it's easy enough to work around by providing the missing files.

Start off by downloading the "Atmel ATtiny Series Device Support" file from http://packs.download.atmel.com/. This is a free and open download, licensed under Apache v2. This file carries the extension atpack but it's actually just a ZIP file:

$ file Atmel.ATtiny_DFP.1.3.229.atpack 
Atmel.ATtiny_DFP.1.3.229.atpack: Zip archive data, at least v1.0 to extract

Note that by default it'll unpack into the working directory, so you'll want to create a temporary folder to work in:

$ mkdir pack

$ cd pack/

$ unzip ~/Atmel.ATtiny_DFP.1.3.229.atpack 
Archive:  /home/leo/Atmel.ATtiny_DFP.1.3.229.atpack
   creating: atdf/
   creating: avrasm/
   creating: avrasm/inc/

From here, you can now copy the relevant files out to where avr-gcc will find them:

$ sudo cp include/avr/iotn?*1[2467].h /usr/lib/avr/include/avr/
$ sudo cp gcc/dev/attiny?*1[2467]/avrxmega3/*.{o,a} /usr/lib/avr/lib/avrxmega3/
$ sudo cp gcc/dev/attiny?*1[2467]/avrxmega3/short-calls/*.{o,a} /usr/lib/avr/lib/avrxmega3/short-calls/

Finally, there's one last task that needs doing. Locate the main avr/io.h file (it should live in /usr/lib/avr/include) and add the following lines somewhere within the main block of similar lines. These are needed to redirect from the toplevel #include <avr/io.h> towards the device-specific file.

#elif defined (__AVR_ATtiny212__)
#  include <avr/iotn212.h>
#elif defined (__AVR_ATtiny412__)
#  include <avr/iotn412.h>
#elif defined (__AVR_ATtiny214__)
#  include <avr/iotn214.h>
#elif defined (__AVR_ATtiny414__)
#  include <avr/iotn414.h>
#elif defined (__AVR_ATtiny814__)
#  include <avr/iotn814.h>
#elif defined (__AVR_ATtiny1614__)
#  include <avr/iotn1614.h>
#elif defined (__AVR_ATtiny3214__)
#  include <avr/iotn3214.h>
#elif defined (__AVR_ATtiny416__)
#  include <avr/iotn416.h>
#elif defined (__AVR_ATtiny816__)
#  include <avr/iotn816.h>
#elif defined (__AVR_ATtiny1616__)
#  include <avr/iotn1616.h>
#elif defined (__AVR_ATtiny3216__)
#  include <avr/iotn3216.h>
#elif defined (__AVR_ATtiny417__)
#  include <avr/iotn417.h>
#elif defined (__AVR_ATtiny817__)
#  include <avr/iotn817.h>
#elif defined (__AVR_ATtiny1617__)
#  include <avr/iotn1617.h>
#elif defined (__AVR_ATtiny3217__)
#  include <avr/iotn3217.h>

Having done this we find we can now compile firmware for these new chips:

avr-gcc -std=gnu99 -Wall -Os -DF_CPU=20000000 -mmcu=attiny814 -flto -ffunction-sections -fshort-enums -o .build/firmware.elf src/main.c
avr-size .build/firmware.elf
   text    data     bss     dec     hex filename
   3727      30     105    3862     f16 .build/firmware.elf
avr-objcopy -j .text -j .rodata -j .data -O ihex .build/firmware.elf firmware-flash.hex

Next post I'll write more about my opinions on these chips, highlighting some of the newer features and changes.


  1. Hi, do you know which pins should I use to write firmware into Attiny416 ?

    1. On any of the ATtiny 1-series, UPDI is on PA0; which on the tiny*16 chips is pin 16 of the SOIC20 package, or pin 19 of the VQFN20.

  2. Hi Paul. Thanks for documenting this so clearly; you've confirmed my guess that it might provide a work-around. I can scarcely believe that in late 2020 Microchip's intransigence over FLOSS support still makes it necessary, but it does. BTW, the same approach may be possible using the appropriate Device Family Pack for the Arduino IDE: that IDE also has the latest avr-gcc (5.40) under the hood.

    1. Sorry, I should have been clearer: the latest avr-gcc toolchain is 3.6.2; the old GNU gcc 5.4.0 is what it's based on. GNU gcc is now up to version 10 and supports the new ATtiny 0- and 1-Series chips, but avr-gcc is years behind.

  3. Thanks for this!
    I found it really helpful. I've subsequently found a cleaner way for users to provide the pack files to the compiler without modifying the /usr/... directories maintained by the package manager.
    If you're interested, I've documented the process here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930195#60