|
Interface USB HID et gcc sous xp? lundi 28 juillet 2008 16:47:13 |
Membre depuis : 17 ans Messages: 4 |
#include <iostream>
#include <windows.h>
#include "mcHID.h"
using namespace std;
int main()
{
HIDBufferOut BufferOut;
char inputChr;
cout << "Chargement de mcHID.dll ... ";
if (LoadHID()){
cout << "erreur";
return 0;
}
else cout << "ok";
// first element is the report ID
BufferOut[0] = 0;
BufferOut[1] = 1;
BufferOut[2] = 10;
BufferOut[3] = 25;
if (WriteEx(VENDOR_ID, PRODUCT_ID, BufferOut)) cout << "write erreur";
else cout << "write ok";
}
// UnloadHID();
return 0;
}
|
Re: Interface USB HID et gcc sous xp? lundi 28 juillet 2008 21:41:57 |
Administrateur Membre depuis : 20 ans Messages: 640 |
|
Re: Interface USB HID et gcc sous xp? mardi 29 juillet 2008 08:09:31 |
Membre depuis : 17 ans Messages: 4 |
|
Re: Interface USB HID et gcc sous xp? mardi 29 juillet 2008 11:58:38 |
Administrateur Membre depuis : 20 ans Messages: 640 |
|
Re: Interface USB HID et gcc sous xp? vendredi 12 septembre 2008 09:56:34 |
Membre depuis : 17 ans Messages: 4 |
#include <windows.h>
extern "C" {//Pour une compilation C++
#include <setupapi.h>
#include "hidsdi.h"
#include "hidpi.h"
}
int VID = 1240;
int PID = 5;
int bufLength = 65; //64 + 1 octet de reportId
HANDLE usbHandle = INVALID_HANDLE_VALUE;
HANDLE getUsbHandle(void)
{
GUID hidGuid; /* GUID for HID driver */
HDEVINFO deviceInfoList;
SP_DEVICE_INTERFACE_DATA deviceInfo;
SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
DWORD size;
int usbDeviceIndex;
int openFlag = FILE_FLAG_OVERLAPPED; //ReadFile et WriteFile non bloquant //FILE_ATTRIBUTE_NORMAL -> ReadFile et WriteFile bloquant
HIDD_ATTRIBUTES deviceAttributes;
//Returns the device interface GUID for HIDClass devices
HidD_GetHidGuid(&hidGuid);
//Returns a handle to a device information set that contains requested device information elements for a local machine
deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
deviceInfo.cbSize = sizeof(deviceInfo);
for(usbDeviceIndex = 0 ;; usbDeviceIndex++){
if(usbHandle != INVALID_HANDLE_VALUE){
CloseHandle(usbHandle);
usbHandle = INVALID_HANDLE_VALUE;
}
//Enumerates the device interfaces that are contained in a device information set
if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, usbDeviceIndex, &deviceInfo))
break;
//* no more entries */
//First do a dummy call just to determine the actual size required
//Returns details about a device interface
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
if(deviceDetails != NULL)
free(deviceDetails);
deviceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*)malloc(size);
deviceDetails->cbSize = sizeof(*deviceDetails);
//This call is for real:
//Returns details about a device interface
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL);
hidPathQstr = QString::fromWCharArray(deviceDetails->DevicePath);
//Attempt opening for R/W -- we don't care about devices which can't be accessed
//Creates or opens a file or I/O device
usbHandle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL);
if(usbHandle == INVALID_HANDLE_VALUE){
errorCode = USBCOM_CNX_ERROR_FAILED_OPENING;
DBG(<< "Open USB port (failed opening) code : " << GetLastError());
//La fonction in GetLastError(void) permet d'obtenir le code d'erreur exacte
//errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore
continue;
}
deviceAttributes.Size = sizeof(deviceAttributes);
HidD_GetAttributes(usbHandle, &deviceAttributes);
if(deviceAttributes.VendorID != VID || deviceAttributes.ProductID != PID)
continue; /* ignore this device */
errorCode = USBCOM_NO_ERROR;
break; /* we have found the device we are looking for! */
}
vendorNameQstr = QString();
productNameQstr = QString();
if (errorCode == USBCOM_NO_ERROR){
//usb détecté, on cherche le nom de vendor & product
int bufLength = 512;
char buffer[bufLength];
//Returns a top-level collection's embedded string that identifies the manufacturer
if (HidD_GetManufacturerString(usbHandle, buffer, sizeof(buffer))){
//buffer l'identifiant du vendor
}
//Returns a top-level collection's embedded string that identifies the product
if (HidD_GetProductString(usbHandle, buffer, sizeof(buffer))){
//buffer l'identifiant du product
}
}
//Deletes a device information set and frees all associated memory
SetupDiDestroyDeviceInfoList(deviceInfoList);
if(deviceDetails != NULL)
free(deviceDetails);
return usbHandle;
}
bool waitingOnReadBl = false;
int readTimeout = 200; //en ms
bool read(char *buffer)
{
if (usbHandle == INVALID_HANDLE_VALUE || waitingOnReadBl) return false;
char reportID = 0;
DWORD bufLengthToRead = bufLength;
DWORD bufLengthRead = 0;
buffer[0] = reportID;
bool readBl = false;
//Ce controle permet d'éviter qu'une procédure de lecture ne soit lancée avant que la précédante ne soit terminée
if(!ReadFile(usbHandle, buffer, bufLengthToRead, &bufLengthRead, &overlapped)){
//Erreur de lecture?
if (GetLastError() != ERROR_IO_PENDING){
//Le ReadFile n'a pas abouti et la procédure de lecture n'est pas en cours, il y a eu une erreur de liaison
//Traiter l'erreur de lecture
DBG(<< "Erreur de lecture (lecture directe) code : " << GetLastError());
readBl = false;
}
else {
//La procédure de lecture est en cours, attendre qu'elle se termine
waitingOnReadBl = true;
}
}
else {
// read completed immediately
//Lecture des data dans buffer sur une longueur de bufLengthRead
readBl = true;
}
if (waitingOnReadBl){
// Si la réponse du readFile n'a pas été immédiate
// on l'attend pendant une durée max de readTimeout
DWORD dwRes = WaitForSingleObject(overlapped.hEvent, readTimeout);
switch (dwRes){
// Read completed.
case WAIT_OBJECT_0:
if (!GetOverlappedResult(usbHandle, &overlapped, &bufLengthRead, FALSE)){
// Error in communications; report it.
DBG(<< "Erreur de lecture (lecture différée) code : " << GetLastError());
readBl = false;
}
else {
// Read completed successfully.
// Lecture des data dans buffer sur une longueur de bufLengthRead
// Reset flag so that another opertion can be issued.
readBl = true;
}
break;
case WAIT_TIMEOUT:
// Operation isn't complete yet. waitingOnReadBl flag isn't
// changed since I'll loop back around, and I don't want
// to issue another read until the first one finishes.
readBl = false;
break;
default:
// Error in the WaitForSingleObject; abort.
// This indicates a problem with the OVERLAPPED structure's
// event handle.
DBG(<< "Erreur de lecture (OVERLAPPED structure's error) code : " << GetLastError());
readBl = false;
break;
}
}
waitingOnReadBl = false;
return readBl;
}
bool write(char *buffer)
{
if (usbHandle == INVALID_HANDLE_VALUE) return false;
DWORD bufLengthToWrite = bufLength;
DWORD bytesWritten;
DWORD dwRes;
bool writeBl;
// Issue write.
if (!WriteFile(usbHandle, buffer, bufLengthToWrite, &bytesWritten, &overlapped)) {
if (GetLastError() != ERROR_IO_PENDING){
//WriteFile failed, but isn't delayed. Report error and abort.
DBG(<< "Erreur d'écriture (écriture immédiate) code : " << GetLastError());
writeBl = FALSE;
}
else {
//On attend la fin de l'opération d'écriture.
dwRes = WaitForSingleObject(overlapped.hEvent, INFINITE);
switch (dwRes){
// OVERLAPPED structure's event has been signaled.
case WAIT_OBJECT_0:
if (!GetOverlappedResult(usbHandle, &overlapped, &bytesWritten, FALSE)){
DBG(<< "Erreur d'écriture (écriture différée) code : " << GetLastError());
writeBl = FALSE;
}
else
// Write operation completed successfully.
writeBl = TRUE;
break;
default:
// An error has occurred in WaitForSingleObject.
// This usually indicates a problem with the
// OVERLAPPED structure's event handle.
DBG(<< "Erreur d'écriture (OVERLAPPED structure's error) code : " << GetLastError());
writeBl = FALSE;
break;
}
}
}
else {
// WriteFile completed immediately.
writeBl = TRUE;
}
return writeBl;
}