カードエッジの Sound Out 端子から MCU に配線し ADC を使う. これによって燃えプロ系のボイスをアナログ経路で録音することに成功. *1
録音手法
- TCx->EVSYS->ADC, ADC->DMA->EVSYS をつなぐ.
- TC から ADC はタイマの OVERFLOW イベントを ADC につなぐ.
- ADC から DMA は EVSYS でもいけると思うが、TRIGSRC からでもいける.
- DMA は block 単位転送完了を EVSYS でつなぎ、割り込みをおこす.
この実装に関して EVSYS の仕様書を見たらバスのつなぎ方に非同期、同期、再同期がありデバイスが求めるバスを適切に接続する必要がある. それに気づいていなかったので全部非同期にしていた. それを直すのに手間取った. 直す過程でバスサイクルが少し悪くなったので後日要調整.
音質に関して
人の声レベルなので元々の音がサンプリングレートが低くく、 MCU の汎用の ADC で取るには結構マシな音質であった. Youtube でのプレイ動画の音質と比べても素人の私には大体同じに聞こえた.
DMA に関して
block 単位の転送完了の割り込みは DMA 単体からは suspend 動作がついてしまうが、 EVSYS 経由で割り込みをおこすと suspend がつかない.
voice の場合は音声再生時間が長くなると MCU の RAM の容量を超えてしまうので、録音途中にPCへ随時送り続けるようにしたい. バッファRAMを半分で2つに分ける. 1つの block を DMA の書き込み、もう1つの block を読み込み(PC へ送信)にする.
この場合、DMA descriptor の使用数を転送サイズ/バッファサイズ/2 にすることも可能だが、 2つの descriptor で無限ループを作ることも可能. 実は以前から address の increment pattern の bit7:0 は 1 つの descriptor で無限ループにしている. address 出力は MCU からは write (送信) なので割り込みはいらない.
この転送途中に割り込みをかけて随時送る方式は今後他の目的でも使いたいので ADC をネタにちゃんと実装したいので実証実験も兼ねている. 実のところ MCU 用のソースコードは早い段階でできているのだが、シミュレータでは無限ループ型の DMA は先述の1つのパターンのみ対応でそれの対応に手間取っている. だから動作確認がとれてないので MCU で動かすのは意味がない.
基本MCU用のソースだけ書いても1発でちゃんと動くわけがないし、デバッグ情報がとれないので MCU 用のソースは依存部分をできるだけ排除して PC でもほぼ同じコードを動かしてデバッグ情報を得ることで直したほうが早い...早いはウソでこれがないと直せない.