Page 1 of 1

Help with usbHidReportDescriptor

Posted: Thu Feb 11, 2010 9:25 am
by schwa226
Hi,

I'm new to V-USB. I found the example 17-Keys HID with keyboard emulation.

I will make a project for an IR receiver (RC5,RC6,..)
I want to send the raw received code to the host.

As in MSDN descripted it is possible to get RAW data from HID devices.

My problem is now to make a right usbHidReportDescriptor for my project.

I want to send 8 bytes (0x00-0xFF) from the AVR to the host.

Can somebody help me?

Re: Help with usbHidReportDescriptor

Posted: Sun Feb 28, 2010 6:39 pm
by christian
If you want to use HID for data, not as an external keyboard, see the hid-data example which ships with the driver.

Re: Help with usbHidReportDescriptor

Posted: Fri Mar 05, 2010 3:06 pm
by schwa226
Hi,

thx for this info!

I found the example and i modified it to 6 byte transfer:

Code: Select all

PROGMEM char usbHidReportDescriptor[21] = {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x01,                    // USAGE (Vendor Usage 1)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x06,                    //   REPORT_COUNT (6)
    0x09, 0x00,                    //   USAGE (Undefined)
    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)
    0xc0                           // END_COLLECTION
};


But now I have the problem that the avr will not get listed in my list of GetRawInputDeviceList: http://msdn.microsoft.com/en-us/library/ms645598(VS.85).aspx!

The AVR is found in the system and have the VID/PID: USB\VID_16C0&PID_05DF

Why it will not be listed in Raw Input Device list?

Registry:

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_16C0&PID_05DF]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_16C0&PID_05DF\5&1bb80c05&0&1]
"DeviceDesc"="@input.inf,%hid.devicedesc%;USB-Eingabegerät"
"LocationInformation"="Port_#0001.Hub_#0005"
"Capabilities"=dword:00000084
"HardwareID"=hex(7):55,00,53,00,42,00,5c,00,56,00,49,00,44,00,5f,00,31,00,36,\
  00,43,00,30,00,26,00,50,00,49,00,44,00,5f,00,30,00,35,00,44,00,46,00,26,00,\
  52,00,45,00,56,00,5f,00,30,00,31,00,30,00,30,00,00,00,55,00,53,00,42,00,5c,\
  00,56,00,49,00,44,00,5f,00,31,00,36,00,43,00,30,00,26,00,50,00,49,00,44,00,\
  5f,00,30,00,35,00,44,00,46,00,00,00,00,00
"CompatibleIDs"=hex(7):55,00,53,00,42,00,5c,00,43,00,6c,00,61,00,73,00,73,00,\
  5f,00,30,00,33,00,26,00,53,00,75,00,62,00,43,00,6c,00,61,00,73,00,73,00,5f,\
  00,30,00,30,00,26,00,50,00,72,00,6f,00,74,00,5f,00,30,00,30,00,00,00,55,00,\
  53,00,42,00,5c,00,43,00,6c,00,61,00,73,00,73,00,5f,00,30,00,33,00,26,00,53,\
  00,75,00,62,00,43,00,6c,00,61,00,73,00,73,00,5f,00,30,00,30,00,00,00,55,00,\
  53,00,42,00,5c,00,43,00,6c,00,61,00,73,00,73,00,5f,00,30,00,33,00,00,00,00,\
  00
"ContainerID"="{073edcf9-2849-11df-9596-005056c00008}"
"ConfigFlags"=dword:00000000
"ClassGUID"="{745a17a0-74d3-11d0-b6fe-00a0c90f57da}"
"Driver"="{745a17a0-74d3-11d0-b6fe-00a0c90f57da}\\0012"
"Class"="HIDClass"
"Mfg"="@input.inf,%stdmfg%;(Standardsystemgeräte)"
"Service"="HidUsb"
"ParentIdPrefix"="6&f11c4ed&5"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_16C0&PID_05DF\5&1bb80c05&0&1\Device Parameters]
"SymbolicName"="\\??\\USB#VID_16C0&PID_05DF#5&1bb80c05&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_16C0&PID_05DF\5&1bb80c05&0&1\LogConf]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_16C0&PID_05DF\5&1bb80c05&0&1\Control]


Also strange is the second device:
Image
I tried to uninstall the mouse. But it is coming again when the AVR gets connected.

Re: Help with usbHidReportDescriptor

Posted: Fri Mar 05, 2010 5:59 pm
by schwa226
Ok, at first:

if the Usage is != Keyboard or Mouse the second device like the picture is showing will apear.

If the Usage != Keybaord or Mouse GetRawInputDeviceInfo will not find the Device. Looks like only Keyboard & Mouse are supported.

So now I don't get it working! I tried also this:

Code: Select all

char ReportDescriptor[20] = {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,                    //   USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x06,                    //   REPORT_COUNT (6)
    0x09, 0x00,                    //   USAGE (Undefined)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0                           //   END_COLLECTION
};


Because of the sample of HID Keys:

Code: Select all

PROGMEM char usbHidReportDescriptor[35] = { /* USB report descriptor */
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,                    // USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0                           // END_COLLECTION
};

It will work that I get the Message WM_INPUT from the device.


Ho to get it working to send 6 Bytes per interrupt to the host? Lib-USB is no way because it isn't working on WIN7!

Re: Help with usbHidReportDescriptor

Posted: Fri Mar 05, 2010 6:10 pm
by christian
When you switch your HID between mouse, keyboard and other types, ALWAYS switch the USB PID as well. Windows caches the association of PID with a driver forever.

Regarding the host side software: Look at the hid-data example, it uses the functions from libs-host. The Windows version uses native Windows functions (not libusb-win32) to send and receive feature reports. Note that these reports are not sent in interrupt transfers, they are sent over the control endpoint 0.

Re: Help with usbHidReportDescriptor

Posted: Fri Mar 05, 2010 8:08 pm
by schwa226
I got the AVR part now compiled but I have problems with the command line tool:
C:\HID\AVR\vusb-20090822\examples\hid-data\commandline>make -f Makefile.windows
gcc -O -Wall -c hidtool.c -o hidtool.o
process_begin: CreateProcess(NULL, gcc -O -Wall -c hidtool.c -o hidtool.o, ...)
failed.
make (e=2): Das System kann die angegebene Datei nicht finden.
make: *** [hidtool.o] Error 2


I installed the complete MinGW.

Re: Help with usbHidReportDescriptor

Posted: Fri Mar 05, 2010 8:23 pm
by christian
The error message says that the make utility can't find the gcc executable. This is some kind of misconfiguration of your MinGW installation.

Re: Help with usbHidReportDescriptor

Posted: Fri Mar 05, 2010 8:49 pm
by schwa226
Any hint how to fix this?

EDIT: PATH variable was needed, after a reboot it's working.

One question about the hidtool: Is there a MSDN documentation how the device get choosen?
Better would be an example for Delphi...

Re: Help with usbHidReportDescriptor

Posted: Sat Mar 06, 2010 10:32 pm
by schwa226
Hi,

I translated the code now to D2010. It's working!

But one more question! Waht is the "reportNumber"?

Code: Select all

int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len)
{
BOOLEAN rval = 0;

    buffer[0] = reportNumber;
    rval = HidD_GetFeature((HANDLE)device, buffer, *len);
    return rval == 0 ? USBOPEN_ERR_IO : 0;
}


And how to do a feature request of 2 different values?
Like once I want to read a var type struct of 6 Bytes.
The other second request will be 6 bytes of eeprom.

Re: Help with usbHidReportDescriptor

Posted: Sun Mar 07, 2010 11:00 am
by schwa226
As I found out the report number is the Report ID.

I have now this usbFunctionSetup function:

Code: Select all

/* ------------------------------------------------------------------------- */

uchar   usbFunctionSetup(uchar data[8])
{
static uchar    replyBuf[7];
usbRequest_t    *rq = (void *)data;

          usbMsgPtr = replyBuf;


    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    // HID class request
        if(rq->bRequest == USBRQ_HID_GET_REPORT){  // wValue: ReportType (highbyte), ReportID (lowbyte)


            if(rq->wValue.bytes[0] == 1){   /* ReportID 1 */
//send dummy repl
                replyBuf[0] = rq->wValue.bytes[0];
                replyBuf[1] = 0x11;
                replyBuf[2] = 0x22;
                replyBuf[3] = 0x33;
                replyBuf[4] = 0x44;
                replyBuf[5] = 0x55;
                replyBuf[6] = 0x66;                         
                return 7;
            }else if(rq->wValue.bytes[0] == 2){ /* ReportID 2 */
                replyBuf[0] = rq->wValue.bytes[0];
            eeprom_read_block(&replyBuf[1], 0, 1);
                return 2; 
            }else if(rq->wValue.bytes[0] == 3){ /* ReportID 3 */
                replyBuf[0] = rq->wValue.bytes[0];
            eeprom_read_block(&replyBuf[1], 1, 6);
                return 7; 
            }
         
        }else if(rq->bRequest == USBRQ_HID_SET_REPORT){
            if(rq->wValue.bytes[0] == 4){   /* ReportID 4 */
            //store Enabled in EEProm:      
            eeprom_write_block(&rq->wValue.bytes[1], (uchar *)0, 1);
            //update Enabled
            Enabled = rq->wValue.bytes[1]; 
                return 1;
            
            }else if(rq->wValue.bytes[0] == 5){  /* ReportID 5 */
            //store Code in EEProm         
            eeprom_write_block(&rq->wValue.bytes[1], (uchar *)1, 6);
                return 1;
            
            }
        }
    }else{
        // ignore vendor type requests, we don't use any
    }
    return 0;
}


Reading Report IDs 1-3 is working as it should.

But the saving to the eeprom isn't working.

Please help!

THX!

Re: Help with usbHidReportDescriptor

Posted: Tue Mar 23, 2010 3:31 pm
by schwa226
Hi,

I want to modify my descriptor!

old:

Code: Select all

PROGMEM char usbHidReportDescriptor[24] = {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x0b, 0x01, 0x00, 0x00, 0xff,  // USAGE (Vendor Defined Page 1:Vendor Usage 1)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x06,                    //   REPORT_COUNT (6)
    0x09, 0x00,                    //   USAGE (Undefined)
    0x82, 0x02, 0x01,              //   INPUT (Data,Var,Abs,Buf)
    0xc0                           // END_COLLECTION
};


new:

Code: Select all

PROGMEM char usbHidReportDescriptor[40] = {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x0b, 0x01, 0x00, 0x00, 0xff,  // USAGE (Vendor Defined Page 1:Vendor Usage 1)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x06,                    //   REPORT_COUNT (6)
    0x09, 0x00,                    //   USAGE (Undefined)
    0x82, 0x02, 0x01,              //   INPUT (Data,Var,Abs,Buf)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x85, 0x01,                    //   REPORT_ID (1)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x09, 0x00,                    //   USAGE (Undefined)
    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)
    0xc0                           // END_COLLECTION
};


But the device get's not init! How to work with input and feature?

thx