Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

displaying numeric's characters with HID Keyboard in BLE, azerty Keyboard

Hi,

I would like display all keycode azerty Keyboard, I started to use uart_event_handle() and I modified send_key_scan_press_release() for the modifier position key [MODIFIER_KEY_POS]. When I connected to smartphone and I receive the character 'c', I display 5 keys: 12345 and when I receive the character 'd', I display 5 keys : &é"'( it's OK. but when I receive the character 'e' , I display: 123'( . I just added for case 'e' the line kb_key_shift_ctrl_alt_altgr = NO_SPECIFIC_KEY_CODE; after while(size < MAX_KEYS_IN_ONE_REPOR)
{
...
}

I can't understand why the SHIFT key seems to be released on the fourth character. 123' (normally number 4) then 5?

static uint8_t m_sample_key_press_scan_str_number[] = /**< Key pattern to be sent when the key press button has been pushed. */
{
    0x1E,      
    0x1F,      
    0x20,      
    0x21,      
    0x22,      
    0x28        /* Key Return */
};

uint8_t kb_key_shift_ctrl_alt_altgr;  // variable for input report MODIFER_KEY_POS, see macro SHIFT_KEY_CODE, CTRL_KEY_CODE....


void uart_event_handle(app_uart_evt_t * p_event)					//$at_06_04_22
{
	uint8_t message[UARTE_MAX_DATA_LEN] = "UART OK";
	uint8_t message_erase_bonds[] = "wait cmd Erase bonds"; 
	uint8_t i;
	
	static uint8_t * p_key = m_sample_key_press_scan_str;
    static uint8_t   size  = 0;
	
    static uint8_t data_array[UARTE_MAX_DATA_LEN];
    static uint8_t index = 0;
    //uint32_t       err_code;
	
    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
			
			switch(data_array[0])
			{
				case 'a':
					for (i = 0; i < strlen((const char*)message_erase_bonds); i++)
					{
						app_uart_put(message_erase_bonds[i]);
					}
					break;
					
				case 'b':
					advertising_start(true);
					break;
					
				case 'c':
					p_key = m_sample_key_press_scan_str_number;
					kb_key_shift_ctrl_alt_altgr = SHIFT_KEY_CODE;
					size = 0;
					if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
					{
						while (size < MAX_KEYS_IN_ONE_REPORT)
						{
							keys_send(1, p_key);
							p_key++;
							size++;
						}
					}
					break;		

				case 'd':
					p_key = m_sample_key_press_scan_str_number;
					kb_key_shift_ctrl_alt_altgr = NO_SPECIFIC_KEY_CODE;
					size = 0;
					if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
					{
						while (size < MAX_KEYS_IN_ONE_REPORT)
						{
							keys_send(1, p_key);
							p_key++;
							size++;
						}
					}
					break;		

				case 'e':
					p_key = m_sample_key_press_scan_str_number;
					kb_key_shift_ctrl_alt_altgr = SHIFT_KEY_CODE;
					size = 0;
					if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
					{
						while (size < MAX_KEYS_IN_ONE_REPORT)
						{
							keys_send(1, p_key);
							p_key++;
							size++;
						}
					}
					kb_key_shift_ctrl_alt_altgr = NO_SPECIFIC_KEY_CODE;
					break;		
					
				default:
					for (i = 0; i < strlen((const char*)message); i++)
					{
						app_uart_put(message[i]);
					}
					break;
			}
            break;

        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}

static uint32_t send_key_scan_press_release(ble_hids_t * p_hids,
                                            uint8_t    * p_key_pattern,
                                            uint16_t     pattern_len,
                                            uint16_t     pattern_offset,
                                            uint16_t   * p_actual_len)
{
    ret_code_t err_code;
    uint16_t offset;
    uint16_t data_len;
    uint8_t  data[INPUT_REPORT_KEYS_MAX_LEN];

    // HID Report Descriptor enumerates an array of size 6, the pattern hence shall not be any
    // longer than this.
    STATIC_ASSERT((INPUT_REPORT_KEYS_MAX_LEN - 2) == 6);

    ASSERT(pattern_len <= (INPUT_REPORT_KEYS_MAX_LEN - 2));

    offset   = pattern_offset;
    data_len = pattern_len;

    do
    {
        // Reset the data buffer.
        memset(data, 0, sizeof(data));

        // Copy the scan code.
        memcpy(data + SCAN_CODE_POS + offset, p_key_pattern + offset, data_len - offset);
		
		/*
        if (bsp_button_is_pressed(SHIFT_BUTTON_ID))
        {
            data[MODIFIER_KEY_POS] |= SHIFT_KEY_CODE;
        }
		*/
		
		data[MODIFIER_KEY_POS] |= kb_key_shift_ctrl_alt_altgr;			//$at_12_04_22
		
        if (!m_in_boot_mode)
        {
            err_code = ble_hids_inp_rep_send(p_hids,
                                             INPUT_REPORT_KEYS_INDEX,
                                             INPUT_REPORT_KEYS_MAX_LEN,
                                             data,
                                             m_conn_handle);
        }
        else
        {
            err_code = ble_hids_boot_kb_inp_rep_send(p_hids,
                                                     INPUT_REPORT_KEYS_MAX_LEN,
                                                     data,
                                                     m_conn_handle);
        }

        if (err_code != NRF_SUCCESS)
        {
            break;
        }

        offset++;
    }
    while (offset <= data_len);

    *p_actual_len = offset;

    return err_code;
}

thanks for help

Alexandre

Parents
  • Hi,

    If you have a look at the implementation of keys_send(), in main.c of the HID keyboard example of nRF5 SDK, you will find the following:

    if ((err_code == NRF_ERROR_RESOURCES) && (actual_len <= key_pattern_len))
        {
            // Buffer enqueue routine return value is not intentionally checked.
            // Rationale: Its better to have a a few keys missing than have a system
            // reset. Recommendation is to work out most optimal value for
            // MAX_BUFFER_ENTRIES to minimize chances of buffer queue full condition
            UNUSED_VARIABLE(buffer_enqueue(&m_hids, p_key_pattern, key_pattern_len, actual_len));
        }

    I suspect the buffer used for queueing letters overflows, resulting in some characters getting lost. The delay that you put in is after all lower case letters has been sent, and before all upper case letters are sent. If the buffer cannot hold all the five letters, for any of the sequences, then some will be lost.

    One way to check if this is what happens, is to replace the UNUSED_VARIABLE macro with an APP_ERROR_CHECK macro instead, then do a debug session to see if you get an error code indicating buffer overflow.

    Please note that we are entering Easter vacation in Norway. You may have to wait until next week for answers to any follow-up questions.

    Regards,
    Terje

Reply
  • Hi,

    If you have a look at the implementation of keys_send(), in main.c of the HID keyboard example of nRF5 SDK, you will find the following:

    if ((err_code == NRF_ERROR_RESOURCES) && (actual_len <= key_pattern_len))
        {
            // Buffer enqueue routine return value is not intentionally checked.
            // Rationale: Its better to have a a few keys missing than have a system
            // reset. Recommendation is to work out most optimal value for
            // MAX_BUFFER_ENTRIES to minimize chances of buffer queue full condition
            UNUSED_VARIABLE(buffer_enqueue(&m_hids, p_key_pattern, key_pattern_len, actual_len));
        }

    I suspect the buffer used for queueing letters overflows, resulting in some characters getting lost. The delay that you put in is after all lower case letters has been sent, and before all upper case letters are sent. If the buffer cannot hold all the five letters, for any of the sequences, then some will be lost.

    One way to check if this is what happens, is to replace the UNUSED_VARIABLE macro with an APP_ERROR_CHECK macro instead, then do a debug session to see if you get an error code indicating buffer overflow.

    Please note that we are entering Easter vacation in Norway. You may have to wait until next week for answers to any follow-up questions.

    Regards,
    Terje

Children
No Data
Related