USBプロジェクト - 複合デバイスを考えた [USB]
Tsuneoさんのコメントを手がかりに複合デバイスについて考えました。 いや、考えただけですから。
要求仕様
hamayanさんからの要求仕様は、「キーボード・デバイスでありながら、PCの指示で電飾がコテコテ光る装置」でした。 これを満たすためには、「同一USBポートにキーボード・デバイスと電飾デバイスを割り当てる」必要があります。
物理的にUSBハブを付けると仕様は満たしますが、それでは、あまりにも不恰好。 その代わりに、一つの物理USBポートに複数の論理USBポートを割り当てると解決します。 この論理USBポートの事をインターフェースと呼ぶらしいです。
必要なのは、PCに複数のインターフェースが存在することを知らせることと、 到着したコントロール転送リクエストが、どのインターフェースに宛てられたものかを判断し、適切に割り振る機能であると認識しました。
デスクリプタは、どうする
Tsuneoさんの書き込みを勝手に引用すると、デスクリプタはこうなるらしいです。
- デバイス・デスクリプタ
- コンフィグレーション・デスクリプタ
- キーボード・インターフェース・デスクリプタ (#0)
- キーボードHIDデスクリプタ
- キーボードINエンドポイント・デスクリプタ (EP1)
- 電飾インターフェース・デスクリプタ (#1)
- 電飾HIDデスクリプタ
- 電飾INエンドポイント・デスクリプタ (EP2)
- キーボード・インターフェース・デスクリプタ (#0)
- ストリング・デスクリプタ
- キーボードHIDレポート・デスクリプタ
- 電飾HIDレポート・デスクリプタ
コンフィグレーション・デスクリプタは、ひとかたまりでPCに伝達されます。 そのため、"GET_DESCRIPTOR"リクエストでどのインターフェースのデスクリプタが要求されたかという事は考えなくても構いません。 問題になるのは、コンフィグレーション・デスクリプタの外に出されてしまった「HIDレポート・デスクリプタ」の方です。
"GET_DESCRIPTOR"リクエストで要求されたのがキーボードのデスクリプタなのか、電飾のデスクリプタなのかを知るための手がかりは、SETUPパケットの"wIndex"に書いてあります。 標準デスクリプタが要求されたときには、このフィールドにはZEROまたは言語IDが入ります。 ところが、HIDクラス・デスクリプタが要求された場合には、インターフェース番号が入ります。 つまり、このフィールドを見て、PCに返すHIDレポート・デスクリプタを返せば良いということがわかります。
SET_REPORTリクエストへの対応が必要
MC908JB16には、EP0以外のエンドポイントが二つしかありません。 つまり、複数のHIDインターフェースを使う場合には、HIDで使用するインタラプトOUTエンドポイントを用意するわけにはいかないので、"SET_REPORT"リクエストの処理が必須になります。
"SET_REPORT"リクエストの場合も、インターフェース番号が"wIndex"フィールドに入ってきます。 このフィールドを見て、どのインターフェースに宛てた"SET_REPORT"リクエストなのかを判断し、しかるべき処理を行います。
何だかできそうな気になってきました。 他に忘れ物は無いかな?
付録 : USBプロジェクト索引
- USBプロジェクト - ファームウェアに立ち返る (1)
- USBプロジェクト - ファームウェアに立ち返る (2)
- USBプロジェクト - ファームウェアに立ち返る (3)
- USBプロジェクト - ファームウェアに立ち返る (4)
- USBプロジェクト - ファームウェアに立ち返る (5)
- USBプロジェクト - ファームウェアに立ち返る (6)
- USBプロジェクト - ファームウェアに立ち返る (7)
- USBプロジェクト - ファームウェアに立ち返る (8)
- USBプロジェクト - ファームウェアに立ち返る (9)
- USBプロジェクト - ファームウェアに立ち返る (10)
- USBプロジェクト - ファームウェアに立ち返る (11)
- USBプロジェクト - ファームウェアに立ち返る (12)
- USBプロジェクト - ファームウェアに立ち返る (13)
- USBプロジェクト - HIDデバイス(1)
- USBプロジェクト - HIDデバイス(2)
- USBプロジェクト - HIDデバイス(3)
- USBプロジェクト - 複合デバイスを考えた
- USBプロジェクト - HIDデバイス(4)
- USBプロジェクト - HIDデバイス(5)
参考文献
USBハード&ソフト開発のすべて―USBコントローラの使い方からWindows/Linuxドライバの作成まで (TECHI―Bus Interface)
- 作者: インターフェース編集部
- 出版社/メーカー: CQ出版
- 発売日: 2006/07
- メディア: 単行本
USBターゲット機器開発のすべて―各種USBコントローラの使い方と基本ソフトウェアの作成法 (TECHI―Bus Interface)
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2005/08
- メディア: 単行本
>MC908JB16には、EP0以外のエンドポイントが二つしかありません。 つまり、複数のHIDインターフェースを使う場合には、HIDで使用するインタラプトOUTエンドポイントを用意するわけにはいかないので...
えーと、EP2はIN EP2 (TX), OUT EP2 (RX)を同時に動作させることができるんだと思っていたのですが、違うのかな。
同じエンドポイント・アドレスが割振られていても、IN EPとOUT EPは全く独立したものである、というのがUSBでの常識です。ただし、デフォルト・エンドポイント(EP0)はかなり融合していますが。
データシートを見る限り、EP2をINにするかOUTにするか、というレジスタ設定は見あたらないようです。
ほとんどのレジスタは、EP2に関してIN/OUT用が独立しています。
IN/OUTの両方に関わるのはこの2つのビットだけのようです。
11.8.7 USB Control Register 2
STALL2 — Endpoint 2 Force Stall Bit
11.8.8 USB Control Register 3
ENABLE2 — Endpoint 2 Enable
中には、USB Endpoint 2 Data Registersのように Read/Writeで切替わるものもありますが。
Tsuneo
by Tsuneo (2008-04-19 21:05)
えっ、EP2は、双方向で使えるのですか?半二重だと思っていた。
データシートを読み返してみると、"Features"には、このように書いてあります。
Endpoint 2 with 8-byte transmit buffer and 8-byte receive buffer.
"or"ではなく"and"と書いてあるので、同時に使えると考えてもおかしくありませんね。ただし、ENABLE2が共通なので、複数のインターフェースにまたがるような使い方はしない方が良いのですね。
ますます、複合デバイスの可能性が広がってきました。あとは、勢いだけだな。
by noritan (2008-04-19 23:46)
私も、Features におけるEP0とEP2の説明が同じになっているのが不思議でした。
参考のために読んでいた他社のデバイスと違うので、ハテ?と思ってました。
そうと分かれば、早く自由に使えるようになりたいな。
by DAI (2008-04-20 00:01)