USBプレヤー(7)
予想通り、並列転送型でこけてしまった。(TT)
まあUSBの250K/Sも1Byte4uと考えると立派ともいえる。
これにSPI出力転送を足して、176KB/S以上出せる魔法のような方式は???
ここにH8ならではの方式がある。
その名はDMA。SCI0はDMAの転送先に使える。(ここでSCI0にした理由が...。)
DMAはハード処理なのでプログラム負担がない。バスはとられるが、たかが知れている。
が、しかし、VS0XXXにバースト転送してもいけない。音楽再生中はバッファフルになってDREQが落ちる。
これで悩んだ。
で以下がこの記事の真骨頂というかエッセンスというか。
最早これだけで成り立っているというか。
・H8のSCIは外部クロックにする
・外部クロックはDREQが落ちると止まり、上がるとまた働く
(H8ではDREQは見ずにDMAが完了したかどうかだけ見る)
・外部クロックは予定されたバイト数を出すまで続ける。
例えば8KByteなら8KByteのクロックを出す
CPLDかと考えたが、この程度ならAVRでできる。
ただVS0XXXのXDCSなども制御するので8pinではなく、20pinのTyny2313にした。
秋月で...
AVRマイコン ATTINY2313-20PU
1個 ¥100
安い!!12Mhzで動かした。早すぎるとSCKの上限を超えるほど強力!!
【H8(3096)の使い方】
H8でSCI0でDMAをかける。
クロック(SCK0)は外部入力にする。
8Kなら8Kの転送指示を出し、後はDMAにまかせる。
DMAはH8が管理しているというより、AVRが出すクロックで送信速度が決まる。
【AVRTiny2313の使い方】
外部を12MHz程度にすれば、PortのOnOffで4MHzのクロックは楽勝で作れる。(タイマは不要)
32Byte単位で送信し、XDCSを制御する。
DREQを見て、Lになれば一旦止め、Hになれば再開する。
8Kなら8Kまでこれを繰り返す。
通常の通信用のSCKも必要なので、クロック切替端子で「XDCSを出さないで1クロック出す」モードもつけておく。
H8からの指定は外部割込みで受けて、取りこぼしがないようにする。
H8とのハンドシェイクであるが、基本的には
・DMA転送
DMAの終わりがAVRが全部送り終わった時点
・クロック転送
送信レジスタがエンプティで送信完了になれば送り終わった時点
となる。
XCS、MOSI、MISO、XRESETはH8側で制御する。
AVRはSCK、XDCS、DREQを処理する。
こんな感じ。
どういう動作になるかというと...
・H8ではUSBを読み込む
例えば8Kなら8Kをバッファに入れる
・H8でSCI0でDMAをかける
AVRに「8K送ってね」と頼む
・H8は次のバッファにUSBを読み込む
前とは別のバッファ(前のバッファは転送中なので)
・H8でDMAが終わったか見る
終わっていれば、AVRに転送依頼する
...を繰り返す。
VS10XXは2048Byteのバッファがあるので、フルであるならwavでも10ms程度は持ちこたえられる。この間にDMAをセットしてしまえばいいだけである。
DMAはバスを使うがプログラムを実行するわけではないので非常に高速で負担がない。(^^)
欠点と言えば、転送が小さな単位ではできず8Kなら8Kを送ってしまって中断できない。(^^!
32Byte単位のDMAもありだが、今度は設定が大変だし、細かすぎて意味が無い。
コメントはありません