トリプル・バッファ化のアイデア

一昨日書いたように、EZ-KIT Lite BF533の上ではAD1836のLRチャンネルだけを取り出すことが出来ません。しかし、もし取り出すことが出来ていたら、トリプル・バッファ化が必要になっていたでしょう。
ダブル・バッファは信号処理とデータ転送を同時に行ううまい方法ですが、バッファ付きのシリアル・ポートを使う場合には注意が必要です。と言うのは、送信DMAの転送ポインタは受信DMAの転送ポインタより先を行っており、DMA完了割り込みの扱いがきわどくなるからです。
ADSP-BF533はDMAに16bit 4ワード、SPORTに16bit 8ワードのFIFOバッファを持っています。そのため、DMAがバッファをアクセスしているのは、実際に送信されているデータよりも12ワード前方になります。この結果、受信DMA完了割り込みで同期を取ると、送信は実際には次のバッファの12ワード目あたりをフェッチしているということになります。
AD1836は1サンプルで32bitワード*8(16bitワード*16)の転送を行いますから、上の送受のずれは、DMAの単位を8サンプル程度にしておけばまあまあ無視できるとわかります。しかし仮にLRデータだけ転送できるとなると、送受のずれは3サンプルです。さらに、もしSPORTが32bitデータではなく16ビットだけ転送するとなると*1、送受のずれは6サンプルになります。
この影響を小さくしたければ、一回のDMAで転送するサンプルを大きくしてください。たとえば48サンプル(16bitワード*96)の転送を一度に行えば、ずれは6/48=1/8=12.5%であり、CPUは全体の87.5%を信号処理に使えます。仮にそれを超えると、送信バッファへのデータ格納の一貫性に深刻な問題が発生します。
大きなバッファを使わずCPUの使用可能時間を100%に近づけたいときにはどうすればいいでしょうか。その場合はトリプルバッファを使います。

続き

結局本サイトのほうに書きました。長い。
http://adsp2191.hp.infoseek.co.jp/tips/tips017.shtml

*1:そんなことをすると送信時の1LSB未満のデータはランダムデータになりますが