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

cant add a custom description to ble hid

hi ,

im try to add some consumer keys and system keys to the project:

nRF5_SDK_16.0.0_98a08e2\examples\ble_peripheral\ble_app_hids_keyboard

and my code of hids_init() like this:

static void hids_init(void)
{
    ret_code_t                    err_code;
    ble_hids_init_t               hids_init_obj;
    ble_hids_inp_rep_init_t     * p_input_report;
    ble_hids_outp_rep_init_t    * p_output_report;
    ble_hids_feature_rep_init_t * p_feature_report;
    uint8_t                       hid_info_flags;

    static ble_hids_inp_rep_init_t     input_report_array[3];
    static ble_hids_outp_rep_init_t    output_report_array[1];
    static ble_hids_feature_rep_init_t feature_report_array[1];
    static uint8_t                     report_map_data[] =
    {
        0x05, 0x01,       // Usage Page (Generic Desktop)
        0x09, 0x06,       // Usage (Keyboard)
        0xA1, 0x01,       // Collection (Application)
			  0x85, 0x01,       // report id (1)
        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 Size (8 bit)
        0x95, 0x02,       // Report Count (2)
        0xB1, 0x02,       // Feature (Data, Variable, Absolute)

        0xC0,              // End Collection (Application)
				
				
				
				
        0x05, 0x0C,                    /* USAGE_PAGE (CONSUMER CTL)                   */
        0x09, 0x01,                    /* USAGE (CONSUMER CTL)                           */
        0xa1, 0x01,                    /* COLLECTION (Application)                       */
				0X85, 0x02,                    			/* REPORT ID(2)																	 */
        0x19, 0x01,                    			/*   USAGE_MINIMUM (CONSUMER CTL)         */
        0x2A, 0xFF,0x02,                  			/*   USAGE_MAXIMUM ()           */
        0x15, 0x00,                    			/*   LOGICAL_MINIMUM (1)                          */
        0x26, 0x9C,0x02,                  			/*   LOGICAL_MAXIMUM (668)                          */
        0x75, 0x10,                    			/*   REPORT_SIZE (16)                              */
        0x95, 0x02,                    			/*   REPORT_COUNT (2)                             */
        0x81, 0x00,                    			/*   INPUT (Data,Var,Abs)                         */
				0xc0,                           /* END_COLLECTION                                 */
	 
        0x05, 0x01,                    /* USAGE_PAGE (Generic Desktop)                   */
        0x09, 0x80,                    /* USAGE (SYSTEM CTL)                           */
        0xa1, 0x01,                    /* COLLECTION (Application)                       */
				0X85, 0x03,                    			/* REPORT ID(2)																	 */
        0x19, 0x81,                    			/*   USAGE_MINIMUM (system power down)         */
        0x29, 0xb8,                  			/*   USAGE_MAXIMUM (system weekup)           */
        0x15, 0x00,                    			/*   LOGICAL_MINIMUM (0)                          */
        0x25, 0x01,                  			/*   LOGICAL_MAXIMUM (1)                          */
        0x75, 0x1,                    			/*   REPORT_SIZE (1)                              */
        0x95, 0x38,                    			/*   REPORT_COUNT (56)                             */
        0x81, 0x02,                    			/*   INPUT ()                         */
				0xc0                           /* END_COLLECTION                                 */
				
				
				
				
				
				
				
    };

    memset((void *)input_report_array, 0, sizeof(ble_hids_inp_rep_init_t));
    memset((void *)output_report_array, 0, sizeof(ble_hids_outp_rep_init_t));
    memset((void *)feature_report_array, 0, sizeof(ble_hids_feature_rep_init_t));

    // Initialize HID Service
    p_input_report                      = &input_report_array[0];
    p_input_report->max_len             = INPUT_REPORT_KEYS_MAX_LEN;
    p_input_report->rep_ref.report_id   = 1;//INPUT_REP_REF_ID;
    p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    p_input_report->sec.cccd_wr = SEC_JUST_WORKS;
    p_input_report->sec.wr      = SEC_JUST_WORKS;
    p_input_report->sec.rd      = SEC_JUST_WORKS;

		
		
		
    p_input_report                      = &input_report_array[1];
    p_input_report->max_len             = 4;
    p_input_report->rep_ref.report_id   = 2;
    p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    p_input_report->sec.cccd_wr = SEC_JUST_WORKS;
    p_input_report->sec.wr      = SEC_JUST_WORKS;
    p_input_report->sec.rd      = SEC_JUST_WORKS;
		
		
		
		
    p_input_report                      = &input_report_array[2];
    p_input_report->max_len             = 7;
    p_input_report->rep_ref.report_id   = 3;
    p_input_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    p_input_report->sec.cccd_wr = SEC_JUST_WORKS;
    p_input_report->sec.wr      = SEC_JUST_WORKS;
    p_input_report->sec.rd      = SEC_JUST_WORKS;
		
		
		
		
		
		
    p_output_report                      = &output_report_array[OUTPUT_REPORT_INDEX];
    p_output_report->max_len             = OUTPUT_REPORT_MAX_LEN;
    p_output_report->rep_ref.report_id   = OUTPUT_REP_REF_ID;
    p_output_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_OUTPUT;

    p_output_report->sec.wr = SEC_JUST_WORKS;
    p_output_report->sec.rd = SEC_JUST_WORKS;

    p_feature_report                      = &feature_report_array[FEATURE_REPORT_INDEX];
    p_feature_report->max_len             = FEATURE_REPORT_MAX_LEN;
    p_feature_report->rep_ref.report_id   = FEATURE_REP_REF_ID;
    p_feature_report->rep_ref.report_type = BLE_HIDS_REP_TYPE_FEATURE;

    p_feature_report->sec.rd              = SEC_JUST_WORKS;
    p_feature_report->sec.wr              = SEC_JUST_WORKS;

    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                  = service_error_handler;
    hids_init_obj.is_kb                          = false;
    hids_init_obj.is_mouse                       = false;
    hids_init_obj.inp_rep_count                  = 3;
    hids_init_obj.p_inp_rep_array                = input_report_array;
    hids_init_obj.outp_rep_count                 = 1;
    hids_init_obj.p_outp_rep_array               = output_report_array;
    hids_init_obj.feature_rep_count              = 1;
    hids_init_obj.p_feature_rep_array            = feature_report_array;
    hids_init_obj.rep_map.data_len               = sizeof(report_map_data);
    hids_init_obj.rep_map.p_data                 = report_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;

    hids_init_obj.rep_map.rd_sec         = SEC_JUST_WORKS;
    hids_init_obj.hid_information.rd_sec = SEC_JUST_WORKS;

    hids_init_obj.boot_kb_inp_rep_sec.cccd_wr = SEC_JUST_WORKS;
    hids_init_obj.boot_kb_inp_rep_sec.rd      = SEC_JUST_WORKS;

    hids_init_obj.boot_kb_outp_rep_sec.rd = SEC_JUST_WORKS;
    hids_init_obj.boot_kb_outp_rep_sec.wr = SEC_JUST_WORKS;

    hids_init_obj.protocol_mode_rd_sec = SEC_JUST_WORKS;
    hids_init_obj.protocol_mode_wr_sec = SEC_JUST_WORKS;
    hids_init_obj.ctrl_point_wr_sec    = SEC_JUST_WORKS;

    err_code = ble_hids_init(&m_hids, &hids_init_obj);
    APP_ERROR_CHECK(err_code);
}

send key code :

void send_keys(uint8_t report_index, uint16_t len, uint8_t *p_data) {
    ret_code_t err_code;
	
	
		NRF_LOG_INFO("m_hids.inp_rep_count =%d",m_hids.inp_rep_count);
    err_code = ble_hids_inp_rep_send(&m_hids, report_index, len, p_data, m_conn_handle);

    if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_RESOURCES) && (err_code != NRF_ERROR_BUSY) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) && (err_code != NRF_ERROR_FORBIDDEN)) {
        APP_ERROR_HANDLER(err_code);
    }
}

static void bsp_event_handler(bsp_event_t event)
{
    uint32_t         err_code;
    static uint8_t * p_key = m_sample_key_press_scan_str;
    static uint8_t   size  = 0;

    switch (event)
    {
        case BSP_EVENT_SLEEP:
            sleep_mode_enter();
            break;

        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;

        case BSP_EVENT_WHITELIST_OFF:
            if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
            {
                err_code = ble_advertising_restart_without_whitelist(&m_advertising);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
            }
            break;

        case BSP_EVENT_KEY_0:
					
					NRF_LOG_INFO("BSP_EVENT_KEY_0");
			    	data[2]=0x04;
				    send_keys(1,8,data);
				/*
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            {
                keys_send(1, p_key);
                p_key++;
                size++;
                if (size == MAX_KEYS_IN_ONE_REPORT)
                {
                    p_key = m_sample_key_press_scan_str;
                    size  = 0;
                }
            }
				*/
            break;

        default:
            break;
    }
}

in the pca10056,i press the button1,and the jlink report err:

00> <info> app: BSP_EVENT_KEY_0
00> 
00> <info> app: m_hids.inp_rep_count =3
00> 
00> <error> app: ERROR 12 [NRF_ERROR_DATA_SIZE] at ..\..\..\main.c:1786
00> 
00> PC at: 0x0002AB01
00> 
00> <error> app: End of error report
00> 

i have see some custom project,the most change is hids_init(),t try to moddify it ,and there is no effection.so i want to konw how can i add custom  desc to ble hid?

  • Hello,

    What is located around line 1786 in your main.c? What function returned 12 [NRF_ERROR_DATA_SIZE] ?

    I don't know exactly how to add a custom descriptor to the HID table, but if it leads to an increased HID report, then you probably need to increase the MTU size, or the characteristic value size. Try to debug to figure out why the function that returned 12 returned it. Was there a check inside the function that returned it, or the softdevice call (sd_...() )?

    BR,
    Edvin

  • hi,Edvin

    i have solve this problem ,the reason is the report id should be start with 1,and the report_index of ble_hids_inp_rep_send should be start with 0,becuase the frist element of arry input_report_array is input_report_array[0],but now the other problem is the bond problem.

    i comment the code  buttons_leds_init(&erase_bonds) in the main duncation. and find the once connect the pc ,and than reset nrf52840,and the jlink will report erro:

    00> <info> peer_manager_handler: Connection security failed: role: Peripheral, conn_handle: 0x0, procedure: Encryption, error: 4102
    00> 
    00> <info> app: Fast advertising.
    00> 
    00> <info> app: Disconnected
    00> 
    00> <info> app: Connected
    00> 
    00> <info> peer_manager_handler: Connection security failed: role: Peripheral, conn_handle: 0x0, procedure: Encryption, error: 4102
    00> 
    00> <info> app: Fast advertising.
    00> 
    00> <info> app: Disconnected

    the device in the status betwen connect and disconnect.

    and i seek the source api .i find the reason is the funcation : nrf_drv_gpiote_in_init

    in the project 

    nRF5_SDK_16.0.0_98a08e2\examples\ble_peripheral\ble_app_hids_keyboard

    if i conment the api nrf_drv_gpiote_in_init in app_button_init,the erro 4102 will report, otherwise the device work well.

    so i dont konw why the pins input funcation will infulence the funcation of bond?

  • Perhaps one of your devices has old bonding data stored, while the other one doesn't? Try to erase the bonding information from both sides. On the phone, use the "forget device" option, and on the nRF, erase the entire chip using "nrfjprog --eraseall", and then reprogram it.

    If the issue seems to be related to some button functionality, perhaps you erase the bonding information based on some of your button status during startup?
    Does your advertising_init() function in main.c have an erase_bonds parameter as input?

  • hi,thank for your reply.i have solve this problem .the problem is the value of erase_bonds in init.

    and now i want to modify the advertise when runing.

    and my code like this in the BSP_EVENT_KEY_0 of project nRF5_SDK_16.0.0_98a08e2\examples\ble_peripheral\ble_app_hids_keyboard

    void cmd_ble_start_advertising(uint8_t para,uint32_t pointer,uint8_t *data)
    {
    	
    	if(para>2)
    		return;
    	
    	
    	
    		ble_gap_addr_t ble_addr;
    	  sd_ble_gap_adv_stop(m_advertising.adv_handle);
    	
    
    	
      uint32_t err_code = sd_ble_gap_addr_get(&ble_addr);
      APP_ERROR_CHECK(err_code);
    
    	NRF_LOG_INFO("ble_addr.addr[0] =%d.",ble_addr.addr[0]);
    //  ble_addr.addr[0] =0xff;// ble_addr.addr[0]+para;
      err_code = sd_ble_gap_addr_set(&ble_addr);
    	NRF_LOG_INFO("err_code =%d.",err_code);
      APP_ERROR_CHECK(err_code);
    
    	
    	/*
    	if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
    	{
    			uint32_t err_code = ble_advertising_restart_without_whitelist(&m_advertising);
    			if (err_code != NRF_ERROR_INVALID_STATE)
    			{
    					APP_ERROR_CHECK(err_code);
    			}
    	}
    */
    
        advertising_start(0);
    
    
    }

    if press the key0,the api cmd_ble_start_advertising will be called. and i prees the key0 and see the nrf connect .the device advertise disappear . and than i press the key0 again.the device reset.so what shoul i do in the project  ble_app_hids_keyboard to change the mac of advertisement?

  • pipixia_8_8 said:
    if press the key0,the api cmd_ble_start_advertising will be called. and i prees the key0 and see the nrf connect .the device advertise disappear .

     Is this an issue, or is it the behavior that you desire?

    If it is an issue, have you tried debugging it? Does the log say anything? Do you see any logs at all?

     

    pipixia_8_8 said:
    the device reset.so what shoul i do in the project  ble_app_hids_keyboard to change the mac of advertisement?

     I struggle a bit to understand the flow here, but if you want to change the BLE address, look into the functions sd_ble_gap_addr_get() and sd_ble_gap_addr_set().

    BR,

    Edvin

Related