Adding Bus Pirate/..-style debugging & probing features to regular MCU boards such as the Raspberry Pi Pico
Go to file
Triss 7cb22d8bd6 update README 2021-06-21 18:11:02 +02:00
CMSIS_5@d61cf40e6c was advised to directly use CMSIS_5 submodule 2021-02-01 10:25:49 -06:00
bsp temperature stuff actually working now 2021-06-21 17:55:06 +02:00
i2c-tiny-usb-misc more debugging stuff (& fix non-stdiousbcdc mode), almost *actually* working this time 2021-06-17 23:52:07 +02:00
libco actually add the libco files (oops) 2021-06-08 02:22:54 +02:00
src temperature stuff actually working now 2021-06-21 17:55:06 +02:00
tinyusb@d49938d0f5 update to use sdk 1.2.0 2021-06-13 20:07:54 +02:00
.gitignore more debugging stuff (& fix non-stdiousbcdc mode), almost *actually* working this time 2021-06-17 23:52:07 +02:00
.gitmodules was advised to directly use CMSIS_5 submodule 2021-02-01 10:25:49 -06:00
CMakeLists.txt temperature sensor: stuff is working, except for the actual temperature readout 2021-06-21 16:22:01 +02:00
Makefile definitely not functuonal but hey its something 2021-06-06 05:10:36 +02:00
README.md update README 2021-06-21 18:11:02 +02:00
dmctl.py temperature sensor: stuff is working, except for the actual temperature readout 2021-06-21 16:22:01 +02:00
pico_sdk_import.cmake fix build stuff, add .gitignore, add JTAG support 2021-05-30 04:16:06 +02:00

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.

Variants

Most TinyUSB supported MCUs can run this code; a subdirectory under bsp needs to be added for the "BOARD" name with a DAP_config.h to control the SWD/JTAG GPIOs and a unique.h to provide unique serial number (if any) and prefix to the USB product name.

Already added BOARD variants include:

For BOARD=raspberry_pi_pico, this project results in a standards-based CMSIS-DAP alternative to the approaches suggested in Chapter 5 and Appendix A of Getting Started with Raspberry Pi Pico. This uses two RP2040 boards (see wiring loom shown in Figure 34 of Appendix A) where one RP2040 is the debugger and the other RP2040 is being debugged. The instructions in Chapter 5 apply, except no Raspberry Pi is needed.

Alternatively, a special one RP2040 “Raspberry Pi Pico” variant is available here.

For BOARD=stm32f072disco, the inexpensive 32F072BDISCOVERY evaluation board can be used as a CMSIS-DAP SWD debugger.

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 -DFAMILIY=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.

Possible BOARD/FAMILY combinations are:

FAMILY BOARD description
rp2040 raspberry_pi_pico Raspberry Pi Pico
stm32f072disco stm32f072disco STM 32072B "Discovery"

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 debuggin

Usage

These microcontrollers support the following protocols:

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

The original repository (Dapper Mime) supported only SWD and UART, and worked for these two boards. 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 UART TX ADC VREF
GP5 UART RX GP28 / ADC2
GND <ground> <ground> GND / AGND
GP6 TDI GP27 / ADC1
GP7 TDO GP26 / ADC0
GP8 nTRST RUN
GP9 nRESET 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.

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 debuggin

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.

I2C-Tiny-USB

The I2C-Tiny-USB functionality can be used as follows: first, load the i2c-dev and i2c-tiny-usb modules (for now you need a patched version of the latter, can be found in the i2c-tiny-usb-misc/ folder in this repo). Then you can use the I2C USB bridge as any other I2C device on your computer. For example, the i2cdetect, i2cget and i2cset tools from i2c-tools should all work. You can find which I2C device corresponds to the I2C-Tiny-USB, by running i2cdetect -l:

$ sudo i2cdetect -l
[...]
i2c-1	i2c       	i915 gmbus dpb                  	I2C adapter
i2c-8	i2c       	Radeon i2c bit bus 0x95         	I2C adapter
i2c-15	i2c       	i2c-tiny-usb at bus 001 device 011	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.py /dev/ttyACM1 --i2ctemp 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/device/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 the Serprog USB serial port.

The currently implemented options are:

  • support: tells you which features this implementation/board supports
  • ctsrts: Enable/disable CTS/RTS-based hardware flow control for the UART port
  • i2ctemp: Get or set the I2C address of the fake I2C device of the temperature sensor. Use 0 for getting the value, 0xff for disabling, and any other for setting the address. The I2C device emulated is an MCP9808. When setting a value, the old value is printed.
usage: dmctl [-h] [-v] [--ctsrts [CTSRTS]] tty

Runtime configuration control for DapperMime-JTAG

positional arguments:
  tty                Path to DapperMime-JTAG Serprog UART device

optional arguments:
  -h, --help           show this help message and exit
  -v, --verbose        Verbose logging (for this utility)
  --ctsrts [CTSRTS]    Enable or disable CTS/RTS flow control (--ctsrts [true|false])
  --i2ctemp [I2CTEMP]  Control the builtin I2C temperature controller: get (0),
                       disable (-1/0xff) or set/enable (other) the current
                       status and I2C bus address
  --support            Get list of supported/implemented functionality

example:

$ ./dmctl.py /dev/ttyACM1 --ctsrts true

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

TODO

  • CMSIS-DAP JTAG implementation
  • Flashrom/SPI support using Serprog
    • Parallel ROM flashing support, too, by having the device switch into a separate mode that temporarily disables all other IO protocols
  • UART with CTS/RTS flow control
    • Needs configurable stuff as well, as some UART interfaces won't use this.
  • Debug interface to send printf stuff directly to USB, instead of having to use the UART interface as a loopback thing.
    • Second UART port for when stdio UART is disabled?
  • I2C support by emulating the I2C Tiny USB
    • Expose RP2040-internal temperature ADC on I2C-over-USB bus?
    • Does SMBus stuff need special treatment here? No. Actually, some parts do, but, laziness.
    • 10-bit I2C address support (Needs poking at the Pico SDK, as it only supports 7-bit ones).
  • Host-side script that is an XVC (or hw_server) cable and communicates with the device to perform the JTAG commands, because Vivado no likey OpenOCD.
  • SUMP logic analyzer?
  • Segger RTT?
  • Maybe use the ADCs for something?
  • General generic manual GPIO mode
  • SD/MMC/SDIO (will be a pain)
  • AVR programming (USBavr emulation?)
    • AVR ISP is hardly used anymore
    • TPI/UPDI requires 5V levels, Pico doesn't do that :/
    • debugWIRE????
  • FT2232 emulation mode?
  • Renesas E7-{0,1,2} programming thing????
    • Renesas tell us how this works pls
  • Maybe steal other features from the Bus Pirate, HydraBus or Glasgow or so
    • 1-wire and 3-wire? Never seen this one in the wild
    • CAN? LIN? If I'd first be able to find a CAN device to test it with, sure