A photo of Evan Pratten
Evan Pratten

Flashing code to a 32u4 chip

Notes for my future self

The ATmega32u4 (aka. 32u4) chip is one of my favorite microcontrollers to work with. It is a low power, 8-bit, AVR-based system developed by Atmel. They are commonly used in Arduino Leonardo development boards and programmed via the Arduino IDE, but I prefer having as much control over the device as I can. So I choose to program these chips directly in AVRASM and AVR-C.

This post will go over how to easily flash code to a 32u4 chip from a Linux host, and exists as reference for when I inevitably need to refresh my memory in the future.

Getting the needed tools

Before starting, the following tools are needed:

Writing a “Hello, world!” for AVR

Since you can’t exactly “print to console” with a microprocessor, this “Hello, world!” will consist of toggling one of the 32u4’s I/O pins once every half second. In this case, we will write to PB5 (pin 9 on an Arduino Leonardo). If you don’t understand how AVR code works, I recommend reading a simple tutorial. This program simply configures DDRB to allow output for PB5, and toggles the PB5 bit in PORTB every 500ms.

// main.cc

#include <avr/io.h>
#include <util/delay.h>

int main(int argc, char const* argv[]) {

    DDRB |= (1 << PB5); 
    for (;;) {
        PORTB= 0b00100000;
        _delay_ms(500); 
        PORTB= 0b00000000; 
        _delay_ms(500);
    }

    return 0;
}

Compiling

This code can now be compiled with:

avr-g++ -DF_CPU=16000000 -D __AVR_ATmega32U4__ -mmcu=atmega32u4 -Iinclude -DBAUD=9600 -std=c++11 -g -Os -w -fdata-sections -MMD -flto -c -o main.o main.cc

And linked with:

avr-g++ -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega32u4 -Iinclude -std=c++11 -DF_CPU=16000000 -o main.elf main.o
avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 main.elf main.eep
avr-objcopy -O ihex -R .eeprom main.elf main.hex

To create a HEX file for the program binary, and an eeprom dump. These are both going to be uploaded to the chip in the next step.

Flashing the 32u4

The 32u4 chip must be in it’s bootloader in order to have it’s memory written. This can be done in one of two ways. The first (my preference) is to quickly reset the chip before running avrdude by pulling the RST line to ground. You can also put the chip in it’s bootloader by connecting to UART at 1200bps. Once in the bootloader, the chip will stay there for 10 seconds.

WIth the 32u4 in it’s bootloader, we can flash our compiled code with:

sudo avrdude -patmega32u4 -cavr109 -P /dev/ttyACM0 -b57600 -v -U flash:w:main.hex:i -U eeprom:w:main.eep

NOTE: /dev/ttyACM0 may need to be changed depending on the system

Once the code has uploaded, reset the chip to start the code.