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 device | Spi Physical Unit |
---|---|---|
SPI2 | SPI_SpiExternalDevice_0 | Spi_PhyConfig_SpiPhyUnit_0 |
SPI3 | SPI_SpiExternalDevice_1 | Spi_PhyConfig_SpiPhyUnit_1 |
SPI4 | SPI_SpiExternalDevice_2 | Spi_PhyConfig_SpiPhyUnit_2 |
SPI5 | SPI_SpiExternalDevice_3 | Spi_PhyConfig_SpiPhyUnit_3 |
SPI6 | SPI_SpiExternalDevice_4 | Spi_PhyConfig_SpiPhyUnit_4 |
SPI7 | SPI_SpiExternalDevice_5 | Spi_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测试
-
参数解析