主要内容

Model SPI Communication

R2026b

SPI is a full-duplex serial protocol that uses a shift register for data transfer. Modeling SPI communication correctly in Simulink® ensures that the generated code communicates reliably with peripheral devices when you deploy to TI’s C2000™ hardware.

For every bit the controller shifts out on MOSI, the peripheral simultaneously shifts one bit back on MISO. This bidirectional behavior applies to both read and write operations and determines how you structure your SPI model. The c28x_spi_eeprom_interrupt model, which communicates with a CAT25256 EEPROM device, illustrates these patterns throughout this topic.

Before you configure SPI communication, select a C2000 hardware board in your model configuration parameters and connect an SPI peripheral device to the appropriate pins on the board.

Depending on your application requirements, you can model SPI communication using one of two approaches:

  • Blocking mode — The processor waits until the transfer completes. Use this mode for straightforward communication with a single peripheral.

  • Interrupt mode — The processor continues executing other tasks during the transfer. Use this mode for time-critical applications with multiple peripherals.

SPI Data Transfer: Shift Register Mechanism

The SPI shift register exchanges one bit in each direction for every clock cycle. When the controller transmits data, the peripheral simultaneously shifts data back. This exchange means every SPI transaction produces both transmitted and received data, regardless of whether the application needs both directions.

This bidirectional mechanism has two practical consequences for your model:

  • Write operations produce junk receive data. When the controller writes to the peripheral (for example, sending an EEPROM write command), the peripheral shifts back whatever its shift register holds. Discard this data in your model.

  • Read operations require dummy transmit data. When the controller reads from the peripheral (for example, reading an EEPROM memory location), the controller must transmit dummy bytes to generate the clock cycles that shift data out of the peripheral.

Simultaneous Data Transfer on SPI Bus

Timing diagram showing MOSI and MISO signals during two SPI transactions. In the write transaction, the controller shifts valid data on MOSI while junk data appears on MISO. In the read transaction, the controller shifts dummy data on MOSI while valid data from the peripheral appears on MISO.

In the EEPROM example, the Write Data subsystem demonstrates a write operation where received junk data is discarded, and the Read Data subsystem demonstrates a read operation where the controller transmits dummy bytes to clock out the stored EEPROM value.

Blocking Mode: Transfer Data with Single Block

The simplest way to model SPI communication is with the C28x/C29x SPI Controller Transfer block. This block handles both transmit and receive operations internally, eliminating the need to pair separate blocks or configure interrupts.

In blocking mode, the processor waits until the block transfers all data before continuing execution. This approach works well when your application communicates with a single peripheral and does not have strict timing constraints on other tasks.

When using the SPI Controller Transfer block:

The SPI Controller Transfer block manages the chip select (CS) pin automatically — it sets CS low before data transfer and sets CS high after the entire transfer completes. For reliable multi-byte transfers, set the CS pin mode to Explicit GPIO calls as described in Configure Chip Select Pin.

Blocking mode wastes processor time when your application uses multiple SPI peripherals. Because the processor is idle during each transfer, blocking mode accumulates dead time across all modules. Interrupt mode eliminates this idle time.

Interrupt Mode: Transfer Data with Separate Blocks and ISR

For applications where blocking the processor is unacceptable — such as control loops with tight timing requirements or systems with multiple SPI peripherals — use interrupt mode. In this mode, the C28x/C29x SPI Transmit block starts the transfer, and an interrupt notifies the processor when data arrives. The processor executes other tasks during the transfer instead of waiting.

Pair SPI Transmit and Receive Blocks

Because SPI uses a shift register, you must use the SPI Transmit block and the C28x/C29x SPI Receive block together on the controller side. When the SPI Transmit block shifts out data, the SPI Receive block reads the data simultaneously shifted in from the peripheral device.

To model a controller-side transmit operation:

  1. Add an SPI Transmit block and an SPI Receive block to your model.

  2. Connect the transmit data to the SPI Transmit block input.

  3. Complete each transmit-receive sequence before starting the next transfer.

  4. Discard the data from the SPI Receive block output during write operations.

Paired SPI Transmit and Receive Blocks in Write Enable Subsystem

Write Enable subsystem showing a Constant block with value 6 (the EEPROM write enable opcode) connected to the SPI Transmit block input. The SPI Receive block output connects to a Terminator block that discards the junk data. Both blocks show Chip select: GPIO1 configuration.

In the EEPROM example, the Write Enable subsystem demonstrates this pattern — paired SPI Transmit and SPI Receive blocks where the received junk data is discarded.

Configure Interrupts for Non-Blocking Transfer

To prevent data loss during SPI communication, configure interrupts so the processor does not need to poll for transfer completion.

  1. On the Hardware tab, click Hardware Mapping. In the Hardware Mapping tool, enable the transmit or receive interrupt for the corresponding SPI module. Each SPI module supports separate interrupts for transmit and receive operations.

    SPI Interrupt Options in Hardware Mapping Tool

    Hardware Mapping tool showing the Hardware Interrupt configuration. The Interrupt group is set to SPI - Serial Peripheral Interface, and the Interrupt name dropdown displays available SPI interrupts: SPIA_RX_INT, SPIA_TX_INT, SPIB_RX_INT, SPIB_TX_INT, SPIC_RX_INT, SPIC_TX_INT. SPIA_RX_INT is selected.

  2. In the Configuration Parameters dialog box, in the Target hardware resources section for the SPI module, set the FIFO interrupt level (Rx) parameter to specify the number of received bytes that trigger the interrupt. Set the value to match the number of data bytes in each SPI transaction. For example, if each transaction transfers 4 bytes, set the FIFO interrupt level to 4.

    FIFO Interrupt Level in Target Hardware Resources

    Configuration Parameters dialog box showing target hardware resources for the SPI module. The SPI section displays settings including FIFO interrupt level (Rx) set to 1, Enable Tx interrupt and Enable Rx interrupt check boxes, and chip select pin assignment fields. The FIFO interrupt level parameter is highlighted with a red box.

  3. In the interrupt service routine (ISR), use the SPI Receive block to read and process (or discard) the received data.

For a complete implementation of interrupt-based SPI communication, see the c28x_spi_eeprom_interrupt model in the Using SPI to Read and Write Data to SPI EEPROM example.

Manage Chip Select Pin in Interrupt Mode

Because the SPI Transmit and SPI Receive blocks operate independently, they each control one transition of the CS pin:

SPI Transmit

Sets CS low before data transfer.

SPI Receive

Sets CS high after data reception.

You must use both blocks together to complete the CS pin assertion cycle. The SPI blocks manage the CS pin — you do not need to configure its state manually using Digital Output blocks.

Compare Blocking and Interrupt Modes

The choice between blocking and interrupt modes primarily affects processor utilization. For example, with three SPI modules (A, B, C), each transmitting 4 uint16 values at a bit rate of 6.25 Mbps:

Blocking mode (SPI Controller Transfer):

  • Time per bit = 1/6.25 MHz = 0.16 µs

  • Transfer time per module = 4 × 16 bits × 0.16 µs = 10.24 µs

  • Total processor time blocked = 3 × 10.24 µs = 30.72 µs

In blocking mode, the processor is idle during the entire 30.72 µs transfer duration.

Interrupt mode (SPI Transmit and Receive):

  1. The SPI Transmit block starts the transfer for each module.

  2. The processor continues executing other tasks during the transfer.

  3. When the receive interrupt triggers, the ISR reads and discards junk data.

In interrupt mode, the processor is free to execute other tasks during the transfer, significantly improving utilization in applications with multiple SPI peripherals or time-critical control loops.

Processor Utilization in Blocking Mode vs. Interrupt Mode

Side-by-side timing diagrams comparing processor utilization for three SPI modules. In blocking mode, the processor is idle for 30.72 microseconds while transfers execute sequentially. In interrupt mode, the processor executes other tasks during the same transfers, with brief ISR servicing when each transfer completes.

Configure Chip Select Pin

Regardless of which transfer mode you use, set the chip select (CS) pin mode to Explicit GPIO calls on both the controller and peripheral sides. This setting gives the generated code full control over the CS pin state, independent of the SPI peripheral hardware behavior.

The CS pin is active low — it is asserted (low) when the peripheral is selected and deasserted (high) when the peripheral is released. The two CS pin modes behave differently during multi-byte transfers:

  • Provided by the SPI peripheral — The hardware controls the CS pin based on the FIFO state. If the FIFO empties between bytes, the CS pin de-asserts (goes high) prematurely, even if the transfer sequence has not completed.

  • Explicit GPIO calls — The generated code keeps the CS pin asserted (low) until all data bytes in the transfer sequence complete.

On the peripheral side, the controller drives the CS pin. The SPI Receive block on the peripheral has no effect on the CS pin state, but you should still set the mode to Explicit GPIO calls for consistent configuration.

Model SPI Peripheral Communication

If your C2000 board operates as an SPI peripheral (receiving commands from an external controller), the configuration is simpler than the controller side.

On the peripheral side, use only the SPI Receive block. You do not need a separate SPI Transmit block because the SPI Transmit block shifts out whatever data the shift register currently holds, which is not the intended behavior for a peripheral receiver. Configure the SPI Receive block with the same SPI mode (clock polarity and phase) and bit rate as the controller side to ensure proper communication.

SPI EEPROM Example: Write and Read Sequences

The c28x_spi_eeprom_interrupt model demonstrates the SPI modeling patterns described in this topic. The model communicates with a CAT25256 EEPROM device using interrupt-mode SPI, with paired Transmit and Receive blocks and a state machine that sequences the operations.

SPI EEPROM Interrupt Example Model Architecture

Top-level view of the c28x_spi_eeprom_interrupt Simulink model showing three main subsystems: Write EEPROM Data (transmits write commands), Transmit Read Command (sends read opcodes), and Read EEPROM Data (receives data from EEPROM). The HWI_SPIA_RX_INT interrupt block triggers the receive path. Input Data constants on the left provide write values, and Data Display blocks on the right show transmitted and received data.

The EEPROM uses an instruction set where each transaction includes an opcode, address, and data payload.

Write Sequence

To write to a memory location, the controller transmits a frame in the format [Opcode, Address, Value], where the opcode for write is 2. Because the shift register always transfers data in both directions, the peripheral shifts junk data back to the controller during this operation. The model discards this data.

In the example model:

  • The Write Data subsystem (inside Write EEPROM Data) transmits the write command using paired SPI Transmit and SPI Receive blocks.

  • The Read Dummy Data subsystem (inside Read EEPROM Data) reads and discards the junk data received during the write.

Write Data Subsystem in EEPROM Example

Write Data subsystem showing three inputs — Write Command (opcode 2), Write Address [0 32], and Data — multiplexed through a Mux block into the SPI Transmit block. The SPI Transmit block is configured with Chip select: GPIO1. A Constant block with value 2 connects to the STATVAR data store to advance the operation state.

Read Sequence

To read a memory location, the controller transmits a frame in the format [Opcode, Address, Junk], where the opcode for read is 3. The junk byte provides the clock cycles needed for the peripheral to shift out the stored value.

In the example model, the Read Data subsystem (inside Read EEPROM Data) receives the valid data from the EEPROM. The STATVAR data store controls the sequence of write and read operations and transitions the model through its operation states.

Read Data Subsystem in EEPROM Example

Read Data subsystem showing the SPI Receive block with its Rx output connected to the SPI_Rx output port, which carries the valid EEPROM data. A Constant block with value 0 connects to the STATVAR data store to reset the operation state after the read completes.

Troubleshoot SPI Communication

If SPI communication does not work as expected after deployment, verify the following configurations:

Bit rate mismatch

Verify that the controller bit rate matches the specifications in the peripheral device datasheet. A mismatch causes data corruption or communication failure.

Incorrect SPI mode

Configure the SPI mode (clock polarity and clock phase) to match the mode supported by the peripheral device. Refer to the peripheral datasheet for the required CPOL and CPHA settings.

Mixed block usage with Controller Transfer

When using the SPI Controller Transfer block, do not use SPI Transmit, SPI Receive, or interrupts for the same SPI module. The Controller Transfer block operates in blocking mode and manages the complete transfer sequence internally.

Missing SPI Receive block

When using the SPI Transmit block, always include a corresponding SPI Receive block. The shift register mechanism requires both blocks to complete a transfer.

Unhandled junk data

During write operations, discard the junk data received from the peripheral. During read operations, transmit dummy data to generate the clock cycles needed to receive valid data from the peripheral.

Incomplete transfer before next byte

Verify that each transmit-receive transaction completes before starting the next byte transfer. Overlapping transfers cause data corruption.

Unstable chip select signal

Set the CS pin mode to Explicit GPIO calls to prevent premature CS assertion between bytes during multi-byte transfers.

Incorrect interrupt configuration

Verify that you configured the FIFO level and interrupt event settings correctly for the corresponding SPI module. The FIFO interrupt level must match the expected number of bytes per transaction.

Incorrect command sequence

Follow the read and write sequence specified in the peripheral device datasheet. If the device requires an opcode before data, transmit the opcode first.

After you configure your SPI model, deploy it to your C2000 hardware to verify communication with the peripheral device. If you encounter communication issues, use the troubleshooting checklist in this section to diagnose common configuration errors.

See Also

| |

Topics