SPI Specification


  • SPI Transfer: An 8 bit, Mode 0 MSB SPI communication

  • Words: 64 bits of 8 little endian SPI transfers

  • Message: A complete SPI transmission consisting of one or more words

  • Forward Channel: SPI communication initiated by firmware to FPGA

  • Reverse Channel: Data transmitted by FPGA to firmware during message transfer

  • Motor Channel:


RAPcores follows Semantic Versioning. This is still a pre-1.0 project so breaking changes are likely to happen with the SPI protocol. This document serves as the “as-built” reference for the RAPcores, and may deviate from documents outside this repository.


The SPI bus operated in peripheral mode 0 MSB.The protocol assumes any complete transfer is a 64 bit word. The word construction is set to little endian for improved compatibility with SPI controller devices.

Header Action Transmission Length (Words) Default Value
0x01 Coordinated Step Timer 2 + 2*N motors N/A
0x0a Motor Enable/Disable 1 0
0x0b Motor Braking on Disable 1 0
0x20 DDA Timer Divider 1 32
0x10 Set Motor Config 1 See Below
0x31 Charge Pump Divider 1 See Below
0xfe Get Version 2 0x...MMmmpp

Set Motor Config - 0x10

Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7 Byte 8
0x10 Motor Channel Reserved Reserved Reserved Reserved Current Microsteps

Current: Current is set 0-255 (0x0-0xff), and this value may be divided by the number of bits of internal resolution avaialble.

Microsteps: Important Note This is set as the increment across the phase table. For example if a single electrical cycle e.g. cosine from 0 to pi, is divided by 64, to achieve full resolution microsteps is set to 1. For 32 divisions, microsteps would be set as 2. This is inverse from other systems that specify the microsteps in full divisions. Whereas this method allows for fractional steps such as 64/3.

Get API Version - 0xfe

Word Word 1 Word 2
Byte Byte 1 2 3 4 5 6 7 8 Byte 1 2 3 4 5 6 7 8
TX 0xfe

Note: For stable release versions the development flag is 0.

Enable/Disable Motors - 0x0a

Word 1
Byte 1 B2 B3 B4 B5 B6 B7 B8
TX 0x0a 0b11111111

Starting from 0x01 of B8, enable or disable (1/0 respectively) a motor channel. This will power up the motors. For example:

Byte 8
Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1
Mot 8 Mot 7 Mot 6 Mot 5 Mot 4 Mot 3 Mot 2 Mot 1
Dis. Dis. Dis. Dis. En. En. En. En.
0 0 0 0 1 1 1 1

Brake motors on Disable - 0x0b

Word 1
Byte 1 B2 B3 B4 B5 B6 B7 B8
TX 0x0b 0b11111111

Starting from 0x01 of B8, brake a motor channel on disable.

Coordinated Step Timer - 0x01

This message type specifies a move segment to be clocked out of the core. It uses 64bit words to specify the DDA values, and returns 32bit precision encoder readings.

I/O Word 1 (Control / Status) Words 2,4,6,etc. Words 3,5,7,etc.
B1 B2 B3 B4 B5 B6 B7 B8 B1 B2 B3 B4 B5 B6 B7 B8 B1 B2 B3 B4 B5 B6 B7 B8
CO0x01 RESERVED 0bPONM_LKJI 0bHGFE_DCBA dda_tickssubstep_increment_Nsubstep_increment_increment_N
CIStatus word is TBD shaft_encoder_N effector_encoder_N


  • CO is the forward SPI channel from the controller to the peripheral (core). CI is the reverse channel.

  • Word1 is the 64bit message header, consisting of 8 bytes, MSbyte = B1, LSbyte = B8

  • Word1 from CO is the control word. Word1 back from the CI is the status word

  • _N is the number of motor channels configured - making the message length 2xN+1 64bit words

  • CO Word1, Byte1 is the message number in the control word

  • CO direction bitfield: bit A is direction for motor 0; bit P is direction for motor 15;

    • Direction is arbitrary - 0 is considered Normal, 1 is Reverse

  • CO dda_ticks is the segment length in DDA ticks. For example, a value of 16000 at a 16 MHz DDA clock sets a 1 mS segment

  • CI shaft_encoder_N is the signed 32-bit absolute, unscaled encoder count for the shaft encoder. If no encoder is present it’s absolute step count.

  • CI effector_encoder_N is the signed 32-bit absolute, unscaled encoder count for the effector encoder; or zero if no encoder present