HI
I am developing a product with nRF52832 and NUS's Central and Peripheral.
The basic operation is to transmit key input to the Peripheral's GPIO to the Central via NUS.
It works well under normal circumstances.
However, in the pairing state, a problem occurs at the point where the pairing boils down and the reception sensitivity is weak.
In the pairing state, the pairing is triggered and an issue occurs when key input on the peripheral device is continuously attempted during pairing.
If pairing is successful, the keys will not work.
1) Close distance pairing and operation normal -> 2) Peripheral moves to a long distance and paring begins -> 3) Peripheral pairing attempt -> 4) While attempting peripheral pairing, press the keys continuously.
-> 5) Move the peripheral to the central side and re-pair successfully -> 6) The peripheral key does not work.
What's unusual is
1. When the peripheral key is not working and the central power is turned off, the peripheral automatically attempts re-pairing (status check is normal).
2. If you turn on the Central in '1' above, pairing is successful again. However, the peripheral keys still do not work.
3. In the above situation, the only way to restart the peripheral key is to reset the peripheral power.
Can you find out the cause of this?
thank.
***************************************************************************************************************************************************************
Additional review was conducted by connecting J-Link.
* Flow for key operation
Press key -> execute void bsp_event_handler(bsp_event_t event) -> call ble_nus_data_send() function
do
{
err_code = ble_nus_data_send(&m_nus, gBLE_Data_key, &gLen_gBLE_Data_key, m_conn_handle);
if ((err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_NOT_FOUND))
{
APP_ERROR_CHECK(err_code);
}
} while (err_code == NRF_ERROR_RESOURCES);
By lowering the tx power of the peripheral to -40dBm and conducting the experiment, the reproduction is better.
If you check the operation through J-Link in this state, even the ble_nus_data_send() function is executed normally.
(Of course, no data is actually received from central.)
Press key -> execute void bsp_event_handler(bsp_event_t event) -> call ble_nus_data_send() function
to sum it up,
The peripheral's key is recognized normally and ble_nus_data_send() is executed, but the actual data does not seem to be transmitted via BLE.
And since the status check is continuously maintained... When the central power is turned off, it is recognized by the peripheral.
prinft로 debug massage를 받아 보면,
** Execute nrf_sdh_ble_evts_poll function in nrf_sdh_ble.c
You can check that the static void nrf_sdh_ble_evts_poll(void * p_context) function is executed in the middle and the tx transmission is completed.
p_ble_evt->header.evt_id) = 0x57 -> BLE_GATTS_EVT_HVN_TX_COMPLETE
/**@brief Function for polling BLE events. * * @param[in] p_context Context of the observer. */ static void nrf_sdh_ble_evts_poll(void * p_context) { UNUSED_VARIABLE(p_context); ret_code_t ret_code; if (!m_stack_is_enabled) { return; } while (true) { /*lint -save -e(587) */ __ALIGN(4) uint8_t evt_buffer[NRF_SDH_BLE_EVT_BUF_SIZE]; /*lint -restore */ ble_evt_t * p_ble_evt; uint16_t evt_len = (uint16_t)sizeof(evt_buffer); ret_code = sd_ble_evt_get(evt_buffer, &evt_len); if (ret_code != NRF_SUCCESS) { break; } p_ble_evt = (ble_evt_t *)evt_buffer; #ifdef DEBUG //NRF_LOG_DEBUG("BLE event: 0x%x.", p_ble_evt->header.evt_id); printf("BLE_EH: 0x%x.", p_ble_evt->header.evt_id); #endif // Forward the event to BLE observers. nrf_section_iter_t iter; for (nrf_section_iter_init(&iter, &sdh_ble_observers); nrf_section_iter_get(&iter) != NULL; nrf_section_iter_next(&iter)) { nrf_sdh_ble_evt_observer_t * p_observer; nrf_sdh_ble_evt_handler_t handler; p_observer = (nrf_sdh_ble_evt_observer_t *)nrf_section_iter_get(&iter); handler = p_observer->handler; handler(p_ble_evt, p_observer->p_context); } } if (ret_code != NRF_ERROR_NOT_FOUND) { APP_ERROR_HANDLER(ret_code); } }
** execute static void nus_data_handler(ble_nus_evt_t * p_evt) in main.c
No actual data received
static void nus_data_handler(ble_nus_evt_t * p_evt) { uint8_t mError = 0; // NRF_UART0->TASKS_STARTRX= 1; // NRF_UART0->TASKS_STARTTX= 1; // NRF_UART0->ENABLE = 1; mSTX_pointer = 0xFF; #ifdef DEBUG printf("> nus_data_H "); #endif if (p_evt->type == BLE_NUS_EVT_RX_DATA) { uint32_t err_code; #ifdef DEBUG // NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART."); // NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length); //printf("> Received data from BLE NUS\r\n"); //printf(" data from BLE NUS"); printf(" L :%x D : ", p_evt->params.rx_data.length); #endif for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++) { do { #ifdef DEBUG err_code = app_uart_put(p_evt->params.rx_data.p_data[i]); #endif if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) { #ifdef DEBUG printf("> Failed receiving NUS message. Error 0x%x. ", err_code); // NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code); #endif APP_ERROR_CHECK(err_code); mError = 1; } // TODO [ 2023-050-10 / yk / PBA Ver.0.0 ] /* else { if( ( 0xFF == mSTX_pointer ) && ( (uint8_t)UART_STX == p_evt->params.rx_data.p_data[i] ) ) { mSTX_pointer = i; } } */ } while (err_code == NRF_ERROR_BUSY); } }
** The operation of the ble_nus_data_send function is as follows.
uint32_t ble_nus_data_send(ble_nus_t * p_nus, uint8_t * p_data, uint16_t * p_length, uint16_t conn_handle) { ret_code_t err_code; ble_gatts_hvx_params_t hvx_params; ble_nus_client_context_t * p_client; VERIFY_PARAM_NOT_NULL(p_nus); err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, conn_handle, (void *) &p_client); VERIFY_SUCCESS(err_code); if ((conn_handle == BLE_CONN_HANDLE_INVALID) || (p_client == NULL)) { return NRF_ERROR_NOT_FOUND; } if (!p_client->is_notification_enabled) { return NRF_ERROR_INVALID_STATE; } if (*p_length > BLE_NUS_MAX_DATA_LEN) { return NRF_ERROR_INVALID_PARAM; } memset(&hvx_params, 0, sizeof(hvx_params)); hvx_params.handle = p_nus->tx_handles.value_handle; hvx_params.p_data = p_data; hvx_params.p_len = p_length; hvx_params.type = BLE_GATT_HVX_NOTIFICATION; return sd_ble_gatts_hvx(conn_handle, &hvx_params); }