一、 概述
本文将会介绍 SemiDrive E3 MCAL Spi 模块的简介以及基本配置。此外会结合实际操作的介绍,帮助新手快速了解并掌握这个模块的使用,文中的 MCAL 是基于 PTG3.0 的版本,开发板是官方的 E3640 网关板。
二、 Spi 模块简介
AutoSar 关于 Spi 模块定义了一些概念,例如 Channel、Job、Sequence。下面将具体介绍这些概念的具体含义以及使用上的一些注意事项,这几个概念之间的关系如下图所示。
图 2.1 AutoSar Spi 模块框架
从图中可以看出 Channel 是对应到具体的 SPI 设备,同个 SPI 控制器不同的片选信号对应不同的 SPI 设备,然后 Job 是和 Channel 进行绑定的,每个 Job 至少绑定一个 Channel,不然这个 Job 没有意义,每个 Job可以绑定多个 Channel,例如图中的 Job1 绑定了 Ch1 和 Ch2;同个 Channel 可以被多个 Job 绑定,例如图中的 Ch2 和 Ch5;Ch2 和 Ch5 的区别是 Ch2 用于不同的外设,而 Ch5 用于同一个外设,不推荐这么使用,容易造成数据混乱。
SPI 的传输是以 Sequence 为单位的,Sequence下面必须要绑定 Job,不然的话该 Sequence 没有意义。每个 Sequence 下面可以有多个 Job,这些 Job 拥有多个同个优先级,每个 Job 是从片选信号开始到片选信号结束,如下图所示。
图 2.2 SPI 传输序列
三、 Spi 模块的主要配置
在配置 SPI 模块之前我们需要对 MCU 模块和 Port 模块先进行配置,首先配置 MCU 模块,使能我们需要用到的 SPI 实例。
图 3.1 使能 SPI 模块
接着配置 Port 模块,对 SPI 引脚进行配置。
图 3.2 配置 SPI 引脚
最后对 SPI 模块进行配置,首先根据实际使用的 SPI 的 Channel、Job、Sequence 数量进行配置。
图 3.3 SPI General 配置
接着配置 SPI 的硬件单元,SpiController 这栏是选择实际的 SPI 控制器,例如这里我们将 SPI2 配置为 CSIB2,不使能 DMA 传输,Master 模式。
图 3.4 配置 SPI 硬件单元
然后配置 SPI 设备,点击右边的加号添加一个 SPI 设备,然后配置该 SPI 设备的波特率,片选引脚,片选极性,采样数据的边缘等,具体的配置选项如图 3.6 所示。
图 3.5 配置 SPI 设备
图 3.6 SPI 设备配置选项
- SpiBaudrate:用于配置该 SPI 设备的波特率
- SpiCsIdentifier:用于选择使用哪个片选引脚
- SpiCsPolarity:用于配置片选信号的极性
- SpiCsSelection:用于选择使用硬件片选还是 GPIO 片选
- SpiDataShiftEdge:用于选择 SPI 数据的采样边缘,LEADING 为第一个边缘,TRAILING 为第二个边缘
- SpiHwUnit:用于选择该 SPI 设备使用哪个 SPI 控制器
- SpiShiftClockIdleLevel:用于配置时钟空闲状态的电平
- SpiTimeClk2Cs:用于配置 CS 有效到时钟产生的时间,单位为秒,范围为 0~0.0001 秒
- SpiTimeClk2CsEnd:用于配置时钟信号结束到 CS 无效的时间,单位为秒,范围为 0~0.0001 秒
接着添加并配置 SPI 的 Job,点击右边的加号符号进行 Job 的添加,这里 SpiJobId 按照顺序递增就好,SpiJobPriority 为 Job 的优先级,配置范围为 0 ~ 3,最后将该 Job 跟 SPI 设备进行绑定。
图 3.7 添加 SPI 的Job 并配置
接着添加并配置 SPI Channel,如下图所示,这里添加了两个 Channel。
图 3.8 添加 SPI Channel 并配置
图 3.9 SPI Channel 的配置参数
如图 3.9 所示,具体配置以下参数:
- SpiChannelId:通道 ID,按照顺序递增就好
- SpiChannelType:配置 Channel 的类型,EB 为使用外部 Buffer,IB 为使用内部 Buffer,选择 EB 的话,用户需要自己分配空间作为 Buffer。IB 的话驱动会自动处理
- SpiDataWidth:配置数据宽度,可以配置为 4\8\16\32
- SpiEbMaxLength:配置 EB Buffer 的最大长度
- SpiIbNBuffers:配置 IB Buffer 的最大大小
- SpiTransferStart:配置传输的大小端,MSB 或 LSB
接着将 Job 和 Channel 进行绑定,这里将 Job10 和 Channel33 绑定,Job11 和 Channel34 绑定。
图 3.10 将 Job 和 Channel 进行绑定
最后新增 Sequence 并且将 Sequence 和 Job 进行绑定,这里我们将 Sequence6 和 Job10 和 Job11 进行绑定,如下图所示。到此则完成了 SPI 模块的所有配置。
图 3.11 将 Sequence 和 Job 进行绑定
四、 实际操作
配置完了以后,打开 MCAL 的工程,我们需要对代码进行修改,主要修改 spi_test.c文件,具体修改如下图所示。
图 4.1 定义缓冲区
定义好缓存区后,我们对缓存区进行初始化,将发送缓存区的值配置为 0x55 和 0xAA。
图 4.2 初始化缓冲区
初始化好缓冲区后,因为我们 Channel 的类型是配置为 EB 的,因此我们需要调用 Spi_SetupEB() 接口将我们定义的缓存设置为 EB 缓存,并指定对应的 Channel。最后我们直接调用 Spi_AsyncTransmit() 接口启动 SPI 传输即可,传参为 SequenceId。
图 4.3 设置 EB 并且启动传输
按照以上修改完代码后,重新编译工程并下载到板子,重新上下电运行。
图 4.4 运行测试用例
输入 “runcase 1800”运行 SPI 的测试例程,同时用逻辑分析仪抓取 SPI 的波形,抓取的波形如下图所示。从图中可以看到总共发送了两个 Job,Job10 和 Job11,发送的数据也是一致的。
图 4.5 抓取的 SPI 波形
五、 使用注意事项
配置 Spi 模块时,需要注意以下事项:
- SPI 的 SCLK 引脚的上下拉配置需要和 SPI 中配置的 Clock 空闲电平一致,SS 引脚的上下拉及初始电平状态需要根据 CS 的极性来配置,如果 CS 的极性为高电平,那么 SS 引脚应配置为下拉并且初始化电平为低电平。
- 同一个 Job 不能在多个 Sequence 之间共享
- JobId,SeqId,ChannelId,配置的时候需要全局唯一,且从 0 开始连续编号
- Slave 启动 DMA 时,对应 DMA 通道的中断优先级需要和 Slave 对应控制器的中断优先级相同,避免出现竞争。
六、 参考资料
1.《SemiDrive_E3_MCAL_User_Guide_Rev03.00.pdf》,2023.08