SPI
Overview
Ameba series products support Motorola’s SPI interface, enabling efficient four-wire full-duplex communication.
Features
Supports master or slave operation modes
Independent interrupt masking capability
Hardware/Software chip select supported
Programmable features
Supports dynamic control of serial interface frequency (effective in master mode)
Configurable data frame size (4~16 bits)
Configurable clock polarity and phase
Programmable delay sample time (effective in master mode)
Transmission modes
Transmit and receive
Transmit only
Receive only
Operation modes
Polling mode
Interrupt mode
DMA mode
Serial Clock Frequency
Interface Frequency (fsclk_out) Support:
Master Mode: Supports up to 50 MHz.
Slave Mode: Supports up to 25 MHz.
Attention
The maximum frequency is affected by the pinmux selection. Please refer to Pin Multiplexing Configuration Strategy.
Support for Slave Overclocking Mode:
Prerequisite: The communicating master device must support the delay sample mechanism.
Delay Sample Mechanism: Using the pre-agreed falling edge for data sampling, the figure contrasts standard sampling edge with the delay sample mechanism.
Theoretical Limit: 50 MHz
Host Delay Sample Mechanism
Dividing Mechanism
Core Formula:
fsclk_out = fssi_clk/divWhere fssi_clk is a clock source from PLL.
Constraints:
The divider coefficient div only supports even values.
The actual output frequency is discrete, which means the output fsclk_out may deviate from the expected value.
Attention
The configuration of PLL output during the bootloader phase affects the SPI serial clock frequency. Methods for adjusting PLL output can be found in ameba_bootcfg .
For example, when the SPI target working clock (fssi_clk) is 100 MHz, and the PLL is set to 524 MHz, the SPI actual working clock is only 86.67 MHz. At this rate, the maximum resultant fsclk_out is just 43.3 MHz, not reaching the desired maximum of 50 MHz.
Pin Multiplexing Configuration Strategy
The interface frequency and pin configuration are listed below:
Configuration Mode |
Master Frequency |
Slave Frequency |
|---|---|---|
Dedicated Pins |
50 MHz |
25 MHz |
Full Matrix Pins |
25 MHz |
12.5 MHz |
Note
For the difference between dedicated pins and full matrix pins, please refer to the Function Multiplexing section.
Operating Modes
SPI Configurable Operating Modes
Polling Mode
This is the most basic operating mode. The CPU polls the SPI status registers and reads or writes the FIFO buffer as needed to send and receive data.
Suited for small-scale data transfers with low real-time requirements.
Interrupt Mode
When configured trigger conditions are met, the SPI hardware sends an interrupt signal to notify the CPU to handle the relevant tasks.
This method reduces the need for frequent polling, lowering CPU usage and improving response speed.
Interrupt Response Delay Leading to Data Transmission Errors
If the CPU cannot respond to interrupts promptly due to OS critical section and other reasons, it may lead to FIFO Overflow/Underflow issues:
Transmission Response Delay
Problems caused by failing to fill the TX FIFO in time, under different SPI roles, are as follows:
Master Device:
An empty FIFO causes the CS pin to be pulled high, interrupting data transmission.
Slave Device:
An empty FIFO triggers an underflow event, rendering the data on the MISO line invalid.
The master device is unaware of this and continues sampling MISO, possibly receiving incorrect data.
Reception Response Delay
Failing to read the RX FIFO in time results in FIFO Overflow:
Impact: Hardware pauses receiving new data.
Outcome: Software data reception is incomplete.
DMA Mode
Through an SPI and DMA handshake mechanism, the DMA controller handles data transfers, reducing the CPU’s processing load.
Suitable for applications that require handling large amounts of data, such as audio/video stream processing and large data transfers.
Note
For considerations when using DMA mode for transfers, please refer to the DMA and Cache section.
Application Examples
The SDK provides two types of functional examples to help developers understand and use SPI functionality:
Mbed Examples
Path:
{SDK}\example\peripheral\mbed\SPI\{demo}Demonstrates how to implement SPI control in the mbed environment.
Raw Examples
Path:
{SDK}\example\peripheral\raw\SPI\{demo}Illustrates how to directly control SPI without abstraction layers.
Below is a brief description of the features of the raw examples:
-
demonstrates how to use SPI in
pollingmode to transmit and receive data. -
demonstrates how to use SPI in
interruptmode to transmit and receive data. -
demonstrates how to use SPI in
DMAmode to transmit and receive data. -
demonstrates using SPI in
slave mode to receivedata. -
demonstrates using SPI in
master mode to senddata. -
demonstrates how to
select slave devicesusingsoftware control.
Note
To see which chips are supported by the examples, refer to the README.md file in the example’s path.
Raw API
SPI Exported Types
-
struct SPI_DevTable
SPI Dev table Structure Definition.
Public Members
-
SPI_TypeDef *SPIx
SPI peripheral base address
-
u32 Tx_HandshakeInterface
GDMA TX handshake interface number
-
u32 Rx_HandshakeInterface
GDMA RX handshake interface number
-
IRQn_Type IrqNum
SPI interrupt request number
-
SPI_TypeDef *SPIx
-
struct SSI_InitTypeDef
SPI Init Structure Definition.
Public Members
-
u32 SPI_DmaRxDataLevel
Specifies the DMA receive data level. The dma_rx_req is generated when the number of valid data entries in the receive FIFO is equal to or above this field value+1,and RDMAE=1. For Amebaz, the value range of this parameter should be 0 to 63,because the depth of Rx FIFO is 64.
-
u32 SPI_DmaTxDataLevel
Specifies the DMA transmit data level. The dma_tx_req is generated when the number of valid data entries in the transmit FIFO is equal to or below this field value,and TDMAE=1. For Amebaz, the value range of this parameter should be 0 to 63,because the depth of Rx FIFO is 64.
-
u32 SPI_RxThresholdLevel
Specifies the receive FIFO threshold level. This Parameter controls the level of entries(or above) at which the receive FIFO controller triggers an interrupt.When the number of receive FIFO entries is greater than or equal to this value +1,the receive FIFO full interrupt is triggered. For Amebaz, the value range of this parameter should be 0 to 63,because the depth of Rx FIFO is 64.
-
u32 SPI_TxThresholdLevel
Specifies the transmit FIFO threshold level. This Parameter controls the level of entries (or below) at which the transmit FIFO controller triggers an interrupt.When the number of transmit FIFO entries is less than or equal to this value,the transmit FIFO empty interrupt is triggered. For Amebaz, the value range of this parameter should be 0 to 63,because of the depth of Rx FIFO is 64.
-
u32 SPI_SlaveSelectEnable
Set the slave select enable flag. This Parameter controls which slave to be selected by master,each bit in SER register corresponds to a slave select line(ss_x_n) from spi master. The default value of this parameter is 0,and one slave is selected.if more slaves to be selected, you may use SW way to do this.And this parameter is used only when the device is master.
-
u32 SPI_ClockDivider
Specifies the SPI Baud Rate. The value of sclk_out equals to ssi_clk devides the value of this parameter The LSB for this field is always set to 0 and is unaffected by a write operation,which ensures an even value is held.
-
u32 SPI_DataFrameNumber
Specifies the number of data frames master wants to receive . When TMOD=10 or TMOD=11,Ctrl1 register uses this value to set the number of data frames to be continuous received. The value of this parameter should be set to the number of data frames that to be received minus one.And this parameter is used only when the device is master.
-
u32 SPI_DataFrameFormat
Selects which serial protocol transfers the data . This parameter can be a value of SPI Frame Format.
-
u32 SPI_DataFrameSize
Selects the data frame length . This parameter can be a value of SPI Data Frame Size. Need to right-justify transmit data before writing into the transmit FIFO The transmit logic ignores the upper unused bits when transmitting the data.
-
u32 SPI_InterruptMask
Specifies which interrupt to be enable. Each bit in this parameter corresponds to a specific interrupt.
-
u32 SPI_SclkPhase
Specifies the serial clock phase. When SPI_SclkPhase = 0, data are captured on the first edge of the serial clock. When SPI_SclkPhase = 1, the serial clock starts toggling one cycle after the slave select line is activated, and data are captured on the second edge of the serial clock. This parameter can be a value of SPI Clock Phase. Valid when the frame format(FRF) is set to Motorola SPI.
-
u32 SPI_SclkPolarity
Specifies the serial clock polarity. When SPI_SclkPolarity = 0, the serial clock remains low when idle. When SPI_SclkPolarity = 1, the serial clock remains high when idle. This parameter can be a value of SPI Clock Polarity. Valid when the frame format(FRF) is set to Motorola SPI.
-
u32 SPI_TransferMode
Selects the mode of transfer for serial communication. This parameter can be a value of SPI Transfer Mode. This transfer mode is only valid when the DW_apb_ssi is configured as a master device.
-
u32 SPI_DmaRxDataLevel
SPI Exported Constants
SPI DMA Control
/* DMA disabled for SPI. */
#define SSI_NODMA (0)
/* RX DMA channel enabled. */
#define SSI_RXDMA_ENABLE (1)
/* TX DMA channel enabled. */
#define SSI_TXDMA_ENABLE (2)
/* Both TX and RX DMA enabled. */
#define SSI_TRDMA_ENABLE (3)
SPI Data Frame Size
/* 4-bit data frame size. */
#define DFS_4_BITS (3)
/* 5-bit data frame size. */
#define DFS_5_BITS (4)
/* 6-bit data frame size. */
#define DFS_6_BITS (5)
/* 7-bit data frame size. */
#define DFS_7_BITS (6)
/* 8-bit data frame size. */
#define DFS_8_BITS (7)
/* 9-bit data frame size. */
#define DFS_9_BITS (8)
/* 10-bit data frame size. */
#define DFS_10_BITS (9)
/* 11-bit data frame size. */
#define DFS_11_BITS (10)
/* 12-bit data frame size. */
#define DFS_12_BITS (11)
/* 13-bit data frame size. */
#define DFS_13_BITS (12)
/* 14-bit data frame size. */
#define DFS_14_BITS (13)
/* 15-bit data frame size. */
#define DFS_15_BITS (14)
/* 16-bit data frame size. */
#define DFS_16_BITS (15)
SPI FIFO Depth
/* SPI transmit FIFO depth in entries. */
#define SSI_TX_FIFO_DEPTH (64)
/* SPI receive FIFO depth in entries. */
#define SSI_RX_FIFO_DEPTH (64)
SPI Frame Format
/* Motorola SPI frame format. */
#define FRF_MOTOROLA_SPI (0)
SPI Role
/* SPI operates as slave device. */
#define SSI_SLAVE (0)
/* SPI operates as master device. */
#define SSI_MASTER (1)
SPI Clock Phase
/* Clock toggles in middle of first data bit. */
#define SCPH_TOGGLES_IN_MIDDLE (0)
/* Clock toggles at start of first data bit. */
#define SCPH_TOGGLES_AT_START (1)
SPI Clock Polarity
/* Inactive serial clock polarity is low. */
#define SCPOL_INACTIVE_IS_LOW (0)
/* Inactive serial clock polarity is high. */
#define SCPOL_INACTIVE_IS_HIGH (1)
SPI Slave Select Toggle Phase
/* Slave select does not toggle between frames. */
#define SPI_SS_NOT_TOGGLE (0)
/* Slave select toggles between successive frames. */
#define SPI_SS_TOGGLE (1)
SPI Transfer Mode
/* Transmit and receive mode. */
#define TMOD_TR (0)
/* Transmit only mode. */
#define TMOD_TO (1)
/* Receive only mode. */
#define TMOD_RO (2)
SPI Exported Functions
-
u32 SPI_GetINTConfig(SPI_TypeDef *spi_dev)
Get SPIx interrupt mask configuration.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
The current interrupt mask register value, which can be a combination of:
SPI_BIT_TXEIM
SPI_BIT_TXOIM
SPI_BIT_RXUIM
SPI_BIT_RXOIM
SPI_BIT_RXFIM
SPI_BIT_MSTIM_FAEIM
SPI_BIT_TXUIM
SPI_BIT_SSRIM
Note
When a bit is 1, the corresponding interrupt is enabled; otherwise, it is disabled.
-
u32 SSI_Busy(SPI_TypeDef *spi_dev)
Check if SPIx is busy.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
SPIx busy status value:
1: Busy
0: Not Busy
-
void SSI_Cmd(SPI_TypeDef *spi_dev, u32 NewStatus)
Enable or disable SPIx peripheral.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
NewStatus –
This parameter can be one of the following values:
ENABLE
DISABLE
-
u32 SSI_GetDataFrameNumber(SPI_TypeDef *spi_dev)
Get SPIx data frame number.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Data frame number
-
u32 SSI_GetDataFrameSize(SPI_TypeDef *spi_dev)
Get SPIx data frame size.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Data frame size in bits (value range: 4-16).
-
u32 SSI_GetIsr(SPI_TypeDef *spi_dev)
Get SPIx Interrupt Status.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Current interrupt status, each bit of this value represents one interrupt status:
bit 7 : SSRIS SS_N Rising Edge Detect Interrupt Status. (valid when device is slave)
0 : ssi_ssr_intr interrupt not active after masking
1 : ssi_ssr_intr interrupt is active after masking
bit 6 : TXUIS Transmit FIFO Under Flow Interrupt Status. (valid when device is slave)
0 : ssi_txu_intr interrupt is not active after masking
1 : ssi_txu_intr interrupt is active after masking
bit 5 : FAEIS Frame Alignment Interrupt Status. (valid when device is slave)
0 : ssi_fae_intr interrupt not active after masking
1 : ssi_fae_intr interrupt is active after masking
bit 5 : MSTIS Multi-Master Contention Interrupt Status. (valid when device is master)
0 : ssi_mst_intr interrupt not active after masking
1 : ssi_mst_intr interrupt is active after masking
bit 4 : RXFIS Receive FIFO Full Interrupt Status.
0 : ssi_rxf_intr interrupt is not active after masking
1 : ssi_rxf_intr interrupt is full after masking
bit 3 : RXOIS Receive FIFO Overflow Interrupt Status.
0 : ssi_rxo_intr interrupt is not active after masking
1 : ssi_rxo_intr interrupt is active after masking
bit 2 : RXUIS Receive FIFO Underflow Interrupt Status.
0 : ssi_rxu_intr interrupt is not active after masking
1 : ssi_rxu_intr interrupt is active after masking
bit 1 : TXOIS Transmit FIFO Overflow Interrupt Status.
0 : ssi_txo_intr interrupt is not active after masking
1 : ssi_txo_intr interrupt is active after masking
bit 0 : TXEIS Transmit FIFO Empty Interrupt Status.
0 : ssi_txe_intr interrupt is not active after masking
1 : ssi_txe_intr interrupt is active after masking
-
u32 SSI_GetRawIsr(SPI_TypeDef *spi_dev)
Get SPIx Raw Interrupt Status.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Current raw interrupt status, each bit of this value represents one raw interrupt status:
bit 7 : SSRIR SS_N Rising Edge Detect Interrupt Status. (valid when device is slave)
0 : ssi_ssr_intr interrupt not active after masking
1 : ssi_ssr_intr interrupt is active after masking
bit 6 : TXUIR Transmit FIFO Under Flow Interrupt Status. (valid when device is slave)
0 : ssi_txu_intr interrupt is not active after masking
1 : ssi_txu_intr interrupt is active after masking
bit 5 : FAEIR Frame Alignment Interrupt Status. (valid when device is slave)
0 : ssi_fae_intr interrupt not active after masking
1 : ssi_fae_intr interrupt is active after masking
bit 5 : MSTIR Multi-Master Contention Raw Interrupt Status.(valid when device is master)
0 : ssi_mst_intr interrupt not active prior to masking
1 : ssi_mst_intr interrupt is active prior to masking
bit 4 : RXFIR Receive FIFO Full Raw Interrupt Status.
0 : ssi_rxf_intr interrupt is not active prior to masking
1 : ssi_rxf_intr interrupt is full prior to masking
bit 3 : RXOIR Receive FIFO Overflow Raw Interrupt Status.
0 : ssi_rxo_intr interrupt is not active prior to masking
1 : ssi_rxo_intr interrupt is active prior to masking
bit 2 : RXUIR Receive FIFO Underflow Raw Interrupt Status.
0 : ssi_rxu_intr interrupt is not active prior to masking
1 : ssi_rxu_intr interrupt is active prior to masking
bit 1 : TXOIR Transmit FIFO Overflow Raw Interrupt Status.
0 : ssi_txo_intr interrupt is not active prior to masking
1 : ssi_txo_intr interrupt is active prior to masking
bit 0 : TXEIR Transmit FIFO Empty Raw Interrupt Status.
0 : ssi_txe_intr interrupt is not active prior to masking
1 : ssi_txe_intr interrupt is active prior to masking
-
u32 SSI_GetRxCount(SPI_TypeDef *spi_dev)
Get SPIx the number of valid entries in receive FIFO.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
The number of valid entries in receive FIFO.Value range:0-64.
-
u32 SSI_GetSlaveEnable(SPI_TypeDef *spi_dev)
Get which slave is selected.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Each bit of this value which is set to 1 corresponds to the slave being selected.
Note
Valid only when the device is configured as a master.
-
u32 SSI_GetStatus(SPI_TypeDef *spi_dev)
Get SPIx transfer status.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Current transfer status, each bit of this value represents one transfer status:
bit 5 : TXE Transmission Error.(valid when device is slave)
0 : No Error
1 : Transmission error
bit 4 : RFF Receive FIFO Full.
0 : Receive FIFO is not full
1 : Receive FIFO is full
bit 3 : RFNE Receive FIFO Not Empty.
0 : Receive FIFO is empty
1 : Receive FIFO is not empty
bit 2 : TFE Transmit FIFO Empty.
0 : Transmit FIFO is not empty
1 : Transmit FIFO is empty
bit 1 : TFNF Transmit FIFO Not Full.
0 : Transmit FIFO is full
1 : Transmit FIFO is not full
bit 0 : BUSY SSI Busy Flag.
0 : idle or disable
1 : active transferring data
-
u32 SSI_GetTxCount(SPI_TypeDef *spi_dev)
Get SPIx the number of valid entries in transmit FIFO.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
The number of valid entries in transmit FIFO.Value range:0-64.
-
void SSI_INTConfig(SPI_TypeDef *spi_dev, u32 SSI_IT, u32 newState)
Mask or unmask SPIx interrupt.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
SSI_IT –
This parameter can be one of the following values or mixed:
SPI_BIT_TXEIM
SPI_BIT_TXOIM
SPI_BIT_RXUIM
SPI_BIT_RXOIM
SPI_BIT_RXFIM
SPI_BIT_MSTIM_FAEIM
SPI_BIT_TXUIM
SPI_BIT_SSRIM
newState –
This parameter can be one of the following values:
ENABLE
DISABLE
Note
BIT_IMR_TXUIM, BIT_IMR_SSRIM are for Slave only.
-
void SSI_Init(SPI_TypeDef *spi_dev, SSI_InitTypeDef *SSI_InitStruct)
Initialize the SPI registers according to the specified parameters in SSI_InitStruct.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
SSI_InitStruct – Pointer to a SSI_InitTypeDef structure that contains the configuration information for the SPI peripheral.
-
bool SSI_RXGDMA_Init(u8 Index, GDMA_InitTypeDef *GDMA_InitStruct, void *CallbackData, IRQ_FUN CallbackFunc, u8 *pRxData, u32 Length)
Init and Enable SPI RX GDMA.
- Parameters:
Index – 0 or 1.
GDMA_InitStruct – Pointer to a GDMA_InitTypeDef structure that contains the configuration information for the GDMA peripheral.
CallbackData – GDMA callback data.
CallbackFunc – GDMA callback function.
pRxData – Rx Buffer.
Length – Rx Count.
- Returns:
The result of RX GDMA initialization:
TRUE: RX GDMA initialization successful
FALSE: RX GDMA initialization failed
-
u32 SSI_ReadData(SPI_TypeDef *spi_dev)
Read data from SPIx receive FIFO .
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Data received from SPI receive FIFO.
-
u32 SSI_Readable(SPI_TypeDef *spi_dev)
Determine SPIx Receive FIFO is empty or not.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Receive FIFO is empty or not:
1: Not Empty
0: Empty
-
u32 SSI_ReceiveData(SPI_TypeDef *spi_dev, void *RxData, u32 Length)
Receive data from rx FIFO.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
RxData – Buffer to save data read from SPI FIFO.
Length – Number of data to be read.
- Returns:
Transfer len
-
u32 SSI_SendData(SPI_TypeDef *spi_dev, void *TxData, u32 Length, u32 Role)
Send data to tx FIFO.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
TxData – Buffer to be written to Tx FIFO.
Length – Number of data to be written.
Role – SSI_MASTER or SSI_SLAVE.
- Returns:
Transfer len
-
void SSI_SetBaudDiv(SPI_TypeDef *spi_dev, u32 ClockDivider)
Set SPIx clock divider.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
ClockDivider – Even value between 2 and 65534. And Fsclk_out=Fssi_clk/ClockDivider.
Note
Valid only when the device is configured as a master. And The LSB is always set to 0,and is unaffected by a write operation.
-
void SSI_SetDataFrameSize(SPI_TypeDef *spi_dev, u32 DataFrameSize)
Set SPIx data frame size.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
DataFrameSize –
This parameter can be one of the following values:
DFS_4_BITS
DFS_5_BITS
DFS_6_BITS
DFS_7_BITS
DFS_8_BITS
DFS_9_BITS
DFS_10_BITS
DFS_11_BITS
DFS_12_BITS
DFS_13_BITS
DFS_14_BITS
DFS_15_BITS
DFS_16_BITS
-
void SSI_SetDataSwap(SPI_TypeDef *spi_dev, u32 SwapStatus, u32 newState)
Set or reset SPIx data swap bit.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
SwapStatus –
This parameter can be one of the following values or mixed:
SPI_BIT_TXBYTESWAP
SPI_BIT_TXBITSWAP
SPI_BIT_RXBYTESWAP
SPI_BIT_RXBITSWAP
newState –
This parameter can be one of the following values:
ENABLE
DISABLE
-
void SSI_SetDmaEnable(SPI_TypeDef *spi_dev, u32 newState, u32 Mask)
Enable or disable SPIx TDMA and RDMA .
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
newState –
This parameter can be one of the following values:
ENABLE
DISABLE
Mask –
This parameter can be one of the following values or mixed:
SPI_BIT_TDMAE
SPI_BIT_RDMAE
-
void SSI_SetDmaLevel(SPI_TypeDef *spi_dev, u32 TxLevel, u32 RxLevel)
Set SPIx DMA TxLevel and RxLevel.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
TxLevel – Transmit FIFO Threshold level.Value range: 0 to 63. The dma_tx_req is generated when the number of valid data entries in the transmit FIFO is equal to or below this field value.
RxLevel – Receive FIFO Threshold level.Value range: 0 to 63. The dma_rx_req is generated when the number of valid data entries in the receive FIFO is equal to or above this field value + 1.
-
void SSI_SetIsrClean(SPI_TypeDef *spi_dev, u32 InterruptStatus)
Clear SPIx interrupt status.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
InterruptStatus – The value of current interrupt status .
-
void SSI_SetReadLen(SPI_TypeDef *spi_dev, u32 DataFrameNumber)
Set SPIx the number of data frame to be received.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
DataFrameNumber – The number of data frames that to be received.
Note
Valid only when the device is configured as a master in TMOD_RO mode
-
void SSI_SetRole(SPI_TypeDef *spi_dev, u32 role)
Set SPIx as Master or Slave.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
role –
This parameter can be one of the following values:
SSI_MASTER
SSI_SLAVE
-
void SSI_SetRxFifoLevel(SPI_TypeDef *spi_dev, u32 RxThresholdLevel)
Set SPIx Rx FIFO threshold level.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
RxThresholdLevel – Rx FIFO Threshold Level.Value range: 0 to 63. When the number of receive FIFO entries is greater than or equal to this value + 1, the receive FIFO full interrupt is triggered.
-
void SSI_SetSSTogglePhase(SPI_TypeDef *spi_dev, u32 TogglePhase)
Set SPI SS Toggle Phase.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
TogglePhase –
This parameter can be one of the following values:
SPI_SS_NOT_TOGGLE , means SPI support continuous transfer when spi_cph=0
SPI_SS_TOGGLE, means SPI does not support continuous transfer when spi_cph=0 and SS(CS) needs break.
Note
SS Toggle function is valid only for master.
-
void SSI_SetSampleDelay(SPI_TypeDef *spi_dev, u32 SampleDelay)
Set SPIx Rx Sample Delay. support from AZ BCUT.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
SampleDelay – The number of ssi_clk cycles that to be delayed.
Note
The max clk delay cycle is 4.
-
void SSI_SetSclkPhase(SPI_TypeDef *spi_dev, u32 SclkPhase)
Set SPIx clock phase.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
SclkPhase –
This parameter can be one of the following values:
SCPH_TOGGLES_AT_START
SCPH_TOGGLES_IN_MIDDLE
-
void SSI_SetSclkPolarity(SPI_TypeDef *spi_dev, u32 SclkPolarity)
Set SPIx clock polarity.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
SclkPolarity –
This parameter can be one of the following values:
SCPOL_INACTIVE_IS_HIGH
SCPOL_INACTIVE_IS_LOW
-
void SSI_SetSlaveEnable(SPI_TypeDef *spi_dev, u32 SlaveIndex)
Enable slave select.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
SlaveIndex – The index of slave to be selected.
Note
Valid only when the device is configured as a master.
-
void SSI_SetTxFifoLevel(SPI_TypeDef *spi_dev, u32 TxThresholdLevel)
Set SPIx Tx FIFO threshold level.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
TxThresholdLevel – Tx FIFO Threshold Level.Value range: 0 to 63. When the number of transmit FIFO entries is less than or equal to this value, the transmit FIFO empty interrupt is triggered.
-
u32 SSI_SlaveErrRecovery(SPI_TypeDef *spi_dev)
Perform FAE (Frame Alignment Error) recovery for SPI.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Recovery result:
TRUE: FAE error was detected and recovery performed.
FALSE: No FAE error detected.
Note
When a FAE error is detected, SSI_EN is reset to recover the peripheral.
-
void SSI_SlaveOutputEnable(SPI_TypeDef *spi_dev, u32 Status)
Set slave output enable.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
Status – Where Status can be ENABLE or DISABLE.
Note
Valid only when the device is configured as a slave.
-
void SSI_StructInit(SSI_InitTypeDef *SSI_InitStruct)
Fill each SSI_InitStruct member with its default value.
- Parameters:
SSI_InitStruct – Pointer to a SSI_InitTypeDef structure which will be initialized.
-
bool SSI_TXGDMA_Init(u32 Index, PGDMA_InitTypeDef GDMA_InitStruct, void *CallbackData, IRQ_FUN CallbackFunc, u8 *pTxData, u32 Length)
Init and Enable SPI TX GDMA.
- Parameters:
Index – 0 or 1.
GDMA_InitStruct – Pointer to a GDMA_InitTypeDef structure that contains the configuration information for the GDMA peripheral.
CallbackData – GDMA callback data.
CallbackFunc – GDMA callback function.
pTxData – Tx Buffer.
Length – Tx Count.
- Returns:
The result of TX GDMA initialization:
TRUE: TX GDMA initialization successful
FALSE: TX GDMA initialization failed
-
void SSI_WriteData(SPI_TypeDef *spi_dev, u32 value)
Write data to SPIx transmit FIFO.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
value – The data value that is to be transmitted .
-
u32 SSI_Writeable(SPI_TypeDef *spi_dev)
Determine whether SPIx transmit FIFO is full or not.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
- Returns:
Transmit FIFO is full or not:
1: Not Full
0: Full
Not supported.
Not supported.
Not supported.
Not supported.
Not supported.
Not supported.
-
void SSI_SetCSForce(SPI_TypeDef *spi_dev, u32 newState)
Set or reset SPIx CSF_EN bit. When set, it enables SPI to force CS signal keep low until the amount of data bits (DFS * NDF) had been sent/received. SPI master will force the CS signal low even when the TX FIFO is empty during transmission.
- Parameters:
spi_dev – Where spi_dev can be SPI0_DEV or SPI1_DEV.
newState –
This parameter can be one of the following values:
ENABLE
DISABLE
Note
Only valid for master If enabled, the NDF in register CTRL1 must be set.
FUNCTION_REF=SSI_SetCSForce
FUNCTION_REF=SSI_SetDataFrameNumber
Mbed API
MBED_SPI Exported Types
Enumeration Type
-
enum ChipSelect
SPI chip select index.
Values:
/* Chip select 0. */ CS_0 = 0 /* Chip select 1. */ CS_1 = 1 /* Chip select 2. */ CS_2 = 2 /* Chip select 3. */ CS_3 = 3 /* Chip select 4. */ CS_4 = 4 /* Chip select 5. */ CS_5 = 5 /* Chip select 6. */ CS_6 = 6 /* Chip select 7. */ CS_7 = 7
-
enum MBED_SPI_IDX
SPI device index enumeration.
Values:
/* SPI0 peripheral index. */ MBED_SPI0 = 0xF0 /* SPI1 peripheral index. */ MBED_SPI1 = 0xF1
-
enum SPI_SCLK_IDLE_LEVEL
SPI serial clock idle level.
Values:
/* SCLK is low when SPI is inactive. */ SPI_SCLK_IDLE_LOW = 0 /* SCLK is high when SPI is inactive. */ SPI_SCLK_IDLE_HIGH = 2
-
enum SPI_SCLK_TOGGLE_MODE
SPI serial clock toggle mode.
Values:
/* SCLK toggles at middle of first data bit. */ SPI_SCLK_TOGGLE_MIDDLE = 0 /* SCLK toggles at start of first data bit. */ SPI_SCLK_TOGGLE_START = 1
-
enum SpiIrq
SPI interrupt event type.
Values:
/* SPI receive interrupt. */ SpiRxIrq /* SPI transmit interrupt. */ SpiTxIrq
Structure Type
-
typedef void (*spi_irq_handler)(uint32_t id, SpiIrq event)
Typedef function pointer to point SPI interrupt handler.
-
typedef struct spi_s spi_t
SPI object type, defined as struct spi_s.
MBED_SPI Exported Constants
/* Enable SPI DMA RX channel. */
#define SPI_DMA_RX_EN (1<<0)
/* Enable SPI DMA TX channel. */
#define SPI_DMA_TX_EN (1<<1)
/* SPI state: idle and ready. */
#define SPI_STATE_READY 0x00
/* SPI state: receive operation in progress. */
#define SPI_STATE_RX_BUSY (1<<1)
/* SPI state: transmit operation in progress. */
#define SPI_STATE_TX_BUSY (1<<2)
MBED_SPI Exported Functions
-
void spi_bus_tx_done_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id)
Register SPI bus Tx done interrupt handler if needed.
- Parameters:
obj – SPI object defined in application software.
handler – Interrupt bus Tx done callback function.
id – Interrupt bus Tx done callback parameter.
-
int spi_busy(spi_t *obj)
Get SPI busy state.
- Parameters:
obj – SPI object defined in application software.
- Returns:
Current busy state.
-
void spi_disable(spi_t *obj)
Disable SPI device clock.
- Parameters:
obj – SPI object defined in application software.
-
void spi_enable(spi_t *obj)
Enable SPI device clock.
- Parameters:
obj – SPI object defined in application software.
-
void spi_flush_rx_fifo(spi_t *obj)
SPI device to flush Rx FIFO.
- Parameters:
obj – SPI object defined in application software.
-
void spi_format(spi_t *obj, int bits, int mode, int slave)
Set SPI format, including DFS, Phase, Polarity and Role.
- Parameters:
obj – SPI object defined in application software.
bits – Data frame size, which can be 4~16.
mode –
This parameter can be one of the following values:
0: [Polarity,Phase]=[0,0].
1: [Polarity,Phase]=[0,1].
2: [Polarity,Phase]=[1,0].
3: [Polarity,Phase]=[1,1].
slave –
This parameter can be one of the following values:
0: Configure SPI as the master.
1: Configure SPI as the slave.
-
void spi_free(spi_t *obj)
Deinitialize the SPI device, including interrupt, DMA, and SPI peripheral.
- Parameters:
obj – SPI object defined in application software.
-
void spi_frequency(spi_t *obj, int hz)
Set SPI baudrate.
- Parameters:
obj – SPI master object defined in application software.
hz – Baudrate for SPI bus in units of Hz.
Attention
Baudrate to be set should be less than or equal to half of the SPI IpClk.
-
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
Initialize the SPI device, including clock, function, interrupt and SPI registers.
- Parameters:
obj – SPI object defined in application software.
mosi – MOSI PinName according to pinmux spec.
miso – MISO PinName according to pinmux spec.
sclk – SCLK PinName according to pinmux spec.
ssel – CS PinName according to pinmux spec.
Attention
Remember to set obj->spi_index to MBED_SPI0 or MBED_SPI1 before calling spi_init.
-
void spi_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id)
Register SPI interrupt handler if needed.
- Parameters:
obj – SPI object defined in application software.
handler – SPI Interrupt callback function.
id – SPI Interrupt callback parameter.
-
int32_t spi_master_read_stream(spi_t *obj, char *rx_buffer, uint32_t length)
Master SPI receives data of target length under interrupt mode.
- Parameters:
obj – SPI master object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
int32_t spi_master_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length)
Master SPI receives data of target length under DMA mode.
- Parameters:
obj – SPI master object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
Note
DMA or Interrupt mode can be used to TX dummy data
-
int spi_master_write(spi_t *obj, int value)
Master SPI sends one frame.
- Parameters:
obj – SPI master object defined in application software.
value – Data to be transmitted.
- Returns:
Data received from slave SPI.
-
int32_t spi_master_write_read_stream(spi_t *obj, char *tx_buffer, char *rx_buffer, uint32_t length)
Master SPI sends and receives data of target length under interrupt mode.
- Parameters:
obj – SPI master object defined in application software.
tx_buffer – Buffer to be written to Tx FIFO.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be sent and receive.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
int32_t spi_master_write_read_stream_dma(spi_t *obj, char *tx_buffer, char *rx_buffer, uint32_t length)
Master SPI sends and receives data of target length under DMA mode.
- Parameters:
obj – SPI master object defined in application software.
tx_buffer – Buffer to be written to Tx FIFO.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be sent and received.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
int32_t spi_master_write_stream(spi_t *obj, char *tx_buffer, uint32_t length)
Master SPI sends data of target length under interrupt mode.
- Parameters:
obj – SPI master object defined in application software.
tx_buffer – Buffer to be written to Tx FIFO.
length – Number of data bytes to be sent.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
int32_t spi_master_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length)
Master SPI sends data of target length under DMA mode.
- Parameters:
obj – SPI master object defined in application software.
tx_buffer – Buffer to be written to Tx FIFO.
length – Number of data bytes to be sent.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
void spi_slave_flush_fifo(spi_t *obj)
Discard all data in SPI slave Tx and Rx FIFOs.
- Parameters:
obj – SPI slave object defined in application software.
-
int spi_slave_read(spi_t *obj)
Slave SPI receives one frame.
- Parameters:
obj – SPI slave object defined in application software.
- Returns:
Data received from master SPI.
-
int32_t spi_slave_read_stream(spi_t *obj, char *rx_buffer, uint32_t length)
Slave SPI receives data of target length under interrupt mode.
- Parameters:
obj – SPI slave object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
int32_t spi_slave_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length)
Slave SPI receives data of target length under DMA mode.
- Parameters:
obj – SPI slave object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
int32_t spi_slave_read_stream_dma_terminate(spi_t *obj, char *rx_buffer, uint32_t length)
Slave SPI receives data of target length under DMA mode and stops if SPI bus is idle.
- Parameters:
obj – SPI slave object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
- Returns:
Number of already read bytes.
-
int32_t spi_slave_read_stream_dma_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms)
Slave SPI receives data of target length under DMA mode before timeout.
- Parameters:
obj – SPI slave object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
timeout_ms – Timeout waiting time in units of ms.
- Returns:
Number of already read bytes.
-
int32_t spi_slave_read_stream_terminate(spi_t *obj, char *rx_buffer, uint32_t length)
Slave SPI receives data of target length under interrupt mode and stops if SPI bus is idle.
- Parameters:
obj – SPI slave object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
- Returns:
Number of data bytes already read if success or -HAL_BUSY if error happens.
-
int32_t spi_slave_read_stream_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms)
Slave SPI receives data of target length under interrupt mode monitored before timeout.
- Parameters:
obj – SPI slave object defined in application software.
rx_buffer – Buffer to save data read from SPI FIFO.
length – Number of data bytes to be read.
timeout_ms – Timeout waiting time in units of ms.
- Returns:
Number of already read bytes.
-
int spi_slave_receive(spi_t *obj)
Check if slave SPI is readable and not busy.
- Parameters:
obj – SPI slave object defined in application software.
- Returns:
Receive-ready state of slave SPI:
1: Readable and not busy
0: Not ready
-
void spi_slave_write(spi_t *obj, int value)
Slave SPI sends one frame.
- Parameters:
obj – SPI slave object defined in application software.
value – Data to be transmitted.
-
int32_t spi_slave_write_stream(spi_t *obj, char *tx_buffer, uint32_t length)
Slave SPI sends data of target length under interrupt mode.
- Parameters:
obj – SPI slave object defined in application software.
tx_buffer – Buffer to be written to Tx FIFO.
length – Number of data bytes to be sent.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
-
int32_t spi_slave_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length)
Slave SPI sends data of target length under DMA mode.
- Parameters:
obj – SPI slave object defined in application software.
tx_buffer – Buffer to be written to Tx FIFO.
length – Number of data bytes to be send.
- Returns:
Operation status:
HAL_OK: Success.
HAL_BUSY: Error.
Troubleshooting
CS Signal Premature High
Phenomenon: The CS (Chip Select) signal goes high prematurely before data transmission is complete, causing transmission interruption and incomplete data sending.
Possible Causes: FIFO buffer not filled in time or data flow control issues leading to data dropouts.
Solutions:
Check FIFO Threshold Configuration: Ensure it matches the data flow requirements.
Optimize Interrupt Priority: Increase interrupt priority to reduce data fill latency.
Use DMA Transfer Mode: This reduces the CPU load and enhances transfer stability.
Minor Data Transfer Errors in DMA Mode
Phenomenon: Initial data transfers may contain a few errors, but subsequent transfers are normal.
Causes and Solutions: Please refer to the DMA and Cache section.