Table of Contents
Wire protocol
The device has a "configuration and command" USB vendor interface, it has subclass number 68 ('D'), and protocol number 80 ('P'). The VID/PID pair is currently cafe:1312.
The host sends a message and the device sends a reply. The device never initiates a transfer.
the first byte of a command is the combination of the mode it is meant for (in the high nybble), and the command number itself in the low nybble. Optional extra command bytes may follow, depending on the command itself. A high nybble of 0 signifies a general configuration command, not meant for a particular mode.
A response consists of a response status byte (enum cfg_resp
), followed by a 7-, 14- or 22-bit VLQ int (little-endian) for the payload length, followed by the payload itself.
Response/status enum:
- Ok:
0x00
- Illegal/unknown/unimplemented command:
0x01
- Bad mode for this command:
0x02
- No such mode exists:
0x03
- Bad command argument:
0x04
- Wrong (mode-specific) state for this command:
0x05
General commands
These commands work at any moment and are used to query the general device state and info.
- Get vesion (
0x00
): returns a payload of 2 bytes with version data. Should currently be0x10 0x00
(00.10h
). - Get modes (
0x01
): returns 2 bytes with a bitmap containing all supported modes. Bit 0 is for general config (aka this command group) and must always be 1. - Get cur mode (
0x02
): returns a single byte containing the current mode number. - Set cur mode (
0x03
): sets the current mode. One extra request byte (the mode number), no response payload. - Get info string (
0x04
): get a null-terminated string containing human-readable info about the device. For display purposes only.
Persistent storage commands
- Get storage info (
0x0c
): returns the 256-byte header data of the persistent storage. No arguments. See Persistent storage. - Get mode storage data (
0x0d
): returns the (variable-length) data of a mode. One argument byte, the mode. - Flush data to storage medium (
0x0e
): writes the storage data when changed. Automatically called on OS USB detach/unmount (as long as there is still power supplied to the device).
Common mode commands
These commands work for any mode, and have the same effect across all of them.
- Get name (
0xM0
): returns a name or other descriptive string in the payload. Null-terminated, for display purposes only. - Get version (
0xM1
): returns a 2-byte version number in the payload. - Get features (
0xM2
): gets a bitmap of supported features. Length and meaning of the bits depends on the mode.
Mode-specific commands
A list of all the currently-implemented modes:
- Default ('misc')
- (N/A)
- (N/A: JTAG pinout scanner)
- SUMP logic analyzer
Mode 1
Features
0x01
: UART<->USB-CDC interface available0x02
: CMSIS-DAP available0x04
: SPI interface available0x08
: I2C interface available0x10
: Temperature sensor available
Commands
- SPI (serprog) command prefix (
0x13
): Perform a SPI command, see below. - I2C command prefix (
0x14
): Perform an I2C command, see below. - Temperature sensor command prefix (
0x15
): Perform a temperature sensor command, see below. - UART↔USB hardware flow control enable/disable (
0x16
): has a single argument byte,0x00
to disable hardware flow control,0xc3
to read the current value (one byte returned), any other value to enable. Baud rate and other line control settings are done using the standard USB-CDC line control things.
SPI commands
The SPI command format used here is based heavily on Serprog. Keep in mind that serprog responses — including its ACK
and NAK
status bytes — are wrapped as a response payload as defined in the beginning of this document!
Supported standard serprog commands:
NOP
(0x00
)Q_IFACE
(0x01
)Q_CMDMAP
(0x02
)Q_PGMNAME
(0x03
)Q_SERBUF
(0x04
)Q_BUSTYPE
(0x05
)Q_WRNMAXLEN
(0x08
)SYNCNOP
(0x10
)Q_RDNMAXLEN
(0x11
)S_BUSTYPE
(0x12
)SPIOP
(0x13
)S_SPI_FREQ
(0x14
)- SPI clock frequency defaults to 512 kHz
S_PINSTATE
(0x15
)
Additionally, a number of nonstandard commands are supported as well, for more specific SPI transfers not necessarily needed for flash programming:
S_CMD_Q_SPI_CAPS
(0x40
): query capabilities of the SPI controller. No arguments. Return struct of 13 bytes (preceded by anACK
):- Minimum frequency: 32-bit little-endian value in Hz
- Maximum frequency: 32-bit little-endian value in Hz
- Capability flags: 16-bit little-endian value
- Bit 0 (lsb): CPHA can be 1
- Bit 1: CPHA can be 0
- Bit 2: CPOL can be 1
- Bit 3: CPOL can be 0
- Bit 4: Standard SPI ("Motorola") frame format is supported
- Bit 5: TI SSP frame format is supported
- Bit 6: NatSemi MicroWire frame format is supported
- Bit 7: MSBit-first transfers are supported
- Bit 8: LSBit-first transfers are supported
- Bit 9: CS can be selected to be active-high instead (CS line control command will take note of this, and send CS high/low commands accordingly (in accordance with the Linux kernel), cf.
S_CMD_S_SPI_SETCS
.) - Bit 10 (msb): 3-wire interface supported
- Number of chip-select lines: 8-bit bitmap
- Minimum bits-per-transfer-word value (8 bit)
- Maximum bits-per-transfer-word value (8 bit)
S_CMD_S_SPI_CHIPN
(0x41
): set which chip select lines are to be controlled. Has a single argument byte, a bitmap of chip select line values. No response (aside from anACK
).S_CMD_S_SPI_SETCS
(0x42
): set the voltage level of the CS line(s) selected byS_CMD_S_SPI_CHIPN
. No response (aside from anACK
).S_CMD_S_SPI_FLAGS
(0x43
): set transfer settings flags, one response byte (actual flags applied), single argument byte:- Bit 0 (lsb):
CPHA
- Bit 1:
CPOL
- Bit 2,3: frame format:
0=standard
,1=SSP
,2=MicroWire
. 3 is undefined. - Bit 4: LSBit-first transfer (clear this bit for MSBit-first transfers)
- Bit 5: CS is used as active-high signal (clear this bit for active-low CS signals)
- Bit 6 (msb): Use 3-wire mode (clear this bit for regular 4-wire SPI)
- Bit 0 (lsb):
S_CMD_S_SPI_BPW
(0x44
): set bits per word used in a SPI transfer. Single argument byte denoting the number of bits. One response byte: bits per word applied.S_CMD_SPI_READ
(0x45
): similar toSPIOP
(0x13
), except without data to write (and no "write data length" argument).S_CMD_SPI_WRITE
(0x46
): similar toSPIOP
(0x13
), except without data to read (and no "read data length" argument).S_CMD_SPI_RDWR
(0x47
): full-duplex SPI transfer (as opposed toSPIOP
(0x13
), which is only half-duplex), same arguments and result format asSPIOP
(0x13
).
I2C commands
The I2C command format used here is based heavily on the one of I2C-Tiny-USB (protocol).
- Echo (
0x00
): one single argument byte is echoed back as payload. - Get functions (
0x01
): get supported I2C and SMBus operations. Response payload is 4 bytes little endian, Linux kernelI2C_FUNC_xxx
flags. - Set delay (
0x02
): sets the clock phase of theSCL
signal, in microseconds, two little-endian bytes. No response payload. - Get status (
0x03
): returns the current status as a single payload byte.0x00
: idle status: nothing happened0x01
: The last transfer was successful, an ACK was received from the target I2C device.0x02
: The last transfer failed, a NAK was received from the target I2C device, or no devices responded to the address.
- Do transfer (
0x04
..0x07
): perform an I2C transfer.- Arguments: 2 little-endian 'flags' bytes (Linux kernel
I2C_M_xxx
flags), 2 little-endian I2C device address bytes, 2 little-endian transfer length bytes. - If the lowest bit (bit 0) of the command byte is set, a "start condition" is performed at the start of the I2C transfer. Otherwise, a "repstart" is done.
- If bit 1 of the command byte is set, a "stop condition" is performed at the end of the transfer, causing the target device to stop listening to further commands, and go back to listening for its address on the bus.
- If
flags & I2C_M_RD
, this is a read operation. The amount of bytes read (max. the number of bytes specified in the arguments) is returned as data payload. - If the transfer length is 0, this is an address probe. Response contains no payload, but a status byte (together with a 0-length byte) is still sent out.
- Otherwise, this is a write transfer. The number of bytes specified in the arguments is read from the USB host, and sent over the I2C bus. Response contains no payload, but a status byte (together with a 0-length byte) is still sent out.
- Arguments: 2 little-endian 'flags' bytes (Linux kernel
Temperature sensor commands
- Get I2C address (
0x00
): gets the address of the virtual temperature sensor device on the I2C bus (the one used in cmd.0x14
).0xff
if disabled. Single byte response payload. - Set I2C address (
0x01
): sets the address of the virtual temperature sensor I2C device,0xff
to disable. Single argument byte, two response bytes (old and new addresses). - Get temperature (
0x02
): returns the 2-byte 8.4 fixed point temperature, little endian. - Get lower temperature limit (
0x03
): returns the 2-byte minimum temperature before things start going bad. - Get upper temperature limit (
0x04
): returns the 2-byte maximum temperature before things start going bad. - Get critical temperature limit (
0x05
): returns the 2-byte critical temperature when things are going really bad.
1wire commands
TODO
commands
0x00 <1 byte mode>
set mode (see interface modes)
1wire interface modes
0x00
controller0x10
controller (overdrive)0x01
peripheral0x11
peripheral (overdrive)
controller operations
0x01 <2 byte write size> <2 byte read size> <write data>
reset, then write / read, returns 1 byte status then up to the number of requested bytes0x02 <read size>
read rom (eg, DS2401). basically a write/read where the write is 0x33, returns 1 byte status then up to the number of requested bytes0x03
TODO match rom (executes the 1wire match rom algorithm)0x04 <2 byte maximum number of devices to return>
search rom (executes the 1wire search rom algorithm to detect all connected peripherals)- TODO
peripheral ops
0x81 <2 byte mode>
set peripheral mode (below)0x82 <2 byte size> <data>
set peripheral data (eg, eeprom contents)
peripheral modes
0x2401
DS2401 emulation (with configurable ID)- TODO
additional peripheral ops
0x83
report timing (returns a measurement of the time taken between one controller query and the next)
Mode 3 (JTAG/SWD/... pinout scanner)
- Scan types:
- JTAG: 0
- SWD: 1
- (SBW: 2)
Commands:
0x33
: Get status: no argument bytes, one result byte0x0x
: scan busy (type:x
, eg. 0x00 = JTAG busy, 0x01 = SWD busy,x
< 0x7f)0x7f
: idle0b1xxxxxxx
: scan finished,0bxxxxxxx
matches found
0x34
: Get scan result (only if status is finished): no argument bytes, 8*x (JTAG) or 6*x (SWD) result bytes- result: for each match:
- JTAG: all bytes: pin numbers of TCK, TMS, TDI, TDO, nTRST, IR length, # of pins toggled, "possibly a short-circuit" warning flag
- SWD: swclk, swdio pin numbers (bytes), ID code (4 bytes, little-endian)
- result: for each match:
0x35
: Start scan (only valid if status is not0x01
): three argument bytes (scan type, start and end pin numbers (inclusive)), no result bytes0x36
: Get pin range: no argument bytes, two result bytes (min and max pin numbers, like start/end pins as in0x35
)0x37
: Force-stop scan. No argument or result bytes, sets mode to idle.
Mode 4 (SUMP logic analyzer)
0x43
: Get overclocking state: no argument bytes, one result byte (overclocking off/on (resp.0x00
or nonzero) (or amount, device-dependent, depending on what future devices may bring?))0x44
: Set overclocking state: one argument byte, no result bytes (same format as0x40
)