Flashing code to a 32u4 chip

Notes for my future self

2020-06-05 avr 32u4 lowlevel

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.



Thank you for reading this post. If you enjoyed the content, and want to let me know, or want to ask any questions, please contact me via one of the methods listed here. If you would like to be notified about future posts, feel free to load my rss feed into your favorite feed reader, or follow me on Twitter for notifications about my work and future posts.

If you have the time to read some more, I recommend checking out one of the following posts:

Connecting to a Minecraft server over IRC
This post outlines the process of writing a custom IRC server that can bridge between your favorite IRC client, and any Minecraft server
My first mechanical keyboard: The Vortex Core
I recently purchased my first mechanical keyboard, and decided to go "all in" with a 40% layout.
Using Bazel to create Minecraft modpacks
I decided to modernize my system for producing builds of my personal Minecraft modpack using the Bazel buildsystem.


Made with ♥ by Evan Pratten | RSS | API Status