Adding Bus Pirate/..-style debugging & probing features to regular MCU boards such as the Raspberry Pi Pico
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
sys64738 0e7dc0010c update README 6 months ago
CMSIS_5@13b9f72f21 cherry-pick more haskal stuff, update CMSIS-DAP to 5.0.8 release, fix warnings 7 months ago
bsp all the other commands 6 months ago
cmake move pico_sdk_import.cmake to a cmake subdir 7 months ago
host XVC implementation that talks to a cmsis-dap device 6 months ago
libco started on new usb itf, it compiles and it lsusbs 7 months ago
scripts cherry-pick more haskal stuff, update CMSIS-DAP to 5.0.8 release, fix warnings 7 months ago
src implement a few extra usb commands 6 months ago
tinyusb@d49938d0f5 update to use sdk 1.2.0 7 months ago
.clang-format clang formatting stuff 7 months ago
.gitignore started on new usb itf, it compiles and it lsusbs 7 months ago
.gitmodules was advised to directly use CMSIS_5 submodule 12 months ago
CMakeLists.txt dynamic memory allocation so the SUMP mode can use all available memory w/o limiting other modes 6 months ago
COPYING add license files 7 months ago
LICENSE add license files 7 months ago
LICENSE.dappermime add license files 7 months ago
LICENSE.picoprobe-sump update README 6 months ago
README.md update README 6 months ago

README.md

DapperMime-JTAG

(name is still WIP)

This project attempts to add Bus Pirate/...-like functionality to a number of MCUs, mainly the Raspberry Pi Pico. It was originally based on Dapper Mime, an SWD debugger probe implementation, with the goal of adding JTAG support as well. However, more and more features got added over time.

Variants

Most support and development effort goes to the RP2040/Pico, but, due to the projects' structure still being based on Dapper Mime's, it is relatively easy to add support for another MCU/board. Any MCU supported by TinyUSB should work. Features can also be disabled per MCU.

Adding support for another MCU is a matter of adding another subfolder in the ./bsp folder, implementing the functionality (which only concerns itself with sending commands to the hardware, protocol parsing is done by shared code), and handling it in the CMakeFiles.txt file.

Building

After initially downloading this project's code, issue the following command to download TinyUSB and CMSIS 5 code:

git submodule update --init --recursive

Compilation is done using CMake:

mkdir cmake-build && cd cmake-build
cmake -DBOARD=raspberry_pi_pico -DFAMILY=rp2040 -DCMAKE_BUILD_TYPE=RelWithDebInfo ..

BOARD and FAMILY should correspond to those used in the TinyUSB hw folder, and with the folders used in ./bsp as well.

A non-exhaustive list of possible BOARD/FAMILY combinations:

FAMILY BOARD description notes
rp2040 raspberry_pi_pico Raspberry Pi Pico default

Notes on compiling for the RP2040 Pico

If you have the Pico SDK installed on your system, and the PICO_SDK_PATH environment variable is specified properly, you can omit the --recursive flag in the git submodule invocation (to avoid many many git clones), and pass the -DUSE_SYSTEMWIDE_PICOSDK=On flag to CMake, too.

Other options are:

  • -DPICO_NO_FLASH=[On|Off]: store the binary in RAM only, useful for development.
  • -DPICO_COPY_TO_RAM=[On|Off]: write to flash, but always run from RAM
  • -DUSE_USBCDC_FOR_STDIO=[On|Off]: export an extra USB-CDC interface for debugging

Usage

These microcontrollers support the following protocols:

MCU SWD JTAG UART SPI (flashrom) I2C Other stuff
RP2040 X X X X X Planned

The original repository (Dapper Mime) supported only SWD and UART, and worked for the RP2040 Pico and the STM32F072 Discovery. This fork focusses on adding more protocols, but the author of this fork only has a Raspberry Pi Pico.

The pin mapping for the RP2040 is as follows:

Pin number Usage Usage Pin number
GP0 stdio UART TX VBUS
GP1 stdio UART RX VSYS
GND <ground> <ground> GND
GP2 SWCLK/TCK 3V3 EN
GP3 SWDIO/TMS 3V3 OUT
GP4 TDI ADC VREF
GP5 TDO GP28 / ADC2
GND <ground> <ground> GND / AGND
GP6 nTRST GP27 / ADC1
GP7 nRESET GP26 / ADC0
GP8 UART TX RUN
GP9 UART RX (1-wire, TODO) GP22
GND <ground> <ground> GND
GP10 UART CTS SCL GP21
GP11 UART RTS SDA GP20
GP12 MISO GP19
GP13 nCS GP18
GND <ground> <ground> GND
GP14 SCLK GP17
GP15 MOSI GP16
<end> <bottom> <bottom> <end>

On the RP2040, two USB CDC interfaces are exposed: the first is the UART interface, the second is for Serprog. If you have no other USB-CDC intefaces, these will be /dev/ttyACM0 and /dev/ttyACM1, respectively. If you have enabled the USE_USBCDC_FOR_STDIO option, there will be a third device file.

UART

The UART pins are for connecting to the device to be debugged, the data is echoed back over the USB CDC interface (typically a /dev/ttyACMx device on Linux). If you want to get stdio readout of this program on your computer, connect GP0 to GP5, and GP1 to GP4, or alternatively, use the USE_USBCDC_FOR_STDIO CMake flag, which adds an extra USB-CDC interface for which stdio is used exclusively, while disabling stdio on the UART.

SWD and JTAG debugging

In SWD mode, the pin mapping is entirely as with the standard Picoprobe setup, as described in Chapter 5 and Appendix A of Getting Started with Raspberry Pi Pico

In JTAG mode, TCK and TMS have the same pins as SWCLK and SWDIO, respectively, TDI and TDO are on the next two consecutive free pins.

In your OpenOCD flags, use -f interface/cmsis-dap.cfg. Default transport is JTAG, if OpenOCD doesn't specify a default to the probe.

Serprog/Flashrom

For Serprog, use the following flashrom options (if /dev/ttyACM1 is the USB serial device on your machine corresponding to the Serprog CDC interface of the Pico):

flashrom -c <flashchip> -p serprog:dev=/dev/ttyACM1:115200 <rest of the read/write cmd>

Different serial speeds can be used, too. Serprog support is techincally untested, as in it does output the correct SPI commands as seen by my logic analyzer, but I don't have a SPI flash chip to test it on.

SPI, I2C and temperature sensor

This functionality depends on custom kernel modules being loaded: In the host/modules/ directory, one can find the sources and a Makefile.

After loading the modules (and modprobing i2c-dev and spidev), devices for these interfaces should appear in /dev.

SPI and I2C can be controlled using the standard tools for these (eg. the utilities from i2c-tools package), and the temperature sensor should show up in lm_sensors.

Using i2cdetect -l, you should be able to see which I2C device belongs to the tool:

$ sudo i2cdetect -l
[...]
i2c-1	i2c       	i915 gmbus dpb                  	I2C adapter
i2c-8	i2c       	Radeon i2c bit bus 0x95         	I2C adapter
i2c-15	i2c       	dmj-i2c-1-1:1.0                 	I2C adapter
i2c-6	i2c       	Radeon i2c bit bus 0x93         	I2C adapter
i2c-13	i2c       	AUX C/DDI C/PHY C               	I2C adapter

I2C temperature sensor emulation

If the board/MCU has a builtin temperature sensor, a fake I2C device on the bus can optionally be enabled to use it as a Jedec JC42.2-compliant temperature sensor (the exact sensor emulated is the Microchip MCP9808). To have it show up in sensors, do the following (with BUSNUM the number from the above i2cdetect -l output):

$ ./dmctl.sh tempsensor --set 0x18     # need to give it an address first
$ sudo modprobe jc42
$ # now tell the jc42 module that the device can be found at this address
$ echo "jc42 0x18" | sudo tee /sys/bus/i2c/devices/i2c-BUSNUM/new_device
$ sudo sensors                               # it should show up now:
jc42-i2c-BUSNUM-18
Adapter: i2c-tiny-usb at bus 001 device 032
temp1:        +23.1°C  (low  = -20.0°C)
                       (high = +75.0°C, hyst = +75.0°C)
                       (crit = +80.0°C, hyst = +80.0°C)

Temperature readout may be a bit higher than the ambient temperature.

Runtime configuration

Several settings can be applied at runtime, using the dmctl Python script. Settings are communicated over a vendor USB interface.

$ ./dmctl.sh --help
usage: dmctl [-h] [--conn CONN] subcommand ...

optional arguments:
  -h, --help       show this help message and exit
  --conn CONN      Connection string. Either a dmj-char device in /dev, a USB
                   bus.device number, or a USB VID:PID pair. Defaults to trying
                   /dev/dmj-* (if there is only one), and cafe:1312 otherwise.

subcommands:
  For more info on each subcommand, run the program with 'subcommand --help' as
  arguments.

  subcommand       Command to send to the device
    get-device-info
                   Shows device info
    get-mode-info  Shows mode info. A mode can optionally be specified, default
                   is the current mode.
    set-mode       Set the device mode
    uart-cts-rts   Get, enable/disable UART hardware flow control
    tempsensor     Get or set the IRC emulation enable/address of the
                   temperature sensor.
    jtag-scan      JTAG pinout scanner
    sump-overclock
                   SUMP logic analyzer overclock settings

Example:

$ ./dmctl.py --conn cafe:1312 get-device-info

License

TinyUSB is licensed under the MIT license.

ARM's CMSIS 5 code is licensed under the Apache 2.0 license.

libco is licensed under the ISC license

Some code has been incorporated from the DapperMime and picoprobe-sump projects. These respective licenses can be found in this and this file.

TODO