SPI处理程序/驱动程序为单片SPI [串行外设接口]处理程序/驱动程序提供功能和API。该软件模块包括处理和驱动功能。这种单片SPI处理器/驱动器的主要目标是充分利用每个微控制器的功能,并根据静态配置实现优化,以尽可能地满足ECU的需求。
因此,该规范定义了可选择的功能级别和可配置特征,以允许设计利用微控制器特性的高可扩展模块。
SPI处理程序/驱动程序是微控制器抽象层(MCAL)的一部分。它提供读取和写入通过SPI总线连接的设备的服务。它还提供了配置片上SPI外设所需的机制。
SPI具有4线同步串行接口。使用片选线(CS)启用SPI通信。SPI通信由3线接口执行,包括用于串行数据主线 - 输出 - 从 - 输入(MOSI),串行数据主 - 输入 - 从 - 输出(MISO)和串行时钟(CLK)的线。
SPI外设可能取决于系统时钟,预分频器和PLL。因此,系统时钟的变化(例如,PLL开启 - > PLL关闭)也可能影响SPI硬件的时钟设置。
SPI处理程序/驱动程序模块不会在初始化函数中设置用于配置时钟,预分频器和PLL的寄存器。这必须由MCU模块完成。
根据微控制器,SPI外设可以与其他外设共享寄存器。在这种典型情况下,SPI处理程序/驱动程序与MCU模块有关系,用于初始化和取消初始化这些寄存器。
根据所选的功能级别,SPI处理程序/驱动程序的一般行为可以是异步或同步的调用方式。
AUTOSAR 提供了三种SPI的抽象。Channel Job Sequence。
一张图可以说明三者的关系。
一个Job 代表了一次完整的SPI通信,一个Job可以由一个或者多个Channel组成,Channel用来装载SPI的发送与接收数据。
一个Sequence可以由一个或者多个Job,可以将一个操作序列抽象成一个Sequence。
SPI传输的最小单元是由连续的Job组成的Sequence,依据Job的优先级将Job 依次发送出去。
AUTOSAR 为SPI 提供了两种方式通信的接口。
同步调用 Spi_SyncTransmit
异步调用 Spi_AsyncTransmit
同步调用,是需要等待返回调用结果,而异步调用这是发起任务,一般可以通过回调函数来告知调用结果。
对于同步调用接口 Spi_SyncTransmit() Sequence状态的切换都是在接口函数中完成的。
将Sequence 状态置为PENDING。
Sequence处理完成 立即置为OK
对于异步接口Spi_AsyncTransmit(),会把Sequence中的Job按照顺序加载到Job的调度表中,同时将Sequence的状态置为PENDING。由Spi_ScheduleJob函数通过DMA加载到硬件。从机返回数据通过DMA加载到对应的Channel的DestBuf中,此时Sequence并没有置为OK,而是通过Spi_Dspi_IsrDmaRx 函数去查询DMA是否传输完成,然后在重新将Sequence的状态置为OK。
这里有两种方式来调用Spi_Dspi_IsrDmaRx()。一种是在SPI的Rx中断中,一种是在MainFunction中。因此只要使用异步调用接口办法直接通过接口返回值来判断数据是否发生完成,也无法判断Slave是否有返回数据。
这里有三种方式来解决这个问题。
将同步调用接口 增加Sequence等待检查,抽象成同步方式;即等待中断服务函数将Sequence的状态切换为OK。
调用异步接口之后不管,在下一次发送相同Sequence时检查Sequence的状态,如果是非OK 就调用Spi_Cancel 函数取消上次Sequence的发送。
使能DMA Rx的Notificaion 功能,通过Call Back函数来告知调用方已经完成传输
以上三种方式,我采用了第二种。我认为第三种方式使用于大量数据传输,菊花链的数据量并不是很大。
SPI的配置项只有在使用DMA功能是才与MCL模块相关联。
在SpiPhyUnits的配置项中,直接关联到硬件的SPI
SpiExternalDevice 中通过HW Uint关联到SpiPhyUints
SpiJob 中通过Device Assignment 关联到Device,通过ChannelList 关联到Channel。
MPC5746R有64个DMA通道,可以通过手册查到应对的DmaMux。