I have a custom board using a SAMD21 microcontroller (as used in Arduino Zero and other dev boards).
After soldering, the chip is blank and a bootloader is useful to upload code via the USB connection.
I found an excellent (as always) tutorial by Adafruit using a JLink probe to upload their custom bootloader here : https://learn.adafruit.com/how-to-program-samd-bootloaders/overview
Unfortunately, directions are only provided for a Windows computer, using Atmel Studio.
Here is how to do it using the JLink command line software under Linux (and it should work with Mac as well).
To enable/disable the bootloader protection, I found very useful information here : https://roamingthings.de/posts/use-j-link-to-change-the-boot-loader-protection-of-a-sam-d21/
You should create two files with the info from the above post :
File SAMD_set_bootloader_protection_8k.mot :
S214804000FAC7E0D85DFCFFFFFFFFFFFFFFFFFFFF63
S9030000FC
File SAMD_clear_bootloader_protection.mot :
S214804000FFC7E0D85DFCFFFFFFFFFFFFFFFFFFFF5E
S9030000FC
In the same directory, download the Adafruit bootloader from https://learn.adafruit.com/how-to-program-samd-bootloaders/setup
So here is the complete process to burn a bootloader to a blank SAMD21 chip :
- Go to the directory where you put the two files above and the bootloader binary
cd ATSAMD21_Bootloader
- Start JLinkExe
$ JLinkExe SEGGER J-Link Commander V6.32h (Compiled Jul 5 2018 18:15:02) DLL version V6.32h, compiled Jul 5 2018 18:14:58 Connecting to J-Link via USB...O.K. Firmware: J-Link Lite-Cortex-M V8 compiled Sep 15 2016 12:05:01 Hardware version: V8.00 S/N: 518006749 License(s): GDB VTref=3.313V Type "connect" to establish a target connection, '?' for help
- Connect to the microcontroller. You have to specify the device type, SWD interface and you can use the default interface speed.
J-Link>connect Please specify device / core. : ATSAMD21G18 Type '?' for selection dialog Device>atsamd21g18 Please specify target interface: J) JTAG (Default) S) SWD TIF>s Specify target interface speed [kHz]. : 4000 kHz Speed> Device "ATSAMD21G18" selected. Connecting to target via SWD InitTarget() Found SW-DP with ID 0x0BC11477 Scanning AP map to find all available APs AP[1]: Stopped AP scan as end of AP map has been reached AP[0]: AHB-AP (IDR: 0x04770031) Iterating through AP map to find AHB-AP to use AP[0]: Core found AP[0]: AHB-AP ROM base: 0x41003000 CPUID register: 0x410CC601. Implementer code: 0x41 (ARM) Found Cortex-M0 r0p1, Little endian. FPUnit: 4 code (BP) slots and 0 literal slots CoreSight components: ROMTbl[0] @ 41003000 ROMTbl[0][0]: E00FF000, CID: B105100D, PID: 000BB4C0 ROM Table ROMTbl[1] @ E00FF000 ROMTbl[1][0]: E000E000, CID: B105E00D, PID: 000BB008 SCS ROMTbl[1][1]: E0001000, CID: B105E00D, PID: 000BB00A DWT ROMTbl[1][2]: E0002000, CID: B105E00D, PID: 000BB00B FPB ROMTbl[0][1]: 41006000, CID: B105900D, PID: 001BB932 MTB-M0+ Cortex-M0 identified.
- Clear bootloader protection fuse
J-Link>loadfile SAMD_clear_bootloader_protection.mot
Downloading file [SAMD_clear_bootloader_protection.mot]...
Comparing flash [100%] Done.
Erasing flash [100%] Done.
Programming flash [100%] Done.
Verifying flash [100%] Done.
J-Link: Flash download: Bank 1 @ 0x00804000: 1 range affected (16 bytes)
J-Link: Flash download: Total time needed: 0.050s (Prepare: 0.037s, Compare: 0.002s, Erase: 0.000s, Program: 0.003s, Verify: 0.000s, Restore: 0.006s)
O.K.
- Reset the target
J-Link>r Reset delay: 0 ms Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
- Upload the bootloader (you may have to change the bin file name).
J-Link>loadbin bootloader-feather_m0-v2.0.0-adafruit.9.bin,0 Downloading file [bootloader-feather_m0-v2.0.0-adafruit.9.bin]... Comparing flash [100%] Done. Verifying flash [100%] Done. J-Link: Flash download: Bank 0 @ 0x00000000: Skipped. Contents already match O.K.
- Set the bootloader protection fuse
J-Link>loadfile SAMD_set_bootloader_protection_8k.mot
Downloading file [SAMD_set_bootloader_protection_8k.mot]...
Comparing flash [100%] Done.
Erasing flash [100%] Done.
Programming flash [100%] Done.
Verifying flash [100%] Done.
J-Link: Flash download: Bank 1 @ 0x00804000: 1 range affected (16 bytes)
J-Link: Flash download: Total time needed: 0.050s (Prepare: 0.037s, Compare: 0.002s, Erase: 0.000s, Program: 0.003s, Verify: 0.000s, Restore: 0.006s)
O.K.
Now unplug and plug back your board and the SAMD21 should enumerate as a composite USB mass storage device and serial interface.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Thank you for this! Previously I would just burn the bootloader on new chips without caring for the lock, and then use the UF2 to upgrade the bootloader, which sets the lock.
If you want an alternative to jlink, but don't want to have to use openocd, the black magic probe can be flashed onto a blue pill board, and used to program those chips (I think, I didn't try myself).
Are you sure? yes | no
I like this, but if you're going to do something, you might as well go all the way.
While the Linux version of j-link software is a good step from the msbinarypit, it's still closed source software, which is the polar opposite of the spirit of writing and running your own code. To do this all the way means replacing j-link software with OpenOCD.
Create a directory, put your bootloader.bin in it, create an openocd.cfg file with the following contents, and then just execute "openocd":
source [find interface/jlink.cfg]
transport select swd
set CHIPNAME at91samd21e18
source [find target/at91samdXX.cfg]
init
reset
halt
at91samd bootloader 0
reset
program bootloader.bin verify reset
shutdown
Are you sure? yes | no
Thanks! I tried a long time ago to get started with openOCD and finally gave up, I will have to give it a try next time. It sure looks as easy as jlink, and for sure easier to integrate into custom scripts.
Are you sure? yes | no
Great comment! Will probably play around with this and openOCD soon. Not tested this myself yet, but is a extra line like this
"at91samd bootloader 8192"
needed at the end to enable the bootloader protection again
Are you sure? yes | no