SPI 高速全双工通信总线
SPI有四根线:
SDO:数据输出-主设备数据输出,从设备数据输入
SDI:数据输入-主设备数据输入,从设备数据输出
SCLK:时钟信号-由主设备产生
CS:片选信号,主设备控制
这是一个主机的通讯时序。NSS、SCK、MOSI信号都由主机控制产生,而MISO的信号由从机产生,主机通过该信号线读取从机的数据。MOSI与MISO的信号只在NSS为低电平的时候才有效,在SCK的每个时钟周期MOSI和MISO传输一位数据。
观察图中的标号处,MOSI及MISO的数据在SCK的上升沿期间变化输出,在SCK的下降沿时被采样。即在SCK的下降沿时刻,MOSI及MISO的数据有效,高电平时表示数据“1”,为低电平时表示数据“0”。在其它时刻,数据无效,MOSI及MISO为下一次表示数据做准备。
SPI每次数据传输可以8位或16位为单位,每次传输的单位数不受限制。
SPI的四种模式
时钟极性CPOL是指SPI通讯设备处于空闲状态时,SCK信号线的电平信号(即SPI通讯开始前、 NSS线为高电平时SCK的状态)。CPOL=0时, SCK在空闲状态时为低电平,CPOL=1时,则相反。
时钟相位CPHA是指数据的采样的时刻,当CPHA=0时,MOSI或MISO数据线上的信号将会在SCK时钟线的“奇数边沿”被采样。当CPHA=1时,数据线在SCK的“偶数边沿”采样。
四种模式是组合而来:
第一步是时钟极性CPOL决定空闲时的时钟线是高电平还是低电平,有个两种情。
第二步时钟相位CPHA决定数据线上的信号将会在奇数边沿或是偶数边沿采样,有两种情况。
上述情况合在一起共有四种SPI模式
以上介绍的是经典SPI协议的内容,这种也被称为标准SPI协议(Standard SPI)或单线SPI协议(Single SPI),其中的单线是指该SPI协议中使用单根数据线MOSI进行发送数据,单根数据线MISO进行接收数据。
为了适应更高速率的通讯需求,半导体厂商扩展SPI协议,主要发展出了Dual/Quad/Octal SPI协议,加上标准SPI协议(Single SPI),这四种协议的主要区别是数据线的数量及通讯方式,具体见表格 22‑1。
扩展的三种SPI协议都是半双工的通讯方式,也就是说它们的数据线是分时进行收发数据的。例如,标准SPI(Single SPI)与双线SPI(Dual SPI)都是两根数据线,但标准SPI(Single SPI)的其中一根数据线只用来发送,另一根数据线只用来接收,即全双工;而双线SPI(Dual SPI)的两根线都具有收发功能,但在同一时刻只能是发送或者是接收,即半双工,四线SPI(Quad SPI)和 八线SPI(Octal SPI)与双线SPI(Dual SPI)类似,只是数据线量的区别。
扩展的SPI协议还增加了SDR模式(单倍速率Single Data Rate)和DDR模式(双倍速率Double Data Rate)。例如在标准SPI协议的SDR模式下,只在SCK的单边沿进行数据传输,即一个SCK时钟只传输一位数据;而在它的DDR模式下,会在SCK的上升沿和下降沿都进行数据传输,即一个SCK时钟能传输两位数据,传输速率提高一倍。
RT1050的FlexSPI就是针对SPI协议设计的一个超级灵活SPI外设,现在也将FlexSPI应用在NXP新产品,用于高速访问片外存储器。
FlexSPI外设包含有A/B两组SPI通讯接口,即图 22‑5中第①部分IO_CTL(IO控制逻辑)引出的“SPI Bus FA port”和“SPI Bus FB port”。每组接口最多可外接2个设备,即A1、A2、B1和B2,具体引脚说明可查阅《IMXRT1050RM》(参考手册),以它为准。
访问FLASH存储器通常包含一些读写功能的的控制指令,主控设备可通过这些指令访问FLASH存储器。
为了适应这种需求,FlexSPI外设中包含有一个指令查找表LUT(Look Up Table),即图 22‑5中第②部分SEQ_CTL(序列控制逻辑)的主要内容,它用来预存储访问外部设备时可能使用到的指令,需要对FLASH进行访问时,FlexSPI会从查找表LUT中获取相应的指令然后通过SPI接口对FLASH发起通讯。
该图中的第①部分是查找表LUT视图,它表示查找表LUT有0~N个序列;第②部分是序列视图,它表示1个序列中包含有8个指令;第③部分是指令视图,表示指令由opcode(指令编码)、num_pads(数据线的数目)、operand(指令参数)三个寄存器域构成。这些指令的存储位置是FlexSPI外设中的寄存器LUT0~LUT63,每个LUT寄存器可以缓存2个指令,即1个指令序列(8个指令)由4个寄存器构成,这些寄存器构成了一个完整的LUT表。
LUT寄存器的各个域说明如下:
OPCODE:指令编码,这是由FlexSPI定义的一些基本指令码,如向FLASH发送控制命令的CMD_SDR指令OPCODE为0x01;发送行地址到FLASH的指令OPCODE为0x02,诸如此类。
NUM_PADS:进行SPI通讯时使用的数据线的数目,它的可用参数为:
0x0:Single模式
0x1:Dual模式
0x2:Quad模式
0x3:Octal模式
OPERAND:指令参数,部分OPCODE指令包含参数,这些参数就由OPERAND设定,参数的具体作用由相应的OPCODE决定。
值得注意的内容说明如下:
1. 数据线的数目由NUM_PADS指定。不同的指令可以通过它自身的NUM_PADS域来指定,因此不同指令可以使用不同的数据线数目。在应用中一些FLASH存储器的命令只使用一根数据线(Single模式),而快速读写的命令则可支持Dual、Quad模式,此时针对命令使用不同的NUM_PADS进行定制即可。
2. OPERAND参数在不同指令下作用不同:
对于CMD_SDR指令,它的功能是向FLASH发送命令代码,此时要发送的FLASH命令代码就是CMD_SDR指令的参数,即由OPERAND域指定(请注意区分FLASH命令和OPCODE)。例如W25Q256型号的FLASH的读取ID命令代码为0xAB,当RT1052要读取FLASH的ID时,利用CMD_SDR指令同时把命令代码0xAB赋予到OPERAND域,这样FlexSPI控制的时候就会通过SPI接口把FLASH命令0xAB发送出去了。
图 22‑5中第③部分是ARB_CTL(仲裁器逻辑),它主要用来决定执行哪一套命令。在其后有一个AHB_CTL(AHB命令控制逻辑)和IP_CTL(IP命令控制逻辑),它们分别代表了内核对FlexSPI的两种控制方式 ,该仲裁器逻辑就是决定它们谁拥有对前面逻辑单元(SEQ_CTL和IO_CTL)的控制权。
图 22‑5中第④部分IP_CTL是IP命令控制逻辑,它包含IP_RX_FIFO和IP_TX_FIFO用来缓冲收发的数据,它们均为16*64Bits大小。IP_CTL连接至32位的ARM IP总线,通过它可以向ARB_CTL(仲裁器逻辑)发送控制命令,从而利用FlexSPI访问外部SPI设备。IP命令实际上就是内核通过访问外设寄存器的方式控制外设,FlexSPI外设的寄存器大都是为这种控制方式服务的,包括IP_RX_FIFO和IP_TX_FIFO都是以寄存器的形式提供给用户进行访问,这种方式其实与前面的GPIO、LPI2C、LPUART等外设的控制方式一样,这样命名主要是为了与后面的AHB命令方式进行区分。
IP命令的控制流程如下:
往IP_TX_FIFO填充要传输的数据;
通过IPCR0寄存器设置要写入的FLASH内部存储单元的首地址,要传输的数据大小以及要执行的LUT命令序列的编号;
对寄存器IPCMD的TRG位置1触发FlexSPI访问;
检查寄存器INTR的IPCMDDONE位以等待至FlexSPI外设执行完该指令;
若执行的命令序列有会接收数据,那么接收到的数据会被缓存至IP_RX_FIFO中。
⑤部分AHB_CTL是AHB命令控制逻辑,它包含有128*64Bits大小的AHB_RX_BUF和8*64Bits大小的AHB_TX_BUF用来缓冲收发的数据,AHB_CTL连接至64位的AHBP总线,通过它可以向ARB_CTL(仲裁器逻辑)发送控制命令,从而FlexSPI访问外部SPI设备。
使用AHB命令的方式是直接访问RT1052内部的0x600 0000-0x1000 0000地址,对这些地址的读写访问会触发FlexSPI产生SPI控制时序,然后对连接的FLASH内部存储单元进行读写,这种功能称为地址映射。
例如可以把外部NOR Flash存储器的内部地址0x0映射到RT1052的0x60000000地址,初始化好FlexSPI后,当我们直接使用指针读取RT1052的0x60000000地址的内容时,会自动触发FlexSPI外设访问外部的NOR Flash存储器的0x0地址获得数据,访问时它会自动使用AHB_RX_BUF及AHB_TX_BUF缓冲数据。
AHB命令仅支持对FLASH存储单元的读写访问,对FLASH存储器的工作模式或状态寄存器的读取需要使用IP命令实现。
特别地,对IP命令的两个FIFO也可以通过地址映射来访问,其中 IP_RX_FIFO映射至0x7FC00000 -0x10000200地址,而IP_TX_FIFO映射至0x7F800000 -0x11000400地址。