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, 仍然可以读取到正确的数据, 这样 传输过程,即使 被 其他中断或者高级任务打断 ,依旧可以正确传输数据!

 

 

posted on 2025-07-10 18:07  所长  阅读(45)  评论(0)    收藏  举报

导航