RISC-V技术论坛
直播中

剪刀脚

9年用户 931经验值
私信 关注
[问答]

把qspi0配置成了普通的fifo模式,读什么都返回0xff,这是怎么回事?

我把qspi0配置成了普通的fifo模式,不是xip模式,但是现在读什么都返回0xff,读id也返回0xff,也不是没有数据,RXDATA寄存器里是有数据的,但是就是0xff,这是怎么回事?

回帖(1)

张生

2025-11-7 17:28:39

你的QSPI0在FIFO模式下读取始终返回0xFF,即使RXDATA寄存器有数据(但值为0xFF),这通常表示QSPI设备未正确响应或通信链路存在问题。以下是可能原因和解决方案:


一、硬件问题排查




  1. 物理连接检查  



    • 确认CLK、CS#、D0-D3等信号线连接正常,无短路/断路。

    • 用示波器或逻辑分析仪检查:

      • CLK信号:是否有时钟输出?频率是否在设备支持范围内(初始调试建议降低频率)。

      • CS#信号:传输时是否拉低?结束后是否拉高?

      • 数据线波形:发送命令时是否有数据输出?接收阶段是否全为高电平(0xFF)?





  2. 设备状态验证  



    • 确认Flash芯片供电正常(测量VCC电压)。

    • 检查Flash是否处于深度睡眠(Deep Power-Down)写保护状态(需发送唤醒命令如0xAB或写使能0x06)。




二、软件配置关键点




  1. 时序配置错误  



    • 检查时钟分频系数:过高频率可能导致通信失败(尝试降低时钟分频比)。

    • 确认采样边沿(CPHA/CPOL)与设备要求一致(通常Mode 0或Mode 3)。




  2. 传输格式配置  



    • 指令阶段:是否发送了正确的命令(如读ID命令0x9F)?

    • 地址/数据阶段

      • 地址长度是否匹配设备要求(读ID通常无需地址)。

      • 接收数据长度是否设置正确(如读ID需读取3字节)。


    • 空周期(Dummy Cycles):部分设备需要额外时钟周期(如读数据需4-8个dummy cycles)。




  3. FIFO控制逻辑  



    • 在发起传输前,清空RX FIFO(避免残留数据干扰)。

    • 发送命令后检查状态寄存器

      • 是否传输完成(TX/RX完成标志)?

      • 是否有错误标志(FIFO下溢/超时)?





三、关键调试步骤




  1. 发送唤醒命令

    尝试发送唤醒指令(如Release from Deep Power-Down):


    // 示例:发送唤醒命令 0xAB 并等待
    QSPI->DR = 0xAB;          // 写入指令
    while (!(QSPI->SR & TX_EMPTY)); // 等待发送完成
    delay_ms(10);             // 等待设备唤醒



  2. 简化测试(单线模式)

    初始调试建议切回单线SPI模式,降低复杂度:


    // 设置单线模式(仅用D0)
    QSPI_CR |= SPI_ONLY_MODE | DATA_WIDTH_1BIT;



  3. 尝试读取状态寄存器

    设备状态寄存器(Status Register)通常更易读取(命令0x05):


    // 发送读状态寄存器命令
    send_command(0x05);      // 发送命令0x05
    uint8_t status = read_byte(); // 读取1字节
    // 正常值应不为0xFF(如0x00或0x02)



  4. 检查片选信号控制  



    • 确认CS#信号由硬件自动管理(配置为自动片选)。

    • 若使用手动GPIO控制CS#,确保在传输前拉低、完成后拉高。




四、典型配置示例(伪代码)


// 1. 初始化QSPI控制器
QSPI_CR = 0; // 复位配置
QSPI_CR |= CLK_DIV_8;      // 降低时钟频率
QSPI_CR |= SPI_MODE_0;     // CPOL=0, CPHA=0
QSPI_CR |= AUTO_CS;        // 自动片选

// 2. 配置读ID命令格式
QSPI_TFR = (0x9F << CMD_OFFSET) |    // 指令=0x9F
           (0 << ADDR_OFFSET) |      // 地址长度=0
           (3 << DATA_OFFSET) |      // 接收3字节数据
           (0 << DUMMY_OFFSET);      // 无空周期

// 3. 触发传输
QSPI_CR |= START_TRANSFER;

// 4. 等待完成并读取数据
while (!(QSPI_SR & RX_NOT_EMPTY)); // 等待RX FIFO非空
uint8_t id1 = QSPI_DR;             // 读Manufacturer ID(应非0xFF)
uint8_t id2 = QSPI_DR;             // Device ID
uint8_t id3 = QSPI_DR;

五、其他可能原因



  • 寄存器映射错误:检查QSPI寄存器基地址是否正确(核对芯片手册)。

  • 总线冲突:确认其他设备未占用相同总线(尤其是多片选场景)。

  • 驱动能力不足:增加信号线上拉电阻(通常4.7kΩ)。



总结:优先用示波器检查CLK/CS#/D0信号,确保物理层通信正常。若硬件无异常,逐步检查时序配置、命令格式和FIFO控制逻辑,从单线模式开始简化调试。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分