7.5.7 SPI User Guide
Hardware Support
-
If SPI uses DMA transfer, the following restrictions must be ensured:
- The transfer length must be aligned to 8 bytes; otherwise, data out-of-bound issues may occur;
- The transmit and receive buffer addresses must be aligned to 64 bytes;
- The maximum data size for a single Channel transfer cannot exceed 4096 bytes;
-
Supports SPI operating as a Slave;
-
When MCU-side SPI operates as Slave and the rate is greater than 9M, only DMA mode can be used;
-
When the MCU operates as an SPI slave device, its communication clock is provided by the master device. Therefore, the slave must respond immediately to every data transfer request from the master. If interrupt handling mode is used, the SPI interrupt service routine execution time must be sufficiently short. If interrupts are blocked for too long and the data register is not processed in time, the receive buffer will overflow. Therefore, DMA transfer mode is strongly recommended to automatically complete data movement through hardware, ensuring communication real-time performance and reliability.
-
When MCU-side SPI operates in 8-bit mode, the following restrictions apply:
- Maximum speed for 1 SPI parallel TX/RX: 50M;
- Maximum speed for 2 SPI parallel TX/RX: 33.3M;
- Maximum speed for 3 SPI parallel TX/RX: 25M;
- Maximum speed for 4 SPI parallel TX/RX: 20M;
- Maximum speed for 5 SPI parallel TX/RX: 15.6M;
- Maximum speed for 6 SPI parallel TX/RX: 12.5M;
-
The SPI peripheral supports MSB only;
-
SPI
SpiCsPolarityandspitimeclk2cconfiguration are not supported.SpiCsPolaritydefaults to active low. -
After
SpiCsToggleEnableis enabled, the CS pin will be pulled high after one SPI frame transmission completes. Only TRAILING mode is supported; LEADING mode is not supported. -
Compared with non-DMA mode, SPI DMA mode consumes lower CPU load.
-
When SPI transmits data in non-DMA mode, if the system load is high, delayed SPI interrupt response may prevent timely writes into the SPI FIFO, causing the CS pin to briefly go high. In this case, DMA mode is recommended.
-
If the use case involves multiple Sequences using the same SPI IP for asynchronous transmission, and there is no transmission completion order dependency between Sequences, Sequence transmission queuing may occur. In this case, interrupt-disable critical section protection must be implemented in the
SchM_Spi.cfile.
Code Paths
McalCdd/Spi/inc/Spi.h: SPI driver header fileMcalCdd/Spi/inc/Spi_Lld.h: SPI low-level driver header fileMcalCdd/Spi/src/Spi.c: SPI driver source fileMcalCdd/Spi/src/Spi_Lld.c: SPI low-level driver source fileMcalCdd/Common/Register/inc/Spi_Register.h: SPI register definition filePlatform/Schm/SchM_Spi.h: SPI module scheduler management header fileConfig/McalCdd/gen_xxx/Spi/inc/Spi_Board.h: SPI board-level configuration header fileConfig/McalCdd/gen_xxx/Spi/inc/Spi_Cfg.h: SPI configuration header fileConfig/McalCdd/gen_xxx/Spi/inc/Spi_PBcfg.h: SPI PB configuration header fileConfig/McalCdd/gen_xxx/Spi/src/Spi_board.c: SPI board-level configuration source fileConfig/McalCdd/gen_xxx/Spi/src/Spi_PBcfg.c: SPI PB configuration source filesamples/Spi/SPI_sample/Spi_sample.c: SPI sample codesamples/Spi/SPI_sample/Spi_common.c: SPI sample code
Application Sample
Software Operation Flow
The general software operation flow is as follows:
-
Initialization
- Modify configuration structures such as
ChannelCfgArrayPtr,JobCfgArrayPtr,SeqCfgArrayPtr,HwCfgPtr, andPhyCfgPtrto configure the corresponding SPI instance with the required baud rate and transfer mode. Refer to the SPI configuration description SPI Configuration Description - Call
Spi_Init(&Spi_Config)orSpi_Init(NULL). When NULL is passed, the default configuration inSpi_PBcfg.cis used. - The driver traverses the configuration information to initialize internal data structures (such as
Spi_ChannelState,Spi_JobState,Spi_HwQueueArray, etc.) and physical SPI hardware units (configure registers according toSpi_PhyCfgTypeandSpi_IpCfg)
- Modify configuration structures such as
-
Set transfer mode:
- The application selects interrupt mode or polling mode through
Spi_SetAsyncMode().
- The application selects interrupt mode or polling mode through
-
Data preparation:
- The application places the data to be transmitted into the buffer associated with the channel through
Spi_WriteIB()orSpi_SetupEB().
- The application places the data to be transmitted into the buffer associated with the channel through
-
Transfer request:
- The application calls
Spi_AsyncTransmit(sequence)orSpi_SyncTransmit(sequence)to start sequence transmission.
- The application calls
-
Driver processing:
- The driver locates the corresponding
Spi_SeqCfgbased on thesequence ID - Obtains the job list according to
Spi_SeqCfg.JobIndexList. - For each job in the sequence:
- Determine the physical SPI hardware unit to use according to
Spi_JobCfg.HWUnit. - Obtain the external device communication parameters corresponding to the job according to
Spi_JobCfg.HwCfgPtr. - Obtain the channel list according to
Spi_JobCfg.ChannelIndexList. - Traverse the channel list and obtain transmit data from the buffer pointed to by
Spi_ChannelCfg.BufferDescriptor. - Configure the physical SPI hardware unit.
- Start hardware transfer.
- The driver locates the corresponding
-
Transfer completion:
- For asynchronous transfer, after the hardware transfer is completed (detected by interrupt or polling), the driver calls the corresponding notification function
- For synchronous transfer, the function waits until the transfer is completed.
-
Status query:
- The application can query the transfer status through functions such as
Spi_GetJobResult()andSpi_GetSequenceResult().
- The application can query the transfer status through functions such as
Single Chip Select Usage Example
The spi_test command is used to test SPI (Serial Peripheral Interface) functionality. This command supports initialization and parameter configuration, displaying current parameters, and executing SPI data transfer tests.
Command Syntax
spi_test <operation> [bus_id] [sync_mode] [trans_mode]
Parameter Description
-
operation: Specifies the operation to execute.
- 0: Initialization and parameter configuration.
- 1: Display currently configured parameters.
- 2: Execute SPI test (asynchronous or synchronous).
-
bus_id (required only when operation is 0): Specifies the SPI bus to use.
- Value range: 2 to 6, corresponding to SPI2 to SPI6.
-
sync_mode (required only when operation is 0): Specifies the SPI communication synchronization mode.
- 0: Asynchronous mode (async)
- 1: Synchronous mode (sync)
-
trans_mode (required only when operation is 0): Specifies the underlying mechanism for SPI data transfer.
- 0: Polling mode (polling)
- 1: Interrupt mode (interrupt)
Using SPI3 as an example, short MISO and MOSI of SPI3 together and run the following command to configure transfer parameters:
D-Robotics:/$ spi_test 0 3 0 0
[055.578172 0]Init&&Parameter setting
[055.578428 0]Show Spi parameter
[055.578792 0]spi_bus = 3
[055.579085 0]sync_mode = async
[055.579443 0]trans_mode = polling
Run the following command to test:
D-Robotics:/$ spi_test 2
[059.643996 0]Sequence: 1, transfer_length = 128 spi_framesize = 16
...
[059.702104 0]=====SPI ASYNC TEST SUCCESS=====
Dual Chip Select Usage Example
The SpiTest_Mul_cs command is used to test SPI (Serial Peripheral Interface) functionality.
Usage and parameter description are as follows:
########################## support test case: ##########################
usag: SpiTest_Mul_cs Case_num Sequences Cs DataWidth DataLen Loop_times
[1]: SpiTest_Mul_cs 1 1 0 8 1 1 -- get versioninfo
[2]: SpiTest_Mul_cs 2 5 0 8 10 1 -- InterruptMode Sync Transfer
[3]: SpiTest_Mul_cs 3 5 0 8 10 1 -- PollingMode Sync Transfer
[4]: SpiTest_Mul_cs 4 5 0 8 10 1 -- InterruptMode Async Transfer
[5]: SpiTest_Mul_cs 5 5 0 8 10 1 -- PollingMode Async Transfer
other: SpiTest 110 -- help
-
Parameter description:
- Case_num (argv[1]): Specifies the operation to execute. Five modes are supported. For interrupt asynchronous transfer, set
Case_numto 4. - Sequences (argv[2]): Specifies which SPI to use. For example, use SPI4 by setting
Sequencesto 4. - Cs (argv[3]): Specifies which CS to use. For example, use CS0 by setting
Csto 0. - DataWidth (argv[4]): Specifies the transfer data width. For example, for 8-bit width, set
DataWidthto 8. - Datalen (argv[5]): Specifies the amount of transferred data. For example, to transfer 10 groups of data, set
Datalento 10. - Loop_times (argv[6]): Specifies how many times to test. For example, to test 5 times, set
Loop_timesto 5.
- Case_num (argv[1]): Specifies the operation to execute. Five modes are supported. For interrupt asynchronous transfer, set
-
Example:
- SPI4, async interrupt transfer, CS1, 8-bit data width, 10 groups of data, test once:
SpiTest_Mul_cs 4 4 1 8 10 1
- SPI4, async interrupt transfer, CS1, 8-bit data width, 10 groups of data, test once:
Short MISO and MOSI of SPI4 together and run the following command:
Robotics:/$ SpiTest_Mul_cs 4 4 1 8 10 1
[get_spi_status 98] [INFO]: SPI status: SPI_IDLE
...
[SpiTest_Mul_cs 479] [INFO]: #####################################################################
Single Chip Select Usage Example
The spi_test command is used to test SPI (Serial Peripheral Interface) functionality. This command supports initialization and parameter configuration, displaying current parameters, and executing SPI data transfer tests.
Command Syntax
Operation 0: Configure parameters for group 1
spi_test 0 <spi_bus> <sync_mode> <trans_mode> <ch_cfg> <cs_seq0> <cs_seq1> <cs_seq2> <cs_seq3>
- bus_id: SPI bus ID (optional, default is 4)
- sync_mode: 0=asynchronous(async) 1=synchronous(sync)
- trans_mode: 0=polling(polling) 1=interrupt(interrupt)
- ch_cfg: SPI channel configuration
- cs_seq0: SPI sequence ID used by cs0, 255=invalid
- cs_seq1: SPI sequence ID used by cs1, 255=invalid
- cs_seq2: SPI sequence ID used by cs2, 255=invalid
- cs_seq3: SPI sequence ID used by cs3, 255=invalid
Configure the basic SPI parameters. After configuration is completed, the parameters are saved in group 1.
D-Robotics:/$ spi_test 0 13 0 1 10 2 3 255 255
[046.803972 0]Init&&Parameter setting
[046.804397 0]Test parameters configured successfully:
...
Operation 1: Display parameter information
Display all current test parameter configurations. The first group stores the custom configuration from operation 0.
spi_test 1
D-Robotics:/$ spi_test 1
[06649.837117 0]Test Parameter at index 0:
...
Operation 2: Execute SPI test
spi_test 2 [bus_id] [cs_id]
- bus_id: SPI bus ID (optional, default is 4). The
bus_idhere must exist in the parameter configuration group (displayed throughspi_test 1); otherwise, the test will fail. - cs_id: Chip select ID, range 0
3 (optional, default is 0. Currently only cs0 testing is supported; cs13 require code modification before testing)
D-Robotics:/$ spi_test 2 4 0
[0323.134926 0]Using SPI Bus ID: 4, CS ID: 0
...
[0323.151786 0]=====SPI SYNC TEST SUCCESS=====
Dual Chip Select Usage Example (BMI088 Test)
The BMI088 sensor is mounted on the S600 MCU daughterboard. The sensor communicates with the MCU through the SPI13 bus, where cs0 is connected to the accelerometer (acc) and cs1 is connected to the gyroscope (gyr).
Usage and parameter description are as follows:
- Initialize the BMI088 sensor
D-Robotics:/$ Bmi088_ShellInit
[Bmi088_Init] ACC+GYR initialized.
- BMI088 sensor self-test
D-Robotics:/$ Bmi088_SelfTestGyr
[Bmi088_SelfTestGyr] SELF_TEST=0x12 (rdy=1 fail=0)
[Bmi088_SelfTestGyr] PASS
D-Robotics:/$ Bmi088_SelfTestAcc
...
[Bmi088_SelfTestAcc] PASS
- Read acc data multiple times
D-Robotics:/$ Bmi088_TestAcc 50
[Bmi088_TestAcc] acc_id(raw)=0x1E
...
- Read gyr data multiple times
D-Robotics:/$ Bmi088_TestGyr 50
[Bmi088_TestGyr] gyr_id(raw)=0x0F
...
Configuration File Description
The configuration file Spi_PBcfg.c stores SPI driver configurations. Among them, Spi_ConfigType is the top-level container that organizes all configuration information (channels, jobs, sequences, hardware units, etc.) together into a complete configuration set used to initialize the SPI driver.
/**
* @struct Spi_ConfigType
* @NO{S01E17C01}
* @brief This is the top level structure containing all the
* needed parameters for the SPI Handler Driver.
*/
typedef struct
{
uint32 SpiCoreUse; /**< CoreID used*/
const Spi_ChannelCfgArray *ChannelCfgArrayPtr; /**< Pointer to Array of channels defined in the configuration.*/
const Spi_JobCfgArray *JobCfgArrayPtr; /**< Pointer to Array of jobs defined in the configuration.*/
const Spi_SeqCfgArray *SeqCfgArrayPtr; /**< Pointer to Array of sequences defined in the configuration.*/
const Spi_HwCfgArray *HwCfgPtr; /**< External device unit attributes.*/
const Spi_PhyCfgArray *PhyCfgPtr; /**< Pointer to Array of device instances.*/
Spi_ChannelType SpiMaxChannel; /**< Number of channels defined in the configuration.*/
Spi_JobType SpiMaxJob; /**< Number of jobs defined in the configuration.*/
Spi_SequenceType SpiMaxSequence; /**< Number of sequences defined in the configuration.*/
Spi_HwNumType SpiMaxHwNum; /**< Number of Spi HW defined in the configuration.*/
#if (SPI_DISABLE_DEM_REPORT_ERROR_STATUS == STD_OFF)
const Mcal_DemErrorType SpiErrorHwCfg; /**< SPI Driver DEM Error: SPI_E_HARDWARE_ERROR.*/
#endif
} Spi_ConfigType;
Member Description
- SpiCoreUse: Specifies which CPU core can use this SPI configuration. For single-core systems, keep the default configuration.
- ChannelCfgArrayPtr: Points to an array containing all
Spi_ChannelCfgconfigurations. This array defines the properties of all available SPI channels in the system, such as buffer type (IB/EB), frame size, default value, and buffer pointers. - JobCfgArrayPtr: Points to an array containing all
Spi_JobCfgconfigurations. This array defines the properties of all available SPI jobs in the system, such as included channel lists, notification functions, priority, and associated physical units (HWUnit). - SeqCfgArrayPtr: Points to an array containing all
Spi_SeqCfgconfigurations. This array defines the properties of all available SPI sequences in the system, such as included job lists, notification functions, and interruptibility. - HwCfgPtr: Points to an array containing all
Spi_HwCfgconfigurations. This array defines the hardware properties of all external devices, mainly communication-related parameters (such as baud rate, clock polarity, and chip select). - PhyCfgPtr: Points to an array containing all
Spi_PhyCfgTypeconfigurations. This array defines the basic operating modes and characteristics of all physical SPI hardware units (Physical SPI Unit, PhyUnit), such as master/slave mode, DMA usage, and transfer mode. - SpiMaxChannel: Total number of channels defined in the configuration. Used for internal driver array allocation and boundary checking.
- SpiMaxJob: Total number of jobs defined in the configuration. Used for internal driver array allocation and boundary checking.
- SpiMaxSequence: Total number of sequences defined in the configuration. Used for internal driver array allocation and boundary checking.
- SpiMaxHwNum: Number of physical SPI hardware units (PhyUnit) involved in the configuration. Used for internal driver array allocation and boundary checking.
- SpiErrorHwCfg: Used to configure SPI hardware error reporting parameters.
Association Relationship Between Members
Applications usually initiate transmission by calling Spi_AsyncTransmit() or Spi_SyncTransmit() and passing a sequence ID. Therefore, Sequence is the entry point directly interacted with by users. Its simplified entity relationship with channels, jobs, hardware configuration, and physical unit configuration is as follows:
Both SPI_HWUNIT and SPI_EXTERNAL_DEVICE need to be associated with a hardware instance (Instance), which determines which SPI interface is used for communication. Since the RDKS100 platform provides a total of 8 SPI controllers, including 2 in the MAIN domain (SPI0 and SPI1) and 6 in the MCU domain (SPI2 to SPI7), SPI numbering in the MCU domain actually starts from SPI2. The green portions in the table below show the mapping relationship between SPI sequence configuration (Spi SeqCfg) and corresponding hardware resources (Spi BusId, HWUnit, Instance).
| SPI SeqCfg | Spi BusId | HWUnit | Instance | Spi Baudrate | Spi Cs | Frame size |
|---|---|---|---|---|---|---|
| SpiSequence_0 | SPI2 | CSIB0 | 0 | 2000000 | CS0 | 16 bit |
| SpiSequence_1 | SPI3 | CSIB1 | 1 | 2000000 | CS0 | 16 bit |
| ... |
| SPI SeqCfg | Spi BusId | HWUnit | Instance | Spi Baudrate | Spi Cs | Frame size |
|---|---|---|---|---|---|---|
| SpiSequence_0 | SPI6 | CSIB2 | 2 | 2000000 | CS0 | 16 bit |
| SpiSequence_1 | SPI6 | CSIB2 | 2 | 2000000 | CS1 | 16 bit |
| ... |
Application Programming Interface
void Spi_Init(const Spi_ConfigType* ConfigPtr)
Description:Service for SPI initialization.
Parameters(in)
ConfigPtr: Pointer to configuration set
Parameters(inout)
None
Parameters(out)
None
Return value:None
Std_ReturnType Spi_WriteIB(Spi_ChannelType Channel, const Spi_DataBufferType* DataBufferPtr)
Description:Service for SPI de-initialization.
Parameters(in)
Channel: Channel ID.
DataBufferPtr: Source data buffer pointer
Parameters(inout)
None
Parameters(out)
None
Return value:Std_ReturnType
E_OK: Spi write IB buffer success.
E_NOT_OK: Spi write IB buffer failed.
Std_ReturnType Spi_AsyncTransmit(Spi_SequenceType Sequence)
Description:Service to transmit data on the SPI bus.
Sync/Async:Asynchronous
Parameters(in)
Sequence: Sequence ID.
Parameters(inout)
None
Parameters(out)
None
Return value:Std_ReturnType
E_OK: set success
E_NOT_OK: set failed
Std_ReturnType Spi_ReadIB(Spi_ChannelType Channel, Spi_DataBufferType* DataBufferPtr)
Description:Service for reading synchronously one or more data from an IB SPI
Handler/Driver Channel specified by parameter.
Sync/Async:Synchronous
Parameters(in)
Channel: Channel ID.
Parameters(inout)
None
Parameters(out)
DataBufferPtr: Pointer to destination data buffer in RAM
Return value:Std_ReturnType
E_OK: set success
E_NOT_OK: set failed
Std_ReturnType Spi_SetupEB(Spi_ChannelType Channel, const Spi_DataBufferType* SrcDataBufferPtr, Spi_DataBufferType* DesDataBufferPtr, Spi_NumberOfDataType Length)
Description:Service to setup the buffers and the length of data for the EB SPI
Handler/Driver Channel specified.
Sync/Async:Synchronous
Parameters(in)
Channel: Channel ID.
SrcDataBufferPtr: Pointer to the memory location that will hold the transmitted data
Length: Length (number of data elements) of the data to be transmitted
Parameters(inout)
None
Parameters(out)
DesDataBufferPtr: Pointer to the memory location that will hold the received data
Return value:Std_ReturnType
E_OK: Spi Setup EB buffer success.
E_NOT_OK: Spi Setup EB buffer failed.
Spi_StatusType Spi_GetStatus(const Spi_ConfigType* ConfigPtr)
Description:Service returns the SPI Handler/Driver software module status.
Sync/Async:Synchronous
Parameters(in)
None
Parameters(inout)
None
Parameters(out)
None
Return value:Spi_StatusType
Spi_StatusType
Spi_JobResultType Spi_GetJobResult(Spi_JobType Job)
Description:This service returns the last transmission result of the specified Job.
Sync/Async:Synchronous
Parameters(in)
Job: Job ID. An invalid job ID will return an undefined result.
Parameters(inout)
None
Parameters(out)
None
Return value:Spi_JobResultType
Spi_JobResultType
Spi_SeqResultType Spi_GetSequenceResult(Spi_SequenceType Sequence)
Description:This service returns the last transmission result of the specified Sequence.
Sync/Async:Synchronous
Parameters(in)
Sequence: Sequence ID. An invalid sequence ID will return an undefined result.
Parameters(inout)
None
Parameters(out)
None
Return value:Spi_JobResultType
Spi_JobResultType
void Spi_GetVersionInfo(Std_VersionInfoType* versioninfo)
Description:This service returns the version information of this module.
Sync/Async:Synchronous
Parameters(in)
None
Parameters(inout)
None
Parameters(out)
versioninfo: Pointer to where to store the version information of this module.
Return value:None
Std_ReturnType Spi_SyncTransmit(Spi_SequenceType Sequence)
Description:Service to transmit data on the SPI bus.
Sync/Async:Synchronous
Parameters(in)
Sequence: Sequence ID.
Parameters(inout)
None
Parameters(out)
None
Return value:Std_ReturnType
E_OK: Transmission command has been accepted
E_NOT_OK: Transmission command has not been accepted
Spi_StatusType Spi_GetHWUnitStatus(Spi_HWUnitType HWUnit)
Description:This service returns the status of the specified SPI Hardware
microcontroller peripheral.
Sync/Async:Synchronous
Parameters(in)
HWUnit: SPI Hardware microcontroller peripheral (unit) ID.
Parameters(inout)
None
Parameters(out)
None
Return value:Spi_StatusType
Spi_StatusType
void Spi_Cancel(Spi_SequenceType Sequence)
Description:Service cancels the specified on-going sequence transmission.
Sync/Async:Synchronous
Parameters(in)
None
Parameters(inout)
None
Parameters(out)
None
Return value:None
Std_ReturnType Spi_SetAsyncMode(Spi_AsyncModeType Mode)
Description:Service to set the asynchronous mechanism mode for SPI
busses handled asynchronously.
Sync/Async:Synchronous
Parameters(in)
Mode: New mode required.
Parameters(inout)
None
Parameters(out)
None
Return value:Std_ReturnType:
E_OK: Setting command has been accepted
E_NOT_OK: Setting command has not been accepted
void Spi_MainFunction_Handling(void)
Description:This function polls the SPI interrupts linked to HW Units
allocated to the transmission of SPI sequences to enable the evolution
of the transmission state machine.
Sync/Async:Synchronous
Parameters(in)
None
Parameters(inout)
None
Parameters(out)
None
Return value:None