PSoCでUSB
by K.I
2006/07/19〜
Index
- PastelMagicから、USBコントローラ内蔵のPSoC、CY8C24794-24LFXIが実装された PS-USP01ボードが発売になった。
- tanago55さんという方の設計で、USBのmini-Bソケット付き、2.45mmピッチで2×16のピンヘッダを2つ立てられるようになってる。
- CY8C24794のパッケージは、自分にはとてもちゃんと半田付け出来そうもなかったので手を出さなかったが、これで試すことが出来そうだ。
→このパッケージの半田付けをしなくて済むだけで嬉しい。
[top]
- PS-USP01のマニュアルを、PastelMagicからダウンロードして、ざっと内容を確認する。
- あらかじめ、AN2298のExample1が書き込まれている状態らしい。
- PS-USP01に未実装な部品を追加する。以下は付属していないので、別途、自分で用意する必要がある。
- プログラム書込み用の、1×5ピンヘッダ →MiniProgを取り付けるためのもの。
- パワーLED →電源モニター用(電流制限抵抗1kΩは実装済み)電池駆動なら付けない方が良い
- 2×16のピンソケット2個の取り付け→ピンヘッダにするかどうか迷うところ。
- 今回は基板側をいろいろ差換えることを考えてソケットにしたけど。
- ピンヘッダの方が良かったかしらん。部品面に付けるって手もあるんだよね。
- LEDは、やっぱり青色にしました。
- あと、バスパワー時の保護用のポリスイッチを付けることも出来るようになっているけど。
- とりあえずデバッグ中はセルフパワーで、MiniProgから電源供給するので、最初はポリスイッチは取り付けない。
- AN2298は、CY8C24794 Evaluation Boardを使ったアプリケーションノートなんだけど、回路がどうなってるのか良く分からない。
- PS-USP01のマニュアルを見ると、Example1は4つのスイッチと4つのLEDをUSBでコントロールするものらしい。
- P22,P23,P24,P25を、スイッチ入力(SW1〜SW4)
- P32,P33,P34,P35を、LED出力(抵抗経由でVDDに接続する)
- 最低限のピンだけ立てたベース基板を作れば良いかな〜と、ピン配置を見る。
- PS-USP01は、ポート番号が基板にシルク印刷されてるので、分かりやすい。
- doggieさんのページでも言っていたけど、これは便利。ピン番号なんか書いてあっても面倒臭いもんね。
- ふーん、ポート番号は連続してるけど、ピン配置はバラけてるな〜。
- これって、ブレッドボードで出来ないかしらん。
- でも、ちょっと無理っぽいな〜。。。。。うーん。
- で、無理矢理に以下のような配線をしてみました。
- ボードとの接続には、ヘッダピンを抜いたものを9本使用1。
→でも指でボタン押せません。竹串が必須。。。
- GNDピンは接続出来なかったので、ICクリップで接続する。
- 下側のLEDは、VDDに接続し難かったので、VSSに接続した。→点灯・消灯が逆になるけどね
- ポリヒューズ付けてないので、MiniProgで電源供給する
- しかし、これじゃスイッチ押せないなぁ。→しかたないので竹串で押すことにする。。
- でも、これは本当に危なっかしい。それこそショートして、本体のUSBインターフェース壊しかねない。
- 本当はちゃんとボード作るべきだよね。とりあえずお試しだけだな。。。
12列のピンのいずれかのみ接続すること、両方接続すると当然ショートします。。
[top]
- PS-USP01は、初めからAN2298のExample1が書き込まれているということなので、USB接続するだけで動くはずだ。
- MiniProgと、USBケーブルを接続して、PSoCプログラマを起動する。
- とりあえずは書込みするわけじゃなく、ただ電源を供給する為だけだ。
- PSoC Programmerで、Power Deviceにチェックすると、USBデバイスとして自動的に認識された。
- デバイスマネージャで、USB HID(ヒューマンインターフェースドライバ)として認識されている。
- でも、デバイスのプロパティでVIDとかPIDの確認は出来なかった。(Windows2000だから?)まぁ、認識されてるから良いか。。
- EZUSBみたいにドライバを起動時に読み込むんじゃなくて、標準ドライバでしてるのかな?
- AN2298に付属しているPCアプリケーションexample1.exeを起動する。
- ふーん。PC側からLEDを点滅させるだけじゃなく、スイッチでLEDを点滅させたり、いろいろ切替えられるようになってるんだ。
- これは結構分かりやすいサンプルだ。これを基にいろいろやってみると良さそうだな〜。
- Example2を試してみようと、コンパイルしてみるが、以下のエラー。
!E ./lib/usb.h(124): redeclaration of `T_USB_XFER_STATUS_BLOCK'
redeclaration?なんでだろう。
以下のようなDialogが出たけど、コンパイル出来た。
- でも、以下のようにデバイス不一致?で書込み出来ませんでした。何でかなぁ。。
Programming Terminated at 23:38:39
Check Device Family/Device setting or Programming Mode
Target Device does not match chosen Device
- マニュアルに載ってるやり方でもやってみたが、同じだった。
- コンパイルの問題じゃなく、書込み時のデバイス不一致だから当然か。
//#include "usb.h"
- 実は、ボードは2つ買ったので、もう1つのボードにISSP端子だけ付けて試してみましたが同じでした。
- ISSP端子しか付いてないから、半田付けの問題とは考え難いし。
- 気になるのは、説明書ではMINI Version 1.71になってるけど、自分のは1.67ってことかな。
- うーん、分からない。如何にも設定の問題のように思えるんだけど。。何か抜けてることがあるのかなぁ。
- ここで、pctoyfanさんより、MiniProg1のファームが古いのではとの指摘。
- 早速、 Cypressの、ソフトウェアおよびドライバのページから、PSoC Programmer2.2をダウンロードした。
- インストーラを起動すると、古いプログラムをremoveするように促されるので、removeする。
- それから、改めてインストーラを起動してプログラムをインストールする必要がある。
- PSoC Programmerを起動して、Programボタンを押すと以下のメッセージ。
Firmware update required at 19:07:59 Update firmware using Utilities/Upgrade Firmware
Open MiniProgrammer at 19:07:59 MINI version Expecting >= 1.71 got 1.67
これはdoggieさんの言ってたメッセージですね。僕のプログラマは相当古かったのかしらん。
- Utilitiesメニュー→Upgrade Firmwareで、MiniProgのファームを書換え。暫し待つ。
- 改めて、Programしてみると、すんなり成功しました。
- ectoyfanさん、doggieさんありがとうございます。PastelMagicのJUNKBOXさんからも同様のコメントを頂きました〜。
- 改めて、Example2を試してみます。
- プロジェクトを眺めても、イマイチ分からないんだけど、P03をA/D変換して、キーボードの振りをしてPCへデータを送るという感じなのかな。
- LCDにも、いろいろ表示されるらしいんだけど、面倒なので何も接続せずにやってみる。
- プロジェクトを、コンパイルしたら、Programmerを起動して書込み。
- これは、要するに特別のアプリケーションを作らなくても、標準のUSBデバイスとして動くことを示すサンプルみたいだ。
- ちゃんと動くみたいなので、これはこれで良しとする。→配線面倒なので。
- これは、同様にコンパイルする。
- デバイスマネージャで、USB HID(ヒューマンインターフェースデバイス)の'Process Monitoring Device'として認識されているんだけど。。
- Example3用のPCアプリケーションを起動すると、以下のように認識されない。
Could not find Process Monitoring Device
Example1とExample2は、問題なくコンパイルして動作したのに、何故Example3だけ認識されないんだろう?
- デバイスマネージャで、デバイスのプロパティでVIDとかPIDの確認は出来てないけど、一致していないのかなぁ。
- ここで、doggieさんもWin2Kで、Example3が動かなかったとの情報を頂く。
- うーん、もしかすると、Example3のPCアプリははW2Kに対応していないのかな?
- doggieさんから教えてもらった usbviewで、プロパティを確認してみよう。
- うーん、これでも見れない。っていうか、MiniProgも見れないなぁ。USBメモリもダメだ。
- もしかすると、ダメなのは拡張USB2基板を使ってるからかなぁ。
- Config Descriptorをチェックすると、さらに細かい仕様が見れるようだ。
- これで、Example3.exeでも認識出来るかな?と思ったけど、それはやっぱりダメでした。
- VBは良く分からないが、Example3のソースを見ると、StartUp.frmに以下の記述があるので、VID,PIDはOKだろう。
SystemName = FindHIDInterface(&H4242, &HEE03, &HFF03)
- VBも、XPも持ってないので、Example3については、とりあえずココまでにしておこう。
[top]
- やはりPC側のアプリケーションをなんとかしないと、良く分かんないなぁ。
- USBって、プラグアンドプレイで使うのは楽なんだけど、いざ作ろうと思うとPC側の負担が大きい規格のように思う。
- トラ技の2006年4月号の桑野さんの記事をみると、USBの1パケットの送受信は結構大変そうだ。
- ターゲット側は、ディスクリプタテーブルというのを作らなきゃいけないらしい。
- PCホスト側は、指定したVIDとPIDの一致するテーブルを持つターゲットと通信するってことなのかな?
- CypressのVBのソースから、Read,Writeを探してみると、こんな感じの行がある。
・Private Function ReadInReport() As Integer
- Success = ReadFile(ReadHandle, InReport(0), 3, BytesRead, ReadOverlap)
・Private Sub Continuous_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Continuous.Click
- Success = WriteFile(WriteHandle, Sample_Rate(0), 2, BytesWritten, 0)
・Private Sub GetOneSample()
- Success = WriteFile(WriteHandle, Sample_Rate(0), 2, BytesWritten, 0)
- 比較的シンプルに作ってあるみたい。
- やっぱりVBを使ったほうが良いんだろうなぁ。でもVBは使ったこと無いし、そもそも無い。
- tanago55さんのページから、 HIDドライバを使ったI/Oの実験のサンプルを試してみる。
- ファームをPSoCに書き込んで、電源を入れるとHIDとして認識される。
- でもW2Kの環境では、でもPC側アプリケーションのUSB_PSOC_IO.exeを実行すると、CPU使用率が100%になってしまって起動しなかった。
- このサンプルは、BorlandC++BuilderでクラスライブラリのVCLを使っている。
- PSoC側のファームはシンプルだし、ほとんどのポートを単純に操作するようになってるので参考になりそう。
- ここらへんは、unit1.cppをみると、ReadFileやWriteFileで記述されている。
- このexeファイルはXP用なので、XPだとスンナリ動くんだろうな〜。
- それに、おそらくW2K用にコンパイルし直せば、動作するのではないかと思う。
- でも、自分はSDKしか使ったことないからなぁ。
- 一般的には、MFCとかVCLのようなクラスライブラリを使うのが、正しい選択だと思うんだけど。。
[top]
- 一足飛びじゃなく、地道にやるか。。
- でも、USBのコントロールは自力では出来そうもない。
- 以前、買って積んでおいた CQ出版の「TECH I・USBハード&ソフト開発のすべて」を引っ張りだしてくる。
- 汎用USBドライバというのを使えば、HIDのコントロールが出来そうな感じだ。
- APIがシンプルなので、ここから始めれば理解し易いんじゃなかろうか。
- 柏野さんのページから、汎用USBドライバをダウンロードする。
- これはベンダIDとプロダクトIDを設定する必要がある。
- USBマウスって意外と、単純な信号を出しているらしい。
- まずはマウスの信号を見るようにしてみようか。ってUSBマウス持ってないじゃん。
Device Descriptor:
bcdUSB: 0x0110
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x08 (8)
idVendor: 0x056E (Elecom Co., Ltd.)
idProduct: 0x0040
bcdDevice: 0x0230
iManufacturer: 0x01
iProduct: 0x02
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: Low
Device Address: 0x03
Open Pipes: 1
Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Interrupt
wMaxPacketSize: 0x0008 (8)
bInterval: 0x0A
- SETUPディレクトリの、uusbd.infのVID,PIDを書換え。3箇所
:
[Kashiwano]
:
%USB\VID_056E&PID_0040.DeviceDesc%=UUSBD.Dev, USB\VID_056E&PID_0040 →VID,PID書換え
:
[Strings]
:
USB\VID_056E&PID_0040.DeviceDesc="Universal USB Driver (Mouse)" →VID,PID書換え
- マウスを繋いだ状態で、ドライバを更新する。
- SETUPディレクトリを指定する
- 再起動を促されたので再起動した。
- UUSBD用USBデバイスとして、マウスが認識された。→でも'!'になってる
Uusbd.sysを使ったUSBデバイスは見つかりません
- これは、uusbd.sysがちゃんと組み込まれてないってこと?
- uusbd.infの設定が悪い?
- それともこのデバイス自体の問題かな?
1 in down n/a 0.204 GET_DESCRIPTOR_FROM_DEVICE
1 in up n/a 0.219 CONTROL_TRANSFER 12 01 10 01 00 00 00 08 0x00000000
2 in down n/a 0.219 GET_DESCRIPTOR_FROM_DEVICE
2 in up n/a 0.219 CONTROL_TRANSFER 09 02 22 00 01 01 00 a0 0x00000000
- うーん。認識されてるようにも見えるけど。
- 考えてみると、正しい動作が分からないから、意味無いよね。。
- USBマウスを最初の状態に戻せば良いか。
- で、uusbdを設定する前の状態に戻そうとして、デバイスマネージャでドライバを削除してみる。
- また再起動しなきゃダメなのか。面倒だなぁ。W2Kだからかなぁ。
- UUSBD用USBデバイスとして、マウスが認識されたまま。→あいかわらず'!'になってるし。。
- あぁ、 ectoyfanさんが、Example1をNET用に移植されましたね。
- これで、開発環境の選択肢が増えたなぁ。うーん。VC++やめて、VBにしようかな。。
ちょっと横道に逸れちゃうけど、VBをいざ読んでみると、なかなか難しい。
- VCなら、WinMainで始まって、イベントループでWinProcが呼ばれるから、その流れが何となく分かるんだけど。。
- VBって、何処がどうなってるのか分かんないなぁ。
- Startupが、WinProcのようなもので、多分メッセージに対応した関数を呼び出すのかな?
- StartupLoadっていうのが、WM_CREATEみたいなもの?
- StartupPaintが、WM_PAINTってこと?Invalidateはどうするんだろ?
- じゃ、WM_TIMERとかに当たるのは?
- 疑問ばかりだ。
- うーん、そもそもMFCみたいにクラスライブラリになってるみたいだから、いろいろ隠蔽されてて構造が分かり難いのかなぁ。。
- 自分はMFCもいまいち合わなくて、SDKで作ることにしたしなぁ。。
- 結局、VBが分かんないというより、クラスライブラリが好きじゃないってことなのかも。
ちゃんと動く
- といいながらも、VS2005 StandardEditionなので、VBもコンパイル出来る。
- ソリューションファイル、example1.slnをダブルクリックしてVSを起動。
- Example1のファームを書き込んで、繋いで見る。
- bin/Example1.exeを実行、簡単に動く。
- うーん。こんなに簡単に動くとマズイな〜。VBの方が楽なのかな〜。マズイよな〜。
- とりあえず、マウスの解析に戻ろう。
- uusbdのアンインストールは、ずいぶん悩んだけど、結局はデバイスマネージャのドライバの更新で、既知のドライバを表示してその一覧から、普通のUSBヒューマンインターフェースドライバに変更すれば良かったのか。。
- いちいち、再起動させられるのは、ちょっと嫌になるけど。
- これで、通常のUSBマウスが繋がった状態だ。
- SnoopyPROを使って、マウスをほんの少しづつ動かして、どんな信号が出てるか見てみよう。
- このツールは、最初はどうすれば良いのかサッパリだったが、以下のようにすれば良いようだ。
- まず、View→USB Devicesで、あらかじめ調べておいたマウスのVID,PIDのものをリストから選択しておいて、以下のように実行。
- File→Unpack Driver
- File→Install Services
- Edit→Install Sniffer
- Edit→Restart Device
- これで、USBlogが表示されるので、マウスをちょっと動かしてから、
- ポーズボタンを押して、Tools→Anarize Logを選ぶ
- ホイール付きだけど、標準的な2ボタンマウスの信号を見てみる。
- ELECOMのM-D8URRD、無線マウスだけど、USBの信号はおそらく同じだろう。
474 ??? up n/a 251.297 BULK_OR_INTERRUPT_TRANSFER 01 00 00 00 0x00000000
476 ??? down n/a 251.297 BULK_OR_INTERRUPT_TRANSFER -
475 ??? up n/a 251.485 BULK_OR_INTERRUPT_TRANSFER 00 00 00 00 0x00000000
477 ??? down n/a 251.485 BULK_OR_INTERRUPT_TRANSFER
右ボタン
476 ??? up n/a 407.516 BULK_OR_INTERRUPT_TRANSFER 02 00 00 00 0x00000000
478 ??? down n/a 407.516 BULK_OR_INTERRUPT_TRANSFER -
477 ??? up n/a 407.719 BULK_OR_INTERRUPT_TRANSFER 00 00 00 00 0x00000000
479 ??? down n/a 407.719 BULK_OR_INTERRUPT_TRANSFER -
- 何故、Dirが???になっちゃうのかな? まぁ、マウスはInputのみだよね。
- 1byte目の、ビット0が左ボタン、ビット1が右ボタンだ。
- 1回のクリックで、どうも2回送信されてるようだ。
- つまり、MouseDownとMouseUpってことか。
490 ??? up n/a 819.735 BULK_OR_INTERRUPT_TRANSFER 00 7e f3 00 0x00000000
492 ??? down n/a 819.735 BULK_OR_INTERRUPT_TRANSFER -
491 ??? up n/a 819.750 BULK_OR_INTERRUPT_TRANSFER 00 1e fa 00 0x00000000
493 ??? down n/a 819.750 BULK_OR_INTERRUPT_TRANSFER -
:
左に移動
495 ??? up n/a 889.781 BULK_OR_INTERRUPT_TRANSFER 00 bb f1 00 0x00000000
497 ??? down n/a 889.781 BULK_OR_INTERRUPT_TRANSFER -
496 ??? up n/a 889.813 BULK_OR_INTERRUPT_TRANSFER 00 fe fe 00 0x00000000
498 ??? down n/a 889.813 BULK_OR_INTERRUPT_TRANSFER -
:
上に移動
498 ??? up n/a 931.531 BULK_OR_INTERRUPT_TRANSFER 00 01 ea 00 0x00000000
500 ??? down n/a 931.531 BULK_OR_INTERRUPT_TRANSFER -
499 ??? up n/a 931.531 BULK_OR_INTERRUPT_TRANSFER 00 01 f7 00 0x00000000
501 ??? down n/a 931.531 BULK_OR_INTERRUPT_TRANSFER -
:
下に移動
518 ??? up n/a 1020.750 BULK_OR_INTERRUPT_TRANSFER 00 01 1a 00 0x00000000
520 ??? down n/a 1020.750 BULK_OR_INTERRUPT_TRANSFER -
519 ??? up n/a 1020.750 BULK_OR_INTERRUPT_TRANSFER 00 00 1a 00 0x00000000
521 ??? down n/a 1020.750 BULK_OR_INTERRUPT_TRANSFER -
:
- マウスは、ちょっと動かしただけで、沢山データが送信されるので、2回分だけ示した。
- これは、つまり2byte目は、X方向の移動で、右方向が正、左方向が負。
- 3byte目は、Y方向の移動、上方向が負、下方向が正ということか。
528 ??? up n/a 1087.047 BULK_OR_INTERRUPT_TRANSFER 00 00 00 01 0x00000000
530 ??? down n/a 1087.047 BULK_OR_INTERRUPT_TRANSFER -
529 ??? up n/a 1087.219 BULK_OR_INTERRUPT_TRANSFER 00 00 00 01 0x00000000
531 ??? down n/a 1087.219 BULK_OR_INTERRUPT_TRANSFER -
下にスクロール
531 ??? up n/a 1127.094 BULK_OR_INTERRUPT_TRANSFER 00 00 00 ff 0x00000000
533 ??? down n/a 1127.094 BULK_OR_INTERRUPT_TRANSFER -
532 ??? up n/a 1127.313 BULK_OR_INTERRUPT_TRANSFER 00 00 00 ff 0x00000000
534 ??? down n/a 1127.313 BULK_OR_INTERRUPT_TRANSFER -
- スクロールホイールは、4byte目で、上方向が正、下方向が負になっているようだ。
- ホイールの無いマウスは3byteなのに対して、スクロールホイール付きのマウスは4byteだけど、信号はTECH Iのp197の解説の通りだな。
- マウスのボタンが逆のような気がするけど、まぁ良しとする。
- なるほどね〜。マウスの信号ってこうなってるのかぁ。
- そういえば、マウスの起動時はどんな信号のやり取りがあるのかな?
1 in down n/a 0.000 GET_DESCRIPTOR_FROM_DEVICE
1 in up n/a 0.016 CONTROL_TRANSFER 12 01 10 01 00 00 00 08 0x00000000
2 in down n/a 0.016 GET_DESCRIPTOR_FROM_DEVICE
2 in up n/a 0.016 CONTROL_TRANSFER 09 02 22 00 01 01 00 a0 0x00000000
3 in down n/a 0.016 GET_DESCRIPTOR_FROM_DEVICE
3 in up n/a 0.016 CONTROL_TRANSFER 09 02 22 00 01 01 00 a0 0x00000000
4 ??? down n/a 0.016 SELECT_CONFIGURATION
4 ??? up n/a 0.032 SELECT_CONFIGURATION 0x00000000
5 out down n/a 0.032 CLASS_INTERFACE -
5 out up n/a 0.032 CONTROL_TRANSFER - 0x00000000
6 in down n/a 0.032 GET_DESCRIPTOR_FROM_INTERFACE
6 in up n/a 0.047 CONTROL_TRANSFER 05 01 09 02 a1 01 05 09 0x00000000
7 ??? down n/a 0.047 BULK_OR_INTERRUPT_TRANSFER -
8 ??? down n/a 0.047 BULK_OR_INTERRUPT_TRANSFER -
ふーん。。よくわかんないや。。。最初にこのデバイスに関してのやり取りがあるんだろうな〜。
- まぁ、こんなもんだということで。ちなみに、このリストは8byte以上表示してないが、SnoopyProでリストの+をクリックすると、全データが見れる。
- Example1は、どんな信号のやりとりしてるんだろ?
1 in down n/a 0.000 GET_DESCRIPTOR_FROM_DEVICE
1 in up n/a 0.016 CONTROL_TRANSFER 12 01 00 02 00 00 00 08 0x00000000
2 in down n/a 0.016 GET_DESCRIPTOR_FROM_DEVICE
2 in up n/a 0.016 CONTROL_TRANSFER 09 02 22 00 01 01 00 80 0x00000000
3 in down n/a 0.016 GET_DESCRIPTOR_FROM_DEVICE
3 in up n/a 0.032 CONTROL_TRANSFER 09 02 22 00 01 01 00 80 0x00000000
4 ??? down n/a 0.032 SELECT_CONFIGURATION
4 ??? up n/a 0.032 SELECT_CONFIGURATION 0x00000000
5 out down n/a 0.032 CLASS_INTERFACE -
5 out up n/a 0.032 CONTROL_TRANSFER - 0x00000000
6 in down n/a 0.032 GET_DESCRIPTOR_FROM_INTERFACE
6 in up n/a 0.032 CONTROL_TRANSFER 06 00 ff 09 01 a1 01 19 0x00000000
7 ??? down n/a 0.047 BULK_OR_INTERRUPT_TRANSFER -
8 ??? down n/a 0.047 BULK_OR_INTERRUPT_TRANSFER -
- PCアプリのボタンを押して、LEDを1個点灯してみる。
9 out down 0x00 42.094 CLASS_INTERFACE 01
9 out up n/a 42.094 CONTROL_TRANSFER - 0x00000000
- うーん。単純だけど。。in,outとdown,upの関係がよく分からないな。
7 ??? up n/a 77.953 BULK_OR_INTERRUPT_TRANSFER 01 0x00000000
10 ??? down n/a 77.953 BULK_OR_INTERRUPT_TRANSFER -
11 out down 0x00 77.953 CLASS_INTERFACE 01
11 out up n/a 77.953 CONTROL_TRANSFER - 0x00000000
8 ??? up n/a 78.110 BULK_OR_INTERRUPT_TRANSFER 00 0x00000000
12 ??? down n/a 78.110 BULK_OR_INTERRUPT_TRANSFER -
13 out down 0x00 78.110 CLASS_INTERFACE 01
13 out up n/a 78.125 CONTROL_TRANSFER - 0x00000000
あぁ、意外と沢山のデータが。。
- シーケンスって順序通りじゃないのか。シーケンス7,8は、後から応答してるってことかな。
- in,outって、PC側からみた方向かと思ってたんだけど、up,downが方向なのかな?いろいろ謎が多いなぁ。
- うーん。ごちゃごちゃしてきたなー。今は良くわからないけど、記録として残しておこう。
- いつか分かる日が来るだろう2。って、未だuusbd使えて無いじゃん。先は長いか。。
- というか、「このデバイスが開始できません」ということで、!マークのままなので、先に進まない。
- uusbdのバージョンは、V1.0、V1.3、そしてV2.0betaと試したが全て同じ結果。
- USBのポートを変えたり、他の全てのUSBデバイスを外しても同じ。
- 別のUSBデバイス(やっぱりマウスだけど)についてもuusbd.infを作り直して試したけど、同じ。
- しかし、いちいち再起動をさせられるので、参った。
pipedumpで認識されない
- pipedumpで、「Uusbd.sysを使ったUSBデバイスは見つかりません」となるので、やっぱりドライバのインストールに失敗しているんだろう。
- uusbd.infは、Vid,Pidしか弄るところがなさそうだし。。
レジストリを消してみる
- 何処かに、標準のマウスの情報が残っている?
- 今度は、ハードウェアウィザードで、HID準拠のマウスを全て削除
- regeditで、HKEY_LOCAL_MACHINE→SYSTEM→CurrentControlSet→Enum→USB→Vid_056e&Pid_0035を確認。
- 削除出来なかったので、regedt32を使って、セキュリティを変更してから削除。
- レジストリは、uusbdのドライバだけになった。
- それで再度デバイスマネージャでデバイスの更新、再起動を繰り返し行ったが、やはりダメだった。
- デバイスマネージャーでは、!マークのままだ。どうやったら認識するんだろ。
Windows2000の新規インストール
- それでは、と別のマシンで、Windows2000を新規インストールしてやってみた。
- いつも使ってるマシンは、いろいろ弄ってるから、システム環境が悪い可能性もあるかもってことで。
- 手順としては、
- まず、USBマウスを繋ぐと、USBマウスとして認識される。
- uusbd.infのVID,PIDを、USBマウスに合わせて修正(3箇所)しておき、
- デバイスマネージャで、ドライバの更新を選び、uusbd.infを選んでドライバをインストール。
- でも、やはりデバイスマネージャで見ると、!マークのまま。
- Cドライブに、uusbd.dllをコピーして、pipedumpを実行すると、
- 「Uusbd.sysを使ったUSBデバイスは見つかりません」となる。
- ハードウェアウィザードで、HID準拠のマウスを消してもダメで、それならと不明のデバイスとか削除してたら、システムがおかしくなってしまった。
- 結局システムが立ち上がらなくなった。。分からないデバイスの削除は止めましょう。。。
- システムの修復をして再度挑戦したが、やはりダメ。何が間違ってるのか。。
- うーん、悔しいけど、打開策を思い付かないのでuusbdは諦めるしかないのかなぁ。。。
USBドライバって難しい
- ectoyfanさんの、 グルグルマウス3は面白い。
- これだったら、uusbdで認識出来るかも。と思ってuusbd.infのVID,PIDを修正して、デバイスマネージャのドライバの更新で指定しようとした。
- でも、今度はドライバの読み込みさえしてくれない。→ドライバを検出すらしてくれない。uusbd.infに何らかの問題があるのか。。
- usbview.exeでみると、ちゃんとVID=4242,PID=EE05(オリジナルから1コずらしてる)に見えるし、ちゃんと動作してるのにな〜。
- ドライバとして認識するデバイスが一個も無いと、uusbdを試すことが出来ない。
- でもELECOMのマウスは2つとも、uusbdへのドライバの変更は出来たのに、これは何で出来ないんだろ?
- USBドライバの組込みって、よくトラぶる気がする。
- 標準のデバイスは良いんだけど、ちょっと変ったデバイスを付けるとなかなか認識してくれなかったり。。
- 傾きマウスは、ヤラレタ〜って感じだなぁ。
- こんなことやってないで、そろそろ何か動かしたくなってきたよ〜。
- と、万策尽きて途方に暮れていたんだけど。。
- そういえば、今まで試した3つのデバイスはみんなマウスだなぁ。
- Example1をuusbdドライバで使うとどうなるんだろう?
- って、あっさり認識した!
- うーん。いままでの苦労は。。。標準のマウスドライバが邪魔してたのか?
- TECH I の記事だと、普通のマウスでも出来てるんだけどなぁ。W2Kじゃないのかしらん。
- 折角買ったマウスは無駄になったけど、まぁマウスのデータを読みたいワケじゃないもんね。
- それにしても、VS2005でコンパイルしてると、単純な文字列操作のエラーが多くて参った。
- 自前のデバッグ用関数が、ほとんど全滅。別に日本語使わないから、char*で良いのに。。
- それに、セキュリティ対応とかで、文字列の長さを指定する関数使わないとwarning出されるのも嫌。
2来るのか?来ると良いなぁ。
3自分が勝手に付けた名前だけど。。
[top]
- uusbdが使えそうなので、PC側のアプリケーションを作ってみよう。
- pipedumpは、uusbdに付属するプログラムで、以下のような機能を持つ。
- コンフィグレーションディスクリプタから、パケットのデータ長を求める。
- Interface0,pipe0に出力されるデータを10個表示する。
- これはコンソールアプリケーションなので、単純にWindowsアプリケーションにしてみる。
- 最初タイマでReadFileしてみたが、SWを押さないとデータが来ないのでうまくなかった。
- それで、データ読込みルーチンをマルチスレッド化して何回でもデータを取れるようにした。
- これで動くようになったが、SWを押さないとデータが来ないので、アプリケーションを終了出来なくなってしまった。
- スレッドを終了せずにアプリケーションを停止するようにすればOKだが、ちょっと気持ちが悪い。
- タイムアウトとか設定出来れば良いんだけど、uusbdではタイムアウトが設定出来ない。
- と思ったが、いろいろ調べてみると非同期I/Oを使えば良いらしい。
- uusbdでは出来ないのかぁと思ったが、オーバーラップI/OでOPENするAPIが用意されていた。
- ということで、pipedumpを読込みをマルチスレッドにして、非同期I/Oで読み込むようにしてみた。
- とりあえずWindowsプログラムの習作ということで、8bit分の入力をラジオボタンで表示するだけ。
- タイムアウトを設定するのに非同期I/Oを使えば出来るということが分かるまでに、1週間程悩んだ。
- COMポートの受信でタイムアウトの設定を使ったことがあったんだけど、COMMTIMEOUTS構造体とか使ってたので、Comポート専用の仕掛けかと思っていた。
- 非同期I/Oは、Open時にFILE_FLAG_OVERLAPPEDフラグを設定して、ReadFile時にオーバーラップ構造体を指定するだけだっだんだけど、
- こういうのって意外と初心者向けの解説には書かれていない。→結局はMicrosoftのReadFileの解説が一番分かりやすかった。。
- uusbdで、非同期I/Oに対応したOpenコマンドがあるのにすぐ気が付かなかったり。。。
- データ出力も非同期I/OでWriteFileで出来ると思ったんだけど、Example1でやってみたが、どうもうまく行かない。
- Intarfaceは同じ0で良いと思うので、pipe番号4を1から順に変えてみたんだけど、データが取れない。
- USBは、エンドポイントという仮想的な通信ポートを作って通信するらしい。
- EP0はコマンドを送信するためのもので、データ入出力用にそれぞれEPを用意することになる。
- 実際、Example1では、どのEPを使ってるのかな?
- PSoC Designerで調べてみると、PCへのデータ送信用にEP1を作成しているようだ。
- でも、それ以外のEPが設定されていない。。どういうこと?
- そもそも、EPって、入力用、出力用に別々に用意する必要があるのかなぁ。
- EP0は、クライアントへのコマンドとディスクリプタ取得とで、入出力が出来るようにみえるけど。
- Example1はデータ出力用にEPを用意せずに、何か別の方法を使っているように見える。
- トラ技2006年4月号の桑野さんの記事で、SET_REPORTで送られてくるという記述があるけど、
- EP0のコマンドで送られてくるということかなぁ。uusbdじゃ出来ないのかな?
- uubsdで、リクエストを送るAPIは、こんな定義。
BOOL APIENTRY Uusbd_ClassRequest(HUSB husb, BOOL dir_in, UCHAR recipient, UCHAR bRequest, USHORT wValue, USHORT wIndex, USHORT wLength, char *data);
BOOL APIENTRY Uusbd_VendorRequest(HUSB husb, BOOL dir_in, UCHAR recipient, UCHAR bRequest, USHORT wValue, USHORT wIndex, USHORT wLength, char *data);
- Uusbd_ClassRequest、Uusbd_VendorRequestで、recipientをUU_RECIPIENT_INTERFACE、bRequestをUSB_REQUEST_SET_INTERFACEとして呼び出してみたが、何も出力されない。
- 例えばこんな感じで、bufのデータを出力したかったんだけど。wValue,wIndexの値を変えても変化なし。。
Uusbd_VendorRequest(g.husb,false,UU_RECIPIENT_INTERFACE,USB_REQUEST_SET_INTERFACE,1,1,1,(char*)&(buf));
- うーん。これじゃダメなのかなぁ。
- こことかみると、StandardRequestというのもあるみたいだが、uusbdではそんなルーチンは無いし。
- 単純にEP0に出力することって出来ないのかなぁ。
- uusbdって、標準リクエストに関するAPIが足りないのかしらん。それとも何か間違ってるのかな〜。
- PastelMagicの掲示板で、ectoyfanさんとJUNK-BOXさんのアドバイスを頂き、以下のようにしたらAN2298のExample1で出力出来るようになりました。
- ずいぶん悩んでいたので、動いた時は嬉しかった〜。本当に感謝です。
Uusbd_ClassRequest(g.husb,false,UU_RECIPIENT_INTERFACE,0x09,0x200,0,1,(char*)&(buf));
- JUNK-BOXさんによるとデバイスリクエストが、以下のようになれば良いらしい。
21 09 00 02 00 00 01 00
これだけだと分からなかったのですが、ectoyfanさんに、 USBのHID1.11クラス定義の、51〜52ページあたりを見れば良いと教えてもらう。
- つまり、SetReportRequestを送れば良いってことらしいです。
| Part | Description | HexData |
| bmRequestType | 00100001 | 21 |
| bRequest | SET_REPORT | 09 |
| wValue | Report Type and Report ID | 00 02 |
| wIndex | Interface | 00 00 |
| wLength | Report Length | 01 00 |
| Data | Report | 実際のデータ |
- 2byteデータは、リトルエンディアンで送る。ReportTypeはHighバイト、ReportIDはLowバイトになる。
- ちゃんとUSBのHIDの定義を調べれば、ちゃんと載ってるってことですね。
- 手間を惜しんで、ネットでチョっと調べて済まそうとしてると、却って遠回りになるっていう見本だなぁ。反省。。
- ということで、Example1用の簡単なアプリケーションを作ってみた。
- 柏野さんの汎用USBドライバuusbdを使っています。
- デバイスマネージャで、USBヒューマンインターフェースドライバの
- プロパティ→ドライバタブ→ドライバの更新→デバイスドライバのアップグレードウィザード
- 次へ→デバイスに最適なドライバを検索する(推奨)→場所を指定→uusbd.infを指定
- 自分がやったところでは、uusbdのインストールはすんなり行くこともあるけど、一度で出来ないこともあった。
- 黄色い!マークが付いてうまく行かない時は削除してもう一度やってみたりすると良いかも。
- uusbdを止めて、元に戻したい時は、
- ドライバの更新→このデバイスの既知のドライバを表示して、その一覧から選択する→USBヒューマンインターフェースデバイスを選ぶ
プログラムの簡単な説明
- Uusbd_Open()で、uusbdを使ったデバイスを開き、
- ベンダIDとプロダクトIDの指定はしていません5。汎用USBを使ったデバイスが複数の場合は、Uusbd_Open_maskで検索条件を指定するようにして下さい。
- データ読み込みは、Uusbd_OpenPipe_Overlapped()で、Interface0,Pipe0(EP1)を非同期I/OでOpenして、ReadFileで読み込みます。
- データが来ない場合でも、1秒のタイムアウトを設定しているので、すぐ終了可能です。
- 読み込み待ちの時、GUIが動かなくなるのは嫌なので、この読み込みはスレッドになっており、メインスレッドと並列に動作します。
- データ書き込みは、書き込み用のEPを開かずに、EP0を使ったSetReportRequestで送信されます。
- 具体的には、LEDスイッチを押した時に、Uusbd_ClassRequestで送信します。
- プログラム終了時には、読み込み用スレッドを停止してから、Uusbd_Closeで、デバイスを開放します。
- VS2005のVC++でプログラムしていますが、SDKなので基本的にCですから、構造は簡単です。
- おそらく、Express Editionでもコンパイル出来ると思います。多分。。→uusbdのインストールとincludeパスの確認を忘れずに
注意点
- uusbdは、インストールに結構手間取るかも。自分の環境(Windows2000)の問題かもしれないが。
- 一度インストールに成功すると、それ以降はあまり苦労しないんだけど。。
- VS2005のVC++だとMFCを使ってないんだけど、 ランタイムが必要?かもしれない6。
- Expressとか、新しいコンパイル環境をインストールしてる人は多分問題ないと思うけれど。
- Vectorのが使えるかも(ちなみにreleaseバージョンのexeじゃないとダメ)
- 逆に、VC5〜6とかでコンパイルした方が問題が少ないかもしれない。
40は入力で使ってるので1からだと思う。実際0でやると固まるし。。
5uusbdが、汎用USBドライバを使ったデバイスを検索してくれるので。でも、結局はuusbd.infで指定してるワケですが。
6VC5とかではそんなことなかったが。。インストーラを作れば良いみたいだが自分にはよく分からなかった。。。
[top]
[電子工作関連に戻る]
⇒ Disqusの広告がうるさすぎるので基本は非表示にしました