ディジタルオーディオ用 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 }