此次 A7159 的调试是在 STM32、IMX6UL 硬件平台环境下实现的,其主要实现内容为以下三点:
1 基于 STM32 库的 GPIO 模拟 SPI总线通信实现
2 基于 STM32 库的 SPI 控制总线通信实现
3 基于 IMX6UL linux驱动的 SPI 控制总线通信实现
该小结先简单介绍了下 SPI 总线相关知识,后简述基于 A7159 datasheet 去调试 SPI 总线过程及不同实现方式的注意事项。
1.认识 SPI 总线
SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola首先在其MC68HCXX 系列处理器上定义的。 SPI 接口主要应用在 EEPROM, FLASH,实时时钟, AD 转换器,还有数字信号处理器和数字信号解码器之间。 SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议, 下面我们看看 SPI 的内部简明图,如下图所示:
SPI 接口一般使用 4 条线通信,如上图所示,其 pin 脚含义如下:
MISO 主设备数据输入,从设备数据输出。
MOSI 主设备数据输出,从设备数据输入。
SCLK 时钟信号,由主设备产生。
CS 从设备片选信号,由主设备控制。
从图中可以看出, 主机和从机都有一个串行移位寄存器,主机通过向它的 SPI 串行寄存器写入一个字节来发起一次传输。寄存器通过 MOSI 信号线将字节传送给从机,从机也将自己的移位寄存器中的内容通过 MISO 信号线返回给主机。这样,两个移位寄存器中的内容就被交换。外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。
SPI 主要特点有: 可以同时发出和接收串行数据; 可以当作主机或从机工作; 提供频率可编程时钟; 发送结束中断标志; 写冲突保护; 总线竞争保护等。
SPI 总线四种工作模式:
SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果 CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果 CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果 CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。 SPI 主模块和与之通信的外设备时钟相位和极性应该一致。不同时钟相位下的总线数据传输时序如图 30.1.2 所示:
注意:
1 由于 SPI 总线为非标准总线,其也支持 3 线通信,即 MISO 和 MOSI 为同一 pin 脚,只能实现半双工通信(STM32F4 在硬件上支持 3线和4线配置)
2 由于 SPI 为非标准总线,其读写时钟、数据以及片选信号波形要严格按照外设的 datasheet 要求进行配置,否则主机与外设将不能正常工作
3 除了 SPI 工作模式要配置外,一般还要配置传输第一位为高位还是低位(MSB/LSB)、1帧多少位(一般为8、16、32,具体看master 和 slave 支持)
2. A7159 模块简介
A7159 拥有超高灵敏度 (-113dBm @ 10Kbps @ 433MHz FSK),低接收电流(低于5mA)与 20dBm PA 输出,Link- budget为133dB。开启DSSS扩频调变后,接收灵敏度可大幅增加5~8 dB (-120dBm @ 10Kchip rate @ 433MHz FSK) ,433MHz的Link-budget可至140dB。除了远距离传输能力外,A7159内建的RSSI 可协助软件工程师侦测干净的传输信道,芯片内部的Auto Calibration机制,用来克服半导体制程的变异,可稳定地在各种环境下工作,自动频率补偿(AFC)的功能可解决RF频偏造成的灵敏度衰退。在数据的处理上,提供直接模式(Direct mode)与FIFO模式。直接模式适合MCU选用自行定义之封包格式,而FIFO模式则使用芯片内建之TXFIFO封包格式(含FEC,CRC与Manchester 编码等功能)。
适合A7159的应用非常多,比如AMR无线自动读表 (如无线热表,燃气表等等),远距离双向汽车防盗器,
工业控制
器 ,智慧建筑之能源管理,家庭
自动化
等等。尤其是由电池供应电源但需要长生命周期的应用。在电源管理部分,支持Deep sleep mode,Sleep,Idle mode 与WOR 模式 (Wake On RX), WOR功能提供A7159 自动唤醒,接收不定时的RF网络封包。Deep Sleep mode相当于完全关掉芯片,其电流消耗仅须100 nA。整体上,A7159是新一代高效能的射频芯片,具有极低接收电流,支持DSSS扩频模式,提供极远的传输距离,内建的电源管理功能可以延长电池的使用寿命。
此次调试的硬件模块原理图如下图所示:
从 datasheet 获知的 pin 脚定义如下图所示:
综上,针对该 A7159 模块,其留出的 10 pin 接口定义如下:
REGI 为电源输入脚,标准电压 3.3v
CKO 可复用的时钟输出脚
GIO2、GIO1 这两个脚是复用 pin 脚,可通过对 08 寄存器进行配置来选择 GIO2/GIO1 的功能 (参考 datasheet page 20)
SDIO 3线 SPI 输入输出 pin 脚
SCK SPI总线时钟引脚,空闲时为低电平
SCS SPI总线片选 pin 脚,低电平有效
A7159 支持 3 线 SPI 或 4 线 SPI 接口,默认是3线 SPI,若要支持 4 线 SPI,则需对 08h 寄存器page8进行配置,对应配置如下:
0x0059 GIO2=WTR, GIO1=SPI SDO
0x0045 GIO2=WTR, GIO1=FSYNC
3.基于 STM32 库的 GPIO 模拟 SPI 总线通信实现
该实现参考代理商提供的 demo 代码(demo 代码基于 51单片机实现)进行配置,在实现前要熟悉该芯片的 SPI 时序,才能正确进行通信。其读写时序图如下所示:
综上,从时序图来看,在 GPIO 模拟 SPI 总线通信要注意如下项:
1 SCS 片选脚低电平有效
2 SCK 空闲状态为低电平(即 CPOL = 0)
3 SDIO 在 SCK 第一个上升沿开始传输数据 (即 CPHA == 0)
4 数据从最高位开始传输(MSB)
5 SPI 通信最大支持 10MHz 时钟频率传输
6 读写命令的发送以及获取读写数据是在一次片选中完成的
具体实现参考SMT32 gpio 模拟 spi 总线通信代码。
4.基于 STM32 库的 SPI 控制总线通信实现
基于 GPIO 模拟 SPI总线注意事项,其 STM32 SPI控制总线初始化如下:
在实现如上初始化,进行 SPI 控制总线实现读写操作时,其并不能正常读取 A7159 0x00 处寄存器值。后经量波形调试发现关于 SPI控制总线实现读写通信时还要注意如下项:
1 在通过库函数 SPI_I2S_SendData(SPI1, TxData); 写数据后一定要加一个固定延时,再拉高 SCS 片选脚,以便 STM32 上的 SPI 控制总线在 SCS 拉高前输出对应时钟和数据。( SPI_I2S_SendData(SPI1, TxData);该函数只是将 8 位数据给写到 SPI DR数据寄存器中,此时硬件 SPI 控制总线并没有立刻发出时钟和数据,而是在一个固定时间后才输出对应时钟和数据的,那么在执行该发送数据的函数后一定要加延时,再拉高SCS,否则部分数据会在 SCS 被拉高的情况下发送,这样时序便不正常了)。
即代码发送数据到硬件响应是有个时间的,具体情况可根据波形图确定。
2 在读 A7159 寄存器值时,是先写“读寄存器命令”的,然后接收数据。在这里先写后读要看成一次操作,即在写“读寄存器命令”后,不能立刻拉高 SCS 片选脚,要保持一直拉低,紧接着进行读操作,才能正确的读出数据,这样也就和 datasheet 上的时序相对应了
具体实现参考 STM32 SPI 控制总线通信实现代码。
5.基于 IMX6UL linux驱动的 SPI 控制总线通信实现
linux 驱动实现 SPI 控制总线,其对 SPI 总线初始化配置同 STM32 SPI配置,只是彼此代码实现方式不同而已。其linux 驱动实现 SPI 控制总线读写时序要注意如下项:
1 由于 linux 驱动将 SPI 控制总线读和写操作分开了,即在写操作完成后立刻拉高 SCS 片选脚,读完成后立刻拉高 SCS 片选脚。因此,针对 A7159 设备,在写驱动时,SCS 片选脚就要自己另行配置,使其能满足 A7159 读时序。(即写完读命令后,SCS不做拉高,保持低电平进行读)
2 imx6ul 平台默认 SPI 时序为 54MHz,远大于 A7159 所支持的 10MHz,因而需要修改设备树,重新配置时序
3 正常情况,在 linux 中,将MISO 和MOSI短接,且在读写函数中分别将 tx_buff 和 rx_buff 置空,可实现 3线传输,但是 imx6ul 平台控制器驱动在 tx_buff 为空时,默认传输 0x00,因而在该平台调试时,将 A7159 配置成了 4线传输
4 在每次对 SPI 进行读写时均要初始化 spi_message ,从量出的波形来看,其耗时较长,因而将 SCS 片选脚的操作放在 spi_sync 函数前后,即在要发送数据前后操作。
5 从量出的波形来看,spi_sync函数执行时会等待硬件传输完数据后才执行下一步。因而在通过 spi_sync 函数进行写操作后无需延时
具体实现参考 A7159 linux驱动代码。
6.小结
设备与设备间的语言是“波形”,不管在什么平台实现,只要保证主设备与从设备通信的时序图与外设的datasheet要求的时序图一致,基本上就可以正常通信了。