SPI Slave Write GPIO
The sample demonstrates how SPI0 slave sends data and SPI1 master receives data by GPIO in interrupt mode. Because the SPI slave does not support sending data when the TX FIFO is empty, the sample toggles a GPIO pin to notify the master after the slave sends data.
Requirements
For hardware requirements, please refer to the Requirements.
Wiring
Connect P1_4 (master SCK) to P1_0 (slave SCK), connect P1_7 (master CS) to P1_3 (slave CS), connect P1_6 (master MISO) to P1_2 (slave MISO), connect P1_5 (master MOSI) to P1_1 (slave MOSI), and connect P2_3 (master GPIO input) to P2_4 (slave GPIO output) on EVB. 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 SPI1_SCK P1_4
#define SPI1_MOSI P1_5
#define SPI1_MISO P1_6
#define SPI1_CS P1_7
#define SPI0_SCK P1_0
#define SPI0_MOSI P1_1
#define SPI0_MISO P1_2
#define SPI0_CS P1_3
#define GPIO_PIN1 P2_3
#define GPIO_PIN0 P2_4
The entry function are as follows, call this function in
main()
to run this sample code. For more details, please refer to the Initialization.spi_slave_gpio_demo();
Building and Downloading
For building and downloading, please refer to the Building and Downloading.
Experimental Verification
Press the Reset button on the EVB.
The slave device sends data to TX FIFO, toggle GPIO to notify master, then master device sends data to slave.
When the data length in the master or slave TX FIFO is equal to or below its threshold value, trigger the
SPI_INT_TXE
interrupt and prints log.spi1_handler: SPI1 TX FIFO Empty spi0_handler: SPI0 TX FIFO Empty
When the data length in slave RX FIFO is equal to or above its threshold value plus 1, trigger the
SPI_INT_RXF
interrupt. Then the data is received in arraySPI_ReadINTBuf
and printed in Debug Analyzer.spi0_handler: SPI_ReadINTBuf[0] 0x11 ... spi0_handler: SPI_ReadINTBuf[5] 0x66
When the data length in master RX FIFO is equal to or above its threshold value plus 1, trigger the
SPI_INT_RXF
interrupt. Then the data is received in arraySPI1_ReadINTBuf
and printed in Debug Analyzer.spi1_handler: SPI1_ReadINTBuf[0] 0x11 ... spi1_handler: SPI1_ReadINTBuf[5] 0x66
Code Overview
Source Code Directory
For project directory, please refer to Source Code Directory.
Source code directory:
sdk\src\sample\io_demo\spi\slave\spi_slave_gpio_demo.c
.
GPIO Interrupt Initialization Flow
Call
hal_gpio_init()
to enable GPIO clock.Call
hal_gpio_int_init()
to initialize GPIO interrupt.Call
hal_gpio_set_debounce_time()
to set GPIO debounce time.Call
hal_gpio_init_pin()
to initialize the GPIO peripheral and callhal_gpio_set_up_irq()
to initialize interrupt-related parameters. The GPIO initialization parameters are configured as shown in the table below.
GPIO Hardware Parameters |
GPIO |
---|---|
PIN Number |
|
GPIO Type |
|
GPIO Mode |
|
GPIO Pull Value |
|
Interrupt Type |
|
Interrupt Polarity |
|
Debounce Enable |
|
Call
hal_gpio_register_isr_callback()
to register gpio interrupt callback.Call
hal_gpio_irq_enable()
to enable gpio interrupt.
GPIO Output Initialization Flow
Call
hal_gpio_init()
to enable GPIO clock.Call
hal_gpio_init_pin()
to initialize the GPIO peripheral. The GPIO initialization parameters are configured as shown in the table below.
GPIO Hardware Parameters |
GPIO |
---|---|
PIN Number |
|
GPIO Type |
|
GPIO Mode |
|
GPIO Pull Value |
Call
hal_gpio_set_level()
to output low level.
SPI Initialization Flow (SPI0 Slave)
The initialization flow for peripherals can refer to Initialization Flow.
SPI initialization flow is shown in the following figure.

SPI Initialization Flow Chart
Call
Pad_Config()
andPinmux_Config()
to initialize the pins.static void board_spi_init(void) { Pinmux_Config(SPI0_SCK, SPI0_CLK_SLAVE); Pinmux_Config(SPI0_MOSI, SPI0_SI_SLAVE); Pinmux_Config(SPI0_MISO, SPI0_SO_SLAVE); Pinmux_Config(SPI0_CS, SPI0_SS_N_0_SLAVE); Pad_Config(SPI0_SCK, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(SPI0_MOSI, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(SPI0_MISO, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(SPI0_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 SPI0 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
Frame Format
Transmit FIFO Threshold Level
0
Receive FIFO Threshold Level
0
Call
SPI_Cmd()
to enable SPI.Call
SPI_INTConfig()
to enable RX FIFO full interruptSPI_INT_RXF
and TX FIFO underflow interruptSPI_INT_TUF
.Call
RamVectorTableUpdate()
to register SPI0 interrupt handler.Call
NVIC_Init()
to enable NVIC of SPI.
SPI Initialization Flow (SPI1 Master)
SPI initialization flow can refer to SPI Initialization Flow Chart.
Call
Pad_Config()
andPinmux_Config()
to initialize the pins.static void board_spi_init(void) { Pinmux_Config(SPI1_SCK, SPI1_CLK_MASTER); Pinmux_Config(SPI1_MOSI, SPI1_MO_MASTER); Pinmux_Config(SPI1_MISO, SPI1_MI_MASTER); Pinmux_Config(SPI1_CS, SPI1_SS_N_0_MASTER); Pad_Config(SPI1_SCK, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(SPI1_MOSI, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(SPI1_MISO, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); Pad_Config(SPI1_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 SPI1 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
Clock Div
400
Frame Format
Transmit FIFO Threshold Level
0
Receive FIFO Threshold Level
0
Call
SPI_Cmd()
to enable SPI.Call
SPI_INTConfig()
to enable RX FIFO full interruptSPI_INT_RXF
.Call
RamVectorTableUpdate()
to register SPI1 interrupt handler.Call
NVIC_Init()
to enable NVIC of SPI.
Functional Implementation
Send Data by Interrupt
Call
SPI_SendBuffer()
to send the data inSPI_WriteBuf
to the slave.Call
SPI_INTConfig()
to enable TX FIFO empty interruptSPI_INT_TXE
.
Interrupt Handle
When the transmit buffer reaches or goes below the TX FIFO threshold level (
SPI_InitTypeDef::SPI_TxThresholdLevel
), TX FIFO empty interrupt will be triggered and enters the interrupt handler:Call
SPI_GetINTStatus()
to checkSPI_INT_TXE
interrupt status.Call
SPI_INTConfig()
to disableSPI_INT_TXE
.
When the receive buffer reaches or goes above the RX FIFO threshold level (
SPI_InitTypeDef::SPI_RxThresholdLevel
+ 1), RX full interrupt will be triggered and enters the interrupt handler:Call
SPI_GetINTStatus()
to checkSPI_INT_RXF
interrupt status.Call
SPI_GetRxFIFOLen()
to get the data length in RX FIFO.Call
SPI_ReceiveData()
to receive data from RX FIFO.
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_GetINTStatus()
to checkSPI_INT_TUF
interrupt status.Call
SPI_INTConfig()
to disable TX FIFO underflow interruptSPI_INT_TUF
.