嵌入式技术论坛
直播中

张国厚

8年用户 1472经验值
私信 关注
[问答]

用QSPI驱动W25Q256FV芯片但读写不正常求解?

最近项目用来了QSPI驱动W25Q256FV这款芯片。
由于SFUD有这款芯片的驱动,就找了bsp STM32l475-atk-pandora下的port
烧录后的现象是可以识别芯片,但是读写不正常。
然后就仔细检查了port文件:
有bug的是下面一段代码

void w25qxx_enter_qspi_mode(struct rt_qspi_device *device)
{
    char status = 0;
    /* 0x38 enter qspi mode */
    char instruction = 0x38;
    char write_status2_buf[2] = {0};
    /* 0x31 write status register2 */
    write_status2_buf[0] = 0x31;
    status = w25qxx_read_status_register2(device);
    if (!(status & 0x02))
    {
        status |= 1 << 1;
        w25qxx_write_enable(device);
        write_status2_buf[1] = status;
        rt_qspi_send(device, &write_status2_buf, 2);
        rt_qspi_send(device, &instruction, 1);
        rt_kprintf("flash already enter qspi mode
");
        rt_thread_mdelay(10);
    }
}
rt_qspi_send(device, &write_status2_buf, 2) 是明显有问题的,
修改成rt_qspi_send(device, write_status2_buf, 2);
本以为问题就解决了,但是没想到还一直有问题。
没办法,接上逻辑分析仪,看了下时许,
发现rt_qspi_send(device, write_status2_buf, 2)这句spi没有发送对应指令,这个指令是开启QSPI,问题应该在这里。
一开始没想是内核代码的问题,一追踪才发现,QSPI内核代码有这样的判断

if (length > 1)
{
        if (device->config.medium_size > 0x1000000 && length >= 5)
        {
            /* medium size greater than 16Mb, address size is 4 Byte */
            message.address.content = (ptr[1] << 24) | (ptr[2] << 16) | (ptr[3] << 8) | (ptr[4]);
            message.address.size = 32;
            message.address.qspi_lines = 1;
            count += 4;
        }
        else if (length >= 4)
        {
            /* address size is 3 Byte */
            message.address.content = (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
            message.address.size = 24;
            message.address.qspi_lines = 1;
            count += 3;
        }
        else
        {
            return -RT_ERROR;
        }
}
所以当length>1后,内核认为一定存在address,所以对于2-3长度的数据都不予处理,直接报错,
所以这rt_qspi_send(device, write_status2_buf, 2);这句直接报错返回了。
这显然是不合理的,先不说在send函数中做了逻辑判断。
关键是qspi发送就不应该有这个逻辑,个人理解这里应该qspi内核的一个bug。
这里rt_qspi_send(device, write_status2_buf, 2)对应的是如下时序,
2.jpg
也是开启芯片QSPI的方法。
至于为什么有的人可以驱动成功,我也查了一些资料,有人说W25Q256有JV和FV两种,JV不需要开启QSPI就可以用QSPI读取,而FV需要开启,不知道是不是这原因导致.
这边为了让驱动能正确运行,我临时修改了一点代码,只是临时解决下问题:

    if (length > 1)
    {
        if (device->config.medium_size > 0x1000000 && length >= 5)
        {
            /* medium size greater than 16Mb, address size is 4 Byte */
            message.address.content = (ptr[1] << 24) | (ptr[2] << 16) | (ptr[3] << 8) | (ptr[4]);
            message.address.size = 32;
            message.address.qspi_lines = 1;
            count += 4;
        }
        else if (length >= 4)
        {
            /* address size is 3 Byte */
            message.address.content = (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
            message.address.size = 24;
            message.address.qspi_lines = 1;
            count += 3;
        }else if(length == 2){
           message.address.content = 0 ;
           message.address.qspi_lines = 0;
           message.address.size = 0;
       }else
           return -RT_ERROR;
    }


回帖(1)

杨福林

2023-4-27 11:34:18
看完您这个问题,吓得我赶紧跟踪了一下我的代码,
发现的确如网页所述gd25q80c_enter_qspi_mode()内的rt_qspi_send的确数据根本就没发出去,我回读status2里的QE位也没有被置位,
就是FLASH根本就没有进去QUAD SPI模式,但奇怪的是我使用SFUD读写都正常啊
难道flash没进入qspi模式也能正常工作,可能这也是好多人没发现问题的原因
举报

更多回帖

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