2024年10月18日金曜日

STM32 SPI 送信受信DMAちゃんと動いてますか?

こんにちわー.SPIの先についてるADCを動かそうとしている者です.皆さんのところではDMAちゃんと動いてますか?

わたしが使っているCPUは、STM32H723です.

やっと動かせたんですけど、ちょっと地雷だったかなぁというわけで地雷を説明しておきます.

地雷は3つ
1)HAL_SPI_TransmitReceive_DMA()を使いましょう
2)buffer memoryはRAM_D3です(BDMAの存在空間に合わせる)
3)DMAはTXとRXを生成しましょう →BDMAが生成されます

地雷1については先日の投稿に書きました.
要約すると、ADCの仕様により、コマンド送信→サンプル値受信という送受信MIXなので、TransmitRecvieve_DMAを使う必要がありました.

地雷2については、こちらで解説しました.I2Cについて書いたのですがSPIでも参考になります.
SPIにひっつくDMAはBDMAというものです.
BDMAは通常のRAM領域とは隔絶されたD3領域に存在するので、buffer memoryもD3領域にアサインする必要があります.これを無視するとうんともすんとも動きません.

地雷3は、TxRx MIXなので当たり前なのですが、BDMAをTXとRX両方とも生成しないと動きません.

地雷ではありませんが、DMA終了はweak宣言されているところの、
 HAL_SPI_TxRxCpltCallback()
で受ければよいです.これもTxとRxとTxRxの3種類あるので注意です.


次回予告: SPIをTIM割り込みで自走させれるのか? ←うごかねぇ....

↑この件、挫折しました.DMA仕様的に無理.
ADCの仕様がSPI-DMAの仕様にマッチしないんです.
ADCの仕様のエグいところは、こうなってます.
 ・SSをassertする
 ・コマンド送信
 ・サンプルデータ受信
 ・SSをde-assertする
1つのSSの枠内で送受信が必要.sample毎にSS枠が必要ともいえる.
しかし、、、
DMAをcircle modeで動かすとSSの枠内で永久に送受信が続くのでダメ.
synchronizationさせると、SSが1BYTE毎に区切れてしまうのでダメ.
event機能で回避もできない.
詰み.

かしこ

0 件のコメント:

コメントを投稿