A phenomenon occurs in which GPIO input is not possible.

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);
}

Parents
  • Hi SHMoon,

    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?

    I am unsure how GPIO key input is related to the pairing. I think it can be a configuration issue of the pin?

    Can you start your code in the debugger and after pairing when you see the issue pressing the key which is not working, pause the debugger to see if you can see the context of the current execution?

    I am guessing that there is some loop or deadlock in the code in the higher priority which might be masking the GPIO interrupt handling. 

  • Hi

    Additional review was conducted by connecting J-Link.

    Please check the reviewed part by connecting the J-LInk above.

    At first, the key didn't work, so I thought it was a GPIO problem like you said, but

    As in the additional review, the key operates normally.

    Even the ble_nus_data_send() function executes normally.

    However, key data is not received.

    In that state, the NUS connection status check confirmed that it was operating normally.

    When key data is not transmitted, the NUS connection status check function operates normally.

    If you turn off the power on the other side, it is detected on the other side.

    ***********************************************************************************************************************

    Let's organize it again

    1) Phenomenon:

       - Key input data from Peripheral is not transmitted to Central (of course, 100% is transmitted in normal condition)

       - NUS continuously checks the connection status between Peripheral and Central.

    2) Conditions for reproducing the problem

     - In the pairing state of Central and Peripheral, move the Peripheral to a point with weak reception sensitivity.

    It seems to occur during the process of pairing being canceled and proceeding again.

  • Hi SHMoon,

    SHMoon said:

    Even the ble_nus_data_send() function executes normally.

    However, key data is not received.

    Do you have a BLE air sniffer log showing that the the NUS data is transmitted from Peripheral side but the central have not acknowledged it? 

     - If the BLE air sniffer log have shown that the packet in question is transmitted in the air and the Central have acknowledged it, then something in the central side is wrong. Does Central have nRF or Peripheral have nRF? 

     - If the BLE packet is transmitted and is clearly shown in the BLE air sniffer log, and the central have not responded, then we need to see why the central is not responding it in the LinkLayer level.

    - If the air sniffer shows that the packet is not being transmitted at all, then we need to debug the Peripheral side as to why it queued the packet in the notification but did not send it in the air.

    If you can give us the air sniffer log, then we can see which side is the issue (Central or Peripheral)

Reply
  • Hi SHMoon,

    SHMoon said:

    Even the ble_nus_data_send() function executes normally.

    However, key data is not received.

    Do you have a BLE air sniffer log showing that the the NUS data is transmitted from Peripheral side but the central have not acknowledged it? 

     - If the BLE air sniffer log have shown that the packet in question is transmitted in the air and the Central have acknowledged it, then something in the central side is wrong. Does Central have nRF or Peripheral have nRF? 

     - If the BLE packet is transmitted and is clearly shown in the BLE air sniffer log, and the central have not responded, then we need to see why the central is not responding it in the LinkLayer level.

    - If the air sniffer shows that the packet is not being transmitted at all, then we need to debug the Peripheral side as to why it queued the packet in the notification but did not send it in the air.

    If you can give us the air sniffer log, then we can see which side is the issue (Central or Peripheral)

Children
No Data
Related