This repo contains notes on creating custom SAMD21 microcontroller boards, ready for CircuitPython or Arduino. It should also work if you want to code with C++, though that wasn't the endpoint I was looking for. I had a slightly frustrating process working this out, particularly because of some issues which aren't explicitly documented, so I'm recording it here.
I cracked this process after reading a few other resources, particularly Adafruit's How to Program SAMD Bootloaders, and the Git repo/Issues for Adafruit's uf2-samdx1 bootloader code repo.
- A SAMD21 chip. I used a TQFP-48 format ATSAMD21G18A-U soldered to a breakout board.
- An SWD programmer. I used a Segger J-link EDU Mini.
- A way to connect the J-link Edu to your board. I used Adafruit's SWD breakout and some jumper wires.
- The accessory components necessary to get the SAMD21 chip running and connected via USB, including a 3v3 power regulator, a 10K resistor, some capacitors, and a 32.768KHz crystal. See the datasheet for the part, and the schematic which I used on a breadboard for the layout.
- Microchip Studio for AVR and SAM Devices. I used the 7.0.2542/Nov 2020 build at the time of writing.
- A bootloader file for the board.
- The easy way to get this is to go to the Adafruit uf2-samdx1 releases page and download the pre-built firmware from there. For my SAMD21G18A board I used the
bootloader-feather_m0-v3.13.0.bin
file. - The hard way to get this is to compile it yourself. I initially did it this way because I'm an idiot and always forget that Git has separate code and releases pages and so tried making my own before remembering pre-built binaries existed.
- Use Git to download the Adafruit SAMDx1 bootloader repo:
git clone https://github.com/adafruit/uf2-samdx1.git
- You need
arm-none-eabi-gcc
to compile the bootloader. However, I got consistent linker errors when using a recent (9.2.1) version of this. In a relatively old issue about linker problems an Adafruiter stated that they were using version 7.2.1/Nov 2017, which can be obtained from arm.com. If your system has another version of this installed you need to make sure the compiler uses the old version when building the bootloader. I'm sure experienced Linux users have a more simple way of doing this, but I:- Moved all
arm-none-eabi-*
binaries from/user/bin/
into a backup folder. - Downloaded v7.2.1 from
arm.com
, and untarred/bzipped it (it extracts into a folder calledgcc-arm-none-eabi
). - Added the
gcc-arm-none-eabi/bin/
folder toPATH
usingexport PATH=$PATH:/path/to/folder/gcc-arm-none-eabi/bin/
. Runarm-none-eabi-gcc --version
to check which version ofgcc
this invokes, it should be v7.2.1. Note that this is temporary and thePATH
will reset the next time you log in. When undoing this change don't forget to move any more recent binaries from the backup folder back intousr/bin/
.
- Moved all
- In the
uf2-samdx1
directory, runmake BOARD=feather_m0
. This should output a file calledbootloader-feather_m0-v3.13.0-2-g56c3e1d.bin
into/uf2-samdx1/build/feather_m0
. This bootloader file should be equivalent to thebootloader-feather_m0-v3.13.0.bin
file you can download from the releases page.
- Use Git to download the Adafruit SAMDx1 bootloader repo:
- The easy way to get this is to go to the Adafruit uf2-samdx1 releases page and download the pre-built firmware from there. For my SAMD21G18A board I used the
- Set up your custom board as desired. The SAMD21G18A requires 3v3 power, so bear that in mind, but the D+/D- pins were happy enough when connected directly to a USB type C breakout.
- Note: When I got to the end of this process I initially had some problems getting the device to be recognised by my (Win10) PC over USB. The capacitors in this schematic are stripped right down to the bare minimum I could get working, but in particular note the 1uF and 10uF capacitors near the crystal. On my breadboard I needed these to be positioned very close to the crystal. Connecting them between 3v3 and GND elsewhere (e.g. beside the MCP1700 3v3 regulator) led to the USB device being detected, but the device descriptor failing.
- Power up the SAM board, and connect the SWD programmer. Your PC shouldn't recognise the board yet.
- Open up Microchip Studio. In the menu bar at the top, go to
Tools > Device Programming
. In theTool
dropdown, select your SWD programmer (SoJ-Link
in my case), and in theDevice
dropdown select your chip (soATSAMD21G18A
in my case). In theInterface
dropdown selectSWD
and click on theApply
button. The options in the rest of the window should change. To confirm that you can talk to the board click on theRead
button beside theDevice signature
box. A value should pop into theDevice signature
box, and theTarget Voltage
should be ~3.3 V
. If none of this works then your SWD debugger can't contact the chip, check your soldering/breadboarding. - Click on the
Fuses
option to the left. In the upper section of the window (where there should be circles with green ticks) look for an option calledUSER_WORD_0.NVMCTRL_BOOTPROT
. This defines an area at the start of the memory which can't be written to, but you want to write the bootloader there, so set it to0 Bytes
and click onProgram
near the bottom of the window. This should take a few seconds to process, andVerify registers ... OK
should show up in the bottom left of the window when complete. - Click on the
Memories
option to the left. In the box belowFlash (256K)
, find your bootloader file (note: by default the file selection dialogue which pops up only shows.hex
and.elf
files, you'll need to change that to showAll Files
orBinary (.bin, .dat) (*.bin; *.dat)
in the bottom right before your bootloader file shows up). When you've selected your bootloader file click on theProgram
button. Again, this should take a few moments to complete andVerify registers ... OK
should show up in the bottom left. - We now need to re-enable the boot protection zone (otherwise when you upload a program to the board it will overwrite the bootloader). Go back to
Fuses
, setUSER_WORD_0.NVMCTRL_BOOTPROT
to8192 Bytes
andProgram
it. - At this point the board should be running, discoverable in Windows Device Manager as a
USB Serial Device (COMxx)
device in thePorts (COM & LPT)
section. If you have an LED connected to physical pin 26/PA17 it should be slowly pulsing. If you quickly double-tap the reset button you should be able to see a drive calledFEATHERBOOT
pop up. - To test the board follow Adafruit's Arduino IDE Setup guide for the Feather M0. Upload the
Blink
sketch: selectAdafruit SAMD (32-bits ARM Cortex-M0+ and Cortex-M4) Boards > Adafruit Feather M0
as the board, and keep everything else default (I had two options for programmers, J-Link and Atmel-ICE over OpenOCD, I don't think it made a difference). You should be able to upload the sketch.
Congratulations! Your custom SAMD21-based board should now be up and running. Go and do crazy things with it.