Commit 6211a2a6 authored by Jake Read's avatar Jake Read
Browse files

on the whey

parents
# Using CMSIS-DAP
[CMSIS-DAP](https://www.keil.com/support/man/docs/dapdebug/dapdebug_introduction.htm) 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](https://en.wikipedia.org/wiki/JTAG) or [SWD](https://en.wikipedia.org/wiki/JTAG#Similar_interface_standards). 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](https://www.kanda.com/blog/microcontrollers/avr-microcontrollers/avr-microcontroller-programming-interfaces-isp-jtag-tpi-pdi-updi/). CMSIS-DAP only talks to JTAG or SWD ports: others need other programmers, i.e. the [ATMEL-ICE](https://www.microchip.com/DevelopmentTools/ProductDetails/ATATMEL-ICE) [AVR ISP](https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATAVRISP2) or [FAB ISP](https://fab.cba.mit.edu/classes/863.16/doc/projects/ftsmin/index.html) 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*](https://learn.adafruit.com/bootloader-basics) 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](max32625pico_maxdap.png)
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](https://github.com/adafruit/Adafruit-Trinket-M0-PCB) is a good ground-zero for the SAMD21E18 chip, and the [Adafruit Feather M4](https://github.com/adafruit/Adafruit-Feather-M4-Express-PCB) 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](https://www.maximintegrated.com/en/products/microcontrollers/MAX32625PICO.html) 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](http://www2.keil.com/mdk5) 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](https://www.keil.com/support/man/docs/uv4/uv4_ca_packinstaller.htm)
- 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](https://platformio.org/) is a great tool that I've been using to write all of my embedded code lately. It's an extension for [VSCode](https://code.visualstudio.com/), which is essentially Microsoft's fork of [atom](https://atom.io/) (in case you're interested).
Using CMSIS-DAP for a platformio project is [supported](https://docs.platformio.org/en/latest/plus/debug-tools/cmsis-dap.html), 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](https://github.com/adafruit/ArduinoCore-samd/tree/master/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 **SAMD21E18**and 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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment