打印
[综合信息]

N32系列MCU的SPI接收DMA硬件疑似有bug

[复制链接]
735|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dopod577w|  楼主 | 2023-7-15 20:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
怀疑N32系列MCU的SPI接收DMA功能有bug,**厂家核实一下
我用N32G4FR读取SPI Flash的厂家ID,时序是发送2个字节,读取3个字节。
将SPI设置为全双工模式,不开中断何DMA,用查询方式,大概代码如下:
        for (n=0;n<5;n++)
        {
                SPI_I2S_TransmitData(SPI3, spi_tx[n]);
                while(SPI_I2S_GetStatus(SPI3, SPI_I2S_TE_FLAG) == RESET);
                while(SPI_I2S_GetStatus(SPI3, SPI_I2S_RNE_FLAG) == RESET);
                spi_rx[n] = SPI_I2S_ReceiveData(SPI3);
        }

就是发送5个字节,前两个是有效的命令字节,后面3个空字节,是为了产生SCK时钟;接收到5个字节,前两个扔掉,后面3个是正确的Flash芯片ID。

然而改为DMA方式实现,就出了问题。首先仍然用查询方式发送2个字节,然后用DMA方式读3个字节。

主要代码如下:
        //首先配置RX
        DMA_EnableChannel(DMA2_CH1, DISABLE);
        DMA2_CH1->TXNUM = len;
        DMA2_CH1->MADDR = (uint32_t)addr;
        DMA_EnableChannel(DMA2_CH1, ENABLE);

        //接着配置TX,输出dummy数据,否则没有CLK
        DMA_EnableChannel(DMA2_CH2, DISABLE);
        DMA2_CH2->TXNUM = len;
        DMA2_CH2->MADDR = (uint32_t)addr;
        DMA_EnableChannel(DMA2_CH2, ENABLE);

读取的数据会有错,比如本来应该读到:11 22 33,结果首次读到的是:00 11 22,把33落下了,下一次读到的是33 11 22,其中第一个33是上次没读到的最后一个字节。

发送DMA是由SPI_I2S_TE_FLAG标志触发,接收DMA是由SPI_I2S_RNE_FLAG触发,由于TE在发送字节写入缓冲器就触发,而RNE是字节传输完毕后才触发,比TE晚了8个SCK时钟,因此我怀疑:接收DMA是用TE触发的,而不是RNE,因此读到的数据比实际要滞后一个字节。

上述代码流程也在ST和AT32的MCU上是调试过,AT32的要在启动DMA之前切换一下SPI的使能,可把片内接收缓冲区清空,但是在N32上就无效。

请厂家帮忙核实一下,谢谢!

使用特权

评论回复
沙发
tpgf| | 2023-8-8 10:43 | 只看该作者
不太明白的就是为什么发送两个字节读取确是3个字节呢

使用特权

评论回复
板凳
qcliu| | 2023-8-8 10:52 | 只看该作者
全双工模式是不是需要四线制的spi啊

使用特权

评论回复
地板
drer| | 2023-8-8 11:43 | 只看该作者
接收dma有不同的触发标志位吗?

使用特权

评论回复
5
coshi| | 2023-8-8 11:57 | 只看该作者
在接收数据的时候 底层不会自动识别是否已经接收完成吗?

使用特权

评论回复
6
kxsi| | 2023-8-8 13:20 | 只看该作者
如果更改这个dma的触发源 是不是可以接收到正确的数据呢

使用特权

评论回复
7
wiba| | 2023-8-8 14:46 | 只看该作者
读取flash的厂家id的目的是什么呢?

使用特权

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

本版积分规则

12

主题

25

帖子

2

粉丝