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

Reenable BLE after disabling fails in ble_conn_params_init() on freertos

Hi, 
I'd like to describe an issue i faced during project development. 
My setup is: nRF52840 + s140 + sdk15+FreeRtos

When i disable BLE I call: 

1) sd_ble_gap_disconnect () .  if connected
2) 
ble_conn_params_stop()

3)nrf_sdh_disable_request();

When I reenable BLE I call: 

nrf_sdh_enable_request()

nrf_sdh_ble_enable()

ble_conn_params_init()

....

The problem is that  ble_conn_params_init() returns NRF_ERROR_INTERNAL at if initing this way. It caused by call 

        err_code = app_timer_create(&p_instance->timer_id,
                            APP_TIMER_MODE_SINGLE_SHOT,
                            update_timeout_handler);
        if (err_code != NRF_SUCCESS)
        {
            return NRF_ERROR_INTERNAL;
        }
 

For FREERTOS i use app_timer implementation from app_timer_freertos.c 
inside it the function 

app_timer_create()
has next lines: 

if (pinfo->osHandle == NULL)
    {
        /* New timer is created */
        memset(pinfo, 0, sizeof(app_timer_info_t));

        timer_mode = (mode == APP_TIMER_MODE_SINGLE_SHOT) ? pdFALSE : pdTRUE;
        pinfo->single_shot = (mode == APP_TIMER_MODE_SINGLE_SHOT);
        pinfo->func = timeout_handler;
        pinfo->osHandle = xTimerCreate(" ", 1000, timer_mode, pinfo, app_timer_callback);

        if (pinfo->osHandle == NULL)
            err_code = NRF_ERROR_NULL;
    }
    else
    {
        /* Timer cannot be reinitialized using FreeRTOS API */
        return NRF_ERROR_INVALID_STATE;
    }

and else case is executed. The comment explains why I get an error. 

/* Timer cannot be reinitialized using FreeRTOS API */

For now I added workaround and skipped error at upper layer but it would be better to get this case fixed in next SDK version. 
I suggest  adding app_timer_remove() and updating ble_conn_params_stop() might be a good option. Or just skip call 

app_timer_create in case if it already created. 

Regards,

 

Parents
  • Hello -

    We too are bumping into this problem with SDK v17.0.0. Skipping the error when re-initializing BLE doesn't seem to work for us. @rsb.29 - would you be able to share the code you used to resolve this issue?

    Regards,

    Brian

  • Hello -

    In case it is helpful for anyone else bumping into this issue, here is what we did to resolve the problem. These changes were applied to SDK v17.0.0.

    In ble_conn_params.c, we modified the code to call a new app_timer_delete() function:

    ret_code_t ble_conn_params_stop(void)
    {
        ret_code_t err_code;
    
        //lint -save -e681 "Loop not entered" when NRF_BLE_CONN_PARAMS_INSTANCE_COUNT is 0
        for (uint32_t i = 0; i < NRF_BLE_CONN_PARAMS_INSTANCE_COUNT; i++)
            {
            err_code = app_timer_stop(m_conn_params_instances[i].timer_id);
    
            switch (err_code)
                {
                case NRF_SUCCESS:
    				app_timer_delete(m_conn_params_instances[i].timer_id);
                    break;
    
                case NRF_ERROR_INVALID_STATE:
                    /* do nothing */
                    break;
    
                case NRF_ERROR_NO_MEM:
                    return NRF_ERROR_BUSY;
    
                case NRF_ERROR_INVALID_PARAM:
                    /* fallthrough */
                default:
                    return NRF_ERROR_INTERNAL;
                }
            }
        //lint -restore
        return NRF_SUCCESS;
    }
    

    Then we added a simple implementation of app_timer_delete() to app_timer_freertos.c:

    uint32_t app_timer_delete(app_timer_id_t timer_id)
    {
        app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id);
        TimerHandle_t hTimer = pinfo->osHandle;
        if (hTimer == NULL)
        {
            return NRF_ERROR_INVALID_STATE;
        }
    
    	if (xTimerDelete(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
    	{
    		return NRF_ERROR_NO_MEM;
    	}
    	
    	pinfo->osHandle = NULL;
    
        return NRF_SUCCESS;
    }
    

    The app_timer_delete() function sets the pInfo->osHandle to NULL, which allows a new timer to be created after BLE is reenabled.

    Regards,

    Brian

Reply
  • Hello -

    In case it is helpful for anyone else bumping into this issue, here is what we did to resolve the problem. These changes were applied to SDK v17.0.0.

    In ble_conn_params.c, we modified the code to call a new app_timer_delete() function:

    ret_code_t ble_conn_params_stop(void)
    {
        ret_code_t err_code;
    
        //lint -save -e681 "Loop not entered" when NRF_BLE_CONN_PARAMS_INSTANCE_COUNT is 0
        for (uint32_t i = 0; i < NRF_BLE_CONN_PARAMS_INSTANCE_COUNT; i++)
            {
            err_code = app_timer_stop(m_conn_params_instances[i].timer_id);
    
            switch (err_code)
                {
                case NRF_SUCCESS:
    				app_timer_delete(m_conn_params_instances[i].timer_id);
                    break;
    
                case NRF_ERROR_INVALID_STATE:
                    /* do nothing */
                    break;
    
                case NRF_ERROR_NO_MEM:
                    return NRF_ERROR_BUSY;
    
                case NRF_ERROR_INVALID_PARAM:
                    /* fallthrough */
                default:
                    return NRF_ERROR_INTERNAL;
                }
            }
        //lint -restore
        return NRF_SUCCESS;
    }
    

    Then we added a simple implementation of app_timer_delete() to app_timer_freertos.c:

    uint32_t app_timer_delete(app_timer_id_t timer_id)
    {
        app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id);
        TimerHandle_t hTimer = pinfo->osHandle;
        if (hTimer == NULL)
        {
            return NRF_ERROR_INVALID_STATE;
        }
    
    	if (xTimerDelete(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
    	{
    		return NRF_ERROR_NO_MEM;
    	}
    	
    	pinfo->osHandle = NULL;
    
        return NRF_SUCCESS;
    }
    

    The app_timer_delete() function sets the pInfo->osHandle to NULL, which allows a new timer to be created after BLE is reenabled.

    Regards,

    Brian

Children
No Data
Related