ソフト S/PDIF トランスミッタ (2)

S/PDIF では、後述するようなブロック/フレーム/サブフレーム構成と BMC (Biphase Mark Code) 変調により、48 kHz のサンプリング周波数に対しては、ビット・レート
128 × fs = 128 × 48 [kHz] = 6.144 [Mbps]
のビット・ストリームとして送信されます。
これを「LED チカチカ」のように本当にソフトでビットを上げ下げしていては間に合いませんから、BMC 変調も含めて最終的なビット列となったデータをメモリに展開しておき、内蔵 SPI/I2S モジュールによりパラレル/シリアル変換を行い、シリアル・ビット・ストリームとして送り出す方針にします。
複数のマイコン上で実現することを考え、SPI/I2S モジュールの最大公約数的な機能として、

  • MSB ファースト
  • 16 ビット転送

を使用することを基準としました。
S/PDIF 自体は LSB ファーストの転送方式ですが、BMC で変調するためのテーブルに LSB ファーストと、MSB ファーストとの変換機能を持たせて作成しておけば、実行時にビット逆転などの操作は不要です。
STM32 の場合、SPI モジュールとしては MSB ファースト / LSB ファーストの切り替えが可能でも、I2S モジュールとしての利用では MSB ファーストに限られてしまいます。
また、PIC32 などは SPI で 32 ビット転送が可能ですが、STM32 では 16 ビット転送までに限られます。
16 ビット転送を行っても、6.144 Mbps に対しては、
6.144 [MHz] / 16 = 384 [kHz]
のレートで 16 ビット・データを供給しなければならず、STM32 の SPI/I2S モジュールではデータ FIFO がないため、割り込みで処理しようすると、そのまま 384 kHz のレートで割り込みが発生することになり、オーバーヘッドが大きくなります。
そこで、DMA を利用してソフトウェア側の負担を少なくします。
STM32 の DMA コントローラでは「circular」モードと呼ばれている、指定回数のデータ転送終了後に停止しないで自動でメモリ・ポインタを初期値に戻し、DMA 転送を再開する機能を利用すると、ソフトウェアの介入なしに連続的にデータ転送することが可能です。
Cortex-M3/M4 ではプログラム・メモリバスとデータ・メモリバスが分離しているハーバード・アーキテクチャなので、プログラム・フェッチと RAM / ペリフェラル・アクセスが直接に競合することはなく、DMA に起因するプログラム実行の速度低下は少なくてすみます。
RAM にアクセスしない、I/O ポートアクセスのみのソフトウェア・ループによる「LED チカチカ」プログラムで I/O ポート・トグル周波数を計測して調べたところ、速度低下は 1 % にも満たない値でした。