This is a super high level (and probably incomplete in some places) guide and list of resources related to using a Raspberry Pi’s GPIO pins to flash USBaspLoader onto an ATmega328P microcontroller unit (MCU) and flashing QMK onto it over USB. I wrote it up after learning a bit about circuit design and MCU programming, and I hope it’s helpful as a resource to others.
You need to have avrdude and avr-gcc installed on a Raspberry Pi.
These two sites were very helpful in wiring up the ATmega328P to the GPIO pins on the Raspberry Pi:
- How to Program an AVR/Arduino using the Raspberry Pi GPIO
- Program an AVR or Arduino Using Raspberry Pi GPIO
The pin numbers in
avrdude.conf are the GPIO numbers, not the physical pin numbers (so with the pinout diagram here you use the gp* numbers in
avrdude.conf, not the numbers on the pins themselves).
Once everything is hooked up, make sure avrdude can see the MCU. This is assuming you named your custom programmer in
avrdude -c pi -p m328p -v
Assuming that was successful, we can erase the MCU to start fresh:
avrdude -c pi -p m328p -v -e
You need to set various fuses on the MCU. This is a super helpful beginner-level tutorial
We’ll set fuses for a 16 MHz crystal oscillator, unprogram CKDIV8 (divide clock speed by 8), disable brown-out detection, and probably some other things I’m forgetting about:
sudo avrdude -c pi -p m328p -v -u -U lfuse:w:0xFF:m sudo avrdude -c pi -p m328p -v -u -U hfuse:w:0xD8:m sudo avrdude -c pi -p m328p -v -u -U efuse:w:0xFF:m
F_CPU = 16000000 DEVICE = atmega328p FLASHADDRESS = 0x7000
Compile and flash USBaspLoader:
make clean make firmware sudo make flash
Physically transfer the ATmega328P to another breadboard that’s wired similar to the
with-zener schematic from the V-USB repo (you can open this with an older free version of EAGLE; version 6.6.0 on macOS works) or the schematic for the plaid keyboard (you can open this with KiCad).
To test that the bootloader is working, hold down the switch that’s wired to the
JUMPER_BIT defined in USBaspLoader’s
bootloaderconfig.h, press the switch that’s wired to the reset pin (pin 1 or PC6), release the reset switch, and then reset the jumper switch. This should boot the MCU into the bootloader that you just flashed, and you should be able to see the chip with avrdude:
avrdude -c usbasp -p m328p -v
If this doesn’t work, something is probably wrong with your wiring or the fuses, or the bootloader didn’t flash correctly.
I don’t have in-depth instructions for this, but the QMK hand-wiring guide is helpful. All of the changes mentioned are in this commit.
Clone the QMK repo here. Define the matrix rows and columns. Comment out soft serial pin. Add your layout to
MCU = atmega328p ARCH = AVR
PROGRAM_CMD = avrdude -c usbasp -p m328p -v -U flash:w:$(BUILD_DIR)/$(TARGET).hex
Compile and flash from the QMK repo directory: