打印
[技术问答]

M484 QPI之坑

[复制链接]
678|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
apleilx|  楼主 | 2020-4-11 15:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
pi, spi, AD, ui, DSP
本帖最后由 apleilx 于 2020-4-11 15:27 编辑

自己做了个M484挂接 SPI-NOR 和 SPI-NAND的评估板,研究下spi- falsh 操作方法。

之前有个板载spi-nor的GD32的板子只有SPI模式,SPI时钟24MHz,连续读取平均 2.4MB/s。

这次的M484,CPU主频192MHz,SPI时钟同样设为24MHz。


先用SPI模式,8bits数据位宽,无论怎么调连续读只能达到,1.1MB/s。
后来读数据时将SPI改为32bits模式,可以达到2.07MB/s,但这种情况其他配置不变,开启字节排序功能后立刻又变为1.1MB/s。十分诡异。

然后测QPI模式,一开始用8位宽,最高只能 2.1MB/s。
改用32bits位宽后,可以到4.4MB/s,同样其他配置不变,如果开启字节排序功能速度立马变为2.1MB/s。

SPI和QPI模式软件开销上只是多了两句寄存器修改,其他一样,QPI理论速度应该是SPI模式3倍以上,实际只有两倍左右,比较费解。


至此已经无能为力了,本来以为24MHz时钟QPI可以达到10MB/s以上的,结果只实现了不到一半的速度。

另外SPI-NAND 添加 lut 只调到了3.8MB/s。 一般用倒可以用,但是没调到理想的效果,不知道问题出在哪里,还望知道其中奥秘的大神不吝赐。
#define gd25_spi_read_delay()  NOP2()
#define gd25_wait_fifo_rst()   while(GDSPI->STATUS & QSPI_STATUS_TXRXRST_Msk)

/*****************************************************************************/ /*!
* [url=home.php?mod=space&uid=247401]@brief[/url]   spi data read.
*****************************************************************************/
uint8_t gd25_spi_read(uint8_t *datar, uint32_t Len)
{
    gd25_wait_fifo_rst();

    if(Len&0x03)
    {
        while(Len--)
        {
            //send data
            QSPI_WRITE_TX(GDSPI, 0);

            //delay
            gd25_spi_read_delay();

            //wait for trans complete
            while(QSPI_IS_BUSY(GDSPI));

            //read data
            *datar++ = QSPI_READ_RX(GDSPI);
        }
    }
    else
    {
        uint32_t *prd32;
        
        //GDSPI->CTL |= QSPI_CTL_REORDER_Msk;//字节排序
        QSPI_SET_DATA_WIDTH(GDSPI, 32);
        
        Len>>=2;
        prd32 = (uint32_t *)datar;
        while(Len--)
        {
            //send data
            QSPI_WRITE_TX(GDSPI, 0);

            //delay
            gd25_spi_read_delay();

            //wait for trans complete
            while(QSPI_IS_BUSY(GDSPI));

            //read data
            *prd32++ = QSPI_READ_RX(GDSPI);
        }

        QSPI_SET_DATA_WIDTH(GDSPI, 8);
        //GDSPI->CTL &= ~QSPI_CTL_REORDER_Msk; //字节排序
    }
   
    return 0;
}

/*****************************************************************************/ /*!
* @brief   spi data write.
*****************************************************************************/
uint8_t gd25_spi_cmd_send(uint8_t *dataw, uint8_t Len)
{
    gd25_wait_fifo_rst();

    while(Len--)
    {
        //send data
        QSPI_WRITE_TX(GDSPI, *dataw++);

        //delay
        gd25_spi_read_delay();

        //wait for trans complete
        while(QSPI_IS_BUSY(GDSPI));
    }

    //wait for trans complete
    while(QSPI_IS_BUSY(GDSPI));

    // clear RX buffer
    QSPI_ClearRxFIFO(GDSPI);

    return (0);
}

/*****************************************************************************/ /*!
* @brief   read data.
*****************************************************************************/
uint8_t gd25_read(uint32_t addr, uint32_t Len, uint8_t *Des)
{
        uint8_t buff[8];

        gd25_cs(0);

        buff[0] = GD25CMD_Read_Data;

        gd25_addr_fill(addr);

        gd25_spi_cmd_send(buff, ADDR_BYTE_NUM + 1);  //cmd + addr

        gd25_spi_read(Des, Len);

        gd25_cs(1);

        return 1;
}

/*****************************************************************************/ /*!
* @brief   read data.
*****************************************************************************/
uint8_t gd25_q_read(uint32_t addr, uint32_t Len, uint8_t *Des)
{
        uint8_t buff[8];

        gd25_cs(0);

        buff[0] = GD25CMD_Quad_Read;

        gd25_addr_fill(addr);

        gd25_spi_cmd_send(buff, ADDR_BYTE_NUM + 2); //cmd + addr + dummy

        gd25_spi_mode(GD25_QPI_READ_MODE);

        gd25_qpi_read(Des, Len);

        gd25_cs(1);

        gd25_spi_mode(GD25_SPI_MODE);

        return 1;
}






使用特权

评论回复
沙发
antusheng| | 2020-4-11 22:14 | 只看该作者
这是要求太高了。

使用特权

评论回复
板凳
heisexingqisi| | 2020-4-12 12:37 | 只看该作者
速度嫌慢?

使用特权

评论回复
地板
xuanhuanzi| | 2020-4-12 23:41 | 只看该作者
没用过这个功能,一般应用要求也不会这么高吧

使用特权

评论回复
5
jasontu| | 2020-4-13 09:02 | 只看该作者
看起来你的CODE是GD的。
可以先用NUVOTON官方的BSP代码作测试。

使用特权

评论回复
6
apleilx|  楼主 | 2020-5-1 11:35 | 只看该作者
jasontu 发表于 2020-4-13 09:02
看起来你的CODE是GD的。
可以先用NUVOTON官方的BSP代码作测试。

不是GD的demo,flash芯片是gd25q系列,底层函数加了gd25前缀而已,驱动代码参考是新唐的官方代码

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

76

帖子

0

粉丝