Bare-metal programming the tinyAVR 0 microcontrollers

Please log in or register to like posts.

All it’s seemingly you’ll perhaps perhaps like is a textual snarl editor, a makefile and a USB-serial cable.


Are you an 8-bit or a 32-bit programmer?

At OMZLO, we devour been mainly focussing our trend efforts on more moderen 32-bit Arm-Cortex chips (STM32 and SAMD), which on the total offer more RAM, more meander, more peripherals, at a identical or more inexpensive price-point than older 8-bit MCUs. But 8-bit MCUs are a long way from ineffective. Microchip has seriously released a brand unique series of chips, collectively branded because the “tinyAVR 0-series”, which offer more up to the moment peripherals than the older AVR chips at a indubitably aggressive price point. They look fancy the finest candidate for easy products that construct not want the total sides and beautiful-tuning capabilities of the more moderen 32-bit MCUs. 8-bit MCUs are moreover substantially more efficient to program, which translates into quicker trend time.

Thanks to the success of the Arduino UNO, there are hundreds tutorials on-line that tag guidelines on how to program 8-bit Atmega328 microcontrollers and their cousins fancy the Attiny85 the utilization of protest register web correct of entry to, with out the Arduino language or any vendor IDE equivalent to Atmel Studio. Correct google “atmega328 blinky”. All it’s seemingly you’ll perhaps perhaps like is an AVR C-compiler, a textual snarl editor, avrdude, and an AVR programmer. Some sources even tag guidelines on how to moreover map the electronics wished to web a smartly-liked atmega328 running on a breadboard. On the opposite hand, it’s arduous to assemble the identical data for these more moderen “tinyAVR 0” chips.

Obviously, Microchip offers the total tools vital to program these more moderen “TinyAVR” MCUs with their windows-fully IDE. There are moreover “Arduino cores” for these sorts of more moderen “TinyAVR” MCUs that mean it’s seemingly you’ll perhaps perhaps be in a region to program them with the Arduino IDE. But all over again, in case you fancy to write code for MCUs in “baremetal” model, alongside side your popular textual snarl editor, a makefile, and a c-compiler, there are few sources accessible on-line.

In this weblog post, we are in a position to record guidelines on how to program a blinky firmware on an Attiny406, from the ground up, the utilization of perhaps the most productive tools. Many of the issues described right here might perhaps perhaps perhaps be easily transposed to varied TinyAVR MCUs. Our map is on the total guided toward macOS or Linux customers, however might perhaps perhaps level-headed moreover be acceptable in an MS-Windows atmosphere with about a minor adjustments.


We determined to play with the Attiny406, with a search of the utilization of it at some point to substitute the Attiny45 we currently exercise on the PiWatcher, our Raspberry-Pi watchdog. The Attiny406 has 4K of flash house, 256 bytes of RAM, and might perhaps well flee at 20Mhz with out an exterior clock source.

Surely one of a truly grand differences between the unique TinyAVR MCUs and the older traditional AVR MCU fancy the Attiny85 is that the more moderen chips exercise a varied programming protocol referred to as UPDI, which requires fully 3 pins, versus the 6-pin ISP on the standard AVRs.

A little bit learn reveals that programming TinyAVRs with UPDI might perhaps perhaps perhaps be finished with a straightforward USB-to-serial cable and a resistor, because of the a python instrument referred to as pyupdi, which implies the following connection procedure for firmware add:

                        Vcc                     Vcc
                        +-+                     +-+
                         |                       |
 +---------------------+ |                       | +--------------------+
 | Serial port         +-+                       +-+  AVR scheme        |
 |                     |      +----------+         |                    |
 |                  TX +------+   4k7    +---------+ UPDI               |
 |                     |      +----------+    |    |                    |
 |                     |                      |    |                    |
 |                  RX +----------------------+    |                    |
 |                     |                           |                    |
 |                     +--+                     +--+                    |
 +---------------------+  |                     |  +--------------------+
                         +-+                   +-+
                         GND                   GND


We created a minimalistic breakout board for the Attiny406. The board might perhaps perhaps perhaps be powered by 5V thru USB or a lower 3.3V thru dedicated VCC/GND pins. An LED and a button devour been moreover fitted on the board. For checking out functions, we determined to embed the 4.7K resistor wished for the UPDI programming without delay in the hardware (i.e. resistor R2).
This offers us the following schematic:


The ensuing breakout board is tiny and suits conveniently on a little breadboard. The originate recordsdata are shared on aisler.receive.

Programming the Attiny406 on the board with a USB-serial cable is finished by connecting the headers on the board edge:



We set in pyupdi following the instructions supplied on their webpage.

We linked our USB-Serial cable to the board with the 4 dedicated UPDI pins accessible on the board. Our USB-Serial converter reveals up because the file /dev/tty.usbserial-FTF5HUAV on a MacOS scheme.

To test that the programmer acknowledges the Attiny406, it’s seemingly you’ll perhaps perhaps be in a region to effort a show similar to the following, adapting the slump for the USB-serial converter to your setup:

pyupdi -d tiny406 -c /dev/tty.usbserial-FTF5HUAV -i

This might well level-headed end result in the following output if all goes nicely:

Tool data: {'household': 'tinyAVR', 'nvm': 'P:0', 'ocd': 'D:0', 'osc': '3', 'device_id': '1E9225', 'device_rev': '0.1'}

The C compiler

The typical avr-gcc accessible on macOS with homebrew failed to appear to acknowledge the Attiny406 as a compiler goal, so we went off to set up the avr-gcc compiler supplied by Microchip, which is accessible right here. Downloading the compiler requires you to personal an fable on the Microchip web pages, which is pretty disturbing.

Once downloaded, we extracted the supplied archive in a dedicated itemizing. The bin itemizing in the archive desires to be added to the PATH variable to form your existence more straightforward. Assuming the downloaded compiler is saved in the itemizing $HOME/Src/avr8-gnu-toolchain-darwin_x86_64, the PATH might perhaps perhaps perhaps be altered by adding the following line to your .bash_profile file:

export PATH=$PATH:$HOME/Src/avr8-gnu-toolchain-darwin_x86_64/bin/

More moderen Attiny MCUs will not be supported out of the sphere by the Microchip avc-gcc compiler. It be a must to download a dedicated Attiny Tool Pack from their web pages, as shown under:

The ensuing downloaded Tool Pack is known as Atmel.ATtiny_DFP.1.6.326.atpack (or identical reckoning on versioning). Though the extension is .atpack, the file is indubitably a zip archive. We modified the extension to .zip and extracted the kit in the itemizing $HOME/Src/Atmel.ATtiny_DFP.1.6.326 next to the compiler recordsdata.

C program

We created the following program that blinks the LED on pin PB5 of our Attiny board at a frequency of 1Hz.

#consist of 
#consist of 

int well-known() {
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0); // living to 20Mhz (assuming fuse 0x02 is living to 2)

    PORTB.DIRSET = (1<<5);
    for (;;) {
        PORTB.OUTSET = (1<<5);
        PORTB.OUTCLR = (1<<5);

The code looks very similar to what it’s seemingly you’ll perhaps perhaps search on a conventional AVR “blinky” program. One visible trade is the utilization of constructions to web correct of entry to varied registers of the MCU: e.g as an alternative of setting bits in PORTB, you web correct of entry to PORTB.DIRSET.

The assorted visible trade is the clock setup code _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0). Out of the sphere, at reset, the Attiny406 runs at 3.33Mhz, which corresponds to a injurious frequency of 20Mhz with a 6x clock divider utilized. To permit the fleshy 20Mhz meander, the register CLKCTRL.MCLKCTRLB is cleared. Because this register desires to be safe in opposition to accidental adjustments, the Attiny406 requires a particular programming sequence to adjust it. Happily, this is natively offered by the macro _PROTECTED_WRITE. Extra little print come in in the Attiny406 datasheet.

When put next with an STM32 or a SAMD21, the code is blissfully easy.


We capture the following itemizing constructing where:

  • Src/Atmel.ATtiny_DFP.1.6.326/ is the set of the Microchip Tool Pack
  • Src/attiny406-test/ is the itemizing where the code above is saved in a file referred to as well-known.c

Compiling the code might perhaps perhaps perhaps be completed by issuing the following show inner attiny406-test/ itemizing,:

avr-gcc -mmcu=attiny406 -B ../Atmel.ATtiny_DFP.1.6.326/gcc/dev/attiny406/ -O3 -I ../Atmel.ATtiny_DFP.1.6.326/consist of/ -DF_CPU=20000000L -o attiny406-test.elf well-known.c

An -O optimization flag is required to form the _delay_ms() characteristic calls work successfully, besides to defining the variable F_CPU to replicate the expected chip clock meander. The relaxation of the parameters present the set of the Attiny406 scheme-particular recordsdata we beforehand extracted from the Tool Pack.

Importing the firmware to the MCU requires a conversion to the intel HEX format and a call to the pyupdi instrument. To take care of all these steps, we created a straightforward Makefile.

ELF=$(notdir $(CURDIR)).elf  
HEX=$(notdir $(CURDIR)).hex

CFLAGS=-mmcu=attiny406 -B ../Atmel.ATtiny_DFP.1.6.326/gcc/dev/attiny406/ -O3
CFLAGS+=-I ../Atmel.ATtiny_DFP.1.6.326/consist of/ -DF_CPU=$(F_CPU)
LDFLAGS=-mmcu=attiny406 -B ../Atmel.ATtiny_DFP.1.6.326/gcc/dev/attiny406/

all:    $(HEX)  

$(ELF): $(OBJS)
                $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)

$(HEX): $(ELF)
                avr-objcopy -O ihex -R .eeprom $< $@

flash:  $(HEX)
                pyupdi -d tiny406 -c /dev/tty.usbserial-FTF5HUAV -f attiny406-test.hex

                pyupdi -d tiny406 -c /dev/tty.usbserial-FTF5HUAV -fr

                rm -rf $(OBJS) $(ELF) $(HEX)

To gather the code, we merely form form. Importing is finished with form flash. This Makefile might perhaps perhaps perhaps be extra enhanced as wished.


With the grand tools, baremetal programming on the unique TinyAVR MCUs is as easy as on its older AVR cousins.

Within the occasion you devour programming guidelines for the AVRTiny, please portion them with us on on Twitter or in the feedback under.



It be mountainous that somebody else is doing issues with these MCUs, I’ve mature them in some most up-to-date initiatives and they’re mountainous, I’m the utilization of the attiny1617 in my well-known initiatives.

I wrote a script to automate setup of the toolchain right here:

Which I judge supports the 406. I have not tried it on a Mac, the heart of attention is Linux.

I’m blissful that I construct not must exercise any fancy libraries (with the exception of the avr C library and their very minimal runtime / startup code) and it’s all easy ample that I can disassemble my firmware and search exactly what’s going down.

Discover Robson, about 4 hours in the past

Hump away a observation

Learn Extra


Already reacted for this post.

Nobody liked ?