USBシステム: ソフトウェアドライバの作成

目的とするUSBデバイス(ゲームPAD)が動作するシンプルなドライバを作成します。

ゲームPADを接続してUSBホストCoreからバスリセットを行うと、USBデバイスはデフォルトステートに移行ます。また、USBホストCoreからはCPUに対して接続イベント(CONNECTION_EVENT)インタラプトが発生します。この状態で、USBデバイスのデフォルトアドレス0に対してアクセスが可能になります。

usb_pic4

デフォルトステートまでの処理

USBデバイスとのデータ転送

USBホストCoreとUSBデバイスは、IN/OUT/SETUPのTransactionを用いてデータ転送を行います。
送信(OUT Transaction)
USBホストからUSBデバイスにデータを転送します。USBホストCoreのUSB_TX_FIFO_DATAに送信するデータを設定、HOST_TX_TRANS_REGレジスタのTRANSACTION_TYPEにOUTDATA0_TRANSまたはOUTDATA1_TRANSを設定した後、
HOST_TX_CONTROL_REGのTRANS_REQ_BITを1に設定すると、OUT Transactionを実行します。

usb_pic5

OUT Transactionフロー

受信(IN Transaction)
USBデバイスからデータを受信します。HOST_TX_TRANS_REGレジスタのTRANSACTION_TYPEにIN_TRANSを設定後、HOST_TX_CONTROL_REGのTRANS_REQ_BITを1に設定すると、USBデバイスにIN Tokenが送信されます。USBデバイスからデータを受信するとUSB_INTERRUPT_STATUS_REGのTRANS_DONE_BITが1になります。USB_RX_FIFO_DATA_COUNT_LSBの値を読み出し、その回数だけUSB_RX_FIFO_DATAのデータをリードします。

usb_pic6

IN Transactionフロー

SETUP Transaction
デバイスリクエスト用のデータをUSB_TX_FIFO_DATAに設定、HOST_TX_TRANS_REGレジスタのTRANSACTION_TYPEにSETUP_REANSを設定後、HOST_TX_CONTROL_REGのTRANS_REQ_BITを1に設定すると、SETUP Transactionを実行します。usb_pic7

ディスクリプタの獲得

どのようなデバイスがUSBバスに接続されているかは、そのデバイスの標準ディスクリプタを獲得する事で判断できます。

  • デバイスディスクリプタ
  • コンフィグレーションディスクリプタ
  • インターフェースディスクリプタ
  • HIDディスクリプタ
  • エンドポイントディスクリプタ

各ディスクリプタは、コントロール転送でUSBデバイスから獲得します。HID(Human Interface Device)ディスクリプタは、HIDクラス独自のディスクリプタです。
各ディスクリプタの詳細はこちら
各ディスクリプタから、USBデバイス(ゲームPAD)についての以下の情報が得られます。

  • コンフィグレーション数は1
  • インターフェース数は1
  • エンドポイント数は1(除くエンドポイント0)
  • インターフェースクラスは3(HID)
  • エンドポイントのアドレスは1
  • エンドポイント1の転送はインタラプトIN転送
  • エンドポイント1の最大パケットサイズは4

インタラプト転送
ディスクリプタ情報から、USBデバイス(ゲームPAD)のデータは、エンドポイント1へのインタラプト転送で獲得できることがわかりました。CPUのタイマー割り込みを用いて、一定間隔のインタラプト転送をUSBデバイスに対して発行し、その時のゲームPADの状態を獲得します。

usb_pic10

インタラプト転送フロー

ゲームPADデータの獲得

ゲームPADのデータ(どのボタンが押されたか、どの方向キーが押されたか)は、インタラプト転送で獲得したデータに格納されています。データフォーマットは、HIDクラスのREPORTディスクリプタから得られます。今回使用したゲームPADは、4ByteのデータとしてPADの状態がホストに返されます。PADの状態は次のフォーマットで格納されています。

Byte フィールド名 説明
0 x方向キー 左: 0センター:0x7f, 右: 0xff
1 y方向キー 上: 0センター:0x7f, 下: 0xff
2 ボタン0グループ 各ビットに8個のボタンの状態をアサイン OFF:0, ON:1
3 ボタン1グループ ビット0と1に、2個のボタンの状態をアサイン OFF:0, ON:1

テストプログラム

簡単なテストプログラムで動作の確認を行いました。

  • USBデバイスのアドレスは5に設定
  • インタラプト転送は、CPUのタイマ割り込みを用いて1秒間隔で実行
  • FPGAからのIRQ1インタラプトでUSBホストCoreのFIFOをリードし、ゲームPAD用の構造体にデータを格納

プログラム(抜粋)

メイン

タイマー設定

インタラプトハンドラ(タイマー割り込み)

インタラプトハンドラ(FPGA IRQ1割り込み)

ゲームPAD用データ構造体


スポンサーリンク
広告大
広告大
  • このエントリーをはてなブックマークに追加
スポンサーリンク
広告大