Bienvenu(e)! Identification Créer un nouveau profil

Recherche avancée

Interface USB HID et gcc sous xp?

Envoyé par winz 
Interface USB HID et gcc sous xp?
lundi 28 juillet 2008 16:47:13
Bonjour,

J'ai suivis le tutoriel "Carte d'interface sur port USB, protocole HID" et j'ai compilé le programme client (généré avec easyHID) avec delphi.

Tout ça est très clair et fonctionne très bien. Merci Bejamin.

Mon problème est le suivant :
Je développe un programme avec la librairie graphique Qt, j'utilise le compilateur gcc sous XP et J'aimerais piloter des pic avec mes applications.

Pouvez vous me dire pourquoi le code ci-dessous ne fonctionne pas :
Il devrait faire clignoter la led du prototype de benjamin mais il ne se passe rien alors que les fonctions LoadHID et WriteEx retournent 0.


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

}

Je ne connais rien de rien à la programmation API win32. Est ce que vous connaissez des librairies qui permettent de communiquer avec les ports USB sous XP avec GCC? ou il n'existe aucune autre alternative à delphi et visual C?


Re: Interface USB HID et gcc sous xp?
lundi 28 juillet 2008 21:41:57
Bonjour

Je pense que Buffer[0]=1 pour la fonction de clignottement, le 0 étant pour l'acquisition du channel analogique.

Regarde si ça ne marche pas mieux comme ça?

A++

Benjamin
Re: Interface USB HID et gcc sous xp?
mardi 29 juillet 2008 08:09:31
Idem, ça reste muet.

J'ai cru comprendre que le premier élément du bufferOut doit être initialisé à 0 et sert de report ID.

Par contre, je me demande si la gestion d'évènement (avec récupération du handle, etc...) n'est pas obligatoire même si l'on veut juste envoyer des données au pic.
Re: Interface USB HID et gcc sous xp?
mardi 29 juillet 2008 11:58:38
Salut,

La meilleur chose que j'ai a te suggérer c'est d'essayer le packet que tu veux envoyé au travers de ce programme :
[www.roboticus.org]

Afin de vérifié que tout est ok dans la formation du packet et au sein du pic...

Si c'est OK, c'est que le probleme vient de ton programme, là malheureusement je ne suis pas un expert sous GCC désolé...

A++

Benjamin
Re: Interface USB HID et gcc sous xp?
vendredi 12 septembre 2008 09:56:34
J'ai fini par le faire, voilà comment, si ça interesse qqun:

Tout d'abord, il faut récupérer 3 fichiers entête ( hidpi.h, hidsdi.h et hidusage.h) fournit gratuitement par microsoft dans son kit de développement Windows Server 2003 DDK (http://www.microsoft.com/whdc/devtools/ddk/default.mspx)

Ensuite on ouvre un handle sur le port USB en précisant le VID et PID avec la méthode:
HANDLE getUsbHandle(void);
J'ouvre le handle en mode asynchrone en passant la constante overlapped au CreateFile pour que les méthodes readFile et writeFile soient non bloquante.
C'est à dire que readFile & writeFile retournent une valeur même si l'opération de lecture/écriture n'est pas terminée.

Puis on écrit/lit le port avec les méthodes :
bool read(char *); //En paramètre le buffer de reception (de 65 octets : 64 + le reportId)
bool write(char*); //En paramètre, le buffer d'émission (de 65 octets : 64 + le reportId)

On ferme un handle avec la méthode:
CloseHandle(handle);

Ci-dessous le code de ces méthodes

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

    }

Seuls les utilisateurs enregistrés peuvent poster des messages dans ce forum.

Cliquez ici pour vous connecter