以前から気になっていたのですがPIC32MXのI2S機能を試してみました。PIC32MXのI2SはSPIとの共用機能になっていて、SPIのレジスタのAUDENを1にするとI2Sとして使えます。I2Sをする場合には適当なクロックが必要なのですが、MicrochipのAN1422には48Kのサンプリング周波数の場合USB PLLの96MHzを使ってREFCLKを12.288MHzにする方法が書かれてあります。USB PLLはPIC32MX1XXにはないので、この方法は使えません。REFCLKをSPIのクロックとして使う設定のMCLKSELを1にして、Baud Rate Generator(BRG)を適当な値にすると、正しいBCLK/LRCLKが出力されます。1フレームのビット数はMODE32=0,MODE16=1にすると片チャン32bitの64bitになり、実際のデータは16bitとなります。
デジタルオーディオのフォーマットはI2Sの他に左寄せ、右寄せ、PCMがあります。I2SのフォーマットはLRCLKから1fs空けて、MSBから出力します。
AK4382Aで出力した波形
PIC32MX220F032B用のコードはここあります。
Pinguino gccとxc32のファイルを使っていて、再現性は低いですがmain.cの中にすべてあります。
DMAを二つ使ってダブルバッファで処理しています。空の割り込みでフラグを立てて、mainのループでつめ直しています。
こちらのURLからのページが大変参考になりました。この方のコードをちょっと修正してPinguinoのgccでビルドできるようにしました。
修正したところはPPSで信号の出力先のピンを指定した事と、REFCLK周りです。オリジナルはMCLKが必要ないDACで試されたようです。
シンセ・アンプラグドさんは違う方法を試されているようですが、参考になりました。
harmonyベースですが、microchipのページ。
当初Microchipのサンプルコードを追いかけていたのですが、うまくできずいろいろ探しました。MicrochipのサンプルコードはPIC18Fなどとも共通になっていて非常に見通しが悪いです。
しかしもって結構な黒魔術です。結構はまりました。
後日追記:おそらくDMAは1本でもできるのではないかと思われますが、いじると動かなくなりそうなので、そのままにしておくつもりです。