2014年1月22日水曜日

FRDM-KL46Z用USBホストライブラリの試作(1)

mbedのOfficialなUSBHostに期待しているだが、
試しに機能限定でコードを書いてみたらLPC1768のOHCIに比べて簡潔に書けたので参考のために公開します。
少なくともUSBHostLiteくらいの機能はあります。

現在の機能・制限

・コントロール転送 送信、受信。
・インタラプト転送、受信のみ。USBマウス、USBキーボードで使用。
・バルク転送 送信、受信。パケットサイズを64バイトに固定。USBフラッシュメモリ、GPSレシーバーで使用。
※全てブロック型なので、転送完了まで待ちます。
・USBハブには対応していない。
・USBデバイスの自動認識は対応していない。予めUSBデバイスを接続しておく。

FRDM-KL46Zで使うには、多くのUSBデバイスはバスパワーで動いているようなので、
例えば、J16をショートしてUSBコネクタに5Vを供給するようにする。


USBデバイスのAプラグをFRDM-KL46ZのミニUSBコネクタに変換するケーブルが無かったので、
とりあえずブレッドボードでAコネクタを2つ向かい合わせて変換しています。


ライブラリ、使用例はmbedサイトに置いてあります。
http://mbed.org/users/va009039/code/KL46Z-USBHost/

***

以下、製作時のメモ:

USBホストモードの基本的な使い方は、KL4x Reference Manualの 35.6 Host Mode Operation Examples が参考になる。
しかしながら、TXバッファだけを使うように書いてあるのは間違い。RXバッファも使う。

実際に動いているコードとしては Freescale USB Stack V4.0.2 のkhci_kinetis.c が参考になる。
USBモジュールの初期設定やバッファの使い方の理解には、mbed USBDevice の USBHAL_KL25Z.cpp が参考になる。
ただし、DMAで動かしているようで、片方のバッファだけに割り当てているようだ。

ホストモードではエンドポイントの送信・受信バッファは、1つのエンドポイントのバッファを共用する。
送信、受信の区別はある。それぞれ、ODD、EVENの2つのバッファを持っている。
つまり、バッファ(ポインタ)は4つだけ。

ロースピードUSBとフルスピードUSBの判断に、JSTATEを見るのだが、
SOFを送信状態にしていると、いつでもフルスピードUSBと誤認識してしまう。
USBデバイスがアタッチするまでは、SOFは止めておく。

DATA0,DATA1のトグルはUSBホストに任せて自動で切り替えてもらう方法と、都度設定する方法がある。
コントロール転送だけで送信、受信でトグルを共用する場合とか、
一方方向だけのインタラプト転送(例えばUSBマウス)、バルク転送(例えばGPSドングルでデータを受信するだけ)なら、
USBホストに任せてもいいが、USBフラッシュメモリのように送受信で2つのエンドポイントを
使う場合には、都度設定する方法を選ばなければならない。

khci_kinetis.c では、トークンのリトライをしているが、現在はしていない、
時々Bus_Timetoutしたり、NAKが返ってくるのは、USBケーブルの配線の問題かもしれない。
USBデバイスによって、エラーの発生具合にばらつきがある。

デバイスのリセットはリファレンスマニュアルでは 10ms だが、khci_kinetis.c では 500ms がいいらしい。

SETUPトークンが成功するとACKだが、USBマウスではNAKが返って来る時がある。

INトークンが成功するとDATA0またはDATA1のステータスが返る。Bus_Timeoutが返って来る時がある。
USBフラッシュメモリーのバルク転送受信で時々発生した。

OUTトークンが成功するとACKが返る。

USBマウスでコンフィグレーションを設定するとステータスステージでSTALLが返ってくる時がある。

(2014/1/22)
---

0 件のコメント: