2016/08/06

USB HIDマウスのデータパスの16bit化

前からPSoC Creatorの3-button Mouseのサンプルのソースコードを弄って色々(これとかこれ)やってましたが,このサンプルはデータパスが8bitなので1回のポーリングで-127~127の範囲の値しか送れませんでした.そこで,データパスを16bit化することにしました.
16bit化することにより,最近のゲーミングマウスと同レベルの値の範囲を使用することができるようになるので,色々と調査が捗るはずです.

しかし,USB HID Noobな私にとっては「どこを弄ればよいのかさっぱり・・・」という感じでネットの海を彷徨うこと数時間・・・
Zowie EC2 EVOのディスクリプタを参考にすることでなんとか解決しました.
参考 : Zowie mouse wheel scroll up/down not working
(このログを出したアナライザー欲しいんですけど1ライセンス$200なんですよね・・・とりあえずはUSBViewとMicrosoft Message Analyzerで誤魔化しています)

デバイスが応答しなくなる問題の対策

ディスクリプタを弄りながらデバイスを何度も接続していると,デバイスの反応がなくなることがありますが再起動すると治るようです.

HID ディスクリプタの設定

最終的なHID Descriptorの設定は以下のようになりました.
(PSoC Creatorの3-button Mouseのサンプルから変更した部分は青線で囲んだ部分だけです.)


ディスクリプタの簡単な解説

前半がボタン関係です.3-button Mouseなので,ボタンのUSAGE_PAGEが3つあり,USAGE_MINIMUMが1でUSAGE_MAXIMUMが3,REPORT_COUNTが1になります.
ボタンは0/1しか表現できないのでLOGICAL_MINIMUMが0,LOGICAL_MAXIMUMが1となり,REPORT_SIZEが1になります.
3ボタンマウスだと,ボタンの状態表現に3bitしか必要ないため,余った5bitをパディングします(中段).

後半がカーソル関係のディスクリプタで,USAGE_PAGEはGeneric Desktop Controls(0x01)になります.USAGEは0x20がX軸で0x21がY軸です.
データパスを16bit化するので,LOGICAL_MINIMUMを-(2^15-1) = -32767 (0x8001)にして,LOGICAL_MAXIMAMは2^15-1=32767(0x7FFF)になります.また,REPORT_SIZEを16にします.
ここで,REPORT_COUNTは変更の必要はなく,XとYの2軸なので2になります.
(ちなみに,データパスが8bitの場合はLOGICAL_MINIMUMが-127,LOGICAL_MAXIMUMが127,REPORT_SIZEが8になります.)

コード

ボタンの状態を1byte(3bit+5bitパディング),X軸で2byte,Y軸で2byteになるので,USBFS_LoadInEP()に渡す配列は5byteになります.
例 : uint8 mouseData[MOUSE_DATA_LEN] = {0u, 0u, 0u, 0u, 0u}
この場合だと,{ボタン,X軸下位8bit,X軸上位8bit,Y軸下位8bit,Y軸上位8bit}という風になります.

X軸の変位をdxとして場合はこんな感じで代入すれば良いと思います.(あまりオーバーフローとか考慮してないですが・・・)
mouseData[1] = (uint8)dx;
mouseData[2] = dx >> 8;


ポーリングごとにdxを1ずつ増やしたり減らしたりするようなコードを書くと,こんな感じの応答になりました.
図のように,8bitデータパスの限界値である±127を超えてデータを送ることができています.

※超絶初心者なので,この記事の記述は間違っている可能性があります.

0 件のコメント:

コメントを投稿