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

NRF_BUSY ERROR in Multilink Uart

Hi,

https://github.com/NordicPlayground/nrf52-ble-app-uart-c-multilink


I have tried the example you modified. It works fine. However, I get ERROR 17 NRF_BUSY when 2-3 peripherals connect to central device at the same time. I used ble_app_uart as peripheral.

These are from debugging:



This is from RTT viewer :

00> <info> app_timer: RTC: initialized.
00> <info> app: BLE UART central example started.
00> <info> app: Connecting to target 893473D394EE
00> <info> app: Connecting to target 5E7D5EC6C9DB
00> <error> app: ERROR 17 [NRF_ERROR_BUSY] at C:\Users\Desktop\SDK\examples\ble_central\multilink-master-uart-c\main.c:408
00> PC at: 0x00030815
00> <error> app: End of error report

Could you please help me about it ?

Thank you in advance,

Best Regards

  • Hi OpenCircuit, 

    Could you verify the Error 17 was returned at mainc line 408 is from function ble_db_discovery_start(). If it's the case please read the description of the function:  

    /**@brief Function for starting the discovery of the GATT database at the server.
     *
     * @param[out] p_db_discovery Pointer to the DB Discovery structure.
     * @param[in]  conn_handle    The handle of the connection for which the discovery should be
     *                            started.
     *
     * @retval NRF_SUCCESS             Operation success.
     * @retval NRF_ERROR_NULL          When a NULL pointer is passed as input.
     * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
     *                                 @ref ble_db_discovery_init, or without calling
     *                                 @ref ble_db_discovery_evt_register.
     * @retval NRF_ERROR_BUSY          If a discovery is already in progress using
     *                                 @p p_db_discovery. Use a different @ref ble_db_discovery_t
     *                                 structure, or wait for a DB Discovery event before retrying.
     * @return                         This API propagates the error code returned by functions:
     *                                 @ref nrf_ble_gq_conn_handle_register and @ref nrf_ble_gq_item_add.
     */
    uint32_t ble_db_discovery_start(ble_db_discovery_t * p_db_discovery,
                                    uint16_t             conn_handle);

    So if you already running service discovery on one peripheral and you may need to wait until that finishes before you continue with service discovery for the next peripheral. Or you can set a timer to retry after you receive the error NRF_ERROR_BUSY

  • Sorry, I don't know how to verify if the Error 17 was returned from mainc line 408 from function ble_db_discovery_start(). Do I need to do something to verify it during the debugging ?


    I can try waiting operation untill discovery service is completed for the next peripheral by using timer.

    If I am not wrong, app_timer_create() function takes 3 parameters (p_timer_id, mode, timeout_handler) and we write the action that we want it to happen in timeout_handler() after the time we entered expires.

    Could you tell me that where I should call app_timer_start() function and which action I should write in the function that executes timeout_handler for the operation you suggested ?

    I hope I have written my question clearly.

    Best Regards

  • Maybe a better option is not to establish a connection until you finish service discovery on each device. You receive an event when the service discovery finishes. Then you can start connecting to the next one. 

    If you want to use the timer and try again for example every one second, you can call app_timer_start() when you receives the NRF_ERROR_BUSY event.

    Please try to get familiar with how to do debugging with our chip, and how to use the app_timer. Try having a look at our example, ble_app_hrs for example. 

  • For the first idea, do you mean BLE_DB_DISCOVERY_COMPLETE event from ble_db_discovery_evt_type_t  in ble_db_discovery.h ? 
    I tried something like:
    if ( p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE ){
        ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
        }
    When I try to use this in both db_disc_handler() function or case BLE_GAP_EVT_CONNECTED from ble_evt_handler (where error occured in main.c line 408 ), it didn't work.
    I know that I am doing something wrong and I am new to BLE so i could get some help here.

    For app_timer idea, it says :

     if (p_db_discovery->discovery_in_progress)
        {
            return NRF_ERROR_BUSY;
        }
    in ble_db_discovery.c . But I don't know where to call app_timer_start() function in main.c after this event.

    Also, the system needs a reset when I get NRF_BUSY ERROR as it is specified in app_error_weak.c after the line NRF_BREAKPOINT_COND. It says : "On assert, the system can only recover with a reset ". So could app_timer idea work after that ?

  • Hi, 
    Please try to get familiar on how to use the app_timer. You can have a look at our example ble_app_hrs for example to see how we start the app_timer. Try to blink an LED with app timer. 

    When you call ble_db_discovery_start() you should be aware of the input variable for the function. Especially the conn_handle. It should be the conn_handle that caused the NRF_ERROR_BUSY. 

    Regarding the assert, you need to use a "if" to avoid the assertion triggered when the return code is NRF_ERROR_BUSY. 

    We wouldn't be able to guide you through before you get familiar with the SDK. Please try to look into the example and get familiar with the code before moving to a more complex one. 

Related