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

PC shows driver wrong when I try to combine HID Mouse and keyboard... How to make a HID device combined with mouse and keyboard???

Hi I have a project to use HID mouse and keyboard at the same time, I have tried , but it really can't work well. I've read the similar question and you don't give the clearly answer. So please help. Here are Link about the similar question and unsolved either.

The related code I coded are as follows:

#define INPUT_REPORT_COUNT              4                                           /**< Number of input reports in this application. */

#define INPUT_REP_BUTTONS_LEN           3                                           /**< Length of Mouse Input Report containing button data. */
#define INPUT_REP_MOVEMENT_LEN          3                                           /**< Length of Mouse Input Report containing movement data. */
#define INPUT_REP_MEDIA_PLAYER_LEN      1                                           /**< Length of Mouse Input Report containing media player data. */
#define INPUT_REP_KEYBOARD_LEN          8                                           /**< Maximum length of the Input Report characteristic. */
#define OUTPUT_REP_KEYBOARD_LEN         1                                           /**< Maximum length of Output Report. */

#define INPUT_REP_BUTTONS_INDEX         0                                           /**< Index of Mouse Input Report containing button data. */
#define INPUT_REP_MOVEMENT_INDEX        1                                           /**< Index of Mouse Input Report containing movement data. */
#define INPUT_REP_MPLAYER_INDEX         2                                           /**< Index of Mouse Input Report containing media player data. */
#define INPUT_REP_KEYBOARD_INDEX        3                                           /**< Index of Input Report. */
#define OUTPUT_REP_KEYBOARD_INDEX       0                                           /**< Index of Output Report. */

#define INPUT_REP_REF_BUTTONS_ID        1                                           /**< Id of reference to Mouse Input Report containing button data. */
#define INPUT_REP_REF_MOVEMENT_ID       2                                           /**< Id of reference to Mouse Input Report containing movement data. */
#define INPUT_REP_REF_MPLAYER_ID        3                                           /**< Id of reference to Mouse Input Report containing media player data. */
#define INPUT_REP_REF_KEYBOARD_ID       4                                           /**< Id of reference to Keyboard Input Report. */
#define OUTPUT_REP_REF_KEYBOARD_ID      4                                           /**< Id of reference to Keyboard Output Report. */



static void hids_init(void)
{
    uint32_t                   err_code;
    ble_hids_init_t            hids_init_obj;
    ble_hids_inp_rep_init_t    inp_rep_array[INPUT_REPORT_COUNT];
    ble_hids_inp_rep_init_t *  p_input_report;
	
    ble_hids_outp_rep_init_t   outp_rep_array[1];
    ble_hids_outp_rep_init_t * p_output_report;
	
    uint8_t                    hid_info_flags;

    static uint8_t rep_map_data[] =
    {
        0x05, 0x01,                     // Usage Page (Generic Desktop)
			
			
        0x09, 0x02,                     // Usage (Mouse)
        0xA1, 0x01,                     // Collection (Application)

        // Report ID 1: Mouse buttons + scroll/pan
        0x85, 0x01,                     //     Report Id 1
        0x09, 0x01,                     //     Usage (Pointer)
        0xA1, 0x00,                     //     Collection (Physical)
        0x95, 0x05,                     //         Report Count (5)
        0x75, 0x01,                     //         Report Size (1)
        0x05, 0x09,                     //         Usage Page (Buttons)
        0x19, 0x01,                     //             Usage Minimum (01)
        0x29, 0x05,                     //             Usage Maximum (05)
        0x15, 0x00,                     //             Logical Minimum (0)
        0x25, 0x01,                     //             Logical Maximum (1)
        0x81, 0x02,                     //             Input (Data, Variable, Absolute)
        0x95, 0x01,                     //             Report Count (1)
        0x75, 0x03,                     //             Report Size (3)
        0x81, 0x01,                     //             Input (Constant) for padding
        0x75, 0x08,                     //             Report Size (8)
        0x95, 0x01,                     //             Report Count (1)
        0x05, 0x01,                     //         Usage Page (Generic Desktop)
        0x09, 0x38,                     //             Usage (Wheel)
        0x15, 0x81,                     //             Logical Minimum (-127)
        0x25, 0x7F,                     //             Logical Maximum (127)
        0x81, 0x06,                     //             Input (Data, Variable, Relative)
        0x05, 0x0C,                     //         Usage Page (Consumer)
        0x0A, 0x38, 0x02,               //             Usage (AC Pan)
        0x95, 0x01,                     //             Report Count (1)
        0x81, 0x06,                     //             Input (Data,Value,Relative,Bit Field)
        0xC0,                           //     End Collection (Physical)

        // Report ID 2: Mouse motion
        0x85, 0x02,                     //     Report Id 2
        0x09, 0x01,                     //     Usage (Pointer)
        0xA1, 0x00,                     //     Collection (Physical)
        0x75, 0x0C,                     //         Report Size (12)
        0x95, 0x02,                     //         Report Count (2)
        0x05, 0x01,                     //         Usage Page (Generic Desktop)
        0x09, 0x30,                     //             Usage (X)
        0x09, 0x31,                     //             Usage (Y)
        0x16, 0x01, 0xF8,               //             Logical maximum (2047)
        0x26, 0xFF, 0x07,               //             Logical minimum (-2047)
        0x81, 0x06,                     //             Input (Data, Variable, Relative)
        0xC0,                           //     End Collection (Physical)
        0xC0,                           // End Collection (Application)

        // Report ID 3: Advanced buttons
        0x05, 0x0C,                     // Usage Page (Consumer)
        0x09, 0x01,                     // Usage (Consumer Control)
        0xA1, 0x01,                     // Collection (Application)
        0x85, 0x03,                     //     Report Id (3)
        0x15, 0x00,                     //     Logical minimum (0) 
        0x25, 0x01,                     //     Logical maximum (1) 
        0x75, 0x01,                     //     Report Size (1) 
        0x95, 0x01,                     //     Report Count (1) 

        0x09, 0xEA,                     //     Usage (Volume Down) 
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
        0x09, 0xE9,                     //     Usage (Volume Up)  
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
        0x09, 0xE2,                     //     Usage (Mute) 
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
				
				0x09, 0xB5,                     //     Usage (Scan Next Track)
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
        0x09, 0xB6,                     //     Usage (Scan Previous Track) 
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
				
        0x09, 0xCD,                     //     Usage (Play/Pause) 
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
				
        0x09, 0xC0,               //     Usage (AL Consumer Control Configuration)MediaPlayer
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
				
        0x09, 0xC1,               //     Usage (AC Back)
        0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
				
				
				// Report ID 4: keyboard
        0x09, 0x06,                 // Usage (Keyboard)
        0xA1, 0x01,                 // Collection (Application)
				0x85, 0x04,                 //     Report Id 4
        0x05, 0x07,                 //     Usage Page (Key Codes)
        0x19, 0xe0,                 //     Usage Minimum (224)
        0x29, 0xe7,                 //     Usage Maximum (231)
        0x15, 0x00,                 //     Logical Minimum (0)
        0x25, 0x01,                 //     Logical Maximum (1)
        0x75, 0x01,                 //     Report Size (1)
        0x95, 0x08,                 //     Report Count (8)
        0x81, 0x02,                 //     Input (Data, Variable, Absolute)

        0x95, 0x01,                 //     Report Count (1)
        0x75, 0x08,                 //     Report Size (8)
        0x81, 0x01,                 //     Input (Constant) reserved byte(1)

        0x95, 0x05,                 //     Report Count (5)
        0x75, 0x01,                 //     Report Size (1)
        0x05, 0x08,                 //     Usage Page (Page# for LEDs)
        0x19, 0x01,                 //     Usage Minimum (1)
        0x29, 0x05,                 //     Usage Maximum (5)
        0x91, 0x02,                 //     Output (Data, Variable, Absolute), Led report
        0x95, 0x01,                 //     Report Count (1)
        0x75, 0x03,                 //     Report Size (3)
        0x91, 0x01,                 //     Output (Data, Variable, Absolute), Led report padding

        0x95, 0x06,                 //     Report Count (6)
        0x75, 0x08,                 //     Report Size (8)
        0x15, 0x00,                 //     Logical Minimum (0)
        0x25, 0x65,                 //     Logical Maximum (101)
        0x05, 0x07,                 //     Usage Page (Key codes)
        0x19, 0x00,                 //     Usage Minimum (0)
        0x29, 0x65,                 //     Usage Maximum (101)
        0x81, 0x00,                 //     Input (Data, Array) Key array(6 bytes)

        0x09, 0x05,                 //     Usage (Vendor Defined)
        0x15, 0x00,                 //     Logical Minimum (0)
        0x26, 0xFF, 0x00,           //     Logical Maximum (255)
        0x75, 0x08,                 //     Report Count (2)
        0x95, 0x02,                 //     Report Size (8 bit)
        0xB1, 0x02,                 //     Feature (Data, Variable, Absolute)
				
        0xC0                            // End Collection
    };

    memset(inp_rep_array, 0, sizeof(inp_rep_array));
    // Initialize HID Service.
    p_input_report                      = &inp_rep_array[INPUT_REP_BUTTONS_INDEX];
    p_input_report->max_len             = INPUT_REP_BUTTONS_LEN;
    p_input_report->rep_ref.report_id   = INPUT_REP_REF_BUTTONS_ID;
    p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.write_perm);

    p_input_report                      = &inp_rep_array[INPUT_REP_MOVEMENT_INDEX];
    p_input_report->max_len             = INPUT_REP_MOVEMENT_LEN;
    p_input_report->rep_ref.report_id   = INPUT_REP_REF_MOVEMENT_ID;
    p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.write_perm);

    p_input_report                      = &inp_rep_array[INPUT_REP_MPLAYER_INDEX];
    p_input_report->max_len             = INPUT_REP_MEDIA_PLAYER_LEN;
    p_input_report->rep_ref.report_id   = INPUT_REP_REF_MPLAYER_ID;
    p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.write_perm);

    p_input_report                      = &inp_rep_array[INPUT_REP_KEYBOARD_INDEX];
    p_input_report->max_len             = INPUT_REP_KEYBOARD_LEN;
    p_input_report->rep_ref.report_id   = INPUT_REP_REF_KEYBOARD_ID;
    p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_input_report->security_mode.write_perm);

    p_output_report                      = &outp_rep_array[OUTPUT_REP_KEYBOARD_INDEX];
    p_output_report->max_len             = OUTPUT_REP_KEYBOARD_LEN;
    p_output_report->rep_ref.report_id   = OUTPUT_REP_REF_KEYBOARD_ID;
    p_output_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_OUTPUT;

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_output_report->security_mode.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&p_output_report->security_mode.write_perm);
		
    hid_info_flags = HID_INFO_FLAG_REMOTE_WAKE_MSK | HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK;

    memset(&hids_init_obj, 0, sizeof(hids_init_obj));

    hids_init_obj.evt_handler                    = on_hids_evt;
    hids_init_obj.error_handler                  = NULL; 
    hids_init_obj.is_kb                          = true;
    hids_init_obj.is_mouse                       = true;
    hids_init_obj.inp_rep_count                  = INPUT_REPORT_COUNT;
    hids_init_obj.p_inp_rep_array                = inp_rep_array;
    hids_init_obj.outp_rep_count                 = 1;
    hids_init_obj.p_outp_rep_array               = outp_rep_array;
    hids_init_obj.feature_rep_count              = 0;
    hids_init_obj.p_feature_rep_array            = NULL;
    hids_init_obj.rep_map.data_len               = sizeof(rep_map_data);
    hids_init_obj.rep_map.p_data                 = rep_map_data;
    hids_init_obj.hid_information.bcd_hid        = BASE_USB_HID_SPEC_VERSION;
    hids_init_obj.hid_information.b_country_code = 0;
    hids_init_obj.hid_information.flags          = hid_info_flags;
    hids_init_obj.included_services_count        = 0;
    hids_init_obj.p_included_services_array      = NULL;

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.rep_map.security_mode.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.rep_map.security_mode.write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.hid_information.security_mode.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.hid_information.security_mode.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_mouse_inp_rep.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_mouse_inp_rep.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_mouse_inp_rep.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_kb_inp_rep.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_kb_inp_rep.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.security_mode_boot_kb_inp_rep.write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_kb_outp_rep.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_boot_kb_outp_rep.write_perm);
		
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_protocol.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_protocol.write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hids_init_obj.security_mode_ctrl_point.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hids_init_obj.security_mode_ctrl_point.write_perm);

    err_code = ble_hids_init(&m_hids, &hids_init_obj);
    APP_ERROR_CHECK(err_code);
}
`
Parents
  • Hi Sad~Sugar,

    Which error do you have when you connect to the PC ? I suspect the structure of the report descriptor having problem.

    I'm not an expert with HID but can you have a look at this report descriptors I attached here? It seems that you need an usage page for the keyboard before declare the usage. This is the descriptors we used for the smart remote 2. In that reference design we combine both mouse and keyboard in one device.

    project_params.h

  • Thank you very much. Yes, my descriptors are wrong, but it still don't work after I correct it according to your file, PC's progress bar stopped for a very long time after I try to connect it, and shows driver wrong after the progress bar finished, I don't know what is the exactly problem. I think it's not only because the descriptor, but also some other settings wrong. I have solved the problem by creating two HID services in one device, it works.

Reply
  • Thank you very much. Yes, my descriptors are wrong, but it still don't work after I correct it according to your file, PC's progress bar stopped for a very long time after I try to connect it, and shows driver wrong after the progress bar finished, I don't know what is the exactly problem. I think it's not only because the descriptor, but also some other settings wrong. I have solved the problem by creating two HID services in one device, it works.

Children
No Data
Related