mikrocontroller.net

Forum: PC-Programmierung HID Gerät Ansprechen


Autor: Dominik Dahlen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ich bin seit einiger Zeit drüber eine eigene USB-Firmware für 
einen AT90USB162 zu schreiben.

Nach dem ich jetzt endlich das Gerät richtig in Windows als HID-Tastatur 
erkannt habe wollte ich nun die ersten Kommunikationsversuche mit dem 
Host starten. Dafür wollte ich mir eine kleine C Application schreiben.

Soweit so gut:
Das Problem ist wenn ich    HidP_GetCaps aufrufe stürtzt mein Programm 
jedesmal mit dem Fehler hidparse.sys konnte nicht gefunden werden.

Jetzt ist die Datei aber im richtigen verzeichniss und auch vorhanden. 
Die richtigen Bibiliotheken müsste ich auch eingebunden haben sonst 
könnte ich es ja nicht compelieren.

Jemand eine idee an was das liegen könnte

hier mal der C-Code
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ddk/hidsdi.h>
#include <ddk/hidpi.h>
#include <ddk/hidusage.h>
#include <setupapi.h>


int main()
{
    PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd;
    SP_DEVICE_INTERFACE_DATA         spdid;
    SP_DEVINFO_DATA                  spdd;
    HDEVINFO                         hDevInfo;
    DWORD                            dwIndex, dwSize, dwType;
    TCHAR                            szProperty[256];
    GUID                             guid;
    HANDLE                           DeviceHandle;
    HIDD_ATTRIBUTES                  Attributes;
    PHIDP_PREPARSED_DATA             PreparsedData;
    HIDP_CAPS                        Capabilities;

    ZeroMemory(&spdid, sizeof(spdid));
    spdid.cbSize = sizeof(spdid);
    HidD_GetHidGuid(&guid);
    hDevInfo = SetupDiGetClassDevs(&guid,NULL,NULL,DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

    if(hDevInfo == INVALID_HANDLE_VALUE)
    {
        printf("SetupDiGetClassDevs failed, Error %u\n", GetLastError());
        return(FALSE);
    }

    for(dwIndex = 0; (SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&guid,dwIndex,&spdid)); dwIndex++)
    {
        printf("Geraete-Index: %u\n", dwIndex);
        dwSize = 0;

        SetupDiGetDeviceInterfaceDetail(hDevInfo,&spdid,NULL,0,&dwSize,NULL);

        if(dwSize)
        {
            if(NULL == (pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSize)))
                continue;

            pspdidd->cbSize = sizeof(*pspdidd);

            ZeroMemory((PVOID)&spdd, sizeof(spdd));
            spdd.cbSize = sizeof(spdd);

            if(SetupDiGetDeviceInterfaceDetail(hDevInfo,&spdid,pspdidd,dwSize,&dwSize,&spdd))
            {
                printf("Name fuer CreateFile(): %s\n", pspdidd->DevicePath);

                if(SetupDiGetDeviceRegistryProperty(hDevInfo,&spdd,SPDRP_FRIENDLYNAME,&dwType,(PBYTE)szProperty,sizeof(szProperty),NULL))
                {
                    if(dwType == REG_SZ)
                        printf("FriendlyName: %s\n", szProperty);
                }
                if(SetupDiGetDeviceRegistryProperty(hDevInfo,&spdd,SPDRP_DEVICEDESC,&dwType,(PBYTE)szProperty,sizeof(szProperty),NULL))
                {
                    if(dwType == REG_SZ)
                        printf("DeviceDescription: %s\n\n", szProperty);
                }
            }
            HeapFree(GetProcessHeap(), 0, pspdidd);
        }
        if((strstr(pspdidd->DevicePath, "hid#vid_03eb&pid_201c#6&1cdb5d6c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}")) != NULL)
            break;
    }
    SetupDiDestroyDeviceInfoList(hDevInfo);
    DeviceHandle = CreateFile(pspdidd->DevicePath,GENERIC_READ,FILE_SHARE_READ,(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0,NULL);
    HidD_GetAttributes(DeviceHandle,&Attributes);
 //   printf("\nVendorID : %X",Attributes.VendorID);
 //   printf("\nProductID: %X",Attributes.ProductID);
 //   printf("\nVersion  : %X",Attributes.VersionNumber);
    HidD_GetPreparsedData(DeviceHandle,&PreparsedData);
    HidP_GetCaps(PreparsedData,&Capabilities);

    return(0);
}

gruß

Autor: Rupplyn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zwar in vb aber vielleicht hilft's...

Autor: Dominik Dahlen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm ?

Autor: Dominik Dahlen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2 Sachen hab ich mitlerweile rausgefunden die ich leider aber auch nicht 
wirklich verstehe.

Es scheint so als würde ich keinen Handle bekommen jedenfalls schlägt 
CreateFile immer mit error-code 3 fehl also ERROR_PATH_NOT_FOUND.

Das passiert aber nur wenn ich vorher SetupDiDestroyDeviceInfoList 
aufrufe.
wenn ich SetupDiDestroyDeviceInfoList nicht aufrufe schlägt CreateFile 
mit error-code 5 also ERROR_ACCESS_DENIED fehl.

Alle andern vorherigen aufrufe funktionieren so wie sie sollen und 
werden bis auf beim ersten mal SetupDiEnumDeviceInterfaces aufrufen mit 
error-code 0 beendet.

gruß

Autor: Rupplyn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Dominik Dahlen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke dein Programm scheint genau das zu sein was ich gesucht habe um 
die ersten Kommunikationsversuche auszuprobieren.

Werds mir gleich zu Hause mal anschauen.

Autor: Dominik Dahlen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo vielleicht kann sich doch nochmal jemand der sache annehmen ich 
komm leider nicht wirklich weiter.

Ich bin mir mitlerweile sicher das mein uC die Daten richtig an den PC 
sendet.. Da ich das Device als Gamecontroller definiert habe und bereits 
unter der Systemsteuerung Gamecontroller das drücken der einzelnen 
knöpfe angezeigt bekomme.


jetzt funktioniert der Code auch soweit bis ich zum Readfile komme. Dort 
bekomm ich dann immer ein ERROR_IO_PENDING.

gruß

#include <iostream>
#include <windows.h>
#include <winerror.h>
#include <stdio.h>
#include <stdlib.h>
#include <ddk/hidsdi.h>
#include <ddk/hidpi.h>
#include <ddk/hidusage.h>
#include <setupapi.h>


int main()
{
    BOOL                             Return;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd;
    SP_DEVICE_INTERFACE_DATA         spdid;
    SP_DEVINFO_DATA                  spdd;
    HDEVINFO                         hDevInfo;
    DWORD                            dwIndex, dwSize, dwType;
    TCHAR                            szProperty[256];
    GUID                             guid;
    HANDLE                           DeviceHandle;
    HIDD_ATTRIBUTES                  Attributes;
    PHIDP_PREPARSED_DATA             PreparsedData;
    HIDP_CAPS                        Capabilities;
    LPVOID                           InputReport;
    DWORD                            *OutputReport;
    DWORD                            numBytesReturned;
    OVERLAPPED                       s_overlapped;
    HANDLE                           hEventObject;


    dwIndex = 0;

    spdid.cbSize = sizeof(spdid);
    HidD_GetHidGuid(&guid);
    printf("\n1. %d",GetLastError());
    hDevInfo = SetupDiGetClassDevs(&guid,NULL,NULL,DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    printf("\n2. %d",GetLastError());
    if(hDevInfo == INVALID_HANDLE_VALUE)
    {
        printf("SetupDiGetClassDevs failed, Error %u\n", GetLastError());
        return(FALSE);
    }

    SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&guid,dwIndex,&spdid);
    printf("\n3. %d",GetLastError());
    dwSize = 0;

    SetupDiGetDeviceInterfaceDetail(hDevInfo,&spdid,NULL,0,&dwSize,NULL);
    printf("\n4. %d",GetLastError());

    if(dwSize)
    {
        pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(dwSize);

        pspdidd->cbSize = sizeof(*pspdidd);
        spdd.cbSize = sizeof(spdd);

        if(SetupDiGetDeviceInterfaceDetail(hDevInfo,&spdid,pspdidd,dwSize,&dwSize,&spdd))
        {
            printf("\n5. %d",GetLastError());
            printf("Name fuer CreateFile(): %s", pspdidd->DevicePath);

            if(SetupDiGetDeviceRegistryProperty(hDevInfo,&spdd,SPDRP_FRIENDLYNAME,&dwType,(PBYTE)szProperty,sizeof(szProperty),NULL))
            {
                printf("\n6. %d",GetLastError());
                if(dwType == REG_SZ)
                    printf("FriendlyName: %s\n", szProperty);
            }
            if(SetupDiGetDeviceRegistryProperty(hDevInfo,&spdd,SPDRP_DEVICEDESC,&dwType,(PBYTE)szProperty,sizeof(szProperty),NULL))
            {
                printf("\n7. %d",GetLastError());
                if(dwType == REG_SZ)
                    printf("DeviceDescription: %s", szProperty);
            }
        }

    }
    SetupDiDestroyDeviceInfoList(hDevInfo);
    DeviceHandle = CreateFile((LPCTSTR)pspdidd->DevicePath,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
    printf("\n8. %d",GetLastError());
    HidD_GetAttributes(DeviceHandle,&Attributes);

    printf("\n9. %d",GetLastError());
    printf("\n  VendorID : %X",Attributes.VendorID);
    printf("\n  ProductID: %X",Attributes.ProductID);
    printf("\n  Version  : %X",Attributes.VersionNumber);

    HidD_GetPreparsedData(DeviceHandle,&PreparsedData);
    printf("\n10. %d",GetLastError());

    HidP_GetCaps(PreparsedData,&Capabilities);
    printf("\n11. %d",GetLastError());
    printf("\n  Usage: %X "
           "\n  UsagePage: %X "
           "\n  InputReport: %X "
           "\n  Outputreport: %X "
           "\n  FeatureReportByteLength: %X"
           "\n  NumberLinkCollectionNodes: %X"
           "\n  NumberInputButtonCaps: %X"
           "\n  NumberInputValueCaps: %X"
           "\n  NumberInputDataIndices: %X"
           "\n  NumberFeatureButtonCaps: %X"
           "\n  NumberFeatureValueCaps: %X"
           "\n  NumberFeatureDataIndices: %X",
            Capabilities.Usage,
            Capabilities.UsagePage,
            Capabilities.InputReportByteLength,
            Capabilities.OutputReportByteLength,
            Capabilities.FeatureReportByteLength,
            Capabilities.NumberLinkCollectionNodes,
            Capabilities.NumberInputButtonCaps,
            Capabilities.NumberInputValueCaps,
            Capabilities.NumberInputDataIndices,
            Capabilities.NumberFeatureButtonCaps,
            Capabilities.NumberFeatureValueCaps,
            Capabilities.NumberFeatureDataIndices);

    HidD_FreePreparsedData(PreparsedData);
    printf("\n12. %d",GetLastError());

    InputReport = (DWORD*) malloc(Capabilities.InputReportByteLength);
//    OutputReport = (DWORD*) malloc(Capabilities.OutputReportByteLength);

    hEventObject = CreateEvent(NULL,TRUE,TRUE,"");
    printf("\n13. %d",GetLastError());
    s_overlapped.hEvent = hEventObject;
    s_overlapped.Offset = 0;
    s_overlapped.OffsetHigh = 0;

//    OutputReport[0] = 0x01;
//    OutputReport[1] = 0x02;

//    WriteFile(DeviceHandle,OutputReport,Capabilities.OutputReportByteLength,&numBytesReturned,(LPOVERLAPPED)&s_overlapped);
    Return = ReadFile(DeviceHandle,InputReport,Capabilities.InputReportByteLength,&numBytesReturned,(LPOVERLAPPED)&s_overlapped);

    printf("\nNumBytesReturned: %d",numBytesReturned);
    printf("\n%X",InputReport);
    printf("\n14. %d",GetLastError());
    return(0);
}

Autor: Xenu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Dort bekomm ich dann immer ein ERROR_IO_PENDING.

Das heisst bei einem Overlapped-Read nur, dass die Datenübertragung noch 
andauert. Du musst mit WaitForSingleObject() auf das Ende der 
Datenübertragung warten.

Autor: Knopf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich stehe vor dem gleichen Problem.


Kannst Du als Beispielcode die PC und die Firmware mal posten. For allem 
jene die funktioniert.

Danke

Ralf

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.