USB, HID and Joysticks (Non DC related).

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
doragasu
DCEmu Cool Poster
DCEmu Cool Poster
Posts: 1048
Joined: Thu May 16, 2002 5:01 pm
Location: Madrid, Spain
Has liked: 0
Been liked: 0

USB, HID and Joysticks (Non DC related).

Post by doragasu » Tue Aug 30, 2005 6:25 am

I have implemented a USB HID Joystick with a microcontroller with USB capabilities using this HID Report descriptor:

Code: Select all

char ReportDescriptor[44] = {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x04,                    // USAGE (Joystick)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x75, 0x02,                    //     REPORT_SIZE (2)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x0c,                    //     USAGE_MAXIMUM (Button 12)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x95, 0x0c,                    //     REPORT_COUNT (12)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0xc0                           // END_COLLECTION
};
It works flawlessly, but now I want to implement two joysticks with a single device (only one MCU chip). I have tried a lot of descriptors with no luck. If I define two COLLECTION(Application) items, it doesn't enumerate, if I define two COLLECTION(Logical) and also use USAGE_PAGE(Ordinals) and USAGE(Instance N), the device gets enumerated but only a Joystick is added with double number of buttons. I have also tried using different Physical collections and Report IDs, but I can't get it to work. Can this be done with a single HID descriptor? Or do I need to define 2 interfaces, 2 endpoints and 2 HID descriptors? Or isn't adding two Joysticks with a single device possible?
doragasu
DCEmu Cool Poster
DCEmu Cool Poster
Posts: 1048
Joined: Thu May 16, 2002 5:01 pm
Location: Madrid, Spain
Has liked: 0
Been liked: 0

Post by doragasu » Wed Aug 31, 2005 3:46 am

Finally I have found the way to do this, I had to use two REPORT_ID items, this is the descriptor I have used to get it working:

Code: Select all

char ReportDescriptor[88] = {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x04,                    // USAGE (Joystick)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0x85, 0x01,                    //   REPORT_ID (1)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x09, 0x31,                    //     USAGE (Y)
    0x09, 0x30,                    //     USAGE (X)
    0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x75, 0x02,                    //     REPORT_SIZE (2)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
    0x29, 0x0c,                    //   USAGE_MAXIMUM (Button 12)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x0c,                    //   REPORT_COUNT (12)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0xc0,                          // END_COLLECTION
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x04,                    // USAGE (Joystick)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0x85, 0x02,                    //   REPORT_ID (2)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x09, 0x31,                    //     USAGE (Y)
    0x09, 0x30,                    //     USAGE (X)
    0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x75, 0x02,                    //     REPORT_SIZE (2)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0x05, 0x09,                    //   USAGE_PAGE (Button)
    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
    0x29, 0x0c,                    //   USAGE_MAXIMUM (Button 12)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x0c,                    //   REPORT_COUNT (12)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
};
Post Reply