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:

Tunneling a printer from a home network to a VPN
I use a self-hosted VPN to access all my devices at all times, and to deal with my school's aggressive firewall. This post explains the process I use for exposing my home printer to the VPN.
2020 Wrap-Up
2020 has been my most productive year so far in terms of software development. This post looks back at the year
How I have tweaked my Minecraft client to be 'just right'
Over the past 10 years, I have been building the perfect Minecraft experience for myself. This post shares the collection of mods I run, and why I use them.


Made with ♥ by Evan Pratten | RSS | API Status