# Serial Peripheral Interfaces (SPI)

The RSL15 system includes two Serial Peripheral Interfaces (SPIs). The SPI is a synchronous 4-wire interface that includes clock, chip select, and IO pads. The SPI supports single and dual I/O modes, as well as the ability to add two additional I/O pins in a quad I/O mode. These SPI interfaces allow the system to communicate with external components, including external analog front ends, external controllers, wireless transceivers, and non-volatile memories (NVMs).

NOTE: The SPIs support master/slave configuration as well as half/full duplex mode. Master mode supports single, dual, and quad I/O configurations as well as configurable clock polarity and active phase configurations. Slave mode supports only the single I/O configuration and configuration of the clock’s active phase.

The SPI interfaces are multiplexed onto the GPIO pads, which can be configured for the input and output signals that form each SPI by using the necessary physical pad configuration. For more information about configuring the multiplexed GPIO functionality, see Functional Configuration.

The SPI interfaces can be enabled or disabled using the SPI_CTRL_ENABLE and SPI_CTRL_DISABLE write only bits in the SPI*_CTRL registers. When the SPI_CTRL_DISABLE bit is set to 1, any ongoing transactions on the specified SPI interface are completed and the interface is disabled.

Data transfers using the SPI interfaces can be controlled directly by the host processor, or indirectly by using the DMA. To enable DMA control, use the SPI_CFG_TX_DMA_ENABLE and SPI_CFG_RX_DMA_ENABLE bits in the SPI*_CFG registers. The RX/TX interrupts and RX/TX DMA requests can be generated concurrently.

## SPI Data Transfers

The SPI interfaces can be configured to operate as an SPI master device or an SPI slave device by setting the SPI_CFG_SLAVE bit in the SPI*_CFG register to 0 or 1 respectively. When configured as SPI master, the SPI_CFG_MODE bit field selects the number of data pins used for communication. In slave mode, this field has no effect and the mode is always set to SPI_MODE_SPI (two separate RX and TX data pins). See the definition of SPI*_IO[0:3], below in this topic, for an explanation of the data pins used for communication.

The differences in the SPI pad configurations between master and slave mode are as follows:

SPI*_CLK

In master mode, the SPI*_CLK signal is supplied by the RSL15. The SPI*_CLK signal is derived from SYSCLK using a power of two prescaler (21 to 210), configurable via the SPI_CFG_PRESCALE bit field from the SPI*_CFG register, using the following equation:

In slave mode, the SPI*_CLK signal is sourced from a remote SPI master device. For proper operation, the frequency of the SPI*_CLK inputs must abide by the following relation:

For both master and slave mode, the SPI_CFG_CLK_PHASE bit in the SPI*_CFG registers is used to control the times when data changes and when data is sampled. An SPI using normal phase updates output signals on the falling edge of SPI*_CLK, and samples input signals on the rising edge of SPI*_CLK. If the phase is inverted, output signals change on the rising edge of SPI*_CLK and input signals are sampled on the falling edge. The SPI_CFG_CLK_POLARITY bit in the SPI_CFG register can be used to set the idle state of SPI*_CLK. Setting SPI_CFG_CLK_POLARITY bit to 0 causes SPI*_CLK to idle low, while setting the bit to 1 causes SPI*_CLK to idle high.

NOTE: This is slightly different from, though still compatible with, the typical definition of SPI modes 0-3, in that the SPI phase is defined in terms of rising and falling edges, instead of leading and trailing edges. To convert between standard SPI modes and these registers, use the "SPI Mode to Register Conversion" table

Table: SPI Mode to Register Conversion
SPI_Mode | SPI_CFG_CLK_POLARITY | SPI_CFG_CLK_PHASE
--- | --- | ---
0 | 0 | 0
1 | 0 | 1
2 | 1 | 1
3 | 1 | 0

SPI*_CS

In master mode, the SPI*_CS pad is an output controlled by the SPI_CTRL_CS* bits from the SPI*_CTRL registers. The signal from this pad is generally routed to the chip select input of a slave device. Write to SPI_CTRL_CS_1 to set, or write to SPI_CTRL_CS_0 to clear.

In slave mode, the SPI*_CS pad is an input sourced from a remote SPI master device.

NOTE: For an SPI device, the chip select input is interpreted as an active-low signal. As such, if the signal on the SPI*_CS pad is high, the SPI slave ignores all communications using the interface. The minimum delay required between a falling edge on the SPI*_CS pad and the first edge on SPI*_CLK pad is:

SPI*_IO[0:3]

These pads are used as data pins for the SPI. The SPI_CFG_MODE bit field in the SPI*_CFG register is used to configure the number of data pins used in SPI master mode. The SPI slave operates only in SPI normal mode; therefore, only SPI*_IO0 and SPI*_IO1 pins are available. These pads are used to receive or transmit data when the following conditions are met:

• SPI*_CLK and SPI*_CS indicate that data needs to be transferred.

• The SPI_CTRL_MODE* bits from the SPI*_CTRL register are configured for an SPI read, write, or read-write (full-duplex) transfer.

The SPI waveform timings for controller and peripheral roles, with the four available combinations of CLK_POLARITY and CLK_PHASE, are shown in the following diagrams:

- The "SPI Timing, CLK_POLARITY = 0, CLK_PHASE = 0" figure
- The "SPI Timing, CLK_POLARITY = 0, CLK_PHASE = 1" figure
- The "SPI Timing, CLK_POLARITY = 1, CLK_PHASE = 0" figure
- The "SPI Timing, CLK_POLARITY = 1, CLK_PHASE = 1" figure

Figure: SPI Timing, CLK_POLARITY = 0, CLK_PHASE = 0

Figure: SPI Timing, CLK_POLARITY = 0, CLK_PHASE = 1

Figure: SPI Timing, CLK_POLARITY = 1, CLK_PHASE = 0

Figure: SPI Timing, CLK_POLARITY = 1, CLK_PHASE = 1

The SPI timing for half and full duplex modes is shown in the "SPI Slave Mode Timing" figure.

Figure: SPI Slave Mode Timing

The SPI operation is configured and controlled by the SPI*_CFG and SPI*_CTRL registers. Write or read access to these registers is not restricted when the SPI is active or idle. All updates in these registers are applied immediately, excluding the SPI_CFG_CLK_POLARITY and SPI_CFG_WORD_SIZE fields in the SPI*_CFG register. Updating these registers with the same field values as their original content does not corrupt SPI communication, even if the SPI is active. As a result, you can update only the fields of interest without affecting the functionality associated with the remaining fields. It is recommended that you only update these registers when the SPI is idle.

The SPIs support a configurable word size for each transfer of 1 to 32 bits of data per word, as specified in the SPI_CFG_WORD_SIZE bit field in the SPI*_CFG register. All data transactions using an SPI start with the MSB of the word received. During such transactions, (SPI_CFG_WORD_SIZE + 1) bits of data per word are transferred.

| • | If the SPI is busy, the update to this register is not transferred to the active counter until the countdown reaches zero and the SPI is idle.

| • | In slave mode, the WORD_SIZE might not be updated during the transmission of the last two bits.

| • | In dual mode, the WORD_SIZE is required to be a multiple of 2. If the value written is not a multiple of 2, it is automatically reset to the next multiple of 2.

| • | In quad mode, the WORD_SIZE is required to be a multiple of 4. If the value written is not a multiple of 4, it is automatically set to the next multiple of 4.

Fields in the SPI*_CTRL register are used to select either half duplex or full duplex mode, as follows:

| • | Set the SPI*_CTRL_MODE_NOP field for no read or write operation

| • | Set the SPI*_CTRL_MODE_WRITE field for write-only data operation

| • | Set the SPI*_CTRL_MODE_READ field for read-only data operation

| • | Set the SPI*_CTRL_MODE_READ_WRITE field for read and write data operation (full duplex in normal SPI mode)

NOTE: In DSPI and QSPI modes, this last setting is not valid. The application must set MODE_WRITE and MODE_READ during different phases of the transaction.

In SPI master mode, a read transaction is started when the SPI*_RX_DATA register is read, or when the SPI_CTRL_START bit in the SPI*_CTRL register is set to 1. A write or a read/write operation is started when the TX buffer is full. If it is empty, the transfer starts when data is written to the SPI_TX_DATA register. The SPI interface has parallel buffers for both transmitted and received data.

SPI*_TX_DATA

Shift register containing the data to transmit using the SPI

SPI*_RX_DATA

Shift register containing the recent data word received from the SPI

Two additional registers can be used to read the data received:

SPI*_RX_DATA_NO_START

This register is for reading the received data without starting a new read transaction when in read mode. Read request flag SPI_STATUS_RX_REQ in the SPI*_STATUS register is cleared automatically on reading the SPI*_RX_DATA_NO_START register.

SPI*_RX_DATA_MIRROR

This register is for reading the received data without starting a new read transaction when in read mode and without clearing the read request flag. It is used for debugging without modifying the behavior of the program.

The SPI*_STATUS register can be used by an application to identify the state of the SPI interface. The states are as follows:

| • | The SPI_STATUS_BUSY bit in the SPI*_STATUS register indicates that the reception or transmission of the data is ongoing. This bit is useful for determining when a transaction has completed on the bus. The application can use the SPI_STATUS_TX_REQ and SPI_STATUS_RX_REQ bits in this register to determine when to read and write to or from the interface.

| • | When the SPI_STATUS_TX_REQ bit is set to 1, the SPI is ready to accept new data in the SPI*_TX_DATA register for transmission. The application must wait for this bit to be set before writing to the SPI*_TX_DATA register.

| • | The SPI_STATUS_RX_REQ bit in the SPI*_STATUS register indicates when new data is available to be read. The application must wait for this bit to be set before reading from the SPI*_RX_DATA register to ensure that the data is valid.

| • | The SPI_STATUS_CS_RISE bit in the SPI*_STATUS register indicates that a rising edge has been detected on the SPI*_CS pin. An SPI slave can use this interrupt to determine whether an SPI master is ending a data transfer.

| • | The SPI_STATUS_OVERRUN and SPI_STATUS_UNDERRUN interrupts in the SPI*_STATUS register are used to determine whether a buffer overrun or buffer underrun condition has occurred during SPI communications.

| • | SPI_STATUS_TX_REQ_SET in the SPI*_STATUS register is provided in slave mode when a master ends a transaction by setting CS high (SPI). At this point the SPI*_STATUS_TX_REQ flag in the same register is zero, which indicates that there is still a byte pending in the TX buffer. To clear this state without resetting the interface, SPI_STATUS_TX_REQ_SET can be set high to request new data. However, this does not generate a new interrupt (TX); only the underlying buffer is flushed empty.

NOTE: When the interface is disabled, any ongoing data transmission is allowed to complete before the interface shuts down.

NOTE: In slave mode, the first value to be transmitted in a frame (i.e., after the CS line goes low) needs to be written into the buffer prior to the CS going low. Therefore, after initializing the SPI interface in slave mode, the SPI*_TX_DATA register must be written to before an externally-connected master initiates a read transaction. Otherwise the SPI_STATUS_UNDERRUN bit in the SPI*_STATUS register is set to indicate that an underrun has occurred.

IMPORTANT: When transmitting data as an SPI slave, the SPI interface must load the SPI*_TX_DATA register between SPI*_CLK edges that update the SPI output signals. If no delay occurs between the words of the SPI transfer, new data must be loaded in one SPI*_CLK cycle.

## SPI Interrupts

Each of the SPI interfaces uses three interrupts that can indicate the following four events:

| • | The start of a data transmission (TX interrupt)

| • | The completion of a data transmission (TX interrupt)

| • | The completion of data being received (RX interrupt)

| • | Buffer overrun/underrun/CS rise events (SPI communication interrupt)

See Nested Vector Interrupt Controller (NVIC) for information regarding interrupt configuration and handling interrupts for the Arm Cortex-M33 processor.

If a user application is transmitting data using an SPI interface, the SPI*_TX_START interrupt indicates the following:

| • | That the interface has started transmitting the data value from the SPI*_TX_DATA register

| • | That the application can now load the next data word (of the specified size) to be transmitted

The SPI*_TX_END interrupt can also be used when transmitting data. This interrupt indicates when the transmission is finished, which can be useful when transmitting the last data word at the end of a transmission. This lets the application know when it is safe to reconfigure or disable the SPI interface, or to transition into a low power mode.

If a user application is receiving data from an SPI interface, the SPI*_RX interrupt indicates that a data word of the specified size has been successfully received and written to the SPI*_RX_DATA register.

SPI*_COM interrupts indicate buffer overrun, underrun, and a rising edge transition on the SPI*_CS pin. An overrun occurs when another data word has been loaded into the SPI*_RX_DATA register prior to the SPI*_RX_DATA register being read. An underrun occurs when data is taken from the SPI*_TX_DATA register for transmission before the SPI*_TX_DATA register has been updated with new data to be transmitted. A CS rise is detected when the interface is enabled in slave mode and the CS goes from low to high.

The status of the different interrupts can be monitored in the SPI*_STATUS register. The different status bits can be reset by writing 1 to the corresponding clear bit locations.

NOTE: In slave mode, if CS rises before a word transaction is completed, that transaction is aborted and the data is lost.

## SPI DMA Control

The SPI can operate in DMA mode by enabling the bits SPI_CFG_TX_DMA_ENABLE and/or SPI_CFG_RX_DMA_ENABLE in the SPI*_CFG register. This allows the SPI to communicate with the DMA controller, which responds to requests by writing or reading to or from the data register.

NOTE: The DMA requests are not gated by the SPI*_STATUS_ENABLE bit of the SPI interface. Therefore, for TX_DMA transfers, the SPI causes the data to be transferred from the DMA into the SPI*_TX_DATA register even if the SPI is disabled. However, the data itself is not shifted out on the SPI until the interface is enabled.

Additionally, while using the DMA to control data transfers over an SPI interface, the SPI*_COM interrupts indicate when an error has occurred.

| • | An overrun occurs when the DMA cannot read the received data from the SPI*_RX_DATA register and transfer this data to the DMA buffer before it is overwritten. To monitor for overrun events, set the SPI_CFG_OVERRUN_INT_ENABLE bit in the SPI*_CFG register. If an overrun occurs and this event monitor is enabled, the SPI_STATUS_OVERRUN bit in the appropriate SPI*_STATUS register is set.

| • | An underrun occurs when the DMA cannot write the SPI_TX_DATA register before a second data transfer starts using this register's previous data. To monitor for underrun events, set the SPI_CFG_UNDERRUN_INT_ENABLE bit in the SPI*_CFG register. If an underrun occurs and this event monitor is enabled, the SPI_STATUS_UNDERRUN bit in the appropriate SPI*_STATUS register is set.

For registers, see SPI Registers.