tommycoolman

tech. blog. repeat.

Menu
Menu
  • HOME
  • QR CODES
  • CONTACT

Burn an Arduino Bootloader with a Raspberry Pi. The easy way.

Posted on February 4, 2023March 21, 2023 by tommy

Table of Contents

  • Getting Started
    • Download the image
    • Write the image to an SD card
    • Booting and credentials
  • Wiring Example
  • avrdude Command
    • The -U flag, further details
      • memtype
      • op
      • format (optional)
  • Examples
    • Uploading blink sketch to ATtiny85
    • Uploading Adafruit OLED demo to Nano
    • Reading EEPROM from ATmega8
  • Compiling Sketches on the Raspberry Pi
  • Samba Filesharing
  • Common ‘part’ names

This process uses a modified version of the official Raspberry Pi OS (2020-02-13-raspbian-buster-lite.img). It has been configured with the tools necessary to burn an Arduino style bootloader using the Raspberry Pi’s GPIO pins (described here).

Brief summary of steps:

  • Wire Raspberry Pi GPIO pins to Arduino ICSP pins
  • Boot the custom Raspberry Pi image
  • Connect a computer to Raspberry Pi WiFi
  • SSH into Raspberry Pi
  • cd to ‘/arduino’ and run ‘./burn.sh’

This requires a Raspberry Pi and six jumper wires to connect to your target Arduino or similar microcontroller. Once the Raspberry Pi is booted, it will broadcast an SSID (unsecured). Once connected to the Raspberry Pi, an SSH client such as PuTTY can be used login and execute commands. Alternatively, a keyboard and monitor can be attached directly.

I will be using an Arduino Uno with the 328p microcontroller, but multiple microcontrollers are supported.

Getting Started

Download the image

Download Link – 460MB

MD5: 543417af80e140c609b8dec69a09f229

Write the image to an SD card

I recommend using the official Raspberry Pi imager. Linux’s ‘dd’, Balena Etcher, or similar programs can also work. The image file is compressed using ‘xz’ — the Raspberry Pi imager will automatically decompress the image, but you may need to do this manually for other programs.

You will need a 4GB microSD card.

Booting and credentials

Once booted, the Raspberry Pi should broadcast an SSID of “raspberry”. This is an open wifi hotspot. You will need to connect and login using any SSH client.

You can also connect a keyboard and monitor directly.

SSID: raspberry
passkey: none (open)

IP Address: 192.168.2.1
username: root
password: pi

Wiring Example

This image shows the wiring from the Raspberry Pi to the Arduino Uno’s ICSP pin header. Not all ICSP pin headers are the same. If you don’t have any ICSP headers, you will need to determine which pins directly correspond to the SCK/MOSI/MISO and VCC/GND/RST.

avrdude Command

Once you’re connected to the Raspberry Pi, there is a directory called ‘/arduino’ that contains the avrdude configuration file, different bootloaders, and a script called ‘burn.sh’ that has examples of how to burn programs to different Arduino boards.

‘burn.sh’ contains a few examples. You will need to use the correct command and fuse settings to match your microcontroller.

Below is the command to burn the blink program (which happens to include a bootloader) to the Arduino Uno. The fuse bytes are included, but not necessary if you want to keep the existing fuse settings.

avrdude -C /arduino/avrdude.conf \
	-p atmega328p \
	-c pi_1 -v \
	-U flash:w:/arduino/hex/atmega328p_blink.hex:i \
	-U lfuse:w:0xf7:m \
	-U hfuse:w:0xd6:m

The -U flag, further details

Performs memory operations. Multiple operations can be performed in one command.

-U memtype:op:filename[:format]

memtype

  • calibration One or more bytes of RC oscillator calibration data.
  • eeprom The EEPROM of the device.
  • efuse The extended fuse byte.
  • flash The flash ROM of the device.
  • fuse The fuse byte in devices that have only a single fuse byte.
  • hfuse The high fuse byte.
  • lfuse The low fuse byte.
  • lock The lock byte.

op

  • r read memory and write to file
  • w read file and write to memory
  • v read memory and file, verify both

format (optional)

  • i Intel Hex
  • s Motorola S-record
  • r binary, little-endian
  • m immediate, 0x for HEX values

Examples

Uploading blink sketch to ATtiny85

avrdude -C /arduino/avrdude.conf \
    -p t85 -c pi_1 -v \
    -U flash:w:/arduino/hex/attiny85_blink.hex:i \
    -U lfuse:w:0xE2:m \
    -U hfuse:w:0xDF:m \
    -U efuse:w:0xFF:m \
    -U lock:w:0xFF:m 

Uploading Adafruit OLED demo to Nano

This sketch takes a little longer to upload and it’s easier to “see” avrdude doing its thing.

Notice how the Nano’s ICSP pins are oriented differently.
avrdude -C /arduino/avrdude.conf \
    -p atmega328p -c pi_1 -v \
    -U flash:w:/arduino/hex/atmega328p_oled.hex:i \
    -U lfuse:w:0xf7:m \
    -U hfuse:w:0xd6:m

Reading EEPROM from ATmega8

I’ve programmed a message into the EEPROM of an ATmega8A and I will read it back to a file called ‘eeprom.dump’ and then I will hexdump the file to see the message.

avrdude -C /arduino/avrdude.conf \
-p m8 -c pi_1 -v \
-U eeprom:r:/arduino/eeprom.dump:r

Compiling Sketches on the Raspberry Pi

‘arduino-cli’ is installed. Within the ‘/arduino’ directory is the standard ‘blink’ program. The script ‘compile.sh’ has an example of how to compile using ‘arduino-cli’

arduino-cli compile --fqbn arduino:avr:uno -v blink/ --output-dir blink

This command will produce the compiled program, including a HEX file, that can be uploaded.

Samba Filesharing

The Raspberry Pi has Samba installed and is sharing the ‘/arduino’ directory.

Common ‘part’ names

These are used with the ‘avrdude’ command and the ‘-p’ flag.

uc3a0512 = AT32UC3A0512
c128 = AT90CAN128
c32 = AT90CAN32
c64 = AT90CAN64
pwm2 = AT90PWM2
pwm216 = AT90PWM216
pwm2b = AT90PWM2B
pwm3 = AT90PWM3
pwm316 = AT90PWM316
pwm3b = AT90PWM3B
1200 = AT90S1200
2313 = AT90S2313
2333 = AT90S2333
2343 = AT90S2343
4414 = AT90S4414
4433 = AT90S4433
4434 = AT90S4434
8515 = AT90S8515
8535 = AT90S8535
usb1286 = AT90USB1286
usb1287 = AT90USB1287
usb162 = AT90USB162
usb646 = AT90USB646
usb647 = AT90USB647
usb82 = AT90USB82
m103 = ATmega103
m128 = ATmega128
m1280 = ATmega1280
m1281 = ATmega1281
m1284 = ATmega1284
m1284p = ATmega1284P
m1284rfr2= ATmega1284RFR2
m128rfa1 = ATmega128RFA1
m128rfr2 = ATmega128RFR2
m16 = ATmega16
m161 = ATmega161
m162 = ATmega162
m163 = ATmega163
m164p = ATmega164P
m168 = ATmega168
m168p = ATmega168P
m168pb = ATmega168PB
m169 = ATmega169
m16u2 = ATmega16U2
m2560 = ATmega2560
m2561 = ATmega2561
m2564rfr2 = ATmega2564RFR2
m256rfr2 = ATmega256RFR2
m32 = ATmega32
m3208 = ATmega3208
m3209 = ATmega3209
m324p = ATmega324P
m324pa = ATmega324PA
m325 = ATmega325
m3250 = ATmega3250
m328 = ATmega328
m328p = ATmega328P
m328pb = ATmega328PB
m329 = ATmega329
m3290 = ATmega3290
m3290p = ATmega3290P
m329p = ATmega329P
m32m1 = ATmega32M1
m32u2 = ATmega32U2
m32u4 = ATmega32U4
m406 = ATMEGA406
m48 = ATmega48
m4808 = ATmega4808
m4809 = ATmega4809
m48p = ATmega48P
m48pb = ATmega48PB
m64 = ATmega64
m640 = ATmega640
m644 = ATmega644
m644p = ATmega644P
m644rfr2 = ATmega644RFR2
m645 = ATmega645
m6450 = ATmega6450
m649 = ATmega649
m6490 = ATmega6490
m64m1 = ATmega64M1
m64rfr2 = ATmega64RFR2
m8 = ATmega8
m8515 = ATmega8515
m8535 = ATmega8535
m88 = ATmega88
m88p = ATmega88P
m88pb = ATmega88PB
m8u2 = ATmega8U2
t10 = ATtiny10
t11 = ATtiny11
t12 = ATtiny12
t13 = ATtiny13
t15 = ATtiny15
t1604 = ATtiny1604
t1606 = ATtiny1606
t1607 = ATtiny1607
t1614 = ATtiny1614
t1616 = ATtiny1616
t1617 = ATtiny1617
t1634 = ATtiny1634
t20 = ATtiny20
t202 = ATtiny202
t204 = ATtiny204
t212 = ATtiny212
t214 = ATtiny214
t2313 = ATtiny2313
t24 = ATtiny24
t25 = ATtiny25
t26 = ATtiny26
t261 = ATtiny261
t28 = ATtiny28
t3214 = ATtiny3214
t3216 = ATtiny3216
t3217 = ATtiny3217
t4 = ATtiny4
t40 = ATtiny40
t402 = ATtiny402
t404 = ATtiny404
t406 = ATtiny406
t412 = ATtiny412
t414 = ATtiny414
t416 = ATtiny416
t417 = ATtiny417
t4313 = ATtiny4313
t43u = ATtiny43u
t44 = ATtiny44
t441 = ATtiny441
t45 = ATtiny45
t461 = ATtiny461
t5 = ATtiny5
t804 = ATtiny804
t806 = ATtiny806
t807 = ATtiny807
t814 = ATtiny814
t816 = ATtiny816
t817 = ATtiny817
t84 = ATtiny84
t841 = ATtiny841
t85 = ATtiny85
t861 = ATtiny861
t88 = ATtiny88
t9 = ATtiny9
x128a1 = ATxmega128A1
x128a1d = ATxmega128A1revD
x128a1u = ATxmega128A1U
x128a3 = ATxmega128A3
x128a3u = ATxmega128A3U
x128a4 = ATxmega128A4
x128a4u = ATxmega128A4U
x128b1 = ATxmega128B1
x128b3 = ATxmega128B3
x128c3 = ATxmega128C3
x128d3 = ATxmega128D3
x128d4 = ATxmega128D4
x16a4 = ATxmega16A4
x16a4u = ATxmega16A4U
x16c4 = ATxmega16C4
x16d4 = ATxmega16D4
x16e5 = ATxmega16E5
x192a1 = ATxmega192A1
x192a3 = ATxmega192A3
x192a3u = ATxmega192A3U
x192c3 = ATxmega192C3
x192d3 = ATxmega192D3
x256a1 = ATxmega256A1
x256a3 = ATxmega256A3
x256a3b = ATxmega256A3B
x256a3bu = ATxmega256A3BU
x256a3u = ATxmega256A3U
x256c3 = ATxmega256C3
x256d3 = ATxmega256D3
x32a4 = ATxmega32A4
x32a4u = ATxmega32A4U
x32c4 = ATxmega32C4
x32d4 = ATxmega32D4
x32e5 = ATxmega32E5
x384c3 = ATxmega384C3
x384d3 = ATxmega384D3
x64a1 = ATxmega64A1
x64a1u = ATxmega64A1U
x64a3 = ATxmega64A3
x64a3u = ATxmega64A3U
x64a4 = ATxmega64A4
x64a4u = ATxmega64A4U
x64b1 = ATxmega64B1
x64b3 = ATxmega64B3
x64c3 = ATxmega64C3
x64d3 = ATxmega64D3
x64d4 = ATxmega64D4
x8e5 = ATxmega8E5
  • Programmatically Validate Addresses with the UPS Developer Kit, Tracking Integration
    May 15, 2022
  • Managing Hyper-V Server in a Workgroup Environment
    January 22, 2022
  • Securing Remote Desktop with SSH Tunneling
    August 10, 2021
  • Control Two Independent Stepper Motors with an Arduino
    July 31, 2021
©2023 tommycoolman