# Flashing a SAMD11 with a Raspberry pi and OpenOCD¶

Let’s say that you want to program a SAMD target, but you don’t have any SWD programmers at hand. In this tutorial, we’ll bootstrap a SWD programmer by flashing its firmware with a raspberry pi first.

## Raspberry pi setup¶

### flashing the OS¶

You can download the latest OS for you pi here. I use an older Raspberry pi 2B so I have to settle for the 32 bit version.

Pick a micro SDHC card with at least 8Gb on it, and burn the image file on it. A good burner is balena etcher.

After this, you could just use the raspberry pi with a screen and keyboard. But if you’re anything like me, you’ll be perfectly happy connecting to the pi remotely with SSH. In that case, you can follow the next section.

If you want to connect remotely, you need to enable ssh before your first boot. There’s a special trick for that: create a blank file named ssh (no file extension) at the root of the boot partition on the SD card.

You can either connect the pi to ethernet or WiFi. If using WiFi, create a file named wpa_supplicant.conf in the boot partition containing:

country=us
update_config=1
ctrl_interface=/var/run/wpa_supplicant

network={
scan_ssid=1
ssid="MyNetworkSSID"
psk="Pa55w0rd1234"
}


where you need to change the country code, your network’s name (SSID) and password (psk).

You can now insert the SD card and boot the pi. There is no built-in WiFi on my Raspberry pi 2B so I’m using a dongle:

Wait a few seconds, your pi should appear on the network. If you’re not sure what’s the IP address, nmap is a good tool for snooping around a network. Let’s scan for an opened SSH port (22) on my 192.168.0.0 subnet:

quentin@desktop:~$nmap -p 22 --open 192.168.0.* Starting Nmap 7.60 ( https://nmap.org ) at 2022-03-19 00:46 CET Nmap scan report for 192.168.0.10 Host is up (0.0012s latency). PORT STATE SERVICE 22/tcp open ssh Nmap scan report for 192.168.0.30 Host is up (0.0025s latency). PORT STATE SERVICE 22/tcp open ssh Nmap done: 256 IP addresses (11 hosts up) scanned in 16.62 seconds  That 192.168.0.30 address is new to me so it must be the pi. I can connect with ssh or putty on windows: ssh pi@192.168.0.30  The password is raspberry by default, you should change this with the passwd command. ## Install OpenOCD¶ We’ll now follow this guide for installing OpenOCD on the pi. Let’s start with the dependencies: sudo apt-get install autoconf libtool libusb-dev  Let’s now pull openocd’s git repo: git clone --recursive git://git.code.sf.net/p/openocd/code openocd-code  Enter the directory and launch ./bootstrap: cd openocd-code/ ./bootstrap  Then configure with raspberry pi GPIO: ./configure --enable-bcm2835gpio  Build, and install (it can take a while): make sudo make install  OpenOCD is now installed, and on the path so we can run it from any folder. You can now delete the openocd-code folder if you wish. ## Configure OpenOCD¶ We now need two configuration files: • Configuration of the protocol and the pins on the pi. • Description of the target and procedure to upload the file. Let’s create a folder and the first file, called raspberrypi-custom.cfg: cd ~ mkdir swd cd swd nano raspberrypi-custom.cfg  Write the following in the file, and uncomment the correct speed configuration for your pi model: # # Custom configuration for Raspberry pi's 1/2/3 GPIO # adapter driver bcm2835gpio bcm2835gpio peripheral_base 0x3F000000 transport select swd # SPEED CONFIG (uncomment one) # ---------------------------- # Raspi1 BCM2835: (700Mhz) # bcm2835gpio speed_coeffs 113714 28 # Raspi2 BCM2836 (900Mhz): bcm2835gpio speed_coeffs 146203 36 # Raspi3 BCM2837 (1200Mhz): # bcm2835gpio speed_coeffs 194938 48 # GPIO CONFIG # ----------- # SWD GPIO set: swclk swdio bcm2835gpio swd_nums 25 24 # SWD GPIO set: reset bcm2835gpio srst_num 18 reset_config srst_only srst_push_pull  We can now create a file specific to our use case, named openocd.cfg: nano openocd.cfg  Write the following: source raspberrypi-custom.cfg set transport swd set CHIPNAME at91samd11c14 source [find target/at91samdXX.cfg] init targets reset halt at91samd bootloader 0 program free_dap_d11c_mini.bin verify at91samd bootloader 4096 reset shutdown  Note the reference to raspberrypi-custom.cfg, and another file specific to the SAMD family, included somewhere in openocd’s internal files. The list of commands tell openocd to do the following: • Reset the chip • Start writing the bootloader at postion 0 in the flash • Write and verify the file named free_dap_d11c_mini.bin • Finish at position 4096 • Reset and exit You should download free_dap_d11c_mini.bin and place it next to openocd.cfg: wget http://academy.cba.mit.edu/classes/embedded_programming/SWD/free_dap_d11c_mini.bin  Let’s check that everything is in place: pi@raspberrypi:~/swd$ ls -l
total 16
-rw-r--r-- 1 pi pi 6536 Feb 25  2020 free_dap_d11c_mini.bin
-rw-r--r-- 1 pi pi  251 Mar 18 22:46 openocd.cfg
-rw-r--r-- 1 pi pi  605 Mar 18 22:51 raspberrypi-custom.cfg


## Connect the target¶

As you saw in the raspberrypi-custom.cfg file, the following pins are used for implementing SWD:

• SWDIO: 24
• SWCLK: 25
• nRESET: 18

Note that those are GPIO numbers, not physical pin numbers on the header. Here’s where to connect your cables (source: element14):

I milled and soldered a SWD programmer based on this project. You can power the target board with a USB extension cable, and connect every pin like mentioned. The color code of the cables is the same as in the diagram:

## Run OpenOCD¶

We now simply need to run openocd in the folder we previously created:

pi@raspberrypi:~/swd $openocd Open On-Chip Debugger 0.11.0+dev-00615-gbe0d68eb6 (2022-03-18-22:01) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : BCM2835 GPIO JTAG/SWD bitbang driver Info : clock speed 400 kHz Info : SWD DPIDR 0x0bc11477 Info : [at91samd11c14.cpu] Cortex-M0+ r0p1 processor detected Info : [at91samd11c14.cpu] target has 4 breakpoints, 2 watchpoints Info : [at91samd11c14.cpu] external reset detected Info : starting gdb server for at91samd11c14.cpu on 3333 Info : Listening on port 3333 for gdb connections Info : SWD DPIDR 0x0bc11477 target halted due to debug-request, current mode: Thread xPSR: 0x21000000 pc: 0x00000ba8 msp: 0x20000fd8 Info : SWD DPIDR 0x0bc11477 target halted due to debug-request, current mode: Thread xPSR: 0x21000000 pc: 0x00000ba8 msp: 0x20000fd8 ** Programming Started ** Info : SAMD MCU: SAMD11C14A (16KB Flash, 4KB RAM) ** Programming Finished ** ** Verify Started ** ** Verified OK ** Info : SWD DPIDR 0x0bc11477 shutdown command invoked Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections  After a successful programming, our board should now show up as a USB device named “CMSIS-DAP Adapter”. You can check this with lsusb: pi@raspberrypi:~/bootloader$ lsusb
Bus 001 Device 013: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
Bus 001 Device 019: ID 6666:6666 Prototype product Vendor ID Generic CMSIS-DAP Adapter
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub


The programmer can now be used as described here.

## Troubleshooting¶

You might get the following error message when running openocd:

Error: Error connecting DP: cannot read IDR


This means that no communication could be established with the target board. Triple check the cable connections and your board’s design/execution.