This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

HID endpoint clarification (feature reports)

I'm trying to wrap my head around the APP_USBD driver, but I'm running into a mental block.  I am implementing a report descriptor for the Battery System usage page, and all of the characteristics are features.  So would I use an in or out endpoint? or both?  I'm in the middle of trying this now and I'm not getting an error, but I'm not seeing the endpoint on the host either - so I'm not sure if this is caused by the endpoint definition or the report.

It has also lead me down a bit of a rabbit hole.  I actually have a composite device with two endpoints working nicely (joystick and keyboard).  When I was adding on this third piece, I remembered that the default keyboard descriptor from the example has an output in it, but there is only an in endpoint.  So this has me feeling like I don't understand what's going on.  Shouldn't there also have to be an out endpoint for the keyboard to get the output from the host?  I thought I would try it, but when I added an out endpoint, the GLOBAL_DEF macro didn't like it and I'm not sure why:

#define HID_KEYBOARD_EPIN       NRF_DRV_USBD_EPIN(2)
#define HID_KEYBOARD_EPOUT       NRF_DRV_USBD_EPOUT(1)

#define ENDPOINT_LIST_KEYBOARD() \
(                           \
        HID_KEYBOARD_EPIN,  \
        HID_KEYBOARD_EPOUT  \
)

APP_USBD_HID_KBD_GLOBAL_DEF(m_app_hid_keyboard,
                            HID_KEYBOARD_INTERFACE,
                            ENDPOINT_LIST_KEYBOARD(),
                            hid_kbd_user_ev_handler,
                            APP_USBD_HID_SUBCLASS_NONE);

gives an "initializer element is not constant" error:

7> Compiling ‘main.c’
7> In file included from ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h:58,
7>                  from C:\some_path\main.c:96:
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h:116:1: error: initializer element is not constant
7> ../../../../../../components/libraries/util/app_util.h:712:37: note: in expansion of macro 'APP_USBD_HID_KBD_INTERVAL'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'MACRO_MAP_1'
7> ../../../../../../components/libraries/util/app_util.h:700:29: note: in expansion of macro 'MACRO_MAP_N_'
7> ../../../../../../components/libraries/util/app_util.h:679:25: note: in expansion of macro 'MACRO_MAP_N'
7> ../../../../../../components/libraries/util/app_util.h:678:24: note: in expansion of macro 'MACRO_MAP_'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h:167:52: note: in expansion of macro 'MACRO_MAP'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h:233:9: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL'
7> C:\some_path\main.c:619:1: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h:116:1: note: (near initialization for 'm_app_hid_keyboard_ep')
7> ../../../../../../components/libraries/util/app_util.h:712:37: note: in expansion of macro 'APP_USBD_HID_KBD_INTERVAL'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'MACRO_MAP_1'
7> ../../../../../../components/libraries/util/app_util.h:700:29: note: in expansion of macro 'MACRO_MAP_N_'
7> ../../../../../../components/libraries/util/app_util.h:679:25: note: in expansion of macro 'MACRO_MAP_N'
7> ../../../../../../components/libraries/util/app_util.h:678:24: note: in expansion of macro 'MACRO_MAP_'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h:167:52: note: in expansion of macro 'MACRO_MAP'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h:233:9: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL'
7> C:\some_path\main.c:619:1: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF'
7> In file included from ../../../../../../components/libraries/usbd/app_usbd.h:46,
7>                  from C:\some_path\main.c:92:
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:463:18: error: initializer element is not constant
7> ../../../../../../components/libraries/util/app_util.h:747:41: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_1__'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'MACRO_MAP_REC_1'
7> ../../../../../../components/libraries/util/app_util.h:708:33: note: in expansion of macro 'MACRO_MAP_REC_N_'
7> ../../../../../../components/libraries/util/app_util.h:687:29: note: in expansion of macro 'MACRO_MAP_REC_N'
7> ../../../../../../components/libraries/util/app_util.h:686:28: note: in expansion of macro 'MACRO_MAP_REC_'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:460:17: note: in expansion of macro 'MACRO_MAP_REC'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:457:17: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_1_'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_1'
7> ../../../../../../components/libraries/util/nordic_common.h:116:31: note: in expansion of macro 'CONCAT_2_'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:440:9: note: in expansion of macro 'CONCAT_2'
7> ../../../../../../components/libraries/util/app_util.h:712:37: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'MACRO_MAP_1'
7> ../../../../../../components/libraries/util/app_util.h:700:29: note: in expansion of macro 'MACRO_MAP_N_'
7> ../../../../../../components/libraries/util/app_util.h:679:25: note: in expansion of macro 'MACRO_MAP_N'
7> ../../../../../../components/libraries/util/app_util.h:678:24: note: in expansion of macro 'MACRO_MAP_'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:583:5: note: in expansion of macro 'MACRO_MAP'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:811:29: note: in expansion of macro 'APP_USBD_CLASS_IFACES_EP_EXTRACT'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:946:9: note: in expansion of macro 'APP_USBD_CLASS_INSTANCE_INITVAL'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h:169:5: note: in expansion of macro 'APP_USBD_CLASS_INST_GLOBAL_DEF'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h:233:9: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL'
7> C:\some_path\main.c:619:1: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:463:18: note: (near initialization for 'm_app_hid_keyboard.specific.iface.ep[0].address')
7> ../../../../../../components/libraries/util/app_util.h:747:41: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_1__'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'MACRO_MAP_REC_1'
7> ../../../../../../components/libraries/util/app_util.h:708:33: note: in expansion of macro 'MACRO_MAP_REC_N_'
7> ../../../../../../components/libraries/util/app_util.h:687:29: note: in expansion of macro 'MACRO_MAP_REC_N'
7> ../../../../../../components/libraries/util/app_util.h:686:28: note: in expansion of macro 'MACRO_MAP_REC_'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:460:17: note: in expansion of macro 'MACRO_MAP_REC'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:457:17: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_1_'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_1'
7> ../../../../../../components/libraries/util/nordic_common.h:116:31: note: in expansion of macro 'CONCAT_2_'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:440:9: note: in expansion of macro 'CONCAT_2'
7> ../../../../../../components/libraries/util/app_util.h:712:37: note: in expansion of macro 'APP_USBD_CLASS_IFACE_EP_EXTRACT_'
7> ../../../../../../components/libraries/util/nordic_common.h:118:31: note: in expansion of macro 'MACRO_MAP_1'
7> ../../../../../../components/libraries/util/app_util.h:700:29: note: in expansion of macro 'MACRO_MAP_N_'
7> ../../../../../../components/libraries/util/app_util.h:679:25: note: in expansion of macro 'MACRO_MAP_N'
7> ../../../../../../components/libraries/util/app_util.h:678:24: note: in expansion of macro 'MACRO_MAP_'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:583:5: note: in expansion of macro 'MACRO_MAP'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:811:29: note: in expansion of macro 'APP_USBD_CLASS_IFACES_EP_EXTRACT'
7> ../../../../../../components/libraries/usbd/app_usbd_class_base.h:946:9: note: in expansion of macro 'APP_USBD_CLASS_INSTANCE_INITVAL'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h:169:5: note: in expansion of macro 'APP_USBD_CLASS_INST_GLOBAL_DEF'
7> ../../../../../../components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h:233:9: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL'
7> C:\some_path\main.c:619:1: note: in expansion of macro 'APP_USBD_HID_KBD_GLOBAL_DEF'
Build failed

which I don't understand.  How could it not be constant?  I got the endpoints the same way I did when there was only one of them.

Anyway, I think maybe I have asked too many questions here, but I'm not 100% if I'm asking the right things so I'm hoping that there is an answer that kind of gets everything since they are related.  If this is wrong, I can always break this into different questions.  Then I can also make another one for my confusion about what the interface parameter does... :-P

Parents
  • Hi

    What does your report descriptor look like?

    Is it based on the one in the USB HID Usage Table document?

    Feature and out reports can use either an output interrupt endpoint or the control endpoint. The control endpoint is always present, so technically no OUT endpoint is needed, which is why the keyboard descriptor can support output reports without configuring an OUT endpoint. 

    Best regards
    Torbjørn

  • The report is based on the usage table doc for HID power devices (cf. the chapter on Battery System and the example in Appendix A here, especially section A.6.9).  Generally, I am doing okay with creating descriptors I think.  I'm just a little fuzzy on getting and setting them using the app_usbd driver, and what the interplay is between endpoints, interfaces, and descriptors in the actual implementation.  Here is the descriptor, I can either use it at its own endpoint, or include it as a on the joystick or keyboard descriptor (I think, no?):

    #define HID_BATT_REPORT_DESC() {  \
        0x05, 0x85,                    /* USAGE_PAGE (Battery System) */ \
     \
        0x09, 0x18,                    /* USAGE (BatteryInsertion) */ \
        0x75, 0x01,                    /* REPORT_SIZE (1) */ \
        0x95, 0x01,                    /* REPORT_COUNT (1) */ \
        0x15, 0x00,                    /* LOGICAL_MINIMUM (0) */ \
        0x25, 0x01,                    /* LOGICAL_MAXIMUM (1) */ \
        0xb1, 0x03,                    /* FEATURE (Cnst,Var,Abs) */ \
     \
        0x09, 0x2c,                    /* USAGE (CapacityMode) */ \
        0x75, 0x01,                    /* REPORT_SIZE (1) */ \
        0x95, 0x01,                    /* REPORT_COUNT (1) */ \
        0xb1, 0x03,                    /* FEATURE (Cnst,Var,Abs) */ \
     \
        0x75, 0x06,                    /* REPORT_SIZE (6) */ \
        0x95, 0x01,                    /* REPORT_COUNT (1) */ \
        0xb1, 0x03,                    /* FEATURE (Cnst,Var,Abs)  ; end byte 1 */ \
     \
        0x09, 0x83,                    /* USAGE (DesignCapacity) */ \
        0x75, 0x18,                    /* REPORT_SIZE (24) */ \
        0x95, 0x01,                    /* REPORT_COUNT (1) */ \
        0x67, 0x01, 0x10, 0x10, 0x00,  /* UNIT (SI Lin:Battery Capacity) */ \
        0x55, 0x00,                    /* UNIT_EXPONENT (0) */ \
        0x15, 0x00,                    /* LOGICAL_MINIMUM (0) */ \
        0x27, 0xfe, 0xff, 0xff, 0x00,  /* LOGICAL_MAXIMUM (16777214) */ \
        0xb1, 0x03,                    /* FEATURE (Cnst,Var,Abs)  ; end byte 1 + 3 = 4 */ \
     \
        0x09, 0x66,                    /* USAGE (RemainingCapacity) */ \
        0x75, 0x24,                    /* REPORT_SIZE (36) */ \
        0x95, 0x01,                    /* REPORT_COUNT (1) */ \
        0x67, 0x01, 0x10, 0x10, 0x00,  /* UNIT (SI Lin:Battery Capacity) */ \
        0x55, 0x00,                    /* UNIT_EXPONENT (0) */ \
        0xb1, 0x03,                    /* FEATURE (Cnst,Var,Abs)  ; end byte 4 + 4 = 8, start byte 9 with 4 bits */ \
     \
        0x75, 0x04,                    /* REPORT_SIZE (4) */ \
        0x95, 0x01,                    /* REPORT_COUNT (1) */ \
        0xb1, 0x03,                    /* FEATURE (Cnst,Var,Abs)  ; end byte 9 */ \
     \
        0x09, 0x42,                    /* USAGE (BelowRemainingCapacityLimit) */ \
        0x09, 0x44,                    /* USAGE (Charging) */ \
        0x09, 0x45,                    /* USAGE (Discharging) */ \
        0x75, 0x01,                    /* REPORT_SIZE (1) */ \
        0x95, 0x03,                    /* REPORT_COUNT (3) */ \
        0x15, 0x00,                    /* LOGICAL_MINIMUM (0) */ \
        0x25, 0x01,                    /* LOGICAL_MAXIMUM (1) */ \
        0x65, 0x00,                    /* UNIT (None) */ \
        0xb1, 0x03,                    /* FEATURE (Cnst,Var,Abs)  ; start byte 10 with 3 bits */ \
     \
        0x75, 0x05,                    /* REPORT_SIZE (5) */ \
        0x95, 0x01,                    /* REPORT_COUNT (1) */ \
        0xb1, 0x03                     /* FEATURE (Cnst,Var,Abs)  ; +5bits = end byte 10 */ \
    }

    As I said before, I try to give it it's own endpoint, but I get an error using the macro APP_USBD_HID_KBD_GLOBAL_DEF.  The most important information first is to know what is the preferred way to set up a report descriptor like this one?

    Then, once I get it setup without throwing errors, I have no idea how to set the feature reports (I found this for BLE HID, but nothing for USBD) so some information about that would be appreciated.  Finally, if you are feeling particularly generous, maybe you could also clear up for me why I might use a separate endpoint for a new report descriptor vs just trying to append it to an existing descriptor?  Is it just if I plan on updating the data separately?

    Thanks for your help!

  • Thanks for the quick response.

    The customer asked for HID peripheral.

    Looking forward if you find any BLE HID keyboard + END point out example.

    Best regards,
    Alberto

  • Hi Alberto

    I couldn't find any example showing how to do a custom HID endpoint over BLE unfortunately. The example I shared earlier is showing custom HID endpoint, but over USB. 

    It should be possible to adapt some of this code (like the report descriptor) to utilize HID over GATT instead of HID over USB. 

    Best regards
    Torbjørn

  • In the last few day I have implemented the example KEYBOARD with the HID end-point-OUT

    https://devzone.nordicsemi.com/f/nordic-q-a/87612/ble-hid-keyboard-example-add-end-poit-out

    Please,

    if you could have a look if everything is right. Thanks.

  • Hi Alberto

    Are you able to share your code project?
    Then I can try to run it here, and see if I run into any issues. 

    If so, please just zip your entire project folder, including source and project files (you might want to remove the build files, or the zip will be very large). 

    Best regards
    Torbjørn

  • The costumer checked the project and all is wortking good.

    If you want to tets the example, you need just to remove the main of keboard BLE HID ecample and put on it my code posted in the other discussion.

    Thanks for the support.

    Best regards,

    Alberto

Reply Children
Related