Explorations into how to program SAMD21 chips like those in Trinket M0, Arduino Zero, etc.
How to program a SAMD21 (or other ARM chip really) using a variety of methods, in order to burn a UF2 bootloader or my own programs.
Ways to program a SAMD21 board: (e.g. Trinket M0, QTPy M0, etc)
Progress so far...
Double-click button on Trinket M0 to get into UF2 bootloader
Create new UF2 bootloader
git clone https://github.com/Microsoft/uf2-samd21/
cd uf2-samd21
make BOARD=trinket
Copy resulting file update-bootloader.uf2
to disk
Tada, new bootloader installed
Edit file boards/trinket/board_config.h
to change bootloader id strings
node uf2-samd21/scripts/bin2uf2.js sketch_nov24a.ino.bin sketch_nov24a.uf2
Solder pads to SWD & SWC pins on back of Trinket M0
Connect following pins from JLink to Trinket M0:
| black | Jlink Gnd | Trinket M0 Gnd pin |
| red | Jlink VTref | Trinket M0 3v3 pin |
| green | Jlink SWDIO | Trinket M0 SWD solder pad |
| blue | Jlink SWCLK | Trinket M0 SWC solder pad |
Power Trinket M0 via USB. Power Jlink via USB.
"VTref" is used to detect target power is applied. It is a signal TO the programmer.
brew install openocd
uf2-samd21/scripts/dbgtool.js
to use Jlink instead of EDBG.
uf2-samd21/scripts/dbgtool.js
:
let zeroCfg = '/Users/tod/projects/samd/openocd-scripts/samd21-jlink.cfg'
make burn
" in uf2-samd21
cd uf2-samd21
node ./scripts/dbgtool.js fuses
node ./scripts/dbgtool.js ./build/trinket/bootloader.bin
Install openocd
as above
Get the bootloader-trinket_m0-v3.16.0.bin
file from adafruit/uf2-samdx1
Connect Jlink to Trinket M0 as above
Program on commandline:
openocd -f ./openocd_jlink_samd21.cfg \
-c "init; targets; halt; " \
-c "at91samd bootloader 0;" \
-c "program bootloader-trinket_m0-v3.16.0.bin verify;" \
-c "at91samd bootloader 8192; reset; shutdown"
NOTE: the at91samd bootloader 0;
disables bootloader protection and
allows you to rewrite the bootloader. The at91samd bootloader 8192;
re-enables bootloader protection.
(from this adfruit forum post)
Can also erase entire chip (assuming no bootloader lock):
openocd -f ./openocd_jlink_samd21.cfg -c "init; targets; at91samd chip-erase; shutdown"`
or in a more general way:
openocd -f ./openocd_jlink_samd21.cfg -c "init; targets; flash erase_sector 0 1 last; shutdown"`
Or list which targets are connected:
openocd -f openocd_jlink_samd21.cfg -c "init; targets; shutdown"
TODO: try:
-c "init; targets; reset halt; program sketch.bin 0x00002000
Install openocd
and get bootloader-xxx.bin
Connect Atmel ICE similar to JLink by using adapter like in image below
Program on commandline:
openocd -f ./openocd_jlink_samd21.cfg \
-c "init; targets; halt; " \
-c "at91samd bootloader 0;" \
-c "program bootloader-trinket_m0-v3.16.0.bin verify;" \
-c "at91samd bootloader 8192; reset; shutdown"
NOTE: the at91samd bootloader 0;
disables bootloader protection and
allows you to rewrite the bootloader. The at91samd bootloader 8192;
re-enables bootloader protection.
(from this adfruit forum post)
You can also choose to install telnet
and do these commands interactively:
In one terminal window run openocd
:
% openocd -f ./openocd_atmel-ice_samd21.cfg
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: JTAG supported
Info : CMSIS-DAP: FW Version = 01.00.0021
Info : CMSIS-DAP: Serial# = J41800054170
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 400 kHz
Info : SWD DPIDR 0x0bc11477
Info : [at91samd21e18.cpu] Cortex-M0+ r0p1 processor detected
Info : [at91samd21e18.cpu] target has 4 breakpoints, 2 watchpoints
Info : starting gdb server for at91samd21e18.cpu on 3333
Info : Listening on port 3333 for gdb connections
And in another terminal window, run telnet
and then openocd commands:
% telnet localhost 4444
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
targets TargetName Type Endian TapName State
0* at91samd21e18.cpu cortex_m little at91samd21e18.cpu running
reset halt
[at91samd21e18.cpu] halted due to debug-request, current mode: Thread xPSR: 0x21000000 pc: 0x00000264 msp: 0x20002de0at91samd bootloader 0
flash erase_sector 0 1 last
SAMD MCU: SAMD21E18A (256KB Flash, 32KB RAM) erased sectors 1 through 1023 on flash bank 0 in 6.106292sprogram bootloader-trinket_m0-v3.16.0.bin verify [at91samd21e18.cpu] halted due to debug-request, current mode: Thread xPSR: 0x21000000 pc: 0x00000264 msp: 0x20002de0 Programming Started Programming Finished Verify Started Verified OK
at91samd bootloader 8192
reset shutdown
Install openocd
and get bootloader-xxx.bin
Connect Trinket M0 to STLink using only: GND, SWDIO, SWCLK, as in image below
Program on commandline:
openocd -f ./openocd_atmel-ice_samd21.cfg \
-c "init; targets; halt; program bootloader-trinket_m0-v3.16.0.bin verify reset; shutdown"
Or interactively:
% telnet localhost 4444
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
reset halt
[at91samd21g18a.cpu] halted due to debug-request, current mode: Thread xPSR: 0x61000000 pc: 0x00000264 msp: 0x20002de0 targets
TargetName Type Endian TapName State
0* at91samd21g18a.cpu hla_target little at91samd21g18a.cpu halted
flash erase_sector 0 1 last
SAMD MCU: SAMD21E18A (256KB Flash, 32KB RAM) erased sectors 1 through 1023 on flash bank 0 in 5.069648sprogram /Users/tod/Downloads/bootloader-trinket_m0-v3.16.0.bin verify reset [at91samd21g18a.cpu] halted due to debug-request, current mode: Thread xPSR: 0x61000000 pc: 0x00000264 msp: 0x20002de0 Programming Started Programming Finished Verify Started Verified OK Resetting Target