STM32のUARTをDMAで使う時の注意

昨日Nucleo F303K8を購入しました。5cm x 2cmという、まさに親指サイズのボードで、

(これを入れる適当な箱があると出張中も遊べるな)

と良からぬことを考えながら買いました。

さて、STM32F746上で開発しているライブラリをこのボードにも移植しました。とりあえずUARTからのメッセージは出力されましたが、一箇所躓いたので自分へのメモ代わりに書き記しておきます。問題はUART Global割り込みに関わるものです。

発生した問題は「メッセージが最初のUART DMA1回分しか表示されない」というものです。突き詰めていくと、これはDMA completeコールバックが発生していないため、クラス内部で同期が取れないということでした。つまり、問題箇所はクラスライブラリの外にあります。

更に突き詰めると、「UART DMA送信割り込みそのものは起きているが、HAL_UART_TxCpltCallback()が呼ばれていない」ことがわかりました。UART DMA送信割り込みはDMA1_Channel7_IRQHandle()という関数に割り当てられていて、これ自身は呼び出されています。この関数を更に追っていくと、DMAバッファのハーフ割り込みコールバックが呼ばれていて、終了コールバックは呼ばれていませんでした。

これは妙なことです。なにしろDMAはnormalモードに設定しており、ハーフ割り込みは起きないはずです。

いろいろ調べた結果、この問題はuartのglobal interruptをイネーブルにすることで解決しました。下の図の3番めの割り込みです。

ちょっと腑に落ちませんが、STM32F746のプロジェクトでもこの割り込みはイネーブルになっており、いつ変更したのだろうと首を傾げています。

調査は後日として、まずはメモ代わり。

 

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください