ディジタルオーディオ用 DAC をマイコンにつなぐ(6)

最後は、SH2 の場合です。
これは Web では公開していない、インターフェース 2006 年 6 月号付録基板 SH7144F を使用したものです。
公開していない理由は、SRAM を外付けしてあって構成が特殊なのと、FM音源プログラムの開発途中で放置してあって、プログラムの版が古いためです。
ディジタルオーディオ用 DAC としては BU9480F と LC7883M を接続してあります。
マイコン側のインターフェースとしては SH2 の SCI (Serial Communication Interface) モジュールのチャンネル3 (SCI3) を使用しています。
SCI は次のようなモードに設定しています。

  • クロック同期式モード
  • MSB ファースト
  • ボーレートクロックのプリスケーリングなし (n=0)
  • 内部クロック / SCK3 端子は出力
  • クロック周波数 = (24 [MHz] / 4) / 2 = 3 [MHz]

SCI の初期化のコードを下に示します。 タイマ関係のコードは省略しています。 (HEW4 付属の標準ツールチェイン使用)

// setup for digital audio DAC
//  
// MACK = TIOC2A (PE6) J2-10  (384fs = 12 MHz)
// LRCK = TIOC3A (PE8) J2-12  (fs = 31.25 kHz)
// BCLK = SCK3   (PE9) J2-13  (3 MHz)
// DATA = TXD3   (PE5) J2-9

void da_dac_setup()
{
// SCI3 = BCLK/DATA generation

  MST.CR1.BIT._SCI3    = 0x00; // en. SCI3
  PFC.PECRL1.BIT.PE9MD = 0x03; // SCK3 for PE9
  PFC.PEIORL.BIT.B9    = 0x01; // data dir = OUT
  PFC.PECRL2.BIT.PE5MD = 0x02; // TXD3 for PE5
  PFC.PEIORL.BIT.B5    = 0x01; // data dir = OUT
  INTC.IPRI.BIT._SCI3  = 0x01; // SCI3 int prio = 1
  SCI3.SMR.BIT.CA      = 0x01; // synch. mode
  SCI3.SMR.BIT.CKS     = 0x00; // no prescaling 
  SCI3.BRR             = 0x01; // SCK3 = (P_phi/4) / (n+1) = 6MHz / 2 = 3MHz
  SCI3.SCR.BIT.RIE     = 0x00; // dis. Rx int
  SCI3.SCR.BIT.RE      = 0x00; // dis. Rx
  SCI3.SCR.BIT.TIE     = 0x00; // dis. Tx int
  SCI3.SCR.BIT.TE      = 0x01; // enable Tx
  SCI3.SCR.BIT.TEIE    = 0x00; // dis. Tx end int
  SCI3.SCR.BIT.CKE     = 0x01; // int clk, SCK3 out
  SCI3.SDCR.BIT.DIR    = 0x01; // MSB first
} // void da_dac_setup()

SCI は、もともと調歩同期式通信のハードウェアが基本ですから、シフトレジスタは送信側/受信側それぞれ独立していますし、送信側にもバッファレジスタが存在しています。
トランスミットデータレジスタ (TDR) が空の場合には、TDR にデータが書き込まれると、ただちにトランスミットシフトレジスタ (TSR) に転送されて、送信がスタートし、TDR は空の状態になって、次のデータを受け入れる準備ができます。
「ただち」にと言っても、SCI モジュール内のクロックにしたがって動作するわけですから、本当に2バイト分を連続して書き込むと正しく動作しません。
2バイト目を書く前にエンプティフラグをチェックするループを置くのが通常ですが、1バイト目の書き込みと2バイト目の書き込みとの間に別の処理を挿入して、時間稼ぎをする方法でも十分実用になります。
タイマ割り込み処理ルーチンを下に示します。 MTU3 のアウトプットコンペアフラグ C 割り込みで起動され、L ch のデータを出力しています。
ふたつの「SCI3.TDR = ... 」の間に MTU3 のフラグクリアなどを挿入して時間稼ぎをしています。 TDR エンプティフラグのチェックはしていません。

// 114 MTU3 TGIC3
void INT_MTU3_TGIC3(void)
{
  SCI3.TDR = da_dac_tgr_buf.b[0];// send  MSByte of DAC data
  SCI3.SSR.BIT.TDRE = 0x00; // clear SCI3 xmit int
  MTU3.TSR.BIT.TGFC = 0; // clear TGRC compare match
  MTU3.TGRC = 0xffff;
  MTU3.TGRD = 0xffff;
  SCI3.TDR = da_dac_tgr_buf.b[1];// send  MSByte of DAC data
  SCI3.SSR.BIT.TDRE = 0x00; // clear SCI3 xmit int
}