SPI Circular DMA Example
Source path: example/rt_device/spi/circular_rx
Supported Boards
sf32lb52-lcd_n16r8sf32lb58-lcd_n16r64n4
Overview
This example validates DMA circular mode in the RT-Thread SPI driver and supports three modes:
Master TRX mode: full-duplex TX/RX, suitable for loopback testing
Slave RX mode: receive only, requires an external Master to provide clock
Slave TX mode: transmit only, requires an external Master to provide clock
API Reference
API |
Description |
|---|---|
|
Configure circular DMA direction |
|
Register RX half-buffer / full-buffer callback |
|
Register TX half-buffer / full-buffer callback |
|
Start TX+RX full-duplex circular DMA |
|
Start RX only circular DMA |
|
Start TX only circular DMA |
|
Stop circular DMA |
Required Configuration
project/proj.conf should include:
CONFIG_BSP_USING_SPI1=y
CONFIG_BSP_SPI1_TX_USING_DMA=y
CONFIG_BSP_SPI1_RX_USING_DMA=y
CONFIG_BSP_USING_SPI_DMA_CIRCULAR=y
Mode Selection
Select by the SPI_CIRCULAR_DEMO_MODE macro:
0: Master TRX mode (default)1: Slave RX only mode2: Slave TX only mode
Example Flow
Master TRX Mode (Mode 0)
Configure SPI1 pinmux
Attach/open the
spi_circulardeviceConfigure SPI (Master, Mode0, 8bit, 20MHz)
Call
rt_spi_take_bus()/rt_spi_release_bus()to trigger DMA handle linkingCall
rt_device_control(..., RT_SPI_CTRL_CONFIG_DMA_CIRCULAR, ...)withTXRXCall
rt_spi_transfer()to start circular DMAShort MOSI and MISO for loopback verification
Slave RX Mode (Mode 1)
Configure SPI1 pinmux
Configure SPI as Slave mode
Call
rt_device_control(..., RT_SPI_CTRL_CONFIG_DMA_CIRCULAR, ...)withRXCall
rt_device_read()to start circular receiveConnect an external SPI Master to provide clock
Slave TX Mode (Mode 2)
Configure SPI1 pinmux
Configure SPI as Slave mode
Call
rt_device_control(..., RT_SPI_CTRL_CONFIG_DMA_CIRCULAR, ...)withTXCall
rt_device_write()to start circular transmitConnect an external SPI Master to provide clock
Hardware Connection
Pin Mapping Table
Board |
Function Pin |
Local Device Pin |
Remote Device Pin |
Physical Pin (CONN2) |
|---|---|---|---|---|
sf32lb52-lcd |
PA_24 |
dio |
SPI_MOSI |
19 |
PA_25 |
di |
SPI_MISO |
21 |
|
PA_28 |
clk |
SPI_CLK |
23 |
|
PA_29 |
cs |
SPI_CS |
24 |
|
sf32lb58-lcd |
PA_21 |
dio |
SPI_MOSI |
8 |
PA_20 |
di |
SPI_MISO |
10 |
|
PA_28 |
clk |
SPI_CLK |
5 |
|
PA_29 |
cs |
SPI_CS |
3 |
The hardware schematic of sf32lb52-lcd_n16r8 is shown below:

Option 1: Single-board Loopback (Master TRX Mode)
Short SPI1 MOSI and MISO:
sf32lb52x:PA24(DIO)↔PA25(DI)sf32lb58x:PA21(DO)↔PA20(DI)
Option 2: External SPI Slave Device (Slave Mode)
Connect with standard 4-wire SPI. An external Master must provide clock.
sf32lb52-lcd_n16r8 Hardware Schematic

Expected Logs
Master TRX Mode
Start SPI circular DMA demo!
Mode: Master TRX (loopback)
Circular DMA started on spi1
Tip: Short MOSI(DO) to MISO(DI) for loopback verification.
RX: half=1 full=0 rx[0..7]: 00 01 02 03 04 05 06 07, rx[mid..mid+7]: 80 81 82 83 84 85 86 87, mismatch=0
Slave RX Mode
Start SPI circular DMA demo!
Mode: Slave RX only
Tip: Connect external SPI Master to provide clock.
Circular DMA started on spi1
RX: half=1 full=0
Slave TX Mode
Start SPI circular DMA demo!
Mode: Slave TX only
Tip: Connect external SPI Master to provide clock.
Circular DMA started on spi1
TX: half=1 full=0 tx[0..7]: 00 01 02 03 04 05 06 07, tx[mid..mid+7]: 80 81 82 83 84 85 86 87
Callback Functions
Use standard RT device callbacks to process half-buffer / full-buffer events:
rt_device_set_rx_indicate((rt_device_t)g_spi_dev, spi_dma_circular_rx_ind);
rt_device_set_tx_complete((rt_device_t)g_spi_dev, spi_dma_circular_tx_ind);
static rt_err_t spi_dma_circular_rx_ind(rt_device_t dev, rt_size_t offset)
{
// offset == 0 -> first half is ready
// offset == buffer_size/2 -> second half is ready
return RT_EOK;
}
static rt_err_t spi_dma_circular_tx_ind(rt_device_t dev, void *buffer)
{
// buffer points to the first or second half of the TX buffer
return RT_EOK;
}
FAQ
1) Stuck after startup
Check:
Whether
rt_spi_take_bus()/rt_spi_release_bus()has been executedWhether DMA configuration in
proj.confhas taken effect
2) half/full does not increase
Check whether SPI pinmux is overridden
Check whether DMA IRQ is enabled
3) sample_mismatch remains high (Master TRX mode)
Poor loopback wire contact
MISO signal interference
Changelog
Version |
Date |
Description |
|---|---|---|
1.0.0 |
03/2026 |
Initial release, supporting Master TRX / Slave RX / Slave TX modes |