Raw SPI is a new mode that provides high-speed access to the Bus Pirate SPI hardware. It was developed in conjunction with Michal Ludvig, so that AVRDude can use the  Bus Pirate to program AVR microcontrollers and EEPROMs.

Firmware v2.3 includes two new raw I/O modes that give computer software and scripts direct access to the Bus Pirate hardware. Hopefully this opens the door to a whole new class of Bus Pirate applications, like chip programmers. In this post we describe the raw SPI access mode. We’ll describe the raw bigbang mode in a few days. The protocol is documented below the break.

Raw SPI mode command table

  • 00000000 – Enter raw bitbang mode, reset to raw bitbang mode
  • 00000001 – SPI mode/rawSPI version string (SPI1)
  • 00000010 – CS low (0)
  • 00000011 – CS high (1)
  • 00001101 – Sniff all SPI traffic
  • 00001110 – Sniff when CS low
  • 00001111 – Sniff when CS high
  • 0001xxxx – Bulk SPI transfer, send 1-16 bytes (0=1byte!)
  • 0010xxxx – Low 4 bits of byte + single byte write/read
  • 0011xxxx – High 4 bits of byte
  • 0100wxyz – Configure peripherals, w=power, x=pullups, y=AUX, z=CS
  • 01010000 – Read peripherals
  • 01100xxx – Set SPI speed, 30, 125, 250khz; 1, 2, 2.6, 4, 8MHz
  • 01110000 – Read SPI speed
  • 1000wxyz – SPI config, w=output type, x=idle, y=clock edge, z=sample
  • 10010000 – Read SPI config

Commands are a single byte, except bulk SPI transfers. The Bus Pirate responds to SPI write commands with the data read from the SPI bus during the write. Most other commands return 0x01 for success, or 0x00 for failure/unknown command.

Key points

  • Send the raw byte value 0x00 into the user command prompt 20 times to enter bitbang mode.
  • Enter 0x01 in bitbang mode to enter raw SPI mode.
  • Return to raw bitbang mode from raw SPI mode by sending 0x00 one time.
  • Operations that write a byte to the SPI bus also return a byte read from the SPI bus.
  • Hex values shown here, like 0x00, represent actual byte values; not typed ASCII entered into a terminal.
  • Other values are shown as 8bit binary numbers. Here’s a binary->decimal->hex converter.


00000000 – Enter raw bitbang mode, reset to raw bitbang mode

This command has two purposes. First, send it to the command line interface 20 times to enter the raw bitbang binary mode. It’s also used to exit the raw SPI mode and return to raw bitbang mode.

Send the value 0x00 to the Bus Pirate command line interface 20 times to enter raw bitbang mode. The Bus Pirate replies ‘BBIOx’, where x is the raw bitbang version number (currently 1).

Once in raw SPI mode (see command 00000001), the 0x00 command returns to raw bitbang mode. Send 0x00 once to return to raw bitbang mode.

00000001 – Enter raw SPI mode, display version string

Once in raw bitbang mode, send 0x01 to enter raw SPI mode. The Bus Pirate responds ‘SPIx’, where x is the raw SPI protocol version (currently 1). Get the version string at any time by sending 0x01 again.

0000001x – CS high (1) or low (0)

Toggle the Bus Pirate chip select pin, follows HiZ configuration setting. CS high is pin output at  3.3volts, or HiZ. CS low is pin output at  ground. Bus Pirate responds 0x01.

00001101 – Sniff all SPI traffic, 0000111x – Sniff when CS low(0)/high(1)

The SPI sniffer is implemented in hardware and should work up to 10MHz. It follows the configuration settings you entered for SPI mode. The sniffer can read all traffic, or filter by the state of the CS pin.

  • [/]  – CS enable/disable
  • \ – escape character precedes a data byte value
  • (\x)  – MISO read

Sniffed traffic is encoded according to the table above. The byte sniffed on the MISO pin is displayed inside (). Data bytes are escaped with the ‘\’ character.

Send a single byte to exit, Bus Pirate responds 0x01 on exit.

0001xxxx – Bulk SPI transfer, send/read 1-16 bytes (0=1byte!)

Bulk SPI allows direct byte reads and writes. The Bus Pirate expects xxxx+1 data bytes. Up to 16 data bytes can be sent at once, each returns a byte read from the SPI bus during the write.

Note that 0000 indicates 1 byte because there’s no reason to send 0. BP replies 0x01 to the bulk SPI command, and returns the value read from SPI after each data byte write.

0100wxyz – Configure peripherals w=power, x=pull-ups, y=AUX, z=CS

Enable (1) and disable (0) Bus Pirate peripherals and pins. Bit w enables the power supplies, bit x toggles the on-board pull-up resistors, y sets the state of the auxiliary pin, and z sets the chip select pin. Features not present in a specific hardware version are ignored. Bus Pirate responds 0x01 on success.

Note: CS pin always follows the current HiZ pin configuration. AUX is always a normal pin output (0=GND, 1=3.3volts).

Read the current settings by sending 01010000.

01100xxx –  SPI speed

000=30kHz, 001=125kHz, 010=250kHz, 011=1MHz, 100=2MHz, 101=2.6MHz, 110=4MHz, 111=8MHz

This command sets the SPI bus speed according to the values shown. Default startup speed is 000 (30kHz).

Read the current settings by sending 01110000.

1000wxyz – SPI config, w=HiZ/3.3v, x=CKP idle, y=CKE edge, z=SMP sample

This command configures the SPI settings. Options and start-up defaults are the same as the user terminal SPI mode. w= pin output HiZ(0)/3.3v(1), x=CKP clock idle phase (low=0), y=CKE clock edge (active to idle=1), z=SMP sample time (middle=0). The Bus Pirate responds 0x01 on success.

Default raw SPI startup condition is 0010. HiZ mode configuration applies to the SPI pins and the CS pin, but not the AUX pin. See the PIC24FJ64GA002 datasheet and the SPI section[PDF] of the PIC24 family manual for more about the SPI configuration settings.

Read the current settings by sending 10010000.

0010xxxx, 0011yyyy – Enter SPI data byte in nibbles, read SPI byte

Data bytes can also be entered in two nibbles using this pair of commands. 0011yyyy loads the upper 4 bits of a data byte. 0010xxxx loads the lower 4 bits of the data byte, and writes it to the SPI bus. The bus write returns a byte read.

A byte is transmitted over SPI each time the low bits are sent. Be sure to send the upper bits first, then send the lower bits to complete the data and transmit it. If the upper four bits are the same as the previous byte, then you can increase speed by sending just the lower four bits.

Entering the upper 4 bits returns 1 for success, or 0 for failure. Entering the low bits returns a byte read from the SPI bus.