NRF52833 USB HID KEYBOARD

HI Q&A

typedef struct {
      uint8_t mods;
      uint8_t reserved;
      uint8_t keys[KEYBOARD_REPORT_KEYS];
}report_keyboard_t;

report_keyboard_t  key_report={0};

#define HID_KBD_INTERFACE 0
#define HID_MOUSE_INTERFACE 1
#define HID_EXTRA_INTERFACE 2

void hid_kbd_user_ev_handler(app_usbd_class_inst_t const *p_inst, app_usbd_hid_user_event_t event);

static const app_usbd_hid_subclass_desc_t *keyboard_hid_report_desc[] = {&kbd_desc};


 APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_kbd,
                                                                        HID_KBD_INTERFACE,
                                                                        hid_kbd_user_ev_handler,
                                                                        (NRF_DRV_USBD_EPIN1),
                                                                        keyboard_hid_report_desc,
                                                                        5,
                                                                        1,
                                                                        0,
                                                                        APP_USBD_HID_SUBCLASS_BOOT,
                                                                       APP_USBD_HID_PROTO_KEYBOARD);

#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)  1bit */ \
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 */ \
}

APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(kbd_desc, APP_USBD_HID_KBD_REPORT_DSC());

I store the received keystroke data into key_report.keys[];

                                    via usb_kbd_keys_send(&key_report);

                                    call app_usbd_hid_generic_in_report_set(&m_app_hid_kbd,report,sizeof(report)); 

The key value in key_report.keys[] is correct every time.

Pressing any key sometimes shows '3' or 'E', which is confusing to me.

  • Hi zbxiong,

    usb_kbd_keys_send() is not a function in our SDK, so it is not possible for me to tell what is wrong here.

    Please give me some more information about your implementation.

    Also, please use the Insert > Code feature to send code snippets.

    Hieu

  • Hi Hieu

      thanks for your reply!

    APP_USBD_CLASS_TYPEDEF(app_usbd_hid_generic, \
    APP_USBD_HID_GENERIC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \
    APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC, \
    APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC \
    );

    void usb_kbd_keys_send(report_keyboard_t *report)  
    {
        ret_code_t err_code;
    
        if (!NRF_USBD->ENABLE)
        {
            return;
        }
        if (!usb_started){
            return;
        }
    
        if(!kbd_report_queue_is_empty())
        {
            NRF_LOG_INFO("usb buffer in");
            memcpy(kbd_report_queue[kbd_report_queue_wp], report, KEYBOARD_REPORT_SIZE);
            kbd_report_queue_wp++;
            kbd_report_queue_wp %= KBD_REP_QUEUE_LEN;
            kbd_key_buffer_send();
            return;
        }
        if (m_report_pending)
        {
            NRF_LOG_INFO("usb buffer in");
            memcpy(kbd_report_queue[kbd_report_queue_wp], report, KEYBOARD_REPORT_SIZE);
            kbd_report_queue_wp++;
            kbd_report_queue_wp %= KBD_REP_QUEUE_LEN;
        }
        else
        {         
             
            err_code =app_usbd_hid_generic_in_report_set(    //app_usbd_hid_generic_in_report_set
                   &m_app_hid_kbd,
                   report,
                   sizeof(*report)); 
                     
            if(err_code == NRF_SUCCESS)
                m_report_pending = true;  
    
            if(err_code == NRF_ERROR_BUSY){
                NRF_LOG_INFO("usb buffer in");
                memcpy(kbd_report_queue[kbd_report_queue_wp], report, KEYBOARD_REPORT_SIZE);
                kbd_report_queue_wp++;
                kbd_report_queue_wp %= KBD_REP_QUEUE_LEN;
            }
            else if(err_code == NRF_SUCCESS){
            m_report_pending = true;        
            }
            else{
               APP_ERROR_CHECK(err_code);
            }
        }
    }
    

    ‘H’ is I pressed the key 50 times ‘3’ and ‘E’ are random displays.

  • Hi zbxiong,

    What is the value of sizeof(*report) in your usb_kbd_keys_send() function? Depends on the organization of the code, it might not work like you think it would.

    Another point to look out is check if your H key is properly debounced. You might want to check if your report queue is working correctly, see if the "3" and "E" coincide with when m_report_pending is set.

  • Hi Hieu

    After tracing the above problems, it is found that when a key value error occurs, the pointer of the app_usbd_hid_generic_in_report_set(&m_app_hid_kbd,report,sizeof(report)) function points to a change in the report buffer address.

    key_report is defined as static so that there are no key-value errors.

     static report_keyboard_t  key_report={0};

    It was a small mistake that caused a lot of trouble.

    Thank you for your reply.

  • No problem. I'm glad to hear you got it figured out. I just want to add that we recommend the nRF Connect SDK for all new projects. For further information, see: (+) nRF Connect SDK and nRF5 SDK statement - Blogs - Nordic Blog - Nordic DevZone (nordicsemi.com).

    Otherwise, please feel free to close this case at your convenience.

Related