|
有人使用STM32H563开发产品,并启用DMA方式的SPI通信。他发现一个问题,就是当SPI的数据宽度配置为16位或32位时,使用STM32 HAL库提供的SPI DMA方式的API启动函数时没有数据的收发。
但是,如果将SPI的数据宽度配置为8位时则收发正常。
这是什么原因呢?反复检查DMA配置并未发现什么问题。既然8位数据宽度可以,按理有关SPI及DMA的配置不会有啥大问题,除非配置时有误操作,但反复检查没有发现哪里有问题。 后来经过跟踪调试,发现代码方面有个小Bug.在下面代码位置进行参数检查时发生错误而退出了。下面代码就是位于前面贴出了的SPI DMA方式的API函数里。
这段代码并非实质性SPI或DMA模块的功能代码,只是针对SPI通信的数据宽度为16位或32位并启用DMA传输时,对参与传输的DMA的源端和目的端的数据宽度做合理性检查。 具体点说,如果SPI的数据宽度设置为32位时,DMA的源端和目的端的宽度必须是32位;如果SPI的数据宽度大于8位,则DMA的目的端或源端的数据宽度不能配置为8位。否则直接退出并返回错误。 从这段代码内容和逻辑来看,并没有什么毛病,但为啥每次在这里做参数的合理性检查通不过呢?刚才在前面说了,如果将SPI的数据宽度配置8位,倒是一切正常。不过,这段代码并不针对SPI数据宽度等于8位时做检查,自然也就不会在这里做出错返回。 后来,借助代码调试发现,hspi.hdmarx->Init和hspi.hdmatx->Init结构体里的所有成员变量都是0值,即该Init结构体的各个成员都没有做初始化,导致针对Init里的DMA源、目的端的数据宽度做检查时总是失败。
这就奇怪了。hspi.hdmarx->Init和hspi.hdmatx->Init结构体的各个成员都是跟DMA传输直接相关的,怎么会没有做针对性的初始化呢?说不过去啊! 后来,经过阅读代码发现,像STM32H5系列,每个DMA配置视为一个传输节点,我们可以在HAL_SPI_MspInit()函数里看到了针对SPI RX/TX的DMA节点的配置。
在这里我们还可以看到NodeConfig临时变量,它也是存放每个DMA通道节点初始化参数的结构体变量,其各个成员跟hspi.hdmarx->Init和hspi.hdmatx->Init结构体里的成员变量基本一样。不妨参看下面代码截图:
代码里基于NodeConfig做相应的初始化配置后,然后进一步写进相应DMA控制寄存器。也就是说,目前的库代码里的确没有对hspi.hdmarx->Init和hspi.hdmatx->Init结构体做初始化,准确点说,现在已经绕过它而使用了另外一种初始化方式。这就导致了针对hspi.hdmarx->Init和hspi.hdmatx->Init结构体的成员变量做检查时出现失败并出错返回。 既然这样,要解决眼前问题,最直接而简单的办法,就是屏蔽API代码中的这段检查代码。
当屏蔽掉这段检查代码后,基于DMA方式SPI 16位、32位数据通信就都正常了。
当然还有个办法,那就是不屏障这段合理性检查代码,而在HAL_SPI_MspInit()函数里,当完成NodeConfig结构体变量初始化并配置好相应DMA节点后,用NodeConfig结构体的部分变量内容对hspi.hdmarx->Init和hspi.hdmatx->Init结构体的相应成员进行赋值,以便后续合理性检查,比方像这样:【下面是针对SPI DMA接收节点的部分配置】
经过验证,这样也是可以的。 这里顺便提醒下,按照上面方式进行赋值时,注意赋值操作的位置。如果赋值语句放在红色框所在位置可能会遇到Hardfault故障,若放在绿色框位置就没事。
如果看官有兴趣的话,可以结合具体代码分析分析为什么会产生Hardfault。今天的分享重点主要是提醒目前HAL库例程的这个小bug,期待未来会改善。现在STM32推出的新款芯片真是又多又快,不少新特性、新功能、新玩法,同时对STM32的生态也是不小的挑战,比方各种技术资料、各种应用例程等,个中出现这样那样的bug在所难免,只要能不断完善就好。 文章出处:茶话MCU |
多通道DMA传输为何有一路异常?
SPI 高温读错最后一位?STM32F42xx 官方根治方案
经验分享 | STM32N6 ADC DMA 传输失败案例分享
经验分享 | DMA发送函数只能第一次调用有效?
经验分享 | LAT1470 SPI传输长度超过1024时出现异常的问题分析
经验分享 | 使用EXIT0同步触发SPI的DMA发送话题
【开发经验】LAT1500 如何通过DMA配合CRC功能
经验分享 | STM32H723 SPI 通讯异常排查:实时观察窗口的 “隐形干扰” 解决方案
我心中的ST中文论坛
【STM32C0评测】4、驱动Lorasx126x,实现透传
微信公众号
手机版