Skip to content

ChipWhisperer USB Protocol

Useful reading: https://www.beyondlogic.org/usbnutshell/usb1.shtml

Basic Overview

USB stuff is handled in usb.c. main_setup_out_received() handles OUT setup packets, while main_setup_in_received() handles IN setup packets.

Both functions select different commands based on the USB bRequest field. OUT packet commands are handled in a callback, while IN packet commands are handled directly in main_setup_in_received().

Depending on the command, wValue and/or payload may be used as command parameters.

If the SAM3U is unable to process the setup packet (aka either setup_*_received() returns false) you'll get a pipe error on the Python side.

ChipWhisperer-Lite

Setup OUT Commands

0x10: REQ_MEMREAD_BULK

Setup a bulk IN transfer to read from the FPGA. This command must be sent before attempting to read from the bulk endpoint. An additional bulk transfer is not setup upon this one completing, meaning this command must be called again to do another bulk read.

wValue

Unused

payload
  • Bytes 0-3: Length of data to read from FPGA
  • Bytes 4-7: FPGA Address to read from

0x11: REQ_MEMWRITE_BULK

Setup a bulk OUT transfer to write to the FPGA. This command must be sent before attempting to write to the bulk endpoint.

wValue

Unused

payload
  • Bytes 0-3: Unused
  • Bytes 4-7: FPGA Address to write to

0x12: REQ_MEMREAD_CTRL

Setup a read from the FPGA as a control IN transfer. An IN transfer with this same bRequest will read data off the FPGA once this command has been called.

wValue

Unused

payload
  • Bytes 0-3: Length of data to read from FPGA
  • Bytes 4-7: FPGA Address to read from

0x13: REQ_MEMWRITE_CTRL

Write data to the FPGA.

wValue

Unused

payload
  • Bytes 0-3: Length of data to write to FPGA
  • Bytes 4-7: FPGA Address to write to
  • Bytes 8+: Data to write to FPGA

0x16: REQ_FPGA_PROGRAM

Setup FPGA bitstream programming

wValue
  • 0xA0: Step 1 - setup peripherals, erase FPGA
  • 0xA1: Step 2 - setup bulk endpoint to write over SPI instead of the external memory interface. You still need to setup via REQ_MEMWRITE_BULK before writing data to the bulk endpoint
  • 0xA2: Step 3 - set bulk endpoint back to external memory interface (usual FPGA communication). Call once the FPGA has been programmed
payload

Unused


0x1A: REQ_USART0_DATA

Sends data over the USART interface

wValue

Unused

payload

Data to send


0x1B: REQ_USART0_CONFIG

USART configuration and special commands

wValue

Selects the USART command. The following commands are valid for OUT packets:

  • 0x0010: USART port configuration - baud, parity, etc.
  • 0x0011: USART port enable
  • 0x0012: USART port disable
payload

Only valid for wValue=0x0010 (USART port configuration):

  • Bytes 0-3: Baud rate
  • Byte 4: Stop bit selection. 0 sets 1 stop bit, 1 sets 1.5 stop bits, 2 sets 2 stop bits
  • Byte 5: Parity selection: 0 sets no parity, 1 sets odd, 2 sets even, 3 sets mark, 4 sets space
  • Byte 6: Sets data length. Values of 5-8 are valid.

0x1C-0x1E: Smart Card Interface

Hasn't been used in a while, may not work

0x1F: USART2 Dump Enable

Seems to be unused


0x20: REQ_XMEGA_PROGRAM

Do XMEGA PDI command

wValue

Low 8 bits: command to perform

  • 0x01: Enter programming mode
  • 0x02: Leave programming mode
  • 0x03: Erase XMEGA
  • 0x04: Write mem
  • 0x05: Read mem
  • 0x06: CRC (does nothing)
  • 0x07: Set param
  • 0x22: Write data to internal rambuf

Upper 8 bits: offset for command 0x22

payload

See pdi/XPROGNewAE.c


0x21: REQ_AVR_PROGRAM

TODO

0x22: REQ_SAM3U_CFG

SAM3U configuration and special commands

wValue
  • 0x01: Turn on slow clock for new AVR programming
  • 0x02: Turn off slow clock
  • 0x03: Enter bootloader for firmware upgrade
  • 0x10: Reset SAM3U (firmware x.30 and later)
  • 0x11: Release FPGA lock - can fix some pipe errors cased by interruption of usb communication (firmware x.30 and later)
payload

Unused


0x31: REQ_CDC_SETTINGS_EN

Allow or disallow CDC interface to change USART settings.

wValue
  • Bit 0: Allow CDC settings change if 1 or disallow if 0
  • Bit 1: Unused, reserved for additional CDC interfaces
payload

Unused


Setup IN Commands

0x12: REQ_MEMREAD_CTRL

Does the actual FPGA read setup by the REQ_MEMREAD_CTRL OUT command.

wValue

Unused

payload

Read FPGA data


0x15: REQ_FPGA_STATUS

Checks whether or not the FPGA has finished being programmed

wValue

Unused

payload

Byte 0: 1 if FPGA programmed, 0 otherwise Bytes 1-3: 0x00


0x17: REQ_FW_VERSION

Get the version of the SAM3U firmware

wValue

Unused

payload

Byte 0: FW_VER_MAJOR Byte 1: FW_VER_MINOR Byte 2: FW_VER_MINOR


0x1A: REQ_USART0_DATA

Read data from the SAM3U's USART buffer

wValue

Unused

payload

USART data


0x1A: REQ_USART0_CONFIG

Read status of SAM3U USART

wValue
  • 0x0010: Reserved
  • 0x0014: Get number of characters in USART RX buffer (in_waiting)
  • 0x0018: Get number of characters in USART TX buffer (tx_in_waiting)
payload

For in_waiting commands:

  • Bytes 0-3: number of characters in buffer

0x20: REQ_XMEGA_PROGRAM

wValue
  • 0x20: Get status
  • 0x21: Read data from internal rambuf
payload

Reqested Data


0x21: REQ_AVR_PROGRAM

TODO


0x31: REQ_CDC_SETTINGS_EN

See whether the CDC port is allowed to modify the USART settings

wValue

Unused

payload
  • Byte 0: 1 if CDC Port 0 can change USART settings, otherwise 0
  • Byte 1: Reserved for additional CDC Ports

ChipWhisperer-Pro

Uses the same commands as the Lite, but adds a few new commands

New OUT Commands

0x14: REQ_MEMSTREAM

TODO

wValue

Unused

payload
  • Bytes 0-3:

New IN Commands

0x14: REQ_MEMSTREAM

TODO

wValue

Unused

payload
  • Bytes 0-3:

ChipWhisperer-Nano

Shares most commands with the Lite/Pro, but some commands have different behaviour. Also has a few new commands.

New/Changed OUT Commands

0x10: REQ_READMEM_BULK

wValue

Unused

payload

Bytes 0-3: number of bytes to read from ADC, up to a maximum of 100 000


0x11: REQ_WRITEMEM_BULK

Does nothing


0x12: REQ_READMEM_CTRL

wValue

Unused

payload

Bytes 0-3: number of bytes to read from ADC, up to a maximum of 100 000 bytes


0x13: REQ_WRITEMEM_CTRL

Does nothing


0x25: REQ_GPIO_OUT

Configures GPIO pins

wValue

Selects GPIO Configuration

  • 0x01: Set pin as output
  • 0x02: Set pin as input
  • 0x03: Set pin high
  • 0x04: Set pin low
  • 0x05: Set pin as peripheral A
  • 0x06: Set pin as peripheral B
payload
  • Byte 0: Bitmask of pins to update

  • GPIO3 = (1 << 2)

  • GPIOnRST = (1 << 4)
  • GPIOPDIC = (1 << 5)
  • GPIOPDID = (1 << 6)

0x27: REQ_CLK_OUT

Sets clock division for output clock

wValue

Unused

payload
  • Byte 0: The clock divisor. Can be 1 or any multiple of 2 up to 64.

0x28: REQ_ADCCLK_OUT

wValue

Unused

payload
  • Byte 0: The clock divisor. Can be 1 or any multiple of 2 up to 64.
  • Bytes 1-2: Unused
  • Byte 3: ADC clock source. If 0, use internal clock. Otherwise, use external clock
  • Byte 4: ADC clock enable. If 0, disable clock. Otherwise, enable clock

0x29: REQ_ARM

Arm the scope.

wValue
  • If 1, arm scope. Otherwise, do nothing
payload

Unused


0x2A: REQ_SAMPLES

Set the number of samples to capture.

wValue

Unused

payload
  • Bytes 0-3: Number of samples to capture. Should not be set above 100 000.

0x2C: REQ_GLITCHSET

Change glitch settings

wValue

Unused

payload
  • Bytes 0-3: Glitch offset
  • Bytes 4-7: Glitch width

0x2D: REQ_GLITCHGO

Manually trigger glitch

wValue

Unused

payload

Unused


New/Changed IN Commands

0x27: REQ_CLK_OUT

wValue

Unused

payload
  • Byte 0: Clock divisor
  • Bytes 1-2: 0x00

0x28: REQ_ADCCLK_OUT

wValue

Unused

payload
  • Byte 0: Clock divisor
  • Bytes 1-2: 0x00
  • Byte 3: Clock source
  • Byte 4: Clock enabled

0x29: REQ_ARM

wValue

Unused

payload
  • Byte 0: 1 if capture done, 0 otherwise

0x2A: REQ_SAMPLES

The number of ADC samples the Nano will capture

wValue

Unused

payload
  • Bytes 0-3: Number of samples to capture

0x2B: REQ_BUFSIZE

ADC sample buffer size - the maximum number of samples that can be captured.

wValue

Unused

payload
  • Bytes 0-3: ADC sample buffer size

0x2C: REQ_GLITCHSET

Read glitch settings

wValue

Unused

payload
  • Bytes 0-3: Glitch offset
  • Bytes 4-7: Glitch width

Removed OUT Commands

0x16: REQ_FPGA_PROGRAM


Removed IN Commands

0x15: REQ_FPGA_STATUS

0x21: REQ_AVR_PROGRAM


ChipWhisperer CW305 Artix

Again, many USB commands are shared between the ChipWhisperer-Lite and CW305.

New/Changed OUT Commands

0x11: REQ_MEMWRITE_BULK

Setup a bulk OUT transfer to write to the FPGA. This command must be sent before attempting to write to the bulk endpoint. The address field is unused.

wValue

Unused

payload
  • Bytes 0-7: Unused

0x15: REQ_MEMWRITE_CTRL_SAMU3

TODO: (seeded encryption for super speed)

0x22: REQ_SAM3U_CFG

SAM3U configuration and special commands

wValue
  • 0x01: Turn on slow clock for new AVR programming
  • 0x02: Turn off slow clock
  • 0x03: Enter bootloader for firmware upgrade
  • 0x04: Turn off FPGA clock
  • 0x05: Turn on FPGA clock
  • 0x06: Toggle trigger pin
payload

Unused


0x30: REQ_CDCE906

Do a write to or read from the CW305's CDCE906 PLL chip over I2C. The status of the command can be read with an IN REQ_CDCE906.

wValue

Unused

payload
  • Byte 0: If 0, do a read. If 1, do a write.
  • Byte 1: CDCE906 Address to read/write
  • Byte 2: Unused if doing a read. The data to write if doing a write.

0x31: REQ_VCCINT

Set the VCCINT voltage for the FPGA chip.

**WARNING: The bounds for this command are 600mV to 1200mV, but the maximum voltage for the FPGA chip is 1100mV. Exceeding this voltage may damage the FPGA. **

wValue

Unused

payload

Bytes 0-1: 16-bit integer representing the desired voltage in mV Byte 2: Checksum. Equal to (payload[0] ^ payload[1] ^ 0xAE)


0x33: REQ_FPGASPI_PROGRAM

Bitbang SPI data to the CW305 SPI chip. Assumes the FPGA is already configured with the passthrough bitstream to route the SAM3U pins to the SPI flash.

wValue

Command select:

  • 0xA0: Init SPI
  • 0xA1: Deinit SPI
  • 0xA2: Set CS pin low
  • 0xA3: Set CS pin high
  • 0xA4: Send data
payload

Data to send to the SPI flash. Unused unless wValue == 0xA4.


0x34: REQ_FPGAIO_UTIL

Generic SAM3U pin configuration control

wValue

Select operation:

  • 0xA0: Configure pin
  • 0xA1: Release IO pin
  • 0xA2: Set IO pin low or high
payload
  • Byte 0: Select pin (based on Atmel ASF GPIO numbering)
  • Byte 1: config

If wValue == 0xA0, config should be set as follows:

  • 0x01: Configure pin as input
  • 0x02: Configure pin as output high
  • 0x10: Configure pin as SPI MOSI
  • 0x11: Configure pin as SPI MISO
  • 0x12: Configure pin as SPI SCK
  • 0x13: Configure pin as SPI CS

If wValue == 0xA2, config should be set as follows:

  • 0x00: Set pin low
  • 0x01: Set pin high

0x35: FREQ_FPGASPI1_XFER

Bitbang SPI. Must configure pins using REQ_FPGAIO_UTIL before using this command.

wValue

Command select:

  • 0xA0: Init SPI
  • 0xA1: Deinit SPI
  • 0xA2: Set CS pin low
  • 0xA3: Set CS pin high
  • 0xA4: Send data
payload

Data to send. Unused unless wValue == 0xA4.


New/Changed IN Commands

0x30: REQ_CDCE906

Read status/data back from an OUT REQ_CDCE906 command. You should do a write/read using the OUT version of this command before calling this one

wValue

Unused

payload
  • Byte 0: Status of command
  • Byte 1: Received data

0x31: REQ_VCCINT

Read what voltage the VCCINT regulator is set to.

wValue

Unused

payload
  • Byte 0: Status
  • Byte 1-2: 16-bit integer representing set voltage in mV

0x33: REQ_FPGASPI_PROGRAM

Read data back from the FPGASPI buffer.

You should use the OUT version of this command to do the actual transfer.

wValue

Unused

payload

Data in the FPGASPI buffer


0x35: REQ_FPGASPI1_XFER

Read data back from the generic bitbang SPI buffer.

You should use the OUT version of this command to do the actual transfer.

wValue

Unused

payload

Data in the SPI buffer


Removed OUT Commands

0x1A: USART0_DATA

0x1B: USART0_CONFIG

0x20: REQ_XMEGA_PROGRAM

0x21: REQ_AVR_PROGRAM

0x31: REQ_CDC_SETTINGS_EN


Removed IN Commands

0x1A: USART0_DATA

0x1B: USART0_CONFIG

0x20: REQ_XMEGA_PROGRAM

0x21: REQ_AVR_PROGRAM

0x31: REQ_CDC_SETTINGS_EN