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

After NCS 1.3.0 nRF Desktop LLPM is disconnected, there is no data on the USB.

I now integrate USB, BLE, LLPM, keyboard HID and Mouse HID to nrf52833.


When I added CONFIG_DESKTOP_HID_MOUSE=y, my project was abnormal.


BLE connection:                     Move Mouse and report keyboard work correctly.

USB connected:                      data cannot be reported to PC.

LLPM cannot be connected:   disconnect after connection, and then repeat the process.

Parents Reply Children
  • I tried 1.4.0 and adding CONFIG_DESKTOP_HID_MOUSE and CONFIG_DESKTOP_HID_KEYBOARD at the same time will cause the USB to not work. I need to know how to add two HID instances. I think I should take a look at Zephyr's USB example.

  • I tried 1.4.0 and adding CONFIG_DESKTOP_HID_MOUSE and CONFIG_DESKTOP_HID_KEYBOARD at the same time will cause the USB to not work. I need to know how to add two HID instances. I think I should take a look at Zephyr's USB example.

  • I try to add HID mouse and HID keyboard device, and then connect the PC via USB.

    I can configure the mouse or keyboard separately, but there are problems when adding them at the same time. In usb_init of usb_state.c

    Set CONFIG_USB_HID_DEVICE_COUNT = 2

    Set up
    CONFIG_DESKTOP_HID_REPORT_MOUSE_SUPPORT=1

    CONFIG_DESKTOP_HID_REPORT_KEYBOARD_SUPPORT=1

    If usb_hid_device[0] is initialized to MOUSE, MOUSE is available, but KEYBOARD is not available.
    If usb_hid_device[0] is initialized to KEYBOARD, KEYBOARD is available, but MOUSE is not available.

    An error occurs when using usb_hid_device[1]. After report_sent, enter the report_issued of usb_state.c to report an error
    LOG_WRN("No subscriber %p", subscriber_id);
    Then MOUSE and KEYBOARD are not available.

    It seems that the logic of the code does not support modification to support both KEYBOARD device and MOUSE device connected via USB.
    So how should I modify it?
    Is it convenient to use build_nrf52840dk_nrf52840 to simulate? I have tried many modifications but failed to achieve the effect, and support KEYBOARD device and MOUSE device at the same time.

  • At the moment mouse will use only one and subsequent usb devices are simply ignored: https://github.com/nrfconnect/sdk-nrf/blob/v1.4.0/applications/nrf_desktop/src/modules/hid_state.c#L1381

    And we have only one USB subscriber: https://github.com/nrfconnect/sdk-nrf/blob/v1.4.0/applications/nrf_desktop/src/modules/hid_state.c#L46. You have to create one additional subscriber per USB HID device.

    Then when USB connects it should overtake reports it wants (at the moment it overtakes all): https://github.com/nrfconnect/sdk-nrf/blob/v1.4.0/applications/nrf_desktop/src/modules/hid_state.c#L488

    Then module should allow different subscribers to use different reports at the same time (at the moment selected subscriber takes them all):

    https://github.com/nrfconnect/sdk-nrf/blob/v1.4.0/applications/nrf_desktop/src/modules/hid_state.c#L1090

  • I tried for a few days and still couldn’t achieve the desired effect. I made the following changes:

    1. usb_state.c

    1.1 Modify usb_init usb_hid_device[1] as KEYBOARD and usb_hid_device[0] as MOUSE.

            usb_hid_device[0].dev = device_get_binding("HID_0");
    	if (usb_hid_device[0].dev == NULL) {
    		LOG_ERR("Cannot get USB HID 0 Device");
    		return 0;
    	}
    
    	usb_hid_register_device(usb_hid_device[0].dev, hid_mouse_report_desc,   // hid_kbd_report_desc   hid_mouse_report_desc
    				sizeof(hid_mouse_report_desc),&hid_ops[0]);
    
    	usb_hid_init(usb_hid_device[0].dev);
    
    
    	usb_hid_device[1].dev = device_get_binding("HID_1");
    	if (usb_hid_device[1].dev == NULL) {
    		LOG_ERR("Cannot get USB HID 1 Device");
    		return 0;
    	}
    
    	usb_hid_register_device(usb_hid_device[1].dev, hid_mouse_report_desc,
    				sizeof(hid_mouse_report_desc),&hid_ops[1]);
    
    	usb_hid_init(usb_hid_device[1].dev);

    2.hid_static.c

    #define SUBSCRIBER_COUNT (IS_ENABLED(CONFIG_DESKTOP_HIDS_ENABLE) + \
    IS_ENABLED(CONFIG_DESKTOP_USB_ENABLE)+IS_ENABLED(CONFIG_DESKTOP_USB_ENABLE))

    Modify hid_state struct to add an additional subscriber for usb_hid_device[1] (KEYBOARD).

    struct hid_state {
    struct report_data report_data[INPUT_REPORT_DATA_COUNT];
    struct subscriber subscriber[SUBSCRIBER_COUNT];
    struct subscriber *selected;
          struct subscriber *selected_extra;//!!
    };

    handle_usb_hid_event{
      if (event->enabled) {
          //if (!get_subscriber_by_type(true)) { //Multiple USB subscribers can be added
              connect_subscriber(event->id, true, 1);
          //}
      } else {
          disconnect_subscriber(event->id);
      }

    Assign the subscriber of MOUSE to state.selected KEYBOARD to state.selected_extra

    connect_subscriber{
    
    static uint8_t usb_count = 0; // sean 1.6
      usb_count++;// sean 1.6
    //				for (size_t j = 0; j < ARRAY_SIZE(state.report_data); j++) { //sean 1.6
    //					struct report_data *rd = &state.report_data[j];
    //
    //					rd->linked_rs = NULL;
    //					clear_report_data(rd);
    //				}
                                      if(usb_count==1)
    				state.selected = NULL;
                                 
    			}
                         
                if(usb_count == 2)
                      state.selected_extra = &state.subscriber[i];
    
    			if (!state.selected ) {
    
                              if(usb_count==1)
                              {
                              state.selected = &state.subscriber[i];
                              LOG_INF("!! Active subscriber %p %d",state.selected->id,i);
                              }
    
    			}
    			...
    }

    Used state.selected_extra at the time of sending keyboard report

    send_report_keyboard
    {
      ...
      event->subscriber = state.selected_extra->id;
    }

    report_send{
      ....
        __ASSERT_NO_MSG(rs->subscriber == state.selected || rs->subscriber == state.selected_extra);
       
       

       

    Press the mouse, the mouse responds.

    You can see that the code is executed to hid_int_ep_write

    LOG print

    usb_hid->dev = 0x20000f18; usb_hid_device[1].dev = 0x20000f00

    Note: usb_hid_device[0].dev = 0x20000f18 (MOUSE)

    Press the keyboard, No characters output on PC !!!

    LOG print

    usb_hid->dev = 0x20000f00; usb_hid_device[1].dev = 0x20000f00

    Note: usb_hid_device[1].dev = 0x20000f00 (KEYBOARD)

    But report_sent_cb is not executed.

    I tried many methods and I don't know how to modify it!

Related