SPI Slave High Speed
This document introduces two SPI communication samples. The sample1 demonstrates how SPI0 slave reads data at high speed in DMA mode. The sample2 demonstrates how SPI0 slave sends data at high speed in DMA mode. In both examples, SPI is configured as a slave operating in DMA mode. The chip writes data to the SPI master or reads data from it.
Requirements
For hardware requirements, please refer to the Requirements.
Wiring
Connect P1_1 (slave CS) to the CS of SPI master device, connect P0_0 (slave SCK) to the SCK of SPI master device, connect P0_1 (slave MISO) to the MISO of SPI master device, and connect P1_0 (slave MOSI) to the MOSI of SPI master device. The hardware connection of SPI sample code is shown in the figure below.

SPI Sample Code Hardware Connection Diagram
Configurations
The following macros can be configured to modify pin definitions.
#define PIN_SPI_SCK P0_0
#define PIN_SPI_MOSI P1_0
#define PIN_SPI_MISO P0_1
#define PIN_SPI_CS P1_1
The entry function are as follows, call this function in
main()
to run this sample code. For more details, please refer to the Initialization.For sample 1, use the following entry function:
spi_slave_rx_dma_hs_demo();
For sample 2, use the following entry function:
spi_slave_tx_dma_hs_demo();
Building and Downloading
For building and downloading, please refer to the Building and Downloading.
Experimental Verification
Sample 1 Verification
Press the Reset button on the EVB.
After the master device sends data to the chip, the chip stores the received the data in array
read_buf
.When completing the transmission, it enters the GDMA interrupt and prints the received data.
spi_slave_rx_dma_handler! rx_len_all 1000 spi_slave_rx_dma_handler: read_buf ... spi_slave_rx_dma_handler: read_buf
Sample 2 Verification
Press the Reset button on the EVB.
The chip sends the data in array
sendbuf
to TX FIFO immediately. When the master device sends data, the data transmission is started.When completing the transmission, it enters the GDMA interrupt and prints log.
spi_slave_tx_dma_handler! tx_len_all 1000
Code Overview
Source Code Directory
For both samples, please refer to the Source Code Directory for the project directory.
Sample 1 source code:
Source code directory:
sdk\src\sample\io_demo\spi\slave\spi_slave_rx_dma_hs_demo.c
.
Sample 2 source code:
Source code directory:
sdk\src\sample\io_demo\spi\slave\spi_slave_tx_dma_hs_demo.c
.
RX DMA Initialization Flow
The initialization flow for peripherals can refer to Initialization Flow.
The SPI RX DMA initialization flow requires first initializing the SPI peripheral, followed by RX DMA initialization. The SPI initialization flow can refer to SPI Initialization Flow Chart. The SPI RX DMA initialization flow can refer to SPI RX DMA Initialization Flow Chart.
Call
Pad_Config()
andPinmux_Config()
to initialize the pin.static void board_spi_init(void) { Pinmux_Config(PIN_SPI_SCK, SPI_CLK_SLAVE); Pinmux_Config(PIN_SPI_MOSI, SPI_MO_SLAVE); Pinmux_Config(PIN_SPI_MISO, SPI_MI_SLAVE); Pinmux_Config(PIN_SPI_CS, SPI_SS_N_0_SLAVE); Pad_Config(PIN_SPI_SCK, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(PIN_SPI_MOSI, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(PIN_SPI_MISO, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(PIN_SPI_CS, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); }
Call
RCC_PeriphClockCmd()
to enable the SPI clock and function.Initialize the SPI peripheral:
Define the
SPI_InitTypeDef
typeSPI_InitStructure
, and callSPI_StructInit()
to pre-fillSPI_InitStructure
with default values.Modify the
SPI_InitStructure
parameters as needed. The SPI initialization parameter configuration is shown in the table below.Call
SPI_Init()
to initialize the SPI peripheral.
SPI Initialization Parameters SPI Hardware Parameters
Setting in the
SPI_InitStructure
SPI
Direction
Device Role (SPI Master or SPI Slave)
Data Frame Size
Clock Polarity
Clock Phase
RX Water Level
31
Call
SPI_Cmd()
to enable SPI.Call
RCC_PeriphClockCmd()
to enable the GDMA clock and function.Call
GDMA_channel_request
to request a free GDMA channel and register the GDMA interrupt handler.Initialize the GDMA peripheral:
Define the
GDMA_InitTypeDef
typeGDMA_InitStruct
, and callGDMA_StructInit()
to pre-fillGDMA_InitStruct
with default values.Modify the
GDMA_InitStruct
parameters as needed. The GDMA initialization parameter configuration is shown in the table below.Call
GDMA_Init()
to initialize the GDMA peripheral.
GDMA Initialization Parameters GDMA Hardware Parameters
Setting in the
GDMA_InitStruct
GDMA
Channel Num
SPI_SLAVE_RX_DMA_CHANNEL_NUM
Transfer Direction
Buffer Size
TEST_SIZE
Source Address Increment or Decrement
Destination Address Increment or Decrement
Source Data Size
Destination Data Size
Source Burst Transaction Length
Destination Burst Transaction Length
Source Address
SPI0->DR
Destination Address
read_buf
Source Handshake
GDMA_Handshake_SPI0_RX
Call
GDMA_INTConfig()
to enable GDMA transfer complete interruptGDMA_INT_Transfer
.Call
NVIC_Init()
to enable NVIC of GDMA.
TX DMA Initialization Flow
The initialization flow for peripherals can refer to Initialization Flow.
The SPI TX DMA initialization flow requires first initializing the SPI peripheral, followed by TX DMA initialization. The SPI initialization flow can refer to SPI Initialization Flow Chart. The SPI TX DMA initialization flow can refer to SPI TX DMA Initialization Flow Chart.
Call
Pad_Config()
andPinmux_Config()
to initialize the pin.static void board_spi_init(void) { Pinmux_Config(PIN_SPI_SCK, SPI_CLK_MASTER); Pinmux_Config(PIN_SPI_MOSI, SPI_MO_MASTER); Pinmux_Config(PIN_SPI_MISO, SPI_MI_MASTER); Pinmux_Config(PIN_SPI_CS, SPI_SS_N_0_MASTER); Pad_Config(PIN_SPI_SCK, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(PIN_SPI_MOSI, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(PIN_SPI_MISO, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(PIN_SPI_CS, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); }
Call
RCC_PeriphClockCmd()
to enable the SPI clock and function.Initialize the SPI peripheral:
Define the
SPI_InitTypeDef
typeSPI_InitStructure
, and callSPI_StructInit()
to pre-fillSPI_InitStructure
with default values.Modify the
SPI_InitStructure
parameters as needed. The SPI initialization parameter configuration is shown in the table below.Call
SPI_Init()
to initialize the SPI peripheral.
SPI Initialization Parameters SPI Hardware Parameters
Setting in the
SPI_InitStructure
SPI
Direction
Device Role (SPI Master or SPI Slave)
Data Frame Size
Clock Polarity
Clock Phase
TX Water Level
46
Call
SPI_Cmd()
to enable SPI.Call
SPI_INTConfig()
to enable TX FIFO overflowSPI_INT_TXO
and TX FIFO underflow interruptSPI_INT_TUF
.Call
NVIC_Init()
to enable NVIC of SPI.Call
RCC_PeriphClockCmd()
to enable the GDMA clock and function.Call
GDMA_channel_request
to request a free GDMA channel and register the GDMA interrupt handler.Initialize the GDMA peripheral:
Define the
GDMA_InitTypeDef
typeGDMA_InitStruct
, and callGDMA_StructInit()
to pre-fillGDMA_InitStruct
with default values.Modify the
GDMA_InitStruct
parameters as needed. The GDMA initialization parameter configuration is shown in the table below.Call
GDMA_Init()
to initialize the GDMA peripheral.
GDMA Initialization Parameters GDMA Hardware Parameters
Setting in the
GDMA_InitStruct
GDMA
Channel Num
SPI_SLAVE_TX_DMA_CHANNEL_NUM
Transfer Direction
Buffer Size
TEST_SIZE
Source Address Increment or Decrement
Destination Address Increment or Decrement
Source Data Size
Destination Data Size
Source Burst Transaction Length
Destination Burst Transaction Length
Source Address
sendbuf
Destination Address
SPI0->DR
Destination Handshake
GDMA_Handshake_SPI0_TX
Call
GDMA_INTConfig()
to enable GDMA transfer complete interruptGDMA_INT_Transfer
.Call
NVIC_Init()
to enable NVIC of GDMA.
Functional Implementation
Slave Receive Data by DMA in High Speed
Call
pm_cpu_slow_freq_set()
to config the slow clock for high speed. For specific value, please refer to High Speed.Call
SPI_GDMACmd()
to disable and then enable SPI GDMA RX Function.Call
GDMA_Cmd()
to enable DMA transfers.
Slave Send Data by DMA in High Speed
Call
pm_cpu_slow_freq_set()
to config the slow clock for high speed. For specific value, please refer to High Speed.Call
SPI_GDMACmd()
to disable and then enable SPI GDMA TX Function.Call
GDMA_Cmd()
to enable DMA transfers.
Slave TX Interrupt Handle
If clocks sent by the master when the slave is at the empty FIFO level, TX FIFO underflow interrupt will be triggered and enters the interrupt handler:
Call
SPI_INTConfig()
to disable TX underflow interruptSPI_INT_TUF
.Call
SPI_ClearINTPendingBit()
to clearSPI_INT_TUF
interrupt.Call
SPI_Cmd()
to reset SPI slave for recover.
If SPI attempts to write into the TX FIFO after it has been completely filled, TX FIFO overflow interrupt will be triggered and enters the interrupt handler:
Call
SPI_INTConfig()
to disable TX overflow interruptSPI_INT_TXO
.Call
SPI_ClearINTPendingBit()
to clearSPI_INT_TXO
interrupt.
Slave GDMA Interrupt Handle
When GDMA transfer is completed, transfer complete interrupt is triggered:
Call
GDMA_GetTransferLen()
to get the GDMA transfer data length.Call
GDMA_INTConfig()
to disable GDMA transfer complete interruptGDMA_INT_Transfer
.Call
GDMA_ClearINTPendingBit()
to clearGDMA_INT_Transfer
interrupt.