本文整理自22. FlexSPI—读写外部SPI NorFlash — [野火]i.MX RT库开发实战指南——基于i.MXRT1052 文档
用作个人学习和分享
指令查找表LUT
访问FLASH存储器通常包含一些读写功能的的控制指令,主控设备可通过这些指令访问FLASH存储器。
为了适应这种需求,FlexSPI外设中包含有一个指令查找表LUT(Look Up Table),即图 22‑5中第②部分SEQ_CTL(序列控制逻辑)的主要内容,它用来预存储访问外部设备时可能使用到的指令,需要对FLASH进行访问时,FlexSPI会从查找表LUT中获取相应的指令然后通过SPI接口对FLASH发起通讯。
该表使用序列的形式缓存指令,最多支持16个指令序列,每个序列最多支持8个指令。例如,在某序列中缓存指令C1、C2、C3…,当控制执行该序列时,指令C1、C2、C3…会被按顺序执行。
查找表LUT的构成
查找表LUT的构成具体见图
该图中的第①部分是查找表LUT视图,它表示查找表LUT有0~N个序列;第②部分是序列视图,它表示1个序列中包含有8个指令;第③部分是指令视图,表示指令由opcode(指令编码)、num_pads(数据线的数目)、operand(指令参数)三个寄存器域构成。这些指令的存储位置是FlexSPI外设中的寄存器LUT0~LUT63,每个LUT寄存器可以缓存2个指令,即1个指令序列(8个指令)由4个寄存器构成,这些寄存器构成了一个完整的LUT表。
LUT寄存器的构成
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决定。
常用指令说明
指令名称 | OPCODE | NUM_PADS | SPI接口发送的内容 | Bits/Bytes/ Cycle的数目 |
---|---|---|---|---|
CMD_SDR/ CMD_DDR | 0x01/0x21 | 0:Single模式 1:Dual模式 2:Quad模式 3:Octal模式 | 发送控制FLASH的命 令代码到FLASH存储 器,即OPERAND [7:0]的内容 | Bits数目:固定为8 |
RADDR_SDR /RADDR_DDR | 0x02/0x22 | 发送行地址到FLASH , AHB命令模式: 由访问的AHB 地址决定; IP命令模式: 由IPCR0寄存器决定 | Bits数目:OPER AND [7:0],即由它指定 地址的位数 | |
WRITE_SDR/ WRITE_DDR | 0x08/0x28 | 发送要写入的数据到FL ASH, 即AHB_TX_BUF 或IP_TX_FIFO 的数据 | Bytes数目,即要传 输的字节数: AHB命令模式: 由AHB突发大小和突发 类型决定 IP命令模式: 由IPCR1.DATS Z寄存器域决定 | |
READ_SDR/ READ_DDR | 0x09/0x29 | 从FLASH接收数据, 收到的数据会被存储到A HB_RX_BUF或I P_RX_FIFO | ||
DUMMY_SDR/ DUMMY_DDR | 0x0C/0x2C | FlexSPI释放对数 据线的控制,时钟信号正 常驱动。这种指令通常是 FLASH设备要求的空 操作等待 | Cycle数目,即DU MMY周期的个数(即S CK的周期数): OPERAND [7:0],由它指定发 送多少个DUMMY周期 | |
STOP | 0x00 | 固定为0,即Singl e模式 | 停止执行,释放CS片选 信号,不发送内容 | SPI接口无数据传输 |
此处对该表中特别值得注意的内容说明如下:
-
查找表支持两套有同功能不同模式的指令。例如CMD_SDR和CMD_DDR的OPCODE为0x01和0x21,它们分别表示使用SDR模式和DDR模式的CMD指令,它们的功能一样,都是向FLASH发送命令代码。其它指令类似,大都有SDR和DDR模式。
-
数据线的数目由NUM_PADS指定。不同的指令可以通过它自身的NUM_PADS域来指定,因此不同指令可以使用不同的数据线数目。在应用中一些FLASH存储器的命令只使用一根数据线(Single模式),而快速读写的命令则可支持Dual、Quad模式,此时针对命令使用不同的NUM_PADS进行定制即可。
-
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发送出去了。
-
对于RADDR_SDR指令,它的功能是向FLASH发送要读写的存储单元地址,该地址由IPCR0寄存器指定,同时OPERAND域用于指定地址的长度。例如部分FLASH的空间比较小,只使用16位来表示地址,那么该命令的OPERAND域的值就应为16,对于W25Q256这种地址为24或32位的存储器,OPERAND域的值就应设置为24或32。
-
对于DUMMY_SDR指令,它的功能是释放FlexSPI对数据线的控制,而时钟正常运行,该指令是针对FLASH存储器的部分时序要求,这时FLASH存储器会忽略数据线上的内容,实质它是要求主机进行等待,在这种情况下可通过OPERAND指定该过程要占多少个SCK的周期数。
-
数据传输指令的数据缓冲区位置分两种情况。WRITE_SDR和READ_SDR指令分别用于向FLASH写入和读取数据,这些指令传输的数据缓冲位置如下:
-
在AHB命令模式下:数据缓存在AHB_TX_BUF(发送缓冲区)以及AHB_RX_BUF(接收缓冲区)中,此时要传输的字节数由AHB突发传输的大小和类型决定。
-
在IP命令模式下:数据缓存在IP_TX_FIFO(发送缓冲区)以及IP_RX_FIFO(接收缓冲区)中,此时要传输的字节数可通过寄存器IPCR1的DATSZ域指定。
-
操作通常使用序列的形式并配合STOP指令(停止指令)使用:以上说明的各个指令通常不会单独执行,而是组成一个指令序列,对于指令数不满8个的序列,需要使用STOP指令表示结束。例如一个使用IP命令模式的读取操作中,通常会使用以下的指令序列:
-
使用CMD_SDR指令向发送FLASH的读取命令,如W25Q256的Quad模式读取命令编码为0x6B,此时CMD_SDR指令的OPERAND域为0x6B;
-
使用RADDR_SDR指令发送要读取的FLASH存储单元地址,OPERAND域的值为24表示使用24位的地址,而地址具体的值由寄存器IPCR0设定;
-
按照FLASH的Quad模式读取命令的要求发送占8个SCK时钟的DUMMY操作,此时使用DUMMY_SDR指令且OPERAND域的值设置为8;
-
使用READ_SDR指令,开始接收FLASH的数据到IP_RX_FIFO中,要读取的字节数由寄存器IPCR1的DATSZ域指定;
-
由于使用的指令不足8个字节,在该序列的最后使用STOP指令表示停止,当FlexSPI执行到STOP指令时,会释放SPI的片选信号CS,结束通讯。