之前一直调用已有的驱动,实现SPI通信,所以调试的难点多在于极性,相位,数据长度,软硬件片选。再深一些,才意识到SPI通信是全双工通信,发送和接收同时进行。主机先发送命令,再发送冗余字节,为从机提供时钟信号。刚开始工作,主要关注的也是单主单从,后来时间久点,开始接触到多主一从。多主一从场景,两个主机不能同时操纵从机,但大家有没有考虑过,空闲状态的主机该如何配置,是否会对正常工作的主机产生影响。最近一段时间,开始接触gpio模拟SPI,工作也开始向底层偏移,有幸看到SPI从机工作的代码。
时间间隔
在上一家公司工作时,调试WIFI芯片SPI驱动代码,粗心大意,在SPI从机写了个输出语句,最后忘记删除,导致主从SPI通信速率一直无法上去,该打。在现在公司调试时,使用的是gpio模拟SPI,从机芯片手册对SPI通信时间间隔这一块,没有给出具体描述,后来经领导提示,才知道,从机回复数据需要时间,主机发送完命令后,无法立即回复,需要等待几十us。且SPI发送完成后,主机要再等几个SPI时钟周期,方可将SPI片选线拉高,结束本次SPI通信。此外,SPI通信时,字节与字节间必须保持若干us的延时。这里可以参考钜泉光电的HT7036芯片,该芯片"SPI初始化"章节部分有关于时间控制的描述。
SPI开始信号与时钟信号延时示意图
字节间隔和结束间隔示意图
多说一点,HT7036作为SPI从机,只能进行指定格式(CMD(1Byte)+冗余字节(3字节0xFF))的通信。SPI通信时,主机要先发送1个字节的命令,再发送三字节的冗余数据,为从机提供时钟信号,以便从机在这期间进行数据回复。
多主一从
最后,开始记录多主一从的注意事项。两个主机同时只能有一个主机工作自不必多说,主要说明一点,空闲主机,如果不将自己的SPI引脚配置成gpio,依然会对另一主机的SPI通信造成影响。这一点要从SPI的引脚采用推挽输出说起,推挽输出是能够真正输出高电平的配置方式,推挽输出配置下,引脚只有高低两种状态。在这种情况下,工作的SPI主机会控制CLK,MOSI引脚的电平,空闲状态的SPI主机难道不会控制CLK,MOSI引脚电平吗。空闲状态的SPI主机希望引脚电平不变,常高或者常低;工作状态的SPI主机希望CLK,MOSI引脚电平,随时听从自己的调度,让它高电平就高电平,让它低电平就低电平;这就会造成电平冲突。为了解决这种冲突,空闲的SPI主机,需要放弃自己对CLK,MOSI的控制权。为此,它需要把自己的功能引脚配置为输入悬空,这样就不会干扰工作状态的SPI主机通信。那两个主机如何协商控制从机呢,为此两个主机间需要再添加两个互通的引脚,通过监控引脚的电平,来获知另一主机是否正在使用SPI从机。
SPI多主一从示意图
SPI通信中,从机并不能主动发起通信,为了解决该问题,可以在主从机之间多加一个互通引脚,一旦从机拉低该引脚电平,主机就发送读取指令。这种方式,一定程度上,可以弥补从机不能发起通信的缺陷。