嵌入式技术william hill官网
直播中

abdkjshd

8年用户 1144经验值
擅长:可编程逻辑
私信 关注
[问答]

STM32H750 SPI DMA接收地址的数据全是0这是啥情况?

修改了 drv_spi.c , spi_config.h 和 dma_config.h,使 rtt 可以用于 spi 的 DMA操作。
现在遇到一个问题,通过示波器量波形,可以确定 DMA 发送成功,且收到了反馈数据,且数据正确。
在 stm32h7xx_hal_spi.c 中的 HAL_SPI_TransmitReceive_DMA 函数中打断点,可以看到 SPI2 外设调试窗口 RXDR 中的数据是正确的,但是本地堆栈窗口的数据全是 0, 且 DMA 接收地址的数据也全是 0。这是啥情况。。

2.jpg

补充一点:不用 DMA,轮询方式是可以正常使用的,威廉希尔官方网站 上没有问题。

回帖(4)

李桂兰

2023-1-29 15:54:08
这题我正好测试过,请楼主确定几个点:

SPI 轮训是正常的

SPI 请使用 DMA1 或者 DMA2

SPI 会使用到 rt_malloc , heap 确保是 AXI SRAM

MPU 配置的 cache 策略

drv_spi.c 中在开启 DMA 之后,对应的 SPI 外设中断是否开启了.

如果 SPI 轮训是正常的,请使用 DMA1 或者 DMA2.
因为 DMA1 DMA2 无法访问到 TCM,如果确保 rt_malloc 是从 AXI SRAM 申请的内存.
cache这里,如果你参考的 ART-Pi 或者 STM32H743-ATK-APLLO 那么这里就不需要修改.
检查是否对用的 外设中断函数是否有.
举报

李桂兰

2023-1-29 15:54:17
在补充一点,在读数据之前加一句 SCB_InvalidateDCache();
举报

李桂兰

2023-1-29 15:54:32
补充下,malloc出来的地址和大小也要确保cache_line对齐哈,如果不能确认,可以用本地buf再拷贝一次。
举报

abdkjshd

2023-1-29 15:55:00
最终搞定了这个问题,具体方法如下:
drv_spi.c 的 spixfer 函数,添加如下代码。
第一部分是动态分配一段CacheLine对齐的内存,采用的策略是先分配比 send_length 大,且对齐之后也能放下数据的内存。之后再取对齐地址进行使用。
之后复制发送内容到分配的内存,并刷新缓存。
注意分配的内存一定不能在 DTCM。
之后执行 HAL_SPI_TransmitReceive_DMA 函数,必须是这个函数,后面的单独 DMA 发送和接收的函数不行。 具体原因不清楚。
2.jpg
第二部分是复制接收数据到接收缓存,且释放动态内存。
注意这部分必须放在 DMA 传输完成之后,即上面的 while 循环之后。
3.jpg
另外要注意动态分配的内存区域对应的内存策略必须是 可缓冲 且 可缓存。其他情况调试了不能通过,具体原因不清楚。


举报

更多回帖

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