8155平台SPI学习笔记
一. SPI数据包格式
-
申请一个Buffer
uint8_t * buffer = new uint8_t[256];
memset(buffer, 0, 256); -
需要用户传入要发送的SPI消息,例如一个字符串数组
input : std::vectorstd::string > msgs; -
计算有哪些SPI消息可以放入本次发送的SPIFrame中
因为SPI Frame长度是有限制的,而且由于SPI通信的特性,MOSI和MISO双攻交换数据的时间是一样的,因此,两边交换的SPI Frame的长度是固定的,例如是256字节
那么SPI Frame是由多个SPI Message组成的,每个SPI Message需要带上一个2字节的长度字段,根据msg中每个元素的长度+2字节算一个SPI Message的长度,可以计算出msgs数组中有多少消息可以进入最终要发送的SPI Frame
SPI Frame结尾一般有两个字节的CRC校验码字段, SPI Frame开头有两个字节的总长度(Frame的总长度,不是某个SPI Messsage的长度)
因此,SPI Frame的格式是:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | …| 66 | 67 | 68 | 69 | … | 255 |
frame长度 msg1长度 ------msg1 内容------ msg2长度 --------msg2 内容------ CRC 0 0 0 0
Frame中有效的内容从frame长度开始,到CRC结束,后面的都填0
二. SPI的特性
SPI一般用于板间通信使用,例如SOC和MCU之间进行通信,SPI通信需要设置主从模式,一般是一个主SPI对应一个或者多个从SPI设备
每个SPI设备至少有四条通信线:CS(SS), SCLK, MISO, MOSI,如果只支持单项传输的情况下,MISO或者MOSI中会缺少一条线
MISO: Master Input Slave Output 主设备输入线,丛设备输出数据
MOSI: Master Output Slave Input 主设备输出线,主设备从该线将数据输出给从设备
CS(SS): Chip Select (Slave Select) 从设备使能线,发出从设备使能信号,由主设备控制,只有CS信号有效选择到从设备的时候,主设备对从设备的操作才是有效的
SCLK: Serial Clock,时钟信号,由主设备产生,从设备不能控制
SPI是串行通信协议,因此数据是一位一位传输的,因此才需要SCLK时钟信号线存在,SCLK需要主从设备都配置相同才行,SCLK使用辅助主从设备来进行数据交换的
根据配置,发送端在时钟的上沿将要发送的消息的当前bit值更新到MOSI/MISO上,然后接收端在时钟的下沿从MISO/MOSI上读取到该bit值,因此一个字节的数据需要经过8个时钟跳变才能完成传输。
三. SPI时钟的极性和相位
极性和相位针对的是SPI的CK时钟线,对数据的传输是有影响的,极性决定了数据空闲时的时钟信号电平,相位决定了数据采样的时机。
极性(CPOL):0:数据空闲时CK时钟线是低电位,1:数据空闲时CK时钟线是高电位
相位(CPHA):设置了当CK时钟线从空闲状态变为数据传输状态后,从第几个跳变沿开始采集数据
0:从第一个跳变沿开始采集数据,1:从第二个跳变沿开始采集数据
四. 8155平台高通提供的SPI常用接口
spi_open
打开spi设置
spi_timeout_set
设置下面这些spi接口函数的超时时间:
spi_setcfg
spi的设置项在 spi_cfg_t 结构体类型中,目前用到该结构体的两个成员 mode 和 clock_rate
spi_xchange
该函数的调用将在当前SPI设备和主控设备之间交换数据,需要传入要保存收到数据的缓存区,还需要提供此次需要发送给主控数据的数据缓存区
spi_register_pulse
将SPI的信号和QNX的channel绑定在一起,应用可以通过MsgReceive接收该Channel上的信号
spi_unregister_pulse
将SPI信号和QNX的Channel的绑定取消,是spi_register_pulse的反操作。
spi_write
主动向SPI主设备发送数据,目前J5SPI-Service项目中没有用到。
spi_close
关闭SPI接口。