本文简单介绍Zynq中的SPI控制器。本文将“master”称为“主机”;将“slave”称为“从机”;将“slave slect”从机选择简称为SS。
SPI控制器
Zynq中的SPI总线控制器能够与各种外设通信,如存储器、温度传感器、压力传感器、模拟转换器、实时时钟、任何支持串行模式的SD卡。SPI控制器可以工作在主机模式、从机模式、舵主模式。Zynq-7000系列包括2个SPI控制器。
- 主机模式:控制器驱动串行时钟(源自PS时钟系统)和从机选择信号。控制器有3个从机选择信号(Slave Select,简称SS),并且可以在外部扩展。控制器通过向32位的读/写数据端口寄存器写入字节,实现读取或写入从机设备。
- 从机模式:控制器接收来自外部设备的串行时钟,并使用SPI_Ref_Clk来同步数据捕获。从机模式包括一个可编程的启动检测机制,当SS信号有效时使能控制器。
- 多主模式:当控制器处于无效状态时,其输出信号是三态的;当控制器使能时,可以检测连接错误。通过复位SPI使能位,控制器输出将立刻转换为三态。
SPI I/O接口和软件之间有读、写FIFO,作为缓存。主机、从机I/O模式下都可使用FIFO。
控制器特性
每个SPI控制器可以独立配置,包括如下特性:
- 四线式总线:MOSI(主机输出-从机输入)、MISO(主机输入-从机输出)、SCLK、SS,主机模式下有3个从机选择信号;
- 全双工工作,支持同时接收和发送;
- 通过APB从接口的32位可编程寄存器;
- 将读/写数据映射到Rx/Tx FIFO,以字节为单位;
- 主机模式下,可选择手动或自动启动数据传输、手动或自动从机选择模式、从机选择信号可以直接与从机设备连接,也可以在外部做扩展(比如3-8译码器)、可编程的SS和MOSI延迟;
- 从机模式下,可编程的启动检测模式;
- 当SPI的I/O信号由MIO引脚引出时,SCLK为50MHz;由EMIO接口引出到PL管脚时,SCLK为25MHz;
- 可编程的时钟相位和极性;
- 可选择中断驱动或轮询状态。
系统框图
SPI控制器的系统框图如下,简单介绍一下各部分。
上图中有两个独立的SPI接口控制器,每个控制器的I/O信号可以路由(Routing)到MIO管脚或EMIO接口。每个控制器有单独的中断信号(中断ID 58和81)到PS中断控制器,还有单独的复位信号。每个控制器都有自己的一组控制寄存器和状态寄存器。
PS时钟子系统为SPI控制器提供一个参考时钟SPI_Ref_Clk,用于控制器的逻辑功能,再通过波特率发生器产生用于主机模式的SCLK。
功能模块框图
SPI控制器的功能模块框图如下所示:
简单介绍一下各部分:
- APB接口:32位,用于响应寄存器的读、写,处理数据端口和FIFO之间的读写命令和数据。数据端口以字节(即[7:0])为单位。
- SPI主机:此时控制器要驱动SCLK,并输出3个从机选择信号。MOSI信号上的从机选择和传输开始,可以在软件中手动控制,也可以由硬件自动控制。
- SPI从机:此时控制器只使用一个从机选择的输入信号(SS0)。SCLK与控制器的参考时钟(SPI_Ref_Clk)同步。
- Tx和Rx FIFO:每个FIFO都是128字节,软件使用寄存器映射后的数据端口寄存器来读、写FIFO。FIFO桥接了两个时钟域:APB接口和控制器的SPI_Ref_Clk。
主机模式
SPI I/O接口向从机发送数据,或者接收从机的数据。控制器一次只能选择一个从机设备。如果从机设备超过3个,可以使用3-8译码器,将3个从机选择信号扩展为8路。
1. 数据传输
发送:SCLK和MOSI信号由主机控制。软件把要传输的数据写入TxFIFO,由手动或自动的方式启动传输,数据驱动到MOSI(主输出-从输入)管脚上。只要TxFIFO中有数据便会连续传输。
接收:数据从MISO(主输入-从输出)管脚上串行接收数据,一次加载8bit到RxFIFO中,软件读取RxFIFO。每向TxFIFO写n字节数据,也会有n字节数据存储在RxFIFO中,软件必须读取完这些数据后才能开启下一次传输。
2. 自动/手动SS与启动
SPI I/O接口上的数据传输可以通过软件手动启动,也可以由控制器硬件自动启动。从机选择也可以由软件或硬件完成。
四种情况总结如下表:
软件中要通过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)的开始,有两种情况:
- 启用控制器时检测:如果在SS无效时使能了控制器,控制器将忽略数据,等待SCLK变为非活跃状态,然后捕获数据。SCLK不活跃时,控制器在SPI_Ref_Clk域中计数,达到设定值(可编程)时,便假定有一个新字(word)。
- SS有效时检测:启用控制器且SS被检测为无效时,当SS转为有效后,下一个SCLK的活跃边沿便被控制器认为是一个字的开始。
一个“开始”必须在至少4个SPI_Ref_Clk周期内保持有效状态。在外部主机“马上”开始数据传输的时候,才使能从机模式,这样会有概率(很小)发生同步错误的情况。
可以采用如下措施避免这个问题:
- 在使能从机模式后,确保至少10个SPI_Ref_Clk周期后外部主机才开始数据传输;
- 确保在使能了外部的主机模式后,再使能从机模式;
- 确保当使能从机时SS输入信号为无效状态。
控制器的FIFO
Rx和Tx FIFO各有128个字节深度。如果控制器试图将数据送入到一个已满的RxFIFO,该数据将会丢失,同时设置溢出(overflow)标志。如果TxFIFO已满,则不要向其写入更多数据。当TxFIFO的级别高于TxFIFO_Not_FULL的阈值级别时,会保持Tx_FIFO_FULL状态。如果我们向已满的TxFIFO写数据,该数据会丢失且不会发出任何指示(比如中断)。
上图展示两个FIFO各自的中断情况。
SPI协议详解
主机模式下,控制器支持几种不同的I/O信号关系,4种时钟相位(CLK_PH)和极性(CLK_POL)的配置组成了通常所说的4种SPI模式。不同的配置参数主要影响SCLK的活跃边沿、SS的选择、SCLK的空闲状态。
具体见下表(高电平无效,低电平有效):
如果以前没有专门了解过SPI协议,看到这个表可能头都要大了,我们结合下面的解释和时序图加深自己的理解(表头,将上表参数部分看作4×4的矩阵)。
- 当CLK_PH=0时,设定的一段时间内,主机设备自动驱动SS输出为无效状态(表[3,1]与[3,2]),最小保持2个SPI_Ref_Clk的周期。两个字间有最短3个SPI_Ref_Clk周期的延迟,这段延迟内卸载(unload)TxFIFO,为下一次并-串转换做准备,并将SS切换为无效。
- 当CLK_PH=1时,字之间的SS输出信号仍保持有效状态(表[3,3]和[3,4])。两个字之间的最小延迟可达1个SPI_Ref_Clk周期,同样会卸载(unload)TxFIFO,为下一次并-串转换做准备。
下面看CLK_PH=0时的时序图。以POL=0为例,“驱动边沿”是指下降沿(表[1,1])处驱动bit间的切换,“采样边沿”是指上升沿处(表[2,1])对信号采样,此时正好位于数据中央。POL=1时,恰好相反(表[1,2]和[2,2])。
下面看CLK_PH=1的时序图,情况如上类似(表[1,3]、[1,4]、[2,3]、[2,4])。
SPI还有一种“背靠背(back-to-back)”传输模式,即连续传输字(word),时序见下图:
看到CLK_PH=0时,字间SS会有短暂的无效状态;而CLK=1时,SS持续有效。
SPI信号路由
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的具体设计实例。