Modifying the SDK Keyboard USB HID Descriptor

I have a product under development that needs to send USB key codes to the PC that are outside the range that is supported by the USBD library and I am wondering the best way to go about altering the HID Keyboard descriptor.

The project implementation relies on the USBD library extensively. The USB Keyboard Descriptor is not taken from the user application; it relies on the USB HID KBD descriptor provided by the USBD library. The Logical Maximum and Usage Maximum reported by the USBD library are both 0x65. This needs to be increased to 0x73 to support keys up to F24, and I cannot determine a way to replace the built-in descriptor with my own.

From "app_usbd_hid_kbd_desc.h":

/**
 * @brief Example of USB HID keyboard report descriptor.
 *
 */
#define APP_USBD_HID_KBD_REPORT_DSC() {                                                    \
        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)                              */\
        0x81, 0x03,                    /*   INPUT (Cnst,Var,Abs)                         */\
        0x95, 0x05,                    /*   REPORT_COUNT (5)                             */\
        0x75, 0x01,                    /*   REPORT_SIZE (1)                              */\
        0x05, 0x08,                    /*   USAGE_PAGE (LEDs)                            */\
        0x19, 0x01,                    /*   USAGE_MINIMUM (Num Lock)                     */\
        0x29, 0x05,                    /*   USAGE_MAXIMUM (Kana)                         */\
        0x91, 0x02,                    /*   OUTPUT (Data,Var,Abs)                        */\
        0x95, 0x01,                    /*   REPORT_COUNT (1)                             */\
        0x75, 0x03,                    /*   REPORT_SIZE (3)                              */\
        0x91, 0x03,                    /*   OUTPUT (Cnst,Var,Abs)                        */\
        0x95, 0x06,                    /*   REPORT_COUNT (6)                             */\
        0x75, 0x08,                    /*   REPORT_SIZE (8)                              */\
        0x15, 0x00,                    /*   LOGICAL_MINIMUM (0)                          */\
        0x25, 0x65,                    /*   LOGICAL_MAXIMUM (101)                        */\
        0x05, 0x07,                    /*   USAGE_PAGE (Keyboard)                        */\
        0x19, 0x00,                    /*   USAGE_MINIMUM (Reserved (no event indicated))*/\
        0x29, 0x65,                    /*   USAGE_MAXIMUM (Keyboard Application)         */\
        0x81, 0x00,                    /*   INPUT (Data,Ary,Abs)                         */\
        0xc0                           /* END_COLLECTION                                 */\
}

What is the "correct" way to change the USB HID KBD descriptor?

To be clear, I need to change the Logical Maximum and Usage Maximum to 0x73, instead of 0x65.

I am very reluctant to edit the content of the SDK. To edit the file within the SDK is likely to work, however it then relies on documenting changes to the SDK, should the SDK ever be changed at some point in the future. This would seem like a solution that will work today, however another developer in future would need to know that there have been changes made to the standard SDK.There is a code maintenance risk in the future.

I would prefer to define my own version of APP_USBD_HID_KBD_REPORT_DSC(), however I cannot see how to do it as the library version is used within app_usbd_hid_kbd:

/**
 * @brief Global definition of app_usbd_hid_kbd_t class.
 *
 * @param instance_name     Name of global instance.
 * @param interface_number  Unique interface index.
 * @param endpoint          Input endpoint (@ref nrf_drv_usbd_ep_t).
 * @param user_ev_handler   User event handler (optional parameter: NULL might be passed here).
 * @param subclass_boot     Subclass boot (@ref app_usbd_hid_subclass_t).
 *
 * Example class definition:
 * @code
   APP_USBD_HID_KBD_GLOBAL_DEF(my_awesome_kbd, 0, NRF_DRV_USBD_EPIN1, NULL, APP_USBD_HID_SUBCLASS_BOOT);
 * @endcode
 */
#define APP_USBD_HID_KBD_GLOBAL_DEF(instance_name, interface_number, endpoint, user_ev_handler, subclass_boot)  \
        APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(keyboard_desc, APP_USBD_HID_KBD_REPORT_DSC());                \
        static const app_usbd_hid_subclass_desc_t * keyboard_descs[] = {&keyboard_desc};                        \
        APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL(instance_name,                                                     \
                                             interface_number,                                                  \
                                             endpoint,                                                          \
                                             user_ev_handler,                                                   \
                                             subclass_boot)

At this point, I cannot see any other way to change the USB HID KBD descriptor, other than to change the file in the SDK.

Can you please help to share the correct method for changing the USB HID KBD descriptor.

SDK 17.1.0.

Parents
  • I have come up with one approach that seems viable.

    For reference, I'm building with Segger Embedded Studio. This would have been all of 5 minutes work if I'd been using a makefile rather than using SES!

    Changes:

    • Take a copy of app_usbd_hid_kbd_desc.h and place it into the project folder.
    • Add app_usbd_hid_kbd_desc.h to the list of included project files.
    • Edit app_usbd_hid_kbd_desc.h to suit my project, including changing the descriptor.
    • Edit the SES project options to add the project path to the Preprocessor User Include Directories, for the common project configuration (as opposed to the Debug or Release configurations).

    By making these changes, SES picks up the project-specific file instead of the file of the same name that is in the Nordic USBD library.

    For extra short-term insurance, I have changed the filename of app_usbd_hid_kbd_desc.h within the SDK, just to be double-sure that the original file from the SDK could not be used.

    In an attempt to increase confidence that the correct descriptor was being picked up, I tried to add a  #ifdef #error to my own copy of the header file to check that APP_USBD_HID_KBD_REPORT_DSC has not previously been defined, however this check always failed. I could not find any other definition of the APP_USBD_HID_KBD_REPORT_DSC macro in the USBD library files anywhere, so I'm not sure what to make of this.

    If this is a legitimate way to replace SDK files with user-modified versions, I'd appreciate the feedback.

Reply
  • I have come up with one approach that seems viable.

    For reference, I'm building with Segger Embedded Studio. This would have been all of 5 minutes work if I'd been using a makefile rather than using SES!

    Changes:

    • Take a copy of app_usbd_hid_kbd_desc.h and place it into the project folder.
    • Add app_usbd_hid_kbd_desc.h to the list of included project files.
    • Edit app_usbd_hid_kbd_desc.h to suit my project, including changing the descriptor.
    • Edit the SES project options to add the project path to the Preprocessor User Include Directories, for the common project configuration (as opposed to the Debug or Release configurations).

    By making these changes, SES picks up the project-specific file instead of the file of the same name that is in the Nordic USBD library.

    For extra short-term insurance, I have changed the filename of app_usbd_hid_kbd_desc.h within the SDK, just to be double-sure that the original file from the SDK could not be used.

    In an attempt to increase confidence that the correct descriptor was being picked up, I tried to add a  #ifdef #error to my own copy of the header file to check that APP_USBD_HID_KBD_REPORT_DSC has not previously been defined, however this check always failed. I could not find any other definition of the APP_USBD_HID_KBD_REPORT_DSC macro in the USBD library files anywhere, so I'm not sure what to make of this.

    If this is a legitimate way to replace SDK files with user-modified versions, I'd appreciate the feedback.

Children
No Data
Related