HID Composite device with reports bigger than 8 bytes

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
wilin
Posts: 4
Joined: Sat Nov 01, 2008 9:32 am

HID Composite device with reports bigger than 8 bytes

Post by wilin » Sat Nov 01, 2008 11:25 am

Hi

Does anybody know, how to successfully send reports for two devices (2 gamepads in my case), that are more than 8 bytes long? (1 byte reportID + 8 bytes data). Because I can send >8 bytes for one joystick (not a composite device) or 2x8bytes (composite device, two joysticks, but then I'm missing 8 buttons on each). This is the last thing that I want to implement in my converter (it's a Playstation/Playstation2 gamepad converter with support for DDR pads and possibly Guitar Hero controllers) and it's been driving me crazy for the past two days (for some reason whatever I tried presented itself as a mouse under linux, and didn't work fully under windows).

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Tue Nov 04, 2008 12:36 pm

When you send reports of more than 8 bytes, concatenate several calls to usbSetInterrupt() and make sure the buffer is empty with usbInterruptIsReady() before you call usbSetInterrupt(). The last chunk should be less than 8 bytes to indicate the end of transfer.

wilin
Posts: 4
Joined: Sat Nov 01, 2008 9:32 am

Post by wilin » Tue Nov 04, 2008 9:32 pm

I've tried sending two reports (first 8 bytes, then one, then 8 again, and one again), and it doesn't really work. Linux detects it as a mouse, while Windows detects it as a gamepad and everything, but eats (doesn't change) 3 bits from the eight and ninth byte (maybe even more). I think I made Windows not eat those bits by sending 18 bytes together (8+8+2), but it still didn't work properly under linux.

I think my problem is somewhere else, probably in the if(rq->bRequest == USBRQ_HID_GET_REPORT) statement. I've uploaded the current main.c (minimalistic version, most of the features cut out) to http://pastebin.com/m5474b7ff

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Wed Nov 05, 2008 1:01 pm

Sorry, I don't have the time to go through your code. But I can confirm that sending a 18 byte report as 8 + 8 + 2 should work as long as you make sure that the buffer is available when you call usbSetInterrupt().

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Wed Nov 05, 2008 1:05 pm

Sorry, I don't have the time to go through your code. But I can confirm that sending a 18 byte report as 8 + 8 + 2 should work as long as you make sure that the buffer is available when you call usbSetInterrupt().

mojo
Rank 1
Rank 1
Posts: 39
Joined: Tue Mar 04, 2008 3:57 pm

Re: HID Composite device with reports bigger than 8 bytes

Post by mojo » Mon Sep 21, 2009 8:37 pm

Christian, can you elaborate a little? When you say you need to make sure the buffer is available with usbInterruptIsReady(), do you mean before every call to usbSetInterrupt() or just once before all the calls?

For example, this does not seem to work properly:

Code: Select all

        if(usbInterruptIsReady())
      {
            /* called after every poll of the interrupt endpoint */
         ReadJoystick();
         usbSetInterrupt((void *)&reportBuffer + 0, 8);
         usbSetInterrupt((void *)&reportBuffer + 8, 8);   // 16
         usbSetInterrupt((void *)&reportBuffer + 16, 8);   // 24
         usbSetInterrupt((void *)&reportBuffer + 24, 8);   // 32
         usbSetInterrupt((void *)&reportBuffer + 32, 8);   // 40
         usbSetInterrupt((void *)&reportBuffer + 40, 7);   // 47
        }


And neither does this:

Code: Select all

        if(usbInterruptIsReady())
      {
            /* called after every poll of the interrupt endpoint */
         ReadJoystick();
         usbSetInterrupt((void *)&reportBuffer + 0, 8);
                        while(!usbInterruptIsReady());
         usbSetInterrupt((void *)&reportBuffer + 8, 8);   // 16
                        while(!usbInterruptIsReady());
         usbSetInterrupt((void *)&reportBuffer + 16, 8);   // 24
                        while(!usbInterruptIsReady());
         usbSetInterrupt((void *)&reportBuffer + 24, 8);   // 32
                        while(!usbInterruptIsReady());
         usbSetInterrupt((void *)&reportBuffer + 32, 8);   // 40
                        while(!usbInterruptIsReady());
         usbSetInterrupt((void *)&reportBuffer + 40, 7);   // 47
        }

mojo
Rank 1
Rank 1
Posts: 39
Joined: Tue Mar 04, 2008 3:57 pm

Re: HID Composite device with reports bigger than 8 bytes

Post by mojo » Mon Sep 21, 2009 8:53 pm

Oh, I tried with this too:

Code: Select all

while (!usbInterruptIsReady()) usbPoll();


Didn't help.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: HID Composite device with reports bigger than 8 bytes

Post by christian » Mon Sep 21, 2009 9:45 pm

This latest version should work, unless parts of your software suffer under the large delay of this construct.

I noticed you compute (void *)&buffer + intvalue. Gcc probably handles it correctly, but strictly speaking, a void pointer has no size and adding a value to it is nonsense. You probably want (char *)&buffer + intvalue.

mojo
Rank 1
Rank 1
Posts: 39
Joined: Tue Mar 04, 2008 3:57 pm

Re: HID Composite device with reports bigger than 8 bytes

Post by mojo » Tue Sep 22, 2009 1:07 am

Thanks for the reply. I am not the OP, but I have a similar problem. I am getting some strange results.

The above code works, sort of. I get 50 bytes returned with the correct data when I use SimpleHIDWrite to check it. For some reason though, the HID gamepad interface just seems to ignore it. I get absolutely nothing, even when I write random rolling values.

The report descriptor seems to be valid (I tried a few, they are all based on the PS3 SIXAXIS one). It must be some kind of issue like that though.

Thanks for the assistance.

Post Reply