STM8S-Discovery (7)

前回の記事で書き忘れましたが、PCM1716E のディジタル入力の電圧レベルは、いわゆる「TTL レベル」で、

  • スレシホールド電圧が約 1.4 V
  • H レベル入力電圧 VIH の最小値が 2.0 V

となっていますから、3.3 V CMOS 系の出力と直結して問題なくインターフェースできます。
STM8S の CLK (Clock control block) の CCOR (Configurable Clock Out Register) の設定により、

  • HSE (High Speed External clock signal)
  • HSI (High Speed Internal clock signal)
  • HSIDIV (High Speed Internal clock signal DIVided)
  • LSI (Low Speed Internal clock signal)
  • MASTER (Master clock signal)
  • CPUCLK (CPU CLocK signal) および分周したもの

の中から選択して CCO_CLK ピンに出力することができます。
クロック同士の関係としては、外部クリスタルによる HSE を MASTER クロックとして選択し、分周なしで CPUCLK として供給しているので、周波数的には
HSE = MASTER = CPUCLK
であり、3つのうち、どれを選んでも同じになります。
ただし、STM8SDP プログラムでは、サンプル・バッファの空きがない場合に wfi() 関数でスリープして待つようになっており、スリープ期間は CPUCLK の出力は停止されてしまいます。
そんなわけで、HSE を選択しています。
プログラムとしては、「main.c」の中のペリフェラルの初期化テーブルの配列「port_init_tab[]」中の適当な場所 (エンドマークの 0x00, ... の前ならどこでも) に次のような行を追加します。

NEAR const PORT_INIT_TAB_T port_init_tab[] = {
  ...

// Configurable Clock Output 
  {(WORD)&(GPIOE->DDR),  0x01, 0x00},  // CLK_CCO : output
  {(WORD)&(GPIOE->CR1),  0x01, 0x00},  // CLK_CCO : push-pull
  {(WORD)&(GPIOE->CR2),  0x01, 0x00},  // CLK_CCO : 10 MHz
  {(WORD)&(CLK->CCOR),   CLK_OUTPUT_HSE+CLK_CCOR_CCOEN,  
                       0xFF}, // output XTAL CLK

  ...

// end of table	
  {0x00, 0x00, 0x00},
};

GPIOE のレジスタの操作をしている部分は、出力ドライバをプッシュ・プルに、スピードを 10 MHz に設定しています。
クロック周波数が高いので、この設定をしないと、まともな出力波形が出ません。
あとは、384fs / 512fs / 768fs モードに応じて LRCK カウンタの分周比を設定するように変更します。

#define TIM2_PERIOD (192)

必要な設定はこれだけなのですが、最初、この状態では歪だらけのひどい音しか出ませんでした。
PCM1716E のスペック上は BCKIN のサイクルタイムの最小値は 100 ns となっており、周波数に直すと 10 MHz ですから、本来は余裕があるはずです。
しかし、これまでの経験から、データがうまく受け取れていない状態の音のように思えたので、SPI クロックを fCPU/4 に変更してみたら、全く問題なく再生されました。
DAC とのインターフェースはハードウェア SPI を使っていますから、SPI クロックの周波数を下げてもプログラムの実行時間が増えるようなことはありません。
プログラムとしては、「port_init_tab[]」中の SPI 設定部分に次のような変更を加えます。

  {(WORD)&(SPI->CR1), ( SPI_FIRSTBIT_MSB         
                      | SPI_CR1_SPE       // enable SPI
                      | SPI_BAUDRATEPRESCALER_4
                      | SPI_MODE_MASTER   // master mode
                      | SPI_CLOCKPOLARITY_LOW
                      | SPI_CLOCKPHASE_1EDGE
                      ),                      0xFF},

(元の「SPI_BAUDRATEPRESCALER_2」を「SPI_BAUDRATEPRESCALER_4」に変更する)