USB HUB HID デモシステムの製作 2013.11.20 2014.1.13

    [Japanes][English]

    1.概 要

     先に公開したUSBのHUBドライバーを内蔵したUSBホストモジュールを使ったデモシステムをもう一つ作成した。

     このデモシステムでは、2つ以上のHIDデバイス(マウスやキーボード、ジョイスティック)を、ハブを通してPIC32MXに接続出来る。

    デモシステム構築に使ったPIC32MX基板SBDBT32

     このデモシステムでも、ランニングエレクトロニクス社から販売されている 「SBDBT32」基板を使った。

     4ポートのハブをこのマイコンボードに接続する。さらに、このマイコンボードとPCをRS-232により接続する。PC上では、ハイパーターミナルやテラタームの通信ソフトを115.2Kbpsで、起動しておく。


    2. 動かし方

    2-1. デモシステムの構築

     以下のプロジェクトファイルをダウンロードして、MPLAB IDE にてコンパイルした後、Pickit3 などのプログラマーを使って、出来上がったバイナリを、 SBDBT32 に書き込む。




    主なプログラムファイルは、次のとおりである。

      Source FileComment
      main.cデモプログラム
      usb_config.cUSBシステム設定
      usb_host.cHUBドライバー内蔵USBホストドライバー
      usb_host_hid.cHIDドライバー
      (複数のデバイス接続に対応)
      usb_host_hid_parser.c
      usb_host_hid_device.cHIDデバイス(マウス、キーボード、ジョイスティック)ドライバー


    2-2. デモシステムの起動とデバイスの接続

    2つのマウスと1つのキーボードを接続した 2つのマウスと2つのジョイスティックを接続した

     デモシステムが書き込まれたSBDBT32とパソコンを接続し、SBDBT32に+5Vの電源を供給するとデモシステムが起動する。 パソコンのターミナルに、次のようなメッセージが表示されればデモシステムは操作可能である。

      *** Demonstration program Menu *********************
      m:Mouse read test.
      k:Keyboard read test.
      j:Joystick read test.
      =>

     次に、SBDBT32のUSBポートにHUBを接続する。HUBを接続しただけでは、画面表示は何も変わらないが、続けて、HUBのポート1にマウスを接続すると、 次のようなメッセージが出力される。

      mouse attached.
       address=2

     ここで、マウスを一旦外して、その後、マウスをHUBのポート4に繋ぎ変えると、次のようなメッセージが出力される。

      mouse detached.
       address=2

      mouse attached.
       address=5

     続けて、別のマウスをHUBのポート1に、キーボードをHUBのポート3に、ジョイスティックをHUBのポート2に接続すると、次のようなメッセージが表示される。

      mouse atached.
       address=2

      keyboard atached.
       address=4

      joystick atached.
       address=3

    次に、エンターキーを押すと、操作メニューが表示される。


    2-3. デモシステムの操作

     以下の操作メニューに従って操作する。

      *** Demonstration program Menu *********************
      m:Mouse read test.
      k:Keyboard read test.
      j:Joystick read test.
      =>

     キーボードをタイプして、'm' を入力すると、マウスのテストを行うことが出来る。また、'k' を入力すると、キーボードのテストを行うことができる。


    2-3-1. マウスのテスト

     マウスのテストでは、マウスの状態を表示する。 'm' を入力した後、手元のマウスのボタンを押したり離したり、左右前後にぐるぐる動かすと、画面に次のようなメッセージが表示される。

     何かキーをタイプすれば、操作メニューに戻ることができる。

      Start mouse test.
      Push any keys of PC keyboards when you will stop the mouse test.

      left button on.
      right button on.
      wheel button on.
      move to up.
      move to down.
      move to right.
      move to left.
      move to right up.
      move to right down.
      move to left up.
      move to left down.
      wheel up.
      wheel down.

    2つ以上のマウスを接続している場合、どのマウスを操作しても、それぞれのマウスの状態変化を表示する。テスト中に全てのマウスを取り外すと、次のメッセージを表示し、テストは終了する。

      Mouse detached, to stop the mouse test!

     あるいは、PCのキーボードのキーを押すと、テストを終了する。

      You pressed any keys, to stop the mouse test!

    2-3-2. キーボードのテスト

     PCのキーボードで、'k' を入力すると、USB接続したUSBキーボードのテストを開始する。

      *** Start USB keyboard test.
      Please press a key of USB keyboard.
      If you press Ctrl+C, to stop the keyboard test.

     もし、キーボードが接続されていなければ、次のようなエラーメッセージが表示される。

      Keyboard not connected. Can't test!

     テスト中、USBキーボードから入力された文字が表示される。Ctrlと'c'を同時に入力するとテストを終了する。


    2-3-3. ジョイスティックのテスト

     PCのキーボードで、'j' を入力すると、ジョイスティックのテストを開始する。

      *** Start joystick test.
      Push any keys of PC keyboards when you will stop the joystick test.

     もし、ジョイスティックが接続されていなければ、次のようなエラーメッセージが表示される。

      Joystick not connected. Can't test!

     ジョイスティックを操作すると、各軸の値やハットスィッチの値、ボタンの状態を表示する。

      X=127
      Y=127
      Z=127
      R=127
      HatSwitch=1
      HatSwitch=2
      btn: 1 2 3 4 5 6 7 8 9 10 11 12
      on


    3. HIDドライバーやHIDデバイスドライバーについて

    マイクロチップが提供するプログラムを修正して、複数のHIDデバイスを動かせるようにした。

    - usb_host.c (マイクロチップ提供、HUBドライバーを追加した)
    - usb_host.c (カスケードハブ対応版)

      追加コードに存在していたバグの修正と、2つの関数、USBHOSTInit()とUSBHOSTShutdown()について、処理を見直すとともに修正を行った。

    - usb_host_hid.c (マイクロチップ提供)

      2つのグローバル変数、'pInterfaceDetails' と 'pCurrentInterfaceDetailes' について、これらを配列変数に変更をして複数のデバイスが同時に動かせるようにした。

       USB_HOST_APP_EVENT_HANDLER のマクロの指す値を、USB_ApplicationEventHandler から、usb_host_hid_device.c の中にある USB_HIDDeviceEventHandler へと変更した。 これは、HIDに関するイベントハンドラーをアプリケーションプログラムではなくHIDのデバイスドライバー内に閉じ込めるための策である。

       さらに、report descriptor の解釈を要求するイベントハンドラーの呼び出しの第3引数に、'deviceInfoHID[].rptDescriptor'を設定するようにした。 これにより、usb_host_hid_device.c の中のイベントハンドラーが呼ばれた時、イベントハンドラー内で、接続されたHIDデバイスの種類(マウスやキーボードなど)を決定できる。

      元のコード:
      if (USB_HOST_APP_EVENT_HANDLER(deviceInfoHID[i].ID.deviceAddress, EVENT_HID_RPT_DESC_PARSED, NULL, 0 ))

      修正したコード:
      if (USB_HOST_APP_EVENT_HANDLER(deviceInfoHID[i].ID.deviceAddress, EVENT_HID_RPT_DESC_PARSED, deviceInfoHID[i].rptDescriptor, 0 ))

    - usb_host_hid_parser.c (マイクロチップ提供)

       このファイルは、テストをした限りでは、何も変更する必要はなかった。最初、グローバル変数である itemListPtrs や deviceRptInfo は、配列変数にする必要があるかと思ったのだが、その必要はなかった。 report descriptor の解釈処理が終われば、その後のデバイスの操作では、これらの変数は使われないようだ。

    - usb_host_hid_device.c (今回開発したもの)

       このソースファイルは、マイクロチップが、ライブラリのサンプルプログラムとして提供している mouse_demo.c や keyboard_demo.c を元に作成した。

       配列変数を使うことで、2つ以上のジョイスティックや2つ以上のマウス、あるいは、種類の異なる複数のデバイスを同時に動かせるようにした。

       アプリケーションプログラムから呼び出される関数は、次の4つである。

      int mouse_read(int num, USB_MOUSE_DATA *data);
      int keyboard_read(int num, USB_KEYBOARD_DATA *data);
      int joystick_read(int num, USB_JOYSTICK_DATA *data);
      int getHIDnumOfDevice(BYTE devicetype);

      (USB_XXX_DATA マクロは、 usb_host_hid_device.hで定義されている)

       xxx_read(int num, USB_XXX_DATA *data) の名前の関数は、アプリケーションプログラムがデバイスからの値を取得するためのものであり、最初の引数 'num' は、複数のデバイスが接続されている時、どのデバイスであるかを識別するものである。例えば、2つのマウスが接続されていた時、2つ目のマウスにアクセスする時には、num に 2 を設定し、mouse_read()関数を呼び出せばよい。

       getHIDnumOfDevice() 関数は、接続されているデバイスの数をアプリケーションに教えるものである。

    - main.c

       これは、アプリケーションプログラムのサンプルとして作ったもので、マウスのテストでは、2つ以上のマウスが接続されている時、全てのマウスにアクセスするようにコーディングした。 テスト中は、マウスを接続したり切り離したり出来るし、一つだけマウスが接続されていればテストは継続される。

       以上、その他の事は、ソースファイルを眺めてみて欲しい。



    4. 最後に

     このデモシステムをPIC24で試してみる時には、CPUチップのリビジョン番号に注意して欲しい。あるリビジョンでは、このプログラムはうまく動かない。 マイクロチップが提供しているシリコンエラッタを参照して欲しい。

    (あるリビジョンでは、マウスなどのロースピードデバイスをHUBを経由して接続した時、HUBに対するPREシグナルを正しく処理しないバグがあります。) 

     このHIDデバイスドライバーの開発にあたっては、Jozsef Laszlo(a.k.a joco, http://joco.homeserver.hu)氏から、貴重なアドバイスを頂いた。 ここに、彼に対し感謝の意を表する。