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;
|