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!

  • Hi Alberto

    Sorry for the slow response. I just got back from several weeks of leave and will need some more time to try and test this on my end. 

    Have there been any developments on your end in the mean time?

    Best regards
    Torbjørn

  • The system have been test on my side and there are no bugs now (I hope also when the customer will test it!).

    There are just to need to reset the white list each time that a win10 O.S. need to connect with-out a disconnection in another before. But this one is another topic.

    Pleas, have a quick look if there is anything working wrong in the BLE standard.

    Best regards,

    Alberto

  • Hi Alberto

    The example seems to work fine for me, at least the normal keyboard commands are received like normal. 

    Best regards
    Torbjørn

  • Thanks a lot,

    have been tricky make it work correctly in the different OS (linux, win10, mac os).

    Thanks for the test and the support.

    Another question about the example. I need to delete the white list sometimes in the system. In particular with the win10 os. Is it possible avoid this? Meaby is another tread.

    Best regards,

    Alberto

  • Hi Alberto

    I can imagine there could be some complications getting everything running everywhere, yes. Please note I didn't try to send any data to your custom HID endpoint in Windows. Have you tried this already? 

    I agree the whitelist issue is probably best for another case. Just include all the things you have tried, and any information relevant to the issue. 

    Best regards
    Torbjørn

Reply Children
Related