LPC1114FN28/102 (13) -- リニア PCM プレイヤー (1)

LPC1114FN28/102 で MMC/SD カード内の (mp3 でない) リニア PCM ファイルを再生するプレイヤーを作っています。
とは言っても、実用的なものを目指してはいないので、持ち運びできる形にするわけではありません。
MMC/SD カードは「ネイティブ・モード」ではなく「SPI モード」でアクセスし、外付けのシリアル入力・ディジタル・オーディオ・ステレオ DAC とのインターフェースにも SPI を利用するので、合計 2 個の SPI が必要になります。
LPC111x シリーズは、SSP0 と SSP1 の 2 系統の SPI を内蔵していますが、ピン数の制限から LPC1114FN28/102 では SSP0 のみがピンに接続されており、残念なことに SSP1 は外部と信号のやり取りができません。
また、UART モジュールは一般的な 14550 UART と互換のタイプで、文字通り「調歩同期式」専用で、SPI 機能はありません。
そのため、ハードウェア SPI の SSP0 と、ソフトウェア SPI とで構成することになります。
(ハード SPI + ソフト SPI) という構成は、以前の STM8S-Discovery 用の LPCM プレイヤー・プログラムでも採用しました。(記事は→こちら)
STM8S 版のプログラムでは、高機能タイマ TIM1 を使い、アセンブラで記述して、ソフト SPI でも SCK 周期を CPU クロック 2 サイクル分で実現することができました。 
CPU クロック 18 MHz (約 15 % オーバークロック) のとき SPI 周波数は 9 MHz で、これはハード SPI の周波数上限と同じです。
LPC1114 版のプログラムでは、ソフト SPI の SCK 周期は CPU クロックの 6 サイクル分という「普通」の性能で、CPU クロック 36 MHz の場合 SCK は 6 MHz となり、ハード SPI の 18 MHz に比べて見劣りします。
実際に破綻なく再生できるサンプリング周波数の上限は、約 60 kHz となり、88.2 kHz や 96 kHz には届きませんでした。
18 MHz クロックの 8 ビット・マイコン STM8S で 48 kHz サンプリングの再生ができるのに、36 MHz クロックの 32 ビット・マイコン LPC1114 で 60 kHz サンプリングまでというのは、ちょっと残念です。
ハードウェア / ソフトウェアの検討の第一段階として、まず、クロック周波数を決定します。
LPC11xx の場合には、PLL クロック出力としては、周波数 10 〜 25 MHz の範囲の基準周波数を外部から加えるか、あるいは 12 MHz の内部 RC クロックを基準周波数にして、それらの整数倍の周波数しか発生できません。
あまり自由度がないので、オーバーサンプリング DAC のシステム・クロックは供給せす、ノンオーバーサンプリング DAC 用の LRCK のみを発生させることにします。
サンプリング周波数 48 kHz 系列と、 44.1 kHz 系列との、いずれに対しても周波数誤差がゼロになる最も低い源発振周波数は、48 kHz と 44.1 kHz の既約な整数比 160:147 にそれぞれ 88.2 kHz と 96 kHz をかけて、
160 × 88200 = 147 × 96000 = 14.112 [MHz]
となります。
必要なサンプリング周波数の 2 倍をかけているのは、デューティー 50 % の LRCK を整数分周で得られるようにするためです。
この周波数の整数倍の周波数のクロックをカウンタに入力し分周すれば誤差ゼロで目的のサンプリング周波数の LRCK が得られます。
LPC1114 の CPU クロックとしては、スペック内では 3 倍の 42.336 MHz、オーバークロックの範囲では 4 倍の 56.448 MHz となります。
この系統の周波数の水晶振動子やクリスタル・オシレータのなかで、digi-key などで在庫があり入手可能なのは 28.224 MHz だけのようです。
この周波数は PLL の外部クロック入力の制限である 25 MHz を超えており、PLL 出力の CPU 周波数としても 56.448 MHz となり、オーバークロックとなります。
スペック内におさめるには 28.224 MHz をそのまま CPU クロックとして使うしかありません。
STM32F4-Discovery の場合には、12.096 MHz の水晶振動子を使って、多数のサンプリング周波数で、ほぼ完璧に誤差ゼロを実現できましたが、LPC1114 の場合には自由度に乏しいです。
12.096 MHz を 7 倍すると 84.672 MHz となり、これは先ほどの 14.112 MHz の 6 倍にあたるので、48 kHz 系でも 44.1 kHz 系でも誤差ゼロが可能です。
LPC1114 の PLL で、もし 3.5 倍の設定が可能なら 12.096 MHz × 3.5 = 42.336 MHz で、都合のよい値となります。
LPC111x シリースの外部クロックから PLL を使ってクロックを発生させる場合の簡略化した系統図を下に示します。
クロック入力選択のためのマルチプレクサなどは省略してあります。

PLL 出力信号は「メイン・クロック」と名づけられており、これは分周器を介して CPU コアや周辺モジュールへのクロックとして供給されています。
SSP モジュールと UART モジュールには専用の分周器があり、システム・クロックと違う周波数に設定もできます。
CPU コアのクロック周波数の上限は 50 MHz ですが、PLL 出力である「メイン・クロック」の周波数の制限については、データシートなどに数値としては明記がありません。
ユーザ・マニュアル (UM10398) の「3.5.3 System PLL control register」に

The PLL can produce a clock up to the maximum allowed for the CPU.

とあるので、メイン・クロックも同じ 50 MHz 制限と考えるのが妥当ですが、もしメイン・クロックに高い周波数が許容されるなら、12.096 MHz の外部クロックを PLL で 7 倍してメイン・クロックとして 84.672 MHz を得て、それを 1/2 した 42.336 MHz を CPU コア・クロック / 周辺クロックとして供給することができます。
48 kHz 系、44.1 kHz 系のいずれかは誤差が出るのを許容すれば選択の余地はひろがります。
その一例が、STM8S の時も使った 18.432 MHz で、
18.432 [MHz] / 48 [kHz] = 384
ですから、48 kHz 系統のサンプリング周波数に対して誤差ゼロとなります。
また、fs = 48 kHz に対して 18.432 MHz を 384 fs のオーバーサンプリング・クロックとして使うことができます。
44.1 kHz 系統に対しては、
18.432 [MHz] / 44.1 [kHz] = 417.959 ...
となり、当然、誤差ゼロではありませんが、分周比を 418 とすると、
18.432 [MHz] / 418 = 44.09569 ... [kHz]
となり、誤差の値は -100 ppm (-0.01 %) 程度となります。
特に高精度ではない、一般的な水晶振動子/クリスタル・オシレータの総合的な周波数偏差は ±数十 ppm のオーダーですから、それと比較すると特に大きな誤差となるわけではなく、実用上は問題ありません。
そういうわけで、外部クロック (システム・オシレータ) として 18.432 MHz の水晶振動子を接続し、PLL で 2 倍の 36.864 MHz として CPU コア / 周辺クロックとして使うことにしました。
コア・クロック周波数は 40 MHz 以下なので、フラッシュのウェイト・ステート数は「1」に設定することになります。
SSP (SPI) モジュールで送受信する場合の SCK 周波数の制限はスペック上は 20 MHz なので、SCK は SSP クロックを 2 分周した 18.432 MHz で動作させます。 (送信オンリーの場合の SCK 周波数の制限は 25 MHz)
次回はソフト SPI のプログラム (の断片) を示します。