ユークエスト株式会社
佐々木 哲(ささき さとし)
![]()
USBメモリがつながるようになったので、少し応用事例を紹介します。
RX62NにはSH2A(SH7262)の様な高機能なオーディオ出力はありませんが、10bitのDACが搭載されており拡張基板WKLCD-62Nを使用すると簡単にステレオオーディオ出力が実現できます。この機能を用いてUSBメモリに保存されたWAVファイルを再生することにします。(写真2)

写真2.WKLCD-62Nを使用して、オーディオスピーカとUSBメモリをつないだ様子
USBメモリのコピーでは、ファイルシステムを使用せずに稼働させましたが、今度はファイルを扱うためにファイルシステムが必要です。
MatrixQuestFs/fatを使用すればコンパイルしてMatrixQuestUSBにリンクするだけで容易に実現できますが、今回はInterface誌でおなじみのfatFsをMatrixQuestUSBにポーティングしてみることにします。今回の構成は図5の様になります。

![]()
移植に必要となる最小限のユーザ作成関数は、disk_initialize() disk_status() disk_read()ですが、サンプルにはdisk_write() disk_ioctl()を合わせて実装しています。
全関数共通の仕様として、サポートドライブは一つとしますので、各関数の引数Driveは0のみ有効です。
・disk_initialize()
ディスク・ドライブを初期化する関数です。USBの初期化はあらかじめ別途行う事としますので、ここではフラグ STA_NOINIT をクリアします。
・disk_status()
ディスク・ドライブの状態を取得する関数です。戻り値と今回のサンプルの関連については以下の表を参照してください。(表4)
| STA_NOINIT | ドライブが初期化されていないことを示すフラグ。 システム・リセットやメディアの取り外し等でセットされ、disk_initialize() の正常終了でクリア、失敗でセットされます。 |
| STA_NODISK | メディアがセットされていないことを示すフラグ。 このバージョンではUSBメモリの有無を示します。 USBカードリーダなどでメディアが無い場合でもこのフラグはクリアされますので、使用できません。 |
| STA_PROTECTED | メディアがライト・プロテクトされていることを示すフラグ。 常にクリアされています。 |
表4. disk_statusが示す状態とUSBの状態の対応
・disk_read()
ディスクからセクタを読み出す関数です。若干の型変換が必要なことを除けばそのまま渡すことができます。
usblBlkRd(usblFatFsInfo.pUsblBlk,(UINT)SectorNumber,(UINT)SctorCount,Buffer);
・disk_write()
ディスクにデータを書き込む関数です。disk_read()同様若干の型変換が必要なことを除けばそのまま渡すことができます。
usblBlkWrt(usblFatFsInfo.pUsblBlk,(UINT)SectorNumber,(UINT)SectorCount,Buffer);
・disk_ioctl()
ディスク・ドライブ自体に対する様々な制御をします。今回はfatFsのサンプルffsample.zipで実装を求められているCTRL_SYNC GET_SECTOR_SIZE GET_SECTOR_COUNT GET_BLOCK_SIZE CTRL_ERASE_SECTOR を実装します。実際にはほとんど何もする必要はありません。(表5)
| コマンド | 解説 | 戻り値 | Bufferの値 |
|---|---|---|---|
| CTRL_SYNC | ディスクへの書き込みを完了します。USBドライバの場合、SYNCで何等かの処理が必要な場合はありません。 | RES_OK | N/A |
| GET_SECTOR_SIZE | それぞれの情報はMSCのクラスドライバで取得して保持しています。この情報が必要となるのは(_USE_MKFS == 1)の場合のみですから、今回は非対応としています。 | RES_PARERR | N/A |
| GET_SECTOR_COUNT | RES_PARERR | N/A | |
| GET_BLOCK_SIZE | サンプルでは固定値を返します。 | RES_OK | 512 |
| CTRL_ERASE_SECTOR | フラッシュ・メモリ用ということですので、USBホストドライバについては無関係ですので、常にOを返します。 | RES_OK | N/A |
表5. disk_ioctlのコマンド対応一覧
たった上記の実装だけでfatFsを使用してUSBメモリのファイルにアクセスできるようになります。
![]()
WAVファイルには、オーディオデータの情報が先頭に記録されており、その後ろにPCMオーディオデータが保存されています。
PCMデータの詳細については、WebサイトTechVillage(http://www.kumikomi.net/archives/2010/07/ep22onse.php)に解説記事が掲載されていますので一読すると良いでしょう。
ディジタルオーディオの出力を確実に行うためにはDAコンバータに対して決められた周期でオーディオデータを出力する必要があります。ご存知の通り、一般的なCDは44.1kHz/16bit/STEREOでサンプリングされています。このデータを滞りなく再生するためにはUSBメモリから読みだすレートを計算すると…
44.1kHz x 16bit x 2ch = 1,411,200bit/sec ≒ 1.35Mbit/sec
となり、約1.35Mbpsのビットレートが必要になります。RX62N内蔵USBを使用する場合、USBはFullSpeedになりますが、MatrixQuestUSBを使用すれば、ビットレートとしては問題になりません。
ただ、このビットレートを保持しながら44.1kHz≒22.7μsecの間隔でオーディオデータをDACに転送する必要があります。
Interface誌2011年6月号の「オープン・ソースMP3デコーダを使ったMP3プレーヤの制作」ではCMTのタイムアウトによる割込みを利用していましたが、RTOSを使用する環境では22.7μsec間隔での割込みは負担になります。
RX62NではCMTの割込みをDMAの転送開始トリガにすることができますので、DACへのオーディオデータの転送をCMTの割込みをDMAコントローラ(以下DMAC)に対するトリガとして発行し、DMACがDACにデータを転送する事でオーディオ出力を実現してみます。DMACの設定はDMAフリーランノーマル転送モードと拡張リピートモードを組み合わせて使用し再生を実現することで、確実なオーディオ再生と安定したUSBの稼働を実現します。(図6)

ただ、このモードには一つだけ欠点があります。DMAの転送先をDACに設定しますが、拡張リピートモードでLch/Rchの順にトリガ毎に転送します。片方のチャンネルを44.1kHzで再生するためには88.2kHzの周波数で左右毎に転送する必要があります。この場合、Lchに対してRchは11.3μsec遅れて再生されることになります。
今回はあくまでUSBを使う事が本来の目標ですので、ここは目を瞑ることにしましょう。
![]()
バッファはコンパイル時にオーディオ再生データ保存用に設定したセクションを使用することにします。 このバッファをA面、B面に分けてダブルバッファとして考えます。つまり、B面を再生中にA面にUSBメモリからのデータを読み込んで、A面再生中にB面を読むという順序になります。
そのほか、以下のような流れです。
1.初期化
2.USBメモリ認識
3.USBメモリ内ファイルのOPEN
4.WAVヘッダ読み捨て
5.A面B面データ読み込み=>0x8000を全データに加算
6.DMA開始
7.A面再生完了待ち
8.A面データ読込み
8-1.詠み込んだデータに0x8000を加算
9.B面再生完了待ち
10.B面データ読込み
10-1.詠み込んだデータに0x8000を加算
11.8または10で終了と判断しなければ7へ
12.終了
7,9では、それぞれ再生(DMACによるDACへのデータ転送)の完了を待ちます。これはDMACの転送元レジスタのアドレスが何処を処理しているかで判断できます。
8-1,10-1では、USBメモリから読みだしたデータに0x8000を加算しています。これはWAVファイル内のデータが2の補数形式で保存されているのに対して、RX62Nでは整数値で扱うことに起因します。例えば、16bitデータの場合、WAVファイルのデータがとりうる値の範囲は符号付きで0x7fff〜0x8000ですがDACは0x0000〜0xffff(ただし上位10bitが有効)となりますので、WAVファイルのデータをそのままDACに書き込んでもうまくいきません。そこで、WAVファイルから読みだしたデータに対して0x8000を加算して整合性がとれるようにしています。
サンプルプログラムの具体的な使用方法はプロジェクト内のreadme.txtを参照してください。
![]()
以下の様に各レジスタを設定します。
| SYSTEM.MSTPCRA.BIT.MSTPA28 = 0; /* スタンバイ解除 */ DMAC0.DMCNT.BIT.DTE = 0; /* 割込み禁止 */ ICU.DMRSR0= 30; /* 起動要因の選択 CMT2の割込みとつなぐ */ DMAC0.DMSAR = (void *)buffptr[0]; /* バッファのアドレス */ DMAC0.DMREQ.BYTE = 0; /* 使用しない */ DMAC0.DMCSL.BIT.DISEL = 0; /* CPUへは割込みしない */ DMAC.DMAST.BIT.DMST =1; /* DMACA起動を許可 */ |
![]()
以下の様に各レジスタを設定します。
| SYSTEM.MSTPCRA.BIT.MSTPA14 = 0; /* スタンバイ解除 */ CMT2.CMCR.BIT.CKS = 0; /* PCLK/8を供給 */ CMT2.CMCR.BIT.CMIE = 1; /* コンペアマッチ割込み許可 */ CMT2.CMCOR = 68; /* 約88.2kHzの周波数 */ |
以下の様に各レジスタを設定します。
| SYSTEM.MSTPCRA.BIT.MSTPA19 = 0; /* DAスタンバイ解除 */ PORT0.DDR.BIT.B3 = 0; /* DA0出力使用 */ PORT0.DDR.BIT.B5 = 0; /* DA1出力使用 */ DA.DADR0 = 0x8000; /* 初期値zeroに設定 */ DA.DADR1 = 0x8000; /* 初期値zeroに設定 */ DA.DADPR.BIT.DPSEL = 1; /* MSB詰め */ DA.DACR.BYTE = 0xFF; /* D-A変換開始 */ |
![]()
以下の設定でDMAが開始されます。
| CMT.CMSTR1.BIT.STR2 = 1; /* カウント開始 */ ICU.IER[03].BIT.IEN6 = 1; /* 割込み許可 */ |
![]()
このサンプルプログラムではUSBメモリへのアクセスが本来の目的ですので、オーディオ再生プログラムとしては未完成です。たとえば以下の様な応用が考えられます。
・マクロ定義で固定しているファイル名をディレクトリ内の一覧から選択、または、順次再生する。
・44.1kHz,16bit,Stereoに固定しているWAV仕様をWAVヘッダの解析を行い、各設定を動的に反映する。
・基板上のSWやタッチパネルと連携して再生、早送り、曲スキップなどの機能を加える。
・LCDを活用して曲イメージに合わせた画像やレベルメータを表示する。
・Interface誌、2011年6月号に掲載されているMP3デコーダを実装してUSBメモリプレーヤーに仕立てる。
など、応用は多彩です。
また、MatrixQuestUSBとfatFsのインターフェース部分はRX62NでもSH2A(SH7262)でも同じですから、USBメモリのコピーで用いたMatrixQuestUSB/lite SH7262版にfatFsを実装する方法はRX62Nと全く同じです。メモリも大容量ですからミドルウェアを使用するメリットを活かして是非実装してみてください。
また、今回のサンプルでは極力プログラムを簡素化するためにRTOSのシステムコールを使わない様にしています。NORTiとMatrixQuestUSB/ex(廉価版)を導入するとNORTiのシステムコールを使って高機能なアプリケーションを開発することもできます。
![]()
雑誌『Interface』のダウンロードページへ
http://www.cqpub.co.jp/interface/download/contents.htm
2011年8月号 USB機器開発トラの巻!の「特集 第5章 USBメモリ内容コピー&WAVE再生プログラムの作成」から、RX62N用サンプルプログラムと、SH-2A用サンプル・プログラムがダウンロードできます。
参考文献
CQ出版社:Interface 2010年6月号 第1章 付属SH2Aマイコン基板の使い方
CQ出版社:Interface 2010年7月号 第4章 3.デバイス接続検知とバス・リセット
CQ出版社:Interface 2010年9月号 第3章 FATファイル・システムの詳細
CQ出版社:Interface 2011年5月号 Prologue 付属RX62Nマイコン基板の応用事例
CQ出版社:Interface 2011年6月号 第4章 オープン・ソースMP3デコーダを使ったMP3プレーヤの制作
ルネサスエレクトロニクス:SH7262 グループ、SH7264 グループハードウェアマニュアル
ルネサスエレクトロニクス:RX62Nグループ、RX621グループ ユーザーズマニュアル ハードウェア編
ルネサスエレクトロニクス:R8A66597FP/DFP/BG ASSP (USB2.0 2Port Host/1Port Peripheral Controller):
ミスポ:μITRON仕様準拠リアルタイムOS NORTi version4 カーネル編 ユーザーズガイド
ユークエスト:MatrixQuestUSB/lite USBホストドライバ ユーザーズガイド
ユークエスト:MatrixQuestUSB/lite Mass Storage クラスドライバ ユーザーズガイド
ユークエスト:MatrixQuest ミドルウェア共通環境 プログラマーズ・ガイド
- MatrixQuestUSB/host
- USB1.1/2.0対応ホストドライバ プロトコルスタック
- MatrixQuestUSB/lite
- 組込みコントローラ用USBホストドライバプロトコルスタック
- MatrixQuestUSB/ex
- マスストレージ機能専用USBホストドライバ
