USB單晶片微電腦步進馬達控制
作者:王楀鴻 資料來源:http://www.cn.nctu.edu.tw/faculty/sklin/ 下載:
HidDevice.cpp
Descriptor.asm
PC 控制端:
//////////////////////////////////////////////////////////////////////////////
// HID Application Software sample
// written by Shir-Kuan Lin
// Dept. of Electrical and Control Engineering
// National Chiao Tung University
// e-mail: sklin@cc.nctu.edu.tw
/////////////////////////////////////////////////////////////////////////////
// HidDevice.cpp: Win32 console application to control HID keyboard
/////////////////////////////////////////////////////////////////////////////
// main Main program
// Get_DeviceHandle Open a handle via a device interface
// Get_att_capab Find HID device by checking capabilities.
// Wait Wait for user input
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// #include "windows.h"
#include
#include "stdio.h"
#include "winioctl.h"
#include "iostream.h"
extern "C"
{
#include "D:\ntddk\inc\hidsdi.h"
} /////////////////////////////////////////////////////////////////////////////////// HANDLE Get_DeviceHandle( GUID* pGuid, DWORD instance);
bool Get_att_capab( HANDLE hidDevice, //PHIDP_PREPARSED_DATA &hidPreparsedData,
USHORT& InputReportLen, USHORT& OutputReportLen); ///////////////////////////////////////////////////////////////////////////////////
// USHORT InputReportLen = 0, OutputReportLen = 0; ///////////////////////////////////////////////////////////////////////////////////
void Wait(void)
{
char line[80];
gets(line);
} //////////////////////////////////////////
bool get_device(HANDLE& hidDevice, USHORT* InputReportLen, USHORT* OutputReportLen)
{
GUID HidGuid;
// bool found = false;
DWORD Instance = 0; HidD_GetHidGuid( &HidGuid); // while( !found)
while(1)
{
hidDevice = Get_DeviceHandle( &HidGuid, Instance );
if( hidDevice==NULL)
return false;
printf(" Found the %dth HID device\n", Instance);
if( Get_att_capab( hidDevice, //hidPreparsedData,
*InputReportLen, *OutputReportLen))
{
// found = true;
printf(" HID Opened OK\n");
return true;
}
CloseHandle(hidDevice);
} // if( !found || InputReportLen==0 || OutputReportLen==0)
// if( !found )
// {
// printf("XXX Could not find the specified HID device\n");
// Wait();
// return false;
// }
// return found;
} ////////////////////////////////////////////////////
bool read_device(HANDLE hidDevice, USHORT InputReportLen)
{
// char* InputReport = new char[InputReportLen];
BYTE* InputReport = new BYTE[InputReportLen];
memset( InputReport, 0, InputReportLen);
bool found =false;
DWORD TransBytes; //************************************
printf(" Press ENTER \n");
Wait(); if( !ReadFile( hidDevice, InputReport, InputReportLen, &TransBytes, NULL))
{
printf("XXX Could not read value %d\n", GetLastError());
//--------------------
// If HID USB has been pulled out, the function GetLastError() will return the code of "1167".
// The code 1167 = ERROR_PROCESS_ABORTED).
//--------------------
}
else if( TransBytes==InputReportLen)
{
found =true;
printf(" Input report length : %d\n", InputReportLen);
printf(" Input report: %d\n", InputReport[0]);
if (InputReportLen > 1)
printf(" Input report 1st byte: %x\n", InputReport[1]);
if (InputReportLen > 2)
printf(" Input report 2nd byte: %x\n", InputReport[2]);
if (InputReportLen > 3)
printf(" Input report 3rd byte: %x\n", InputReport[3]);
for( USHORT i=4; i<InputReportLen; i )
printf(" Input report %dth byte: %x\n", i, InputReport[i]);
}
else
{
printf("XXX Wrong number of bytes read: %d\n",TransBytes);
} delete InputReport;
return found;
}
//////////////////////////////////////////////////// bool write_device(HANDLE hidDevice, USHORT OutputReportLen)
{
BYTE* OutputReport = new BYTE[OutputReportLen];
memset( OutputReport, 0, OutputReportLen);
bool found =false;
DWORD TransBytes; for( USHORT i=1; i<OutputReportLen; i )
{ printf("\n Please key in the number (0--255): ");
int a;
cin>>a;
printf("The %dth output data in Hex is: %x \n",i,a);
OutputReport[i]=a;
} if( !WriteFile( hidDevice, OutputReport, OutputReportLen, &TransBytes, NULL))
{
printf("XXX Could not write value %d\n", GetLastError());
//--------------------
// If HID USB has been pulled out, the function GetLastError() will return the code of "1167".
// The code 1167 = ERROR_PROCESS_ABORTED).
//--------------------
}
else if( TransBytes==OutputReportLen)
{
printf(" Writing success \n");
found = true;
}
else
{
printf("XXX Wrong number of bytes written: %d\n",TransBytes);
}
delete OutputReport;
return found;
}
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// Close device
bool close_device(HANDLE hidDevice)
{
if( !CloseHandle(hidDevice))
{
printf("XXX CloseHandle failed %d\n",GetLastError());
//--------------------
// If HID USB has been pulled out, the function GetLastError() will return the code of "1167".
// The code 1167 = ERROR_PROCESS_ABORTED).
//--------------------
return false;
}
else
{
printf(" CloseHandle worked\n");
return true;
}
} /////////////////////////////////////////////////////////////////////////////
void main()
{
HANDLE hidDevice = NULL;
USHORT InputReportLen = 0, OutputReportLen = 0; printf("\n HID Application Sample by S. K. Lin\n"); if (!get_device(hidDevice, &InputReportLen, &OutputReportLen) )
{
printf("XXX Could not find the specified HID device\n");
Wait();
}
else
{
if(InputReportLen > 0)
{
if(!read_device(hidDevice, InputReportLen) )
goto end_device;
} if(OutputReportLen > 0)
{
if (!write_device(hidDevice, OutputReportLen) )
goto end_device;
}
read_device(hidDevice, InputReportLen);
end_device:
close_device(hidDevice);
}
printf(" Press ENTER to close this window\n");
} /////////////////////////////////////////////////////////////////////////////
// Get_DeviceHandle: Open a handle via a device interface HANDLE Get_DeviceHandle( GUID* pGuid, DWORD instance)
{
// Get handle to relevant device information set
HDEVINFO info = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if(info==INVALID_HANDLE_VALUE)
{
printf("No HDEVINFO available for this GUID\n");
return NULL;
} // Get interface data for the requested instance
SP_INTERFACE_DEVICE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, instance, &ifdata))
{
printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance %d \n", instance 1);
SetupDiDestroyDeviceInfoList(info);
return NULL;
} // Get size of symbolic link name
DWORD ReqLen;
SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
if( ifDetail==NULL)
{
SetupDiDestroyDeviceInfoList(info);
return NULL;
} // Get symbolic link name
ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if( !SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
{
SetupDiDestroyDeviceInfoList(info);
delete ifDetail;
return NULL;
} printf("Symbolic link is %s\n",ifDetail->DevicePath);
// Open file
HANDLE pDevice = CreateFile( ifDetail->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( pDevice==INVALID_HANDLE_VALUE) pDevice = NULL; delete ifDetail;
SetupDiDestroyDeviceInfoList(info);
return pDevice;
} ///////////////////////////////////////////////////////////////////////////////////
// Get_att_capab: Get HID device capabilities. Return true if specified HID is found
// hidPreparsedData, InputReportLen and OutputReportLen returned
// Don't forget to HidD_FreePreparsedData(hidPreparsedData) bool Get_att_capab( HANDLE hidDevice, //PHIDP_PREPARSED_DATA& hidPreparsedData,
USHORT& InputReportLen, USHORT& OutputReportLen)
{
HIDD_ATTRIBUTES HidAttributes;
PHIDP_PREPARSED_DATA hidPreparsedData;
HIDP_CAPS Capab; if( !HidD_GetAttributes( hidDevice, &HidAttributes))
{
printf("XXX Could not get HID attributes\n");
return false;
} printf(" HID attributes: VendorID=X, ProductID=X, VersionNumber=X\n",
HidAttributes.VendorID, HidAttributes.ProductID,
HidAttributes.VersionNumber); bool found = false;
// if( HidAttributes.VendorID==0x1234 &&
// HidAttributes.ProductID==0x5678)
if( HidAttributes.VendorID==0x046D &&
HidAttributes.ProductID==0xC00C &&
HidAttributes.VersionNumber==0x0620)
{
printf(" Found HID IO Board\n\n");
found = true;
} wchar_t mString[256];
char ch_buffer[256];
char blank[1]="";
if( HidD_GetManufacturerString( hidDevice, mString, sizeof(mString)) )
{
if (wcstombs(ch_buffer, mString, 256) ==-1) // -1 = conversion failure
ch_buffer[0] =blank[0];
printf("XXX Manufacturer: %s\n",ch_buffer);
} if( HidD_GetProductString( hidDevice, mString, sizeof(mString)) )
{
if (wcstombs(ch_buffer, mString, 256) ==-1) // -1 = conversion failure
ch_buffer[0] =blank[0];
printf("XXX Product: %s\n",ch_buffer);
} if( HidD_GetSerialNumberString( hidDevice, mString, sizeof(mString)) )
{
if (wcstombs(ch_buffer, mString, 256) ==-1) // -1 = conversion failure
ch_buffer[0] =blank[0];
printf("XXX Serial Number: %s\n\n",ch_buffer);
}
if( !HidD_GetPreparsedData( hidDevice, &hidPreparsedData))
{
printf("XXX Could not get HID preparsed data\n");
found = false;
}
else
{
NTSTATUS status = HidP_GetCaps( hidPreparsedData, &Capab); if( status==HIDP_STATUS_SUCCESS)
{
printf(" Top level Usage page %d usage %d\n", Capab.UsagePage, Capab.Usage);
printf(" InputReportByteLength %d\n", Capab.InputReportByteLength);
printf(" OutputReportByteLength %d\n", Capab.OutputReportByteLength);
printf(" FeatureReportByteLength %d\n\n", Capab.FeatureReportByteLength);
printf(" NumberLinkCollectionNodes %d\n\n", Capab.NumberLinkCollectionNodes);
printf(" NumberInputButtonCaps %d\n", Capab.NumberInputButtonCaps);
printf(" NumberInputValueCaps %d\n", Capab.NumberInputValueCaps);
printf(" NumberOutputButtonCaps %d\n", Capab.NumberOutputButtonCaps);
printf(" NumberOutputValueCaps %d\n", Capab.NumberOutputValueCaps);
printf(" NumberFeatureButtonCaps %d\n", Capab.NumberFeatureButtonCaps);
printf(" NumberFeatureValueCaps %d\n\n", Capab.NumberFeatureValueCaps); // Remember max lengths of input and output reports
InputReportLen = Capab.InputReportByteLength;
OutputReportLen = Capab.OutputReportByteLength;
}
} HidD_FreePreparsedData( hidPreparsedData);
return found;
} 步進馬達控制端: CPU 63743
;*******************************************************************
; SAMPLE CODES OF THE DESCRIPTORS
; for a low-speed 105-Key keyboard with an integrated mouse
; as a sample in Appendix E of the document of
; "Device Class Definition for Human Interface Device, V. 1.11"
;
; Code Writer: S. K. Lin, on 11/06/2002 in TAIWAN
;******************************************************************* XPAGEOFF
;=======================================
device_descriptor:
db 12h ; bLength (18 bytes)
db 01h ; bDescriptorType (device descriptor)
db 10h, 01h ; bcdUSB (ver 1.1)=0x0110
db 00h ; bDeviceClass (each interface specifies class info)
db 00h ; bDeviceSubClass (not specified)
db 00h ; bDeviceProtocol (not specified)
db 08h ; bMaxPacketSize0 (8 bytes)
db FFh, FFh ; idVendor -User must change this to own VID
db 01h, 00h ; idProduct - Product No. 0x0001
db 00h, 01h ; Device release number (1.00)
db 04h ; iManufacturer (index 4)
db 0Eh ; iProduct (index 14)
db 30h ; iSerialNumber (index 48)
db 01h ; bNumConfigurations (1)
end_device_descriptor:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;=======================================
string_descriptor:
db 04h ; bLength
db 03h ; bDescriptorType (3=string)
db 09h, 04h ; bLANGID[0] (9=English, 4=US) imanufacturer_string:
.begin: ; Length is (# of characters 1) * 2
db .end-.begin ; bLength
db 03h ; bDescriptorType (3=string)
dsu "ACME" ; bString in UNICODE (4 characters)
.end:
iproduct_string:
.begin:
db .end-.begin ; bLength
db 03h ; bDescriptorType (3=string)
dsu "Locator Keyboard" ; bString in UNICODE (16 characters)
.end: isnumber_string:
.begin:
db .end-.begin ; bLength
db 03h ; bDescriptorType (3=string)
dsu "ABC123" ; bString in UNICODE (6 characters)
; If a serial number is used, this must be unique for every device
; Otherwise, the device may not enumerate properly
.end:
end_string_descriptor:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;=========================================
config_descriptor:
db 09h ; bLength (9 bytes)
db 02h ; bDescriptorType (CONFIGURATION)
dwl end_config_descriptor - config_descriptor ; wTotalLength (59 bytes in this case)
db 02h ; bNumInterfaces (1)
db 01h ; bConfigurationValue (1)
db 00h ; Configuration string (none)
db 10100000b ; bmAttributes (bus powered, support remote wakeup)
db 32h ; Max power consumption (100mA)
interface_descriptor00:
db 09h ; bLength (9 bytes)
db 04h ; bDescriptorType (INTERFACE)
db 00h ; bInterfaceNumber (0)
db 00h ; bAlternateSetting (0)
db 01h ; bNumEndpoints (1)
db 03h ; bInterfaceClass (3=HID)
db 01h ; bInterfaceSubClass (1=Boot)
db 01h ; bInterfaceProtocol (1=Keyboard)
db 00h ; Index of string (none) hid_descriptor00:
db 09h ; bLength (9 bytes)
db 21h ; bDescriptorType (HID)
db 11h, 01h ; bcdHID (1.11)
db 00h ; bCountryCode (not localized)
db 01h ; bNumDescriptors (1)
db 22h ; bDescriptorType (HID Report)
dwl end_hid_report_descriptor00 - hid_report_descriptor00
; wDescriptorLength endpoint_descriptor00:
db 07h ; bLength (7 bytes)
db 05h ; bDescriptorType (ENDPOINT)
db 81h ; bEndpointAddress (IN endpoint, endpoint 1)
db 03h ; bmAttributes (interrupt endpoint)
db 08h, 00h ; wMaxPacketSize (8 bytes)
db 0Ah ; bInterval (10ms); polling interval for host getting data from device interface_descriptor01:
db 09h ; bLength (9 bytes)
db 04h ; bDescriptorType (INTERFACE)
db 01h ; bInterfaceNumber (1)
db 00h ; bAlternateSetting (0)
db 01h ; bNumEndpoints (1)
db 03h ; bInterfaceClass (3=HID)
db 01h ; bInterfaceSubClass (1=Boot)
db 02h ; bInterfaceProtocol (2=Mouse)
db 00h ; Index of string (none) hid_descriptor01:
db 09h ; bLength (9 bytes)
db 21h ; bDescriptorType (HID)
db 11h, 01h ; bcdHID (1.11)
db 00h ; bCountryCode (not localized)
db 01h ; bNumDescriptors (1)
db 22h ; bDescriptorType (HID Report)
dwl end_hid_report_descriptor01 - hid_report_descriptor01
; wDescriptorLength endpoint_descriptor01:
db 07h ; bLength (7 bytes)
db 05h ; bDescriptorType (ENDPOINT)
db 82h ; bEndpointAddress (IN endpoint, endpoint 2)
db 03h ; bmAttributes (interrupt endpoint)
db 08h, 00h ; wMaxPacketSize (8 bytes)
db 0Ah ; bInterval (10ms); polling interval for host getting data from device
end_config_descriptor:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;===============================
hid_report_descriptor00:
db 05h, 01h ; Usage Page (Generic Desktop)
db 09h, 06h ; Usage (Keyboard)
db A1h, 01h ; Collection (Application)
db 05h, 07h ; Usage Page (Keyboard)
db 19h, E0h ; Usage Minimum (224)
db 29h, E7h ; Usage Maximum (224)
db 15h, 00h ; Logical Minimum (0)
db 25h, 01h ; Logical Maximum (1)
db 75h, 01h ; Report Size (1) (bits)
db 95h, 08h ; Report Count (8) (fields)
db 81h, 02h ; Input (Data, Variable, Absolute)
db 75h, 08h ; Report Size (8) (bits)
db 95h, 01h ; Report Count (1) (fields)
db 81h, 01h ; Input (Constant) db 19h, 00h ; Usage Minimum (0)
db 29h, 65h ; Usage Maximum (101)
db 15h, 00h ; Logical Minimum (0)
db 25h, 65h ; Logical Maximum (101)
db 75h, 08h ; Report Size (8) (bits)
db 95h, 06h ; Report Count (6) (fields)
db 81h, 00h ; Input (Data, Array) db 05h, 08h ; Usage Page (LEDs)
db 19h, 01h ; Usage Minimum (1)
db 29h, 05h ; Usage Maximum (5)
db 15h, 00h ; Logical Minimum (0)
db 25h, 01h ; Logical Maximum (1)
db 75h, 01h ; Report Size (1) (bits)
db 95h, 05h ; Report Count (5) (fields)
db 91h, 02h ; Output (Data, Variable, Absolute)
db 75h, 03h ; Report Size (3) (bits)
db 95h, 01h ; Report Count (1) (fields)
db 91h, 01h ; Output (Constant) db C0h ; End Collection
end_hid_report_descriptor00:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;===============================
hid_report_descriptor01:
db 05h, 01h ; Usage Page (Generic Desktop)
db 09h, 02h ; Usage (Mouse)
db A1h, 01h ; Collection (Application)
db 09h, 01h ; Usage Page (Pointer)
db A1h, 00h ; Collection (Physical)
db 05h, 09h ; Usage Page (Buttons)
db 19h, 01h ; Usage Minimum (1)
db 29h, 03h ; Usage Maximum (3)
db 15h, 00h ; Logical Minimum (0)
db 25h, 01h ; Logical Maximum (1)
db 75h, 01h ; Report Size (1) (bits)
db 95h, 03h ; Report Count (3) (fields)
db 81h, 02h ; Input (Data, Variable, Absolute)
db 75h, 05h ; Report Size (5) (bits)
db 95h, 01h ; Report Count (1) (fields)
db 81h, 01h ; Input (Constant) db 05h, 01h ; Usage Page (Generic Desktop)
db 09h, 30h ; Usage (X)
db 09h, 31h ; Usage (Y)
db 15h, 81h ; Logical Minimum (-127)
db 25h, 7Fh ; Logical Maximum (127)
db 75h, 08h ; Report Size (8) (bits)
db 95h, 02h ; Report Count (2) (fields)
db 81h, 06h ; Input (Data, Variable, Relative)
db C0h ; End Collection
db C0h ; End Collection
end_hid_report_descriptor01:
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/*生活是一種藝術,用心生活才能享受生活*/
發表人 - axsoft 於 2003/10/13 14:18:38