zynq qspi 传输方式研究
总结放在前面:
1、CS 使用 手动模式, 因为 在 写TX FIFO过程中,被别的线程或者中断打断, 填充 TX FIFO 的速度小于 QSPI 传输速度,则会导致,CS自动模式下,会自动拉高,导致 后续数据 读写失败,因为CS拉高 , FLASH 认为上一个命令 完成了,所以失败;
2、if mod ,CR的31位,要设为 0, 如果设置为1则会根据第一个字节的命令 ,修改 传输在总线上的数据,比如 03 读取数据时,第5-后续 都会是0, 这会导致 4字节地址 不能使用,超过 16MB 的 FLASH 不能使用 ;
3、TX FIFO 和 RX FIFO 阈值 设定为1,这样可以根据状态寄存器 ,来判断 FIFO 是否存在数据;
4、使用 1字节,2字节,3字节,4字节 填充 TX FIFO 时, 优先使用 4字节 填充, 最后剩余的 使用 1、2、3字节传输, 但是要等 TX FIFO 清空后,再 使用 1、2、3 字节 填充;
5、 使用 1、2、3 字节填充 TX_FIFO 时, 对应的 RX FIFO 也要 右移 1字节需要右移 24bit, 2字节 需要 右移 16bit , 3字节 需要 右移 8bit;
我的配置如下,仅供参考:
bsp_qspi read_module_id:0x1090101. bsp_qspi cfg.reg:0xA44D1. bsp_qspi delay.reg:0x0. bsp_qspi gpio.reg:0x1. bsp_qspi interrupt_disable.reg:0x0. bsp_qspi interrupt_enable.reg:0x0. bsp_qspi interrupt_mask.reg:0x0. bsp_qspi interrupt_status.reg:0x4. bsp_qspi loopback_delay.reg:0x20. bsp_qspi lqspi_cfg.reg:0x0. bsp_qspi lqspi_sr.reg:0x0. bsp_qspi rx_fifo_threshold.reg:0x1. bsp_qspi tx_fifo_threshold.reg:0x1.
1、ZYNQ QSPI 特点
- TX FIFO 63 字;
- RX FIFO 63 字;
- TX FIFO 填充数据后,可以自动触发传输,也可以手动触发;
- cs 使能脚,可以手动控制,也可以自动控制;
- 支持线性地址模式;
- 支持 FIFO 阈值设定,取值范围 0-63;
- 支持 中断,具体详看中断寄存器;
2、框图
3、发送数据有4种方式
1、单独传输1个字节,使用寄存器 XQSPIPS_TXD_01_OFFSET, 同时 接收寄存器,需要 右移 24位,才是接收的数据;
2、单独传输2个字节,使用寄存器 XQSPIPS_TXD_10_OFFSET, 同时 接收寄存器,需要 右移 16位,才是接收的数据;
3、单独传输3个字节,使用寄存器 XQSPIPS_TXD_11_OFFSET, 同时 接收寄存器,需要 右移 8位,才是接收的数据;
4、单独传输4个字节,使用寄存器 XQSPIPS_TXD_00_OFFSET, 同时 接收寄存器,不需要右移;
注意: 经过我测试,上面4种方式 可以 一起使用!但是要注意使用方法,详细看 :https://i.cnblogs.com/posts/edit;postId=18977482
1、可以选择 混合使用,具体看 :https://i.cnblogs.com/posts/edit;postId=18977482
2、可以选择,只使用 4字节发送,不够4字节时,补充 0xFF;
因此读取 17个字节时,命令+地址4个字节, 读取数据长度17个字节 ,应该传输 21 字节,但是因为 FIFO 传输的问题,需要多传输3个字节 ,结果如下:
注意 这里有个奇怪的现象,除了最开始的4个字节 03 00 00 00, 其他的 20个字节应该是 0xFF, 但是实际是 0x00, 可能QSPI 底层给改了!
原因; XQSPIPS_CR_IFMODE_MASK =1 则 会识别 第一个传输字节
// 0: legacy SPI mode ; 1: Flash memory interface mode;
// This control is required to enable or disable automatic recognition of instruction bytes in the first byte of a transfer.
// If this mode is disabled, the core will operate in standard SPI mode, with no dual- or quad-bit
// input or output capability; the extended bits will be configured as inputs to prevent any
// driver contention on these pins. If enabled, flash memory interface instructions
// are automatically recognized and the I/O configured accordingly.
在使用 5A 命令时, 没有改成0, 实测如下:
使用 02 写入命令时,也没有更改:
注: 多写的 0xFF 会不会影响 后面的 数据 , 目前测试不会,因为 FLASH 只能把1写0,不能 把0写成1, 这也是利用 的 FLASH 的 特性!!!
4、擦除一个扇区 , 4KB , 耗时 26ms
5、寄存器表格
5、使用 自动控制 CS模式(填充FIFO的速度小于传输速度时,CS会拉高) , 读取 FLASH 数据 ,使用 vTaskDelay延迟模拟打断行为,CS中间会拉高,会导致后续数据传输失败,因此 采用手动控制 CS 方式, 可以有效解决这个问题!
总结: QSPI FLASH , 在读取或者写入时, 只要 cs 没有拉高, 传输 中间 被中断,也可以 成功传输数据;
测试过程: 传输4个字节,中间间隔 1ms, 仍然可以读取到正确的数据, 这样 传输过程,即使 被 其他中断或者高级任务打断 ,依旧可以正确传输数据!