华大 MCU 之七 DMA 导致 SPI 异常停止的原因分析、DMA 配置的那些坑
緣起
??在最近的項目測試中發(fā)現(xiàn),SPI 通信總是莫名其妙的失敗,查看寄存器發(fā)現(xiàn) SPI 已經(jīng)被停止了。根據(jù)手冊,SPI 在異常情況下會被強制停止(SPI 的使能為被清零),而根據(jù)波形顯示通信過程沒有問題。下圖是我實際中的 DMA 及 SPI 使用情況:
問題分析
??最初懷疑是 SPI 的問題,因為在初始實現(xiàn)這部分功能時就遇到了很多坑,我也寫過博文華大 MCU 之五 SPI 從機 DMA 模式 配置(不能正常接收問題處理) 來專門記錄遇到的問題。但是再一次整理了一下 SPI 的配置流程,并沒有發(fā)現(xiàn)啥問題。在測試中發(fā)現(xiàn),將 SPI2 使用的 DMA 停止,則不會出現(xiàn)問題,于是開始調(diào)查 DMA 的問題。
DMA 的坑
??最開始將問題重點放到了 DMA 的配置上,懷疑是不是 DMA 部分配置項不正確。但是,讀數(shù)情況下 SPI 是工作正常的,如果是配置不對,應(yīng)該是一個必出現(xiàn)的問題。轉(zhuǎn)而又開始懷疑是不是配置時序(寄存器的配置的先后順序)不對,反復(fù)查看代碼也沒有發(fā)現(xiàn)問題。正在一籌莫展之時,有同事提出了手冊中 DMA 章節(jié)給出的一個注意事項:
??其實,最開始實現(xiàn) SPI 驅(qū)動時就關(guān)注過該注意事項,只是開始的理解是,這條注意事項是針對同一通道而言的,同一通道在工作時不能再次配置上面說的這些寄存器,不同 DMA 通道之間應(yīng)該互不影響。然而實際情況是,只要 DMA 有任意一個通道在傳輸數(shù)據(jù),其他所有通道都不可以配置!
??這就導(dǎo)致了一個很大的問題,外設(shè)在工作中不可避免的要重新配置 DMA。例如,SPI 的 DMA 發(fā)送,由于發(fā)送數(shù)據(jù)長度是動態(tài)變化的,必須每次重新進行配置,則根據(jù)上面這一條,必須把該 DMA 下的其他通道(例如上面我的 SPI1 使用的通道)也都全部停止,這樣就可能導(dǎo)致其他外設(shè)丟失數(shù)據(jù)。
??最麻煩的是,這個問題沒有找到任何其他的解決方法,只能是停止該 DMA 下的所有通道,進而來配置自己需要的那個通道參數(shù)。起初在尋找解決方法的時候,也考慮是不是可以用下圖所示的寄存器位來進行一下判斷,而是實際是下面的位根本沒有任何用處。
還是以我上面的使用示例來說,SPI2 作為從機接收,由于使用了 DMA,MCU 并不能確定數(shù)據(jù)何時到來。即使 MCU 檢測 DMAACT 未動作,可能在實際配置通道時,DMA 又變?yōu)榱藙幼鳡顟B(tài)。
配置
??根據(jù)手冊,使用 DMA 時需要先寫寄存器將 DMA 控制器使能,使能方法是寫 DMA 使能寄存器 DMA_EN.EN 位。 如下圖所示:
我試了一下,不先使能貌似也沒法發(fā)現(xiàn)啥問題啊!不知道為啥!?
無法獲取當(dāng)前傳出數(shù)據(jù)長度
??先來說一下需求:在串口驅(qū)動中,串口的接收使用 DMA 來實現(xiàn),DMA 配置為循環(huán)模式,在指定緩沖區(qū)中循環(huán)存放收到的數(shù)據(jù),通過讀寫指針來標記數(shù)據(jù)的讀和寫位置。
??然而,驅(qū)動庫中 DMA 接口并沒有能獲取當(dāng)前 DMA 傳輸了多少字節(jié)的接口!!!無奈只能選擇修改驅(qū)動庫,添加一些指定的接口,如下圖所示:
??后來,為了不修改驅(qū)動庫,我直接把接口放到了自己的驅(qū)動里面,然后使用寄存器直接讀取:M4DMA1->MONRPT0_f.DRPT,這樣的話,需要注意與通道號的對應(yīng)關(guān)系,如 MONRPT0 即通道 0。
中斷的使用
??在華大的 DMA 中,中斷默認都是開啟的,這點在配置 DMA 的時候需要特殊注意。我們需要使用 DMA 的屏蔽中斷寄存器來屏蔽不使用的中斷。如下圖示:
在實際寫代碼時,需要調(diào)用 en_result_t DMA_DisableIrq(M4_DMA_TypeDef* pstcDmaReg, uint8_t u8Ch, en_dma_irq_sel_t enIrqSel); 來關(guān)閉不需要的中中斷。例如,DMA 的塊傳輸完成中斷 和 傳輸完成中斷 通常不會一起使用!這點對于用慣了 ST MCU 的人來說需要特殊注意!
結(jié)論
參考
總結(jié)
以上是生活随笔為你收集整理的华大 MCU 之七 DMA 导致 SPI 异常停止的原因分析、DMA 配置的那些坑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 之五 最新 2021 一图看
- 下一篇: Linux 之七 SSH、SSL、Ope