本文简单介绍Zynq中的SPI控制器。本文将“master”称为“主机”;将“slave”称为“从机”;将“slave slect”从机选择简称为SS。
Zynq中的SPI总线控制器能够与各种外设通信,如存储器、温度传感器、压力传感器、模拟转换器、实时时钟、任何支持串行模式的SD卡。SPI控制器可以工作在主机模式、从机模式、舵主模式。Zynq-7000系列包括2个SPI控制器。
SPI I/O接口和软件之间有读、写FIFO,作为缓存。主机、从机I/O模式下都可使用FIFO。
每个SPI控制器可以独立配置,包括如下特性:
SPI控制器的系统框图如下,简单介绍一下各部分。
上图中有两个独立的SPI接口控制器,每个控制器的I/O信号可以路由(Routing)到MIO管脚或EMIO接口。每个控制器有单独的中断信号(中断ID 58和81)到PS中断控制器,还有单独的复位信号。每个控制器都有自己的一组控制寄存器和状态寄存器。
PS时钟子系统为SPI控制器提供一个参考时钟SPI_Ref_Clk,用于控制器的逻辑功能,再通过波特率发生器产生用于主机模式的SCLK。
SPI I/O接口向从机发送数据,或者接收从机的数据。控制器一次只能选择一个从机设备。如果从机设备超过3个,可以使用3-8译码器,将3个从机选择信号扩展为8路。
发送:SCLK和MOSI信号由主机控制。软件把要传输的数据写入TxFIFO,由手动或自动的方式启动传输,数据驱动到MOSI(主输出-从输入)管脚上。只要TxFIFO中有数据便会连续传输。
接收:数据从MISO(主输入-从输出)管脚上串行接收数据,一次加载8bit到RxFIFO中,软件读取RxFIFO。每向TxFIFO写n字节数据,也会有n字节数据存储在RxFIFO中,软件必须读取完这些数据后才能开启下一次传输。
SPI I/O接口上的数据传输可以通过软件手动启动,也可以由控制器硬件自动启动。从机选择也可以由软件或硬件完成。四种情况总结如下表:
手动SS | 手动启动 | 说明 |
---|---|---|
1 | 1 | 软件控制从机选择,必须发出开始串行化数据的命令 |
1 | 0 | 软件控制从机选择,当TxFIFO中有数据时,控制器硬件自动开始串行化数据 |
0 | 1 | 控制器硬件控制从机选择,但软件必须发出开始串行化TxFIFO中数据的命令,适用于发送小块数据的应用 |
0 | 0 | 控制器硬件控制从机选择,TxFIFO中有数据时自动开始串行化 |
软件中要通过Tx/Rx FIFO的阈值级别来避免FIFO中数据不够或溢出。当TxFIFO中的字节数小于TxFIFO阈值级别时,标记TxFIFO Not Full状态;当RxFIFO中的字节数达到128时,标记RxFIFO Full状态。
控制器接收来自外部主机的数据,同时输出一个应答。SCLK锁存MOSI(输入)信号上的数据。如果SS(输入)信号为无效状态,控制器便忽略MOSI上的输入。当SS有效时,在传输期间必须持续保持有效状态。如果传输过程中SS变为无效,控制器会发出中断,以提醒用户。
软件把要发送给主机的数据写入TxFIFO中,然后控制器将其串行化到MISO信号上。当TxFIFO中有数据且SS信号持续有效时,将保持传输状态。SS输入管脚必须由SCLK输入同步驱动。控制器工作在SPI_Ref_Clk时钟域,输入信号也是在SPI_Ref_Clk域中同步并进行分析。
从机模式在SPI_Ref_Clk时钟域中检测一个字(word)的开始,有两种情况:
一个“开始”必须在至少4个SPI_Ref_Clk周期内保持有效状态。在外部主机“马上”开始数据传输的时候,才使能从机模式,这样会有概率(很小)发生同步错误的情况。可以采用如下措施避免这个问题:
Rx和Tx FIFO各有128个字节深度。如果控制器试图将数据送入到一个已满的RxFIFO,该数据将会丢失,同时设置溢出(overflow)标志。如果TxFIFO已满,则不要向其写入更多数据。当TxFIFO的级别高于TxFIFO_Not_FULL的阈值级别时,会保持Tx_FIFO_FULL状态。如果我们向已满的TxFIFO写数据,该数据会丢失且不会发出任何指示(比如中断)。
上图展示两个FIFO各自的中断情况。
主机模式下,控制器支持几种不同的I/O信号关系,4种时钟相位(CLK_PH)和极性(CLK_POL)的配置组成了通常所说的4种SPI模式。不同的配置参数主要影响SCLK的活跃边沿、SS的选择、SCLK的空闲状态。具体见下表(高电平无效,低电平有效):
PH=0, POL=0 | PH=0, POL=1 | PH=1, POL=0 | PH=1, POL=1 | |
---|---|---|---|---|
驱动边沿 | 下降沿 | 上升沿 | 上升沿 | 下降沿 |
采样边沿 | 上升沿 | 下降沿 | 下降沿 | 上升沿 |
字间的SS状态 | 无效 | 无效 | 有效 | 有效 |
字外的SCLK状态 | 有效 | 有效 | 无效 | 无效 |
如果以前没有专门了解过SPI协议,看到这个表可能头都要大了,我们结合下面的解释和时序图加深自己的理解(表头,将上表参数部分看作4×4的矩阵)。
SPI接口信号可以路由到MIO管脚(50MHz)或EMIO接口(25MHz)。使用EMIO接口时,用户必须在PL部分创建逻辑,将SPI EMIO接口直接连到PL管脚上的I/O Buffer。
用于可以连接每个SPI控制器和外部的SPI从机设备。在主机模式下,如果不使用SS0信号,则必须将其连接到VCC。这是因为主机模式下,控制器会检查这个信号以判断是否是多主机模式。如果SS0为逻辑低,控制器会假设为多主机模式,发出命令前会一直等待SS0变为无效。
路由到MIO的主机模式框图如下,SS信号直接相连的情况下,最多可以连接3个从机设备:
路由到EMIO的主机模式框图如下,确保使能了PS-PL电压电平转换器,且为PL提供电源和配置,否则SPI控制器将无法工作:
路由到MIO的从机模式框图如下:
将SPI接口路由到MIO接口时的配置很简单,配置ZYNQ IP核,选择MIO管脚即可。路由到EMIO则有点麻烦,很多人看到这么多信号可能都懵了,我的天,不应该只有简简单单的SCLK、MOSI、MISO、SS0、SS1、SS2共6根线就够了吗?
在EMIO接口上可用的SPI I/O接口信号虽然只有6“种”,但绝不是6“根”,很多信号都有3态接口。以SPI 0为例,14根信号如下表所示(一般我们不会全部用到):
本文简单介绍了Zynq种的SPI控制器、支持的SPI协议以及如何路由到MIO或EMIO。后面文章给出各种SPI的具体设计实例。