« 2006年10月 | トップページ | 2006年12月 »

2006年11月11日 (土)

USB入門

USBデバイスを作る4

平成18年秋季全国火災予防運動
「消さないで あなたの心の 注意の火。」

 11月9日(木)~11月15日(水)

一応書いとこ。

今週も引き続きUSBである。AVRでパケットの受信をする事が出来た
ので、送信部のコードを書いて見ようと思う。

AVRを使いソフトウェアだけで送受信が可能と思われる、USBの転送
レートはロースピードの1.5Mbps限られる。なのでAVR側で1.5MHzを
カウントし、このタイミングでポートから1ビットのデータを入出力する
必要がある。

ブレッドボード上のMega88にはクロック源として、20MHzのセラロック
を繋いである。この場合1.5MHz1周期を作るのに13.3333・・・回分の
CPUクロックを数えればいい。もちろん少数を含む数をカウンタで数
える事は出来ないので、ブレセンハムのアルゴリズムを応用する。
この場合、1.5MHz1周期とCPU13クロックの誤差は0.3333・・・つまり
1/3なので、CPU13クロックを1サイクルの工程と考えた場合、X軸が
この工程1サイクル、Y軸が1.5MHz1周期という座標系に描かれる
傾き1/3の直線の方程式と考える事が出来る・・・などと難しく考える
事も可能だが、単純に3サイクルに1回CPU1クロック分を加算した
サイクルを作ればいい。つまり、13CPUクロックで1回の1ビット入出
力を行い、次の13CPUクロックで1回、次は14CPUクロックで1回の
入出力。この繰り返しを必要なビット数分行えばいい。これで誤差の
累積を防ぐ事が出来る。

また、クロック源にセラロックを使っているのだが、セラロックの発振
精度でUSBパケットが送受信可能かどうかを考えてみる。
ソフトウェアでUSBパケットを受信する場合、ホストと同期を行えるタ
イミングはパケット送信最初に送られて来る、SYNC領域のみだ。
USARTのように1バイト単位で同期を取れる通信方法と違い、SYNC
領域で同期したら、パケット最後まで同期を失う事なくデータを受信
することが出来る程度のクロック精度が必要になる。
ロースピードのデバイスで受信するデータ数最大値は、PID/DATA/
CRC16の領域の88ビットと、必要に応じてビット挿入される0値の
ビットの合計96ビット程だと思う。また、1つのビットを受信するため
に必要なCPUクロックは13.3333・・・・なので同期時にビットを検出す
るタイミングをビットの区切りから中間の7クロック目に合わせるとす
れば、96ビットを受信し終えた時点でクロックのずれが6クロック分
に収まっていれば、正常にデータを受信出来るはず。実際に計算す
ると、

 約0.46875%

う~ん。実際には必要精度がこれより高くなるだろうが、セラロックの
精度は±0.5%程度、ちょっと厳しいが条件が良ければ動いてしまう
かもと期待してしまう数値ではある。実の所手元のブレッドボード上
のMega88ではセラロックの発信源で快調にデータを受信している。
もう少し様子をみて、問題があるようならクリスタルにしてみよう。

で、パケット送信部を書く。前回エニュメレーション時に送られて来た
標準要求に応答してみる。この事でセットアップトランザクションが
完了するので、次にディスクリプタを載せる為のINトランザクション
が発生するはず。AVRで送られて来るパケットをメモリに収め、後か
らパケット内容をRS232Cで送信しPC上でモニタする。
無事INトークンを含むパケットを受信した。

Tiny2313 

 

 

 

 

 

 

秋月電子でTiny2313が安かったんで、つい買ってしまった。

| | コメント (0) | トラックバック (0)

2006年11月 1日 (水)

USB入門

USBデバイスを作る3

AVRでUSBホストからのパケットを受信する事が出来たので、
次は送信部のコードといきたいところだが、その前に少し下準備
をする。

USBでは受信したパケットの誤りを検出するためCRCが用いられ
る。そこで用意したパケットに添付すべく、CRCを計算する必要が
ある。また、実際のUSBの信号線には、NRZIという方法で符号化
したデータが流れている。これは、送受信器間で同期を失う事を
防ぐために0や1が連続して送信する事を抑制する働きをする。
なので、HEXデータ(Decimalで表記してもいいが・・・)をNRZIで符
号化する事も必要になる。

まず、CRC計算部だが、実の所このCRC計算法にしてもNZRIに
しても、今回USBを調べて始めて知り得たにわか知識なので、こ
れらの事を調べる事から始めなければいけない。

CRC計算ルーチンを書くにあたって計算法を調べてみた。幸い幾
つかの説明とサンプルコードを掲載しているサイトを見つける事が
できたので、早速コードを書いてみる。先日のパケット受信実験で
得られたデータパケットのCRCを実際に計算し、そのパケットに添
えられていたCRCを比較してみたが、値が一致しない。この事で2
晩程悩んだが、HEROさんの所の "AVRusb.ZIP" に含まれる資料
から "ハードウェアCRC16計算回路" を見て納得。計算方法が違って
いた。この回路をエミュレートする形で計算部を実装してみると、
うまく値が一致した。

次に、データをNRZI符号化するコードを考える。こちらはそんなに
難しくはないのだが、バイト単位のデータをビットの連続として捕ら
えなければならないので、実装がちょっとめんどくさい。また、1が
6ビット連続するデータを変換する場合1ビットの0を挿入するので、
変換後のデータは必ずしも8の倍数にならない。故に変換後の
データはバイト単位ではなくビット単位で管理する必要があり、
ここら辺の実装も幾らか煩雑になる気がする。これらを踏まえて実
際のコードを書く。

しかし、それなりに思い悩んだ末に書き上げたたコードなのに、
エディタ上で眺めてみると、思っていたほど高度に見えないのは
なんでだろう。

| | コメント (0) | トラックバック (0)

« 2006年10月 | トップページ | 2006年12月 »