しばらく作業時間が取れなかったSLICを使ったプロジェクトを再開。次の段階として、WT32を使ったHFP通話をSLICとつなぐことにします。まずは、WT32をSTM32L476のUSARTと接続。
改めてSTM32のUSARTの仕様を確かめると、FIFOがないんですね。SPIやSAIにはFIFOが用意されているのですが、USARTにはFIFOが無いのは従来のデバイスとの互換性を考慮してのことでしょうか。あるいはDMAを使うことを前提としており、FIFO無しで構わないということなんでしょうか。STM32L476にはDMAが14チャネルもあるので、迷うこともなくDMAを使ってUSART送受信することにします。STM32L4のDMAにはサーキュラーモードがありますので、これを使うだけでリングバッファへの受信処理が実現できてしまいます。
ただし、USART受信においてDMAを使う場合にはタイムアウト処理が必要となります。受信バッファが一杯になった場合には、DMA完了割り込みでそれを知ることができますが、バッファが一杯になる前に相手からのデータ送信が止まった場合には、 タイムアウトにて受信待ちを打ち切らないとせっかく受信できたデータを処理することができません。今回は、FreeRTOSを使っているのでイベント待ちをタイムアウトすることで、受信待ちを打ち切ることにします。
タイムアウトが発生したら、どこまでDMAが進んだかを調べれば、受信バッファのどこまでデータを受信できたのかがわかります。STM32L4ではDMA_CMARxがDMA転送先のメモリアドレスを示しますが、このレジスタはDMAの先頭アドレスをを示すだけで、DMAが進んでも更新されるわけでは無いということに気づかずにハマってしまいました。DMAがどこまで進んだかを調べるには、転送数を示すDMA_CNDTRxの値から求める必要があります。
こうしてWT32の出力するイベントメッセージをUSARTでDMA受信した内容を、まずはそのままRTTを使って出力してみました。
なお、受信DMAのタイムアウト処理に関しては、AN3109にても言及されており、ここではUSART_RX端子をタイマーの入力キャプチャー端子につないで、入力のアイドル時間を監視するという方法が紹介されていました。機会があれば、試してみようかな。
改めてSTM32のUSARTの仕様を確かめると、FIFOがないんですね。SPIやSAIにはFIFOが用意されているのですが、USARTにはFIFOが無いのは従来のデバイスとの互換性を考慮してのことでしょうか。あるいはDMAを使うことを前提としており、FIFO無しで構わないということなんでしょうか。STM32L476にはDMAが14チャネルもあるので、迷うこともなくDMAを使ってUSART送受信することにします。STM32L4のDMAにはサーキュラーモードがありますので、これを使うだけでリングバッファへの受信処理が実現できてしまいます。
ただし、USART受信においてDMAを使う場合にはタイムアウト処理が必要となります。受信バッファが一杯になった場合には、DMA完了割り込みでそれを知ることができますが、バッファが一杯になる前に相手からのデータ送信が止まった場合には、 タイムアウトにて受信待ちを打ち切らないとせっかく受信できたデータを処理することができません。今回は、FreeRTOSを使っているのでイベント待ちをタイムアウトすることで、受信待ちを打ち切ることにします。
タイムアウトが発生したら、どこまでDMAが進んだかを調べれば、受信バッファのどこまでデータを受信できたのかがわかります。STM32L4ではDMA_CMARxがDMA転送先のメモリアドレスを示しますが、このレジスタはDMAの先頭アドレスをを示すだけで、DMAが進んでも更新されるわけでは無いということに気づかずにハマってしまいました。DMAがどこまで進んだかを調べるには、転送数を示すDMA_CNDTRxの値から求める必要があります。
こうしてWT32の出力するイベントメッセージをUSARTでDMA受信した内容を、まずはそのままRTTを使って出力してみました。
なお、受信DMAのタイムアウト処理に関しては、AN3109にても言及されており、ここではUSART_RX端子をタイマーの入力キャプチャー端子につないで、入力のアイドル時間を監視するという方法が紹介されていました。機会があれば、試してみようかな。