SPI protocol

Description of the SPI protocol and its implementation in the Typhoon HIL toolchain.

Protocol introduction

Note: This introduction presents a basic overview of the SPI protocol. To read the excerpted content in its full context, please refer to [1]

The Serial Peripheral interface (SPI) is a synchronous serial communication interface specification used for short-distance communication, primarily in embedded systems.

SPI devices communicate in full duplex mode using a master-slave architecture usually with a single master. The master (controller) device originates the frame for reading and writing. Multiple slave-devices may be supported through selection with individual chip select (CS), sometimes called slave select (SS) lines.


The SPI bus specifies four logic signals

  • SCLK: Serial Clock (output from master)
  • MOSI: Master Out Slave In (data output from master)
  • MISO: Master In Slave Out (data output from slave)
  • CS /SS : Chip/Slave Select (output from master to indicate that data is being sent)

MOSI on master connects to MOSI on slave. MISO on master connects to MISO on slave.

Clock polarity and phase

SPI has 4 operating modes that correspond to the four possible clocking configurations. These configurations are defined with the clock polarity (CPOL) and clock phase (CPHA).

  • Mode 0: Data is sampled on the rising edge of the clock pulse with a non-inverted clock polarity (CPOL = 0, CPHA = 0)
  • Mode 1: Data is sampled on the falling edge of the clock pulse with a non-inverted clock polarity (CPOL = 0, CPHA = 1)
  • Mode 2: Data is sampled on the falling edge of the clock pulse with an inverted clock polarity (CPOL = 1, CPHA = 0)
  • Mode 3: Data is sampled on the rising edge of the clock pulse with an inverted clock polarity (CPOL = 1, CPHA = 1)

Independent slave configuration

In the independent slave configuration, there is an independent chip select line for each slave. The master asserts only one chip select at a time. Since the MISO pins of all slaves are connected together, they are required to be tri-state pins (high, low or high-impedance), where the high-impedance output must be applied when the slave is not selected.

Daisy chain configuration

Some products that implement SPI may be connected in a daisy chain configuration, the first slave output being connected to the second slave input, etc. The SPI port of each slave is designed to send out during the second group of clock pulses an exact copy of the data it received during the first group of clock pulses. The whole chain acts as a communication shift register; daisy chaining is often done with shift registers to provide a bank of inputs or outputs through SPI. Each slave copies input to output in the next clock cycle until active low SS line goes high. Such a feature only requires a single SS line from the master, rather than a separate SS line for each slave.

SPI protocol in Typhoon HIL toolchain

Currently, only SPI Slave functionality is implemented in the Typhoon HIL toolchain. It is supported by the following Typhoon HIL devices: HIL404 and HIL606.

SPI is implemented using the GPIO connector on a HIL device. This limits the use of the protocol to the devices that have this type of connector. The list of devices that have the GPIO connector can be found in the General Specifications.

The pinout for the SPI protocol can be customized through the SPI Slave component in Schematic Editor, as shown in Table 1. The pinout for the GPIO connector can be found in the Mechanical page.

SPI Slave

The SPI Slave component implements the Slave part of the SPI protocol. Using this component you can configure the SPI Slave operating mode described in Protocol introduction, define the Register map and define the message frames.

The SPI component icon and dialog window are shown in Table 1.

Table 1. SPI Slave component
Icon Dialog window Properties

SPI Slave

  • General
    • Execution rate
    • SPI mode
    • MOSI pin
    • MISO pin
    • SCLK pin
    • CS/SS pin
  • Message
    • Default return
    • Write frame
    • Read frame
    • Message output
    • Receive output
    • Generate message structure
  • Registers
    • Registers
    • Generate registers

The SPI Slave component properties are described in Table 2.

Table 2. SPI Slave component properties
Tab Property name Description
General Execution rate Signal Processing execution rate
SPI mode Defines the SPI operation mode
MOSI pin Defines which GPIO pin is used for the MOSI signal
MISO pin Defines which GPIO pin is used for the MISO signal
SCLK pin Defines which GPIO pin is used for the SPI clock signal
CS/SS pin Defines which GPIO pin is used for the chip select signal
Message Default return Defines a 1 byte value which will be sent by the SPI Slave in parts of the message not reserved for register data.
Write frame Defines the structure of the write frame. This property is defined as a list of Python dictionaries.
Read frame Defines the structure of the read frame. This property is defined as a list of Python dictionaries.
Message output Defines the structure of the data that is returned as a response to the read frame. This property is defined as a list of Python dictionaries.
Receive output Choose whether the message output is sent in the same message as the read frame (this appends the output frame to the read frame), or as part of the next message (output is sent at the start of the next message).
Generate message structure Pressing the button will present an additional dialog window that allows the user to specify the message frames in more intuitive manner.
Registers Register Definition of the SPI Slave register map. The property is defined as a Python dictionary. A detailed description of the register map specification is in Register map
Generate registers Pressing the button will present an additional dialog window that allows the user to specify the register map in more intuitive manner.

Message frames

Three message frames are defined:
  • Write frame - represents the write command coming from the SPI Master. Using this message, the Master can change the value of the Slave register on the specified address
  • Read frame - represents the read command coming from the SPI Master. Using this message, the Master requests data from the Slave on the specified address
  • Output frame - represents the Slaves answer to the read message form the Master

These message frames have customizable structures which can be defined based on user requirements. For the structure to be functional, it has to follow these requirements:

  • Write and read frames must contain Command and Address parts
  • Write and output frames must contain a Register data field
  • Command and Address parts of the write and read frame must start from the same bit and have the same length
  • If the output frame is sent in the next message, read and write frames must have a size greater or equal to the size of the output frame
  • The start bit of the first part in the Output frame should be equal to the total size of the Read frame
Table 3. Field descriptions for Message frames configuration dialog
Field Description
Message part Defines whether the part is a Command, Address, Register data or Input data (Input data is used as a filler and its contents is ignored)
Start bit Position of first bit of that message part in the message frame
Length Size of that message part, defined in bits
Logic Defines the logic for the command (not available other frame parts)
Value Defines the value for the command (not available for other frame parts)

Register map

The Register map defines the list of registers on the Slave device, their addresses, types, lengths and Endianness. These registers define inputs and outputs of the SPI Slave component.

Table 4. Field descriptions for registers configuration dialog
Field Description
Signal name Defines the name of the register
Register address Defines the register address which is used to access register data
IO type Defines the register as an input or output (constant type registers can only be defined as outputs)
Signal type Defines the register as a variable or constant (input registers can only be defined as variables)
Data type Defines the type of data that the register holds (only registers defined as constant can have the String data type)
Length Defines the register size in bytes (depends on the register data type)
Endian Defines the Endianness of the register data
Signal value Defines the initial register value (values can only be set for output registers)

Accessing registers

Register data can be accessed using the user-defined register address or the addresses generated for each byte of a register. These addresses are automatically generated based on the user-defined register address using 1 byte increments. An example of this is shown in Figure 1.

Figure 1. Register address generation

Interractions between registers

User-defined registers are stored in memory as a C array, with their order being the same as the order of definition (register address does not affect order). This makes it possible to access data from multiple registers with a single write or read command.

For example, if the registers are defined as shown in Figure 1 a read Frame can be sent with the Address 0x10 requesting 2 bytes of data. The response would contain data from Registers 2 and 3.

SPI reset

The SPI Slave application can be disabled by providing a non-zero value to the the reset input while the simulation is running. This will cause the application to reset and stay in a disabled state until a 0 is detected at the reset input. Resetting the SPI Slave application will clear all active SPI status codes.

Note: Since the SPI Slave application is unable to differentiate between individual message frames, it is recommended that it is reset before enabling transmission from the SPI Master device. Starting the SPI Slave application while a message frame is being sent will most likely cause irregularities in message frames and could corrupt data in the SPI registers.

SPI status

The SPI status output is used to monitor the SPI status which can help troubleshoot potential errors. Table 5 contains possible error codes and their descriptions. Each error has dedicated bit value(s) that respresent the error code status.

Table 5. SPI status codes
Value Error
64 (0x40) Transfer buffer underflow
32 (0x20) Receive buffer full
16 (0x10) Transfer buffer full
2 (0x02) Modfail
1 (0x01) Receive buffer overflow

SPI Slave example

This example uses a SCADA Input to set the value of the input register, as well as Probes to read the values of the output registers. The SPI Slave component is configured as shown in the following figures.

The message structure definition is shown in Figure 2.

Figure 2. Message structure

The registers definition is shown in Figure 3.

Figure 3. Register definition

Timing diagrams of message frames

The timing diagrams for the specified message structures are as follows:

  • Write frame

  • Read frame with output frame in the same message

  • Output frame in a new message


  1. https://en.wikipedia.org/wiki/Serial_Peripheral_Interface