Autosar SPI 概述(Specification of SPI Handler/Driver )
基础知识介绍
在AutoSar标准中,与SPI通讯相关的三个术语:Channel、Job和Sequence。
1个Channel对应1个发送缓冲区和1接收缓冲区;1个Job对应着1次SPI通讯发送的内容(既SPI 一次片选过程所传输的内容)。1个Sequence 对应着1个SPI通讯序列(job序列)。多个Job可以分配给一个Sequence。
关于每个术语的详细解释,参考AutoSar标准。SPI通讯是基于Sequence触发的,即使发送1个Job也要将该Job分配给1个队列,然后通过触发Sequence来实现Job的传输。
两种使用方法
方法1: 对应1个SPI外设芯片,分配1个Job、1个Sequence。使用此种方法,触发一次Sequence,只能传输一个Job,当对外设发送多个Job时,需要多次触发Sequence,且在下一次触发Sequence时,必须确保上一次Sequence已经传输完毕,否则下一次Sequence传输会因为上一次Sequence传输占用SPI总线而失败。
**方法2:**对应1个SPI外设芯片,结合对外设芯片的控制方法,分配多个Job和多个Sequence,有目的分配Job到相应的Sequence中。在不同控制逻辑中,触发不同的Sequence,传输不同个数的Job序列。当对1个Sequence分配多Job时,触发此Sequence就可以完成多个Job的传输,SPI 驱动本身来保证Job序列的传输,不会产生下一个Job传输因为上一个Job占用SPI总线而失败的情况。
对外设传输多个Job时,使用方法2可以降低CPU使用率。
Channel、Job、Sequence
AUTOSAR 提供了三种SPI的抽象。Channel Job Sequence。
一张图可以说明三者的关系。
同步调用与异步调用
AUTOSAR 为SPI 提供了两种方式通信的接口。
同步调用 Spi_SyncTransmit
异步调用 Spi_AsyncTransmit
同步调用,是需要等待返回调用结果,而异步调用这是发起任务,一般可以通过回调函数来告知调用结果。
数据类型定义
1、 Spi_ConfigType结构体
Channel配置包含:
- EB/IB buffer的使用情况
- 传输位宽 (1~32bits)
- 传输数据个数
- 传输字节序LSB/MSB
- 传输的默认值
Job配置包含:
- 使用哪个SPI硬件实例
- 使用该实例的哪个片选引脚cs
- 片选功能是否启用
- 片选高/低有效
- 波特率
- clock 和 chip select之间的时间
- 时钟在空闲时是高/低
- 数据传输在上升沿/下降沿
- 优先级(低0~3高)
- Job完成的通知函数
- MCU相关的属性(可选)
- Channels(至少1个)
sequence配置包含:
- Jobs (至少1个)
- 在每个Job完成后是否产生中断
- Sequence完成的通知函数
2、部分API函数
void Spi_Init( const Spi_ConfigType ConfigPtr )*
1. 初始化所有ConfigPtr相关寄存器
2. 定义ConfigPtr相关的默认值
3. 设置SPI状态为“IDLE”,job、sequence的状态设为“ok”
4. 对于Level2,异步模式设为polling,禁用spi相关中断
Std_ReturnType Spi_DeInit( void )
1. 如果驱动状态不是BUSY,将spi外设置为复位上电后的状态
2. 如果驱动状态是BUSY,请求被拒绝
3. 去初始化后,模块的状态是UINIT
Std_ReturnType Spi_WriteIB( Spi_ChannelType Channel, const Spi_DataBufferType DataBufferPtr )*
1. 返回值:E_OK:该命令被接受,E_NOT_OK:该命令被拒绝。
2. 将入参数据写入对应channel的内部缓存
3. 如果入参DataBufferPtr为NULL,将传输默认值
Std_ReturnType Spi_ReadIB( Spi_ChannelType Channel, Spi_DataBufferType DataBufferPointer )*
1. 返回值:E_OK:该命令被接受,E_NOT_OK:该命令被拒绝。
2. 同步读取一条或多条数据
3. 应该在Transmit后调用,以获取相关数据
Std_ReturnType Spi_SyncTransmit( Spi_SequenceType Sequence )
1. 返回值:E_OK:该命令被接受,E_NOT_OK:该命令被拒绝。
2. 在SPI总线上传输数据
3. 驱动状态设为“BUSY”
4. Sequence、Job状态设为“PENDING”
5. 此时如果有其他Sequence正在传输,应该返回 E_NOT_OK,并上报错误。
Spi_StatusType Spi_GetStatus( void )
1. 获取驱动状态