HID - Consumer device (multimedia keys)

191 views
Skip to first unread message

MatSOBDev

unread,
Mar 19, 2023, 1:02:44 PM3/19/23
to btstack-dev
I've managed to make it working on Pico W USB (CherryUSB USB stack), so it works on Windows using consumer device (multimedia keyboard keycodes are only working for Unix systems, like in USB HID spec.). But now copying the same HID descriptor to Pico W BTstack 'hog_keyboard_demo' example, only standard keyboard part (report_id 0x01 is working). My HID descriptor (standard part for CherryUSB and BTstack is the same - just quick visual comparision):

const uint8_t hid_descriptor_keyboard_boot_mode[] = {

    0x05, 0x01,                    // Usage Page (Generic Desktop)
    0x09, 0x06,                    // Usage (Keyboard)
    0xa1, 0x01,                    // Collection (Application)

    0x85,  0x01,                   // Report ID 1

    // Modifier byte

    0x75, 0x01,                    //   Report Size (1)
    0x95, 0x08,                    //   Report Count (8)
    0x05, 0x07,                    //   Usage Page (Key codes)
    0x19, 0xe0,                    //   Usage Minimum (Keyboard LeftControl)
    0x29, 0xe7,                    //   Usage Maxium (Keyboard Right GUI)
    0x15, 0x00,                    //   Logical Minimum (0)
    0x25, 0x01,                    //   Logical Maximum (1)
    0x81, 0x02,                    //   Input (Data, Variable, Absolute)

    // Reserved byte

    0x75, 0x01,                    //   Report Size (1)
    0x95, 0x08,                    //   Report Count (8)
    0x81, 0x03,                    //   Input (Constant, Variable, Absolute)

    // LED report + padding

    0x95, 0x05,                    //   Report Count (5)
    0x75, 0x01,                    //   Report Size (1)
    0x05, 0x08,                    //   Usage Page (LEDs)
    0x19, 0x01,                    //   Usage Minimum (Num Lock)
    0x29, 0x05,                    //   Usage Maxium (Kana)
    0x91, 0x02,                    //   Output (Data, Variable, Absolute)

    0x95, 0x01,                    //   Report Count (1)
    0x75, 0x03,                    //   Report Size (3)
    0x91, 0x03,                    //   Output (Constant, Variable, Absolute)

    // Keycodes

    0x95, 0x06,                    //   Report Count (6)
    0x75, 0x08,                    //   Report Size (8)
    0x15, 0x00,                    //   Logical Minimum (0)
    0x25, 0xff,                    //   Logical Maximum (1)
    0x05, 0x07,                    //   Usage Page (Key codes)
    0x19, 0x00,                    //   Usage Minimum (Reserved (no event indicated))
    0x29, 0xff,                    //   Usage Maxium (Reserved)
    0x81, 0x00,                    //   Input (Data, Array)

    0xc0,                          // End collection
 0x05, 0x0C, /* usage page (consumer device) */
0x09, 0x01, /* usage -- consumer control */
0xA1, 0x01, /* collection (application) */
0x85, 0x02, /* report id */
/* 4 Media Keys */
0x15, 0x00, /* logical minimum */
0x26, 0xFF, 0x03, /* logical maximum (3ff) */
0x19, 0x00, /* usage minimum (0) */
0x2A, 0xFF, 0x03, /* usage maximum (3ff) */
0x95, 0x04, /* report count (4) */
0x75, 0x10, /* report size (16) */
0x81, 0x00, /* input */
0xC0 /* end collection */
};
Copied the same, so apple to apple comparision, HID is just HID, but appending my extra part to original descriptors gives the same results - USB works, BTstack just standard keyboard).

So using:

static void send_report(uint8_t rep_id, uint8_t modifier, uint8_t keycode, uint8_t keycode_last){
    uint8_t report[] = {rep_id, modifier, 0, keycode, 0, 0, 0, 0, keycode_last};
    switch (protocol_mode){
        case 0:
            hids_device_send_boot_keyboard_input_report(con_handle, report, sizeof(report));
            break;
        case 1:
           hids_device_send_input_report(con_handle, report, sizeof(report));
           break;
        default:
            break;
    }
}
to press and release keys. 'rep_id' is value of 0x85 report id. 0x01 for standard keyboard and 0x02 - consumer device. I call:
send_report(0x02, 0xEA, 0x00, 0x00);
to press
and:
send_report(0x02, 0x00, 0x00, 0x00);
to release volume key down if remember correctly. CherryUSB has similar grammatic, and it works with different 'rep_id". For BTstack it does nothing. It sends 9 bytes instead of 8 of original example without report id in front of it. For consumer device first key will be 'modifier' variable, but doesn't mattes - 8 keys available in that mode. But if I do like that:
send_report(0x01, 0x00, 0x10, 0x00);
and:
send_report(0x01, 0x00, 0x00, 0x00);
to release and it works - just standard keyboard as it should. HCI dump shows it sends 9 bytes including 0x01 'rep_id' in front of it. 'rep_id' 0x02 has corresponding pattern, witn 0x02 in front obviously, no data corruption then, but doesn't work> If data sent seems ok than I have no clue, what is going on, if HID desctiptor works on other stack.

MatSOBDev

unread,
Mar 26, 2023, 2:35:47 AM3/26/23
to btstack-dev
Just kinda solved, at least works, more here.

Emanuel Lopes

unread,
Mar 20, 2024, 11:10:28 AMMar 20
to btstack-dev

How did you solved the issue?
Reply all
Reply to author
Forward
0 new messages