Skip to content
Snippets Groups Projects
Jake Read's avatar
Jake Read authored
6211a2a6
History
Name Last commit Last update
README.md
max32625pico_maxdap.png

Using CMSIS-DAP

CMSIS-DAP is an interface firmware that connects microcontrollers to our PCs over USB, specifically for debugging code running on our microcontrollers, or loading new code onto them.

If you know how all of this stuff generally works, continue past the next two sections.

Que?

If the above statement doesn't make immediate sense, here's what's up:

Every time our our microcontroller is reset, it starts operating the program that currently resides in its memory. This means that in order to load a new program onto the microcontroller, we need some way of writing into that memory from another device.

This normally means that we write (human readable) code on our PC / Laptop / Whatever, compile it using a toolchain that knows how our device is shaped (alignments, bus widths, processor architectures etc) into byte code (machine readable), and then use some device to write that byte-code into the microcontroller's memory. Then, next time it wakes up (or we reset it) the microcontroller starts running our program!

Microcontrollers have pins that are specifically made for loading programs into their memory - these are known as 'debug ports' and ARM chips commonly use JTAG or SWD. Our programming device (here it's the CMSIS-DAP) communicates to our PC using a USB connection on one side, and to our microcontroller using JTAG or SWD on the other side.

Different microcontrollers have different debug ports: AVR chips have ISP (In System Programming) debug ports, XMEGA chips use PDI, and some ATTINYs use UPDI - these are well explained here. CMSIS-DAP only talks to JTAG or SWD ports: others need other programmers, i.e. the ATMEL-ICE AVR ISP or FAB ISP that you can make yourself.

Here's an abbreviated list of the system layers (not aligned) we're putting together when we do this:

rows are not aligned

Human Codes Compilers Byte Code -> Device Port (tool) Device Debug Ports
c avr-gcc cmsis-dap jtag
c++ gnu-arm-gcc atmel-ice swd
avr-isp pdi
fab-isp isp
usb updi
bootloader (self program)

What's a bootloader?

Occasionally, we don't need a programming device in order to load code onto microcontrollers, as is the case with Arduino and other development boards. What gives?

These boards have bootloaders already written into their program memory. These are little programs that run in the microcontroller when they are reset. They start up, listen for some communication from your computer telling them that a new program is incoming, and if one doesn't exist, continue to the code loaded in the rest of their memory.

Basically, when a bootloader is present, the microcontroller itself takes on the role of the 'byte code -> device port' tool: this is known as 'self-programming' - the microcontroller writes your new program into its own memory.

Trouble is, when we make our own boards, we need to be able to load our own bootloaders (bootstrapping them...) and we need to do this with a tool like a CMSIS-DAP, AVR ISP etc.

1: Connect CMSIS-DAP to your Device

CMSIS-DAP tools will normally have the standard JTAG Pinout, which is 2x5, this is true of the MAXDAP that we have in the lab:

dap

To connect this to your circuit, you'll want to put a 2x5 header on your circuit:

  • connect pins 3, 5, and 9 to GND
  • connect 10 to the microcontroller's reset line
    • you might also want to pull up the reset line
    • you might also want a button to reset the board manually
    • some boards need an RC filter on the reset line, beware
  • connect 1 to the microcontroller's voltage
  • *if your chip uses SWD (most SAMD chips)
    • connect SWDIO to SWDIO (read the datasheet!)
    • connect SWDCLK to SWDCLK (consider a pullup on this line as well)

Note the CMSIS-DAP tool does not provide power to your circuit, it merely reads it to check that the device is alive. When you're programming the circuit, be sure to power it as well! For this reason, I often put a USB connector on my circuits to easily supply 5v.

TODO: example schem for the D51 and D21

This is all a bit much. A strategy I often use to make sure I will have programming success is to copy someone else's basic schematic: i.e. the Adafruit Trinket M0 is a good ground-zero for the SAMD21E18 chip, and the Adafruit Feather M4 is a good ground-zero for the SAMD51J19. Thanks adafruit! One note: they don't use the 2x5 pin header, instead, they use pogo pins on the board to break out SWDIO and SWDCLK. Just swap in a connector!

2: Connecting CMSIS-DAP to your Computer

A CMSIS-DAP tool itself should announce itself to your computer automatically (over usb). I am using the MAXDAP on a windows machine. When I plugged this in and it appears in my device manager as 'CMSIS-DAP', and drivers were automatically installed, so I think I'm clear to proceed.

Now I need to get a software system that will talk to the CMSIS-DAP tool.

3a: ARM MDK to CMSIS-DAP

To verify I could flash my board using the CMSIS-DAP tool, I first tried operating it with the ARM MDK which is an install that will bring with it everything you need to write and flash code onto any ARM microcontroller.

This can be a little intimidating if you've not experienced big IDEs before, but it's well supported and used commercially, so it's a good ground truth also. Here's what I did:

OK, this looks like it works, but our target board is a bit messed up.

  • had to install package manually, https://packs.download.microchip.com/ find D21 support package, download, rename .atpack to .pack, import in keil package manager
  • pack installer
  • to setup project, bring in core components in keil as well during 'new project' wizard: selections,
  • do boilerplate code main.c, int main(void){}, do #include "samd21e17a.h" for HAL
  • get your pins right
  • atmel-ice, sam port, do device progamming -> memories ...
  • load trinket m0 booloader (zero bl uses xtal)
  • keil setup,
  • cmsis-dap automatically announces itself (on windows)
  • keil setup to do
    • tools ... setup flash tools ... find tab 'debug'
    • 'use' cmsis-dap debugger
    • do 'setup' to the right
      • do 'port' SW (not JTAG)

confirmed that the cmsis-dap works. need to be able to flash with the cmsis-dap. first, do that, or find some gui (doubt it) for it.

3b: Platformio to CMSIS-DAP

Platformio is a great tool that I've been using to write all of my embedded code lately. It's an extension for VSCode, which is essentially Microsoft's fork of atom (in case you're interested).

Using CMSIS-DAP for a platformio project is supported, but I still need to figure out how to set it up for use on a custom board... this is on the way.

4: Loading .bin .hex etc directly

Sometimes, the move is to use a tool like CMSIS-DAP to load a bootloader onto our device, and then just use that bootloader routinely to re-program it / develop code.

To do this, you'll want to borrow a bootloader from someone who's written lots of them: I use Adafruit Bootloaders fairly often. To ensure that this works, I need to make that my circuit is compatible with the bootloader I'm going to use. The Trinket M0 Bootloader is a great, lightweight bootloader for the SAMD21E18and the Feather M4 Express Bootloader is similar for the SAMD51J19.

Note these need to be very compatible: i.e. the E18 and J19 variants of the D21 and D51 respectively need to be used for those bootloaders to work. Additionally, external crystals (and USB lines) must be connected for these to work, if they're present in the design you're borrowing a bootloader from.

TODO: how to command-line (?) cmsis-dap .hex files?

https://github.com/adafruit/Adafruit-Trinket-M0-PCB https://github.com/arduino/ArduinoCore-samd/ https://github.com/adafruit/ArduinoCore-samd/tree/master/bootloaders/trinketm0