跳到主要内容

SPI使用指南

硬件支持

  • 如果SPI使用DMA传输,必须保证以下限制:
    • 传输长度需要保证8字节对齐,否则会出现数据越界的问题;
    • 发送和接收数据的buffer地址必须对齐为64字节;
    • Channel单次传输数据量不能超过4096字节;
  • 支持SPI作为Slave功能;
  • Mcu侧SPI做Slave时,速率大于9M,只能采用DMA模式;
  • Mcu侧SPI在8位模式下工作时,具有以下限制:
    • 1个SPI并行收发最大速度: 50M;
    • 2个SPI并行收发最大速度: 33.3M;
    • 3个SPI并行收发最大速度: 25M;
    • 4个SPI并行收发最大速度: 20M;
    • 5个SPI并行收发最大速度: 15.6M;
    • 6个SPI并行收发最大速度: 12.5M;
  • SPI外设只支持MSB;
  • SPI SpiCsPolarity和spitimeclk2c都不支持配置,SpiCsPolarity默认为低电平有效。
  • SPI SpiCsToggleEnable配置使能后,Spi传输完一个frame后,会拉高CS引脚,仅支持TRAILING模式,LEADING模式不支持。
  • SPI DMA模式相对于非DMA模式,消耗CPU负载更低。
  • 当SPI采用非DMA方式发送数据时,若系统负载比较大,会因为SPI中断响应不及时导致SPI FIFO未能及时写入,从而导致CS引脚短暂拉高,此时推荐采用DMA模式。
  • 如果使用场景是多个Sequence使用同一个SPI IP进行异步传输,且Sequence之间并没有传输完成先后顺序,则会存在Sequence传输排队的现象,此时需要在SchM_Spi.c文件中实现关中断临界区保护。

代码路径

  • McalCdd/Spi/inc/Spi.h - SPI驱动程序的头文件
  • McalCdd/Spi/inc/Spi_Lld.h - SPI底层驱动程序的头文件
  • McalCdd/Spi/src/Spi.c - SPI驱动程序的源文件
  • McalCdd/Spi/src/Spi_Lld.c - SPI底层驱动程序的源文件
  • McalCdd/Common/Register/inc/Spi_Register.h - SPI寄存器定义文件
  • Platform/Schm/SchM_Spi.h - SPI模块的调度管理头文件
  • Config/McalCdd/gen_s100_sip_B_mcu1/Spi/inc/Spi_Cfg.h - SPI配置头文件
  • Config/McalCdd/gen_s100_sip_B_mcu1/Spi/inc/Spi_PBcfg.h - SPI PB配置头文件
  • Config/McalCdd/gen_s100_sip_B_mcu1/Spi/src/Spi_PBcfg.c - SPI PB配置源文件
  • samples/Spi/SPI_sample/Spi_sample.c - SPI sample 代码

应用sample

  • Sample中使用了DMA,但是没有进行初始化,是因为在Target/Target-hobot-lite-freertos-mcu1/target/HorizonTask.c文件中已经进行了初始化。

S100 有SPI2-SPI7六个SPI硬件,SPI通道和外部设备以及物理单元抽象关键信息对应如下:

SPI通道External deviceSpi Physical Unit
SPI2SPI_SpiExternalDevice_0Spi_PhyConfig_SpiPhyUnit_0
SPI3SPI_SpiExternalDevice_1Spi_PhyConfig_SpiPhyUnit_1
SPI4SPI_SpiExternalDevice_2Spi_PhyConfig_SpiPhyUnit_2
SPI5SPI_SpiExternalDevice_3Spi_PhyConfig_SpiPhyUnit_3
SPI6SPI_SpiExternalDevice_4Spi_PhyConfig_SpiPhyUnit_4
SPI7SPI_SpiExternalDevice_5Spi_PhyConfig_SpiPhyUnit_5

配置说明

以SPI4为例,配置如下:

//Config/McalCdd/gen_s100_sip_B_mcu1/Spi/src/Spi_PBcfg.c
static const Spi_PhyCfgType Spi_PhyConfig_SpiPhyUnit_2 =
{
(uint8)2U, /* Instance */
SPI_SPURIOUS_CORE_ID, /* SpiCoreUse */
/* Spi Slave mode*/
(boolean)FALSE, //FALSE为master模式,true为slave模式
/* Spi Test Mode Operation Enable*/
(boolean)FALSE, // 回环模式,不走线
/* Spi Sample Point*/
(uint32)0U,
#if (SPI_DMA_ENABLE == STD_ON)
(boolean)FALSE, //DMA配置
#endif
SPI_IP_POLLING, /* Transfer mode 可选中断模式和轮询模式*/
(uint8)2U, /* State structure element from the array */
//SPI_PHYUNIT_SYNC /* IsSync */
SPI_PHYUNIT_ASYNC //同步模式或异步模式
};

static const Spi_ChannelCfg SpiChannel_2 =
{
/* SpiChannel_2*/
EB, /* BufferType IB or EB */ //使用外部内存或者内部内存
8U, /* Frame size */
(uint32)1U, /* In the case SpiDefaultData is disabled. Set this value is 1U */
Spi_TxDefaultBufferSpiChannel_2,
Spi_RxDefaultBufferSpiChannel_2,
256U, /* Length (configured in SpiEbMaxLength) */
&Spi_BufferSpiChannel_2,
SPI_SPURIOUS_CORE_ID,
&Spi_ChannelState[2U] /* Spi_ChannelState pointer */
};

使用示例

spi_test 命令用于测试SPI(Serial Peripheral Interface,串行外设接口)功能。该命令支持初始化和参数设置、获取参数以及执行SPI测试。

  • spitest 命令支持以下三种操作模式,通过第一个参数指定:

    • 0:初始化和参数设置
    • 1:获取参数
    • 2:执行SPI测试
  • 参数解析

    • 操作模式 (argv[1]): 指定要执行的操作,取值范围为0、1或2。
    • 设备ID (argv[2]): 指定SPI设备的ID,与使用哪一个SPI相关,对应情况可参考本文首节中SPI关键信息对应表。
    • 通道号 (argv[3]): 指定SPI通道号,对应上文的Spi_ChannelCfg配置,通常只在切换内部内存和外部内存时需要更改。
    • 同步模式 (argv[4]): 仅在操作模式为0时使用,指定SPI通信的同步模式。
      • 0: 异步模式
      • 1: 同步模式
    • 传输模式 (argv[5]): 仅在操作模式为0时使用,指定SPI数据的传输模式。
      • 0: 轮询模式 (Polling)
      • 1: 中断模式 (Interrupt)
提示

应用层配置与底层配置应保持一致,否则会出现错误。

将SPI4的MISO和MOSI短接,运行以下命令

D-Robotics:/$ spi_test 2
[0433.628723 0]set interrupt
[0433.628914 0]interrupt,2
[0433.639657 0]interrupt,2
[0433.649684 0]
RxChBuf0 (256 bytes):
0CC20DC0: 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 00 | 123456789:;<=>?.
0CC20DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20DE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20EA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CC20EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
[0433.679963 0]
TxChBuf0 (256 bytes):
0CBC3040: 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 00 | 123456789:;<=>?.
0CBC3050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC30A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC30B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC30C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC30D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC30E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC30F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
0CBC3130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
[0433.700110 0]=====SPI ASYNC TEST SUCCESS=====

应用程序接口

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 asyn-chronously.

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 shall polls the SPI interrupts linked to HW Units
allocated to the transmission of SPI sequences to enable the evolution
of transmission state machine.

Sync/Async:Synchronous
Parameters(in)
None
Parameters(inout)
None
Parameters(out)
None
Return value:None