PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 |
2011.7.10 前へ 次へ 目次へ戻る ホームページトップへ戻る |
☆C++でUSB(HID)アクセスプログラムを作成 PIC側のプログラムはC18コンパイラを使わずPICアセンブラで作成しますが、パソコン側のUSB(HID)アクセスプログラムはBorland C++コンパイラで作成します。 しかしこれがまた難物で悪戦苦闘の連続でありました。 |
[第48回]
●HIDテストプログラム(HIDデバイス検出)のまとめ
前回までで、やっとUSBに接続されているHIDデバイスのProductIDとVenderIDが検出できるようになりました。
そのテストでは秋月のPICプログラマとともに、私がつくった試作回路(PIC18F4550回路)も接続して、ともに検出できることを確認しました。
ここから先は、ProductIDとVenderIDの検出に使ったhandleをそのまま使って、ターゲットデバイスに対してWriteFile関数とReadFile関数によって、データの送受信を行う部分の作業をしていくことになります。
ですけれど、やっとHIDデバイスの検出ができた、とは言っても、それはWindowsマシンの側のソフトができた、と言う話で、相手側のPICのプログラムについては、何もまだ説明をしておりません。
Windowsマシンの側のプログラムについてだけ、どんどん先に進んでいっても、相手側のプログラムをどう作っていくのかも説明しなければ、実際のところ、何もできないのと同じです。
ということで、やっとHIDデバイスの検出ができて、一区切りつきましたので、これから先はしばらくの間、いよいよPICの側のプログラムについて説明をしていきたいと思います。
その前に、今まで説明をしてきましたHIDテストプログラム(HIDデバイス検出)を簡単にまとめて整理しておくことにします(そうしておきませんと、また全部すっかりきれいに忘れてしまいます)。
ソースプログラムは、[第39回]にあります。
ですが、その後にWindowsXPでUSBマウスが検出できないことがわかり、そのための対策を書き加えました([第47回])ので、一部が変更になりました。
ですので、前回の修正を加えた、現在までのところの最終リストをまずお見せしたうえで、簡単な説明をしていくことにいたします。
●HIDテストプログラム(HIDデバイス検出)のソースリストです
//HID sample // //10/1/18 10/1/19 1/20 1/29 //2/6 2/7 4/5 4/7 4/9 //from hidtest1_8_b // #include <windows.h> #include <setupapi.h> extern "C" { #include "hidsdi.h" } #include <iostream.h> #pragma comment(lib, "hid.lib") void main( void ) { cout << hex; // // HIDclass識別子取得 // GUID hidGuid; HidD_GetHidGuid(&hidGuid); // // HIDデバイス情報セット取得 // HDEVINFO devinf; devinf = SetupDiGetClassDevs(&hidGuid, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); cout <<"devinf="<<devinf<<endl; // // 個別デバイス情報の構造体の取得 // SP_DEVICE_INTERFACE_DATA spid; spid.cbSize = sizeof(spid); // for( int index = 0; ; index++ ) { cout<<"search"<<endl; if(!SetupDiEnumDeviceInterfaces(devinf, NULL, &hidGuid, index, &spid)) { cout<<"end"<<endl; break; } cout<<"index="<<index<<endl; // // デバイスインターフェイスの詳細情報の取得 // unsigned long size; SetupDiGetDeviceInterfaceDetail( devinf, &spid, NULL, 0, &size, 0 ); PSP_INTERFACE_DEVICE_DETAIL_DATA dev_det = PSP_INTERFACE_DEVICE_DETAIL_DATA( new char[size] ); dev_det->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); // SetupDiGetDeviceInterfaceDetail( devinf, &spid, dev_det, size, &size, 0 ); cout << dev_det->DevicePath << endl; // // ファイルハンドルの取得 // HANDLE handle = CreateFile( dev_det->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if(handle==INVALID_HANDLE_VALUE){cout<<"INVALID_HADLE"<<endl;continue;} // // VenderIDとProductIDの取得 // HIDD_ATTRIBUTES attr; HidD_GetAttributes( handle, &attr ) ; cout<<"VenderID: " <<attr.VendorID <<endl; cout<<"ProductID: " <<attr.ProductID<<endl; cout<<endl; // CloseHandle(handle); } } |
GUID hidGuid; HidD_GetHidGuid(&hidGuid); |
HDEVINFO devinf; devinf = SetupDiGetClassDevs(&hidGuid, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); cout <<"devinf="<<devinf<<endl; |
SP_DEVICE_INTERFACE_DATA spid; spid.cbSize = sizeof(spid); // for( int index = 0; ; index++ ) { cout<<"search"<<endl; if(!SetupDiEnumDeviceInterfaces(devinf, NULL, &hidGuid, index, &spid)) { cout<<"end"<<endl; break; } cout<<"index="<<index<<endl; |
unsigned long size; SetupDiGetDeviceInterfaceDetail( devinf, &spid, NULL, 0, &size, 0 ); PSP_INTERFACE_DEVICE_DETAIL_DATA dev_det = PSP_INTERFACE_DEVICE_DETAIL_DATA( new char[size] ); dev_det->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); // SetupDiGetDeviceInterfaceDetail( devinf, &spid, dev_det, size, &size, 0 ); cout << dev_det->DevicePath << endl; |
HANDLE handle = CreateFile( dev_det->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if(handle==INVALID_HANDLE_VALUE){cout<<"INVALID_HADLE"<<endl;continue;} |
HIDD_ATTRIBUTES attr; HidD_GetAttributes( handle, &attr ) ; cout<<"VenderID: " <<attr.VendorID <<endl; cout<<"ProductID: " <<attr.ProductID<<endl; cout<<endl; |