Making_Custom_SAMD_boards

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.

You will need

  • 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 called gcc-arm-none-eabi).
        • Added the gcc-arm-none-eabi/bin/ folder to PATH using export PATH=$PATH:/path/to/folder/gcc-arm-none-eabi/bin/. Run arm-none-eabi-gcc --version to check which version of gcc this invokes, it should be v7.2.1. Note that this is temporary and the PATH 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 into usr/bin/.
      • In the uf2-samdx1 directory, run make BOARD=feather_m0. This should output a file called bootloader-feather_m0-v3.13.0-2-g56c3e1d.bin into /uf2-samdx1/build/feather_m0. This bootloader file should be equivalent to the bootloader-feather_m0-v3.13.0.bin file you can download from the releases page.

The process

  • 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 the Tool dropdown, select your SWD programmer (So J-Link in my case), and in the Device dropdown select your chip (so ATSAMD21G18A in my case). In the Interface dropdown select SWD and click on the Apply button. The options in the rest of the window should change. To confirm that you can talk to the board click on the Read button beside the Device signature box. A value should pop into the Device signature box, and the Target 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 called USER_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 to 0 Bytes and click on Program near the bottom of the window. This should take a few seconds to process, and Verify 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 below Flash (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 show All Files or Binary (.bin, .dat) (*.bin; *.dat) in the bottom right before your bootloader file shows up). When you've selected your bootloader file click on the Program button. Again, this should take a few moments to complete and Verify 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, set USER_WORD_0.NVMCTRL_BOOTPROT to 8192 Bytes and Program it.
  • At this point the board should be running, discoverable in Windows Device Manager as a USB Serial Device (COMxx) device in the Ports (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 called FEATHERBOOT pop up.
  • To test the board follow Adafruit's Arduino IDE Setup guide for the Feather M0. Upload the Blink sketch: select Adafruit 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.