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

Can't disable Softdevice in ble_app_uart

Hi all,

I want to disable SD and reinit SD and reinit my services.

I try by ble_app_uart example.

I add code for button, when I press button 1, it disable SD. When I press button 2, it reinit SD and my service.

But when I disable SD and check by funtion nrf_sdh_is_enabled(), RTT print SD still enable. And right away, I receiver Fatal error by timeout of button

This is my code : 

    // Enter main loop.
    for (;;)
    {
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        if(disable_SD)
        {
            disable_SD = false;
            uint8_t res = 0;
            uint32_t err_code = sd_softdevice_disable();
            APP_ERROR_CHECK(err_code);
            res = nrf_sdh_is_enabled();
            if(res == 1)
            {
                NRF_LOG_INFO("SD is enable");
            }
            else
            {
                NRF_LOG_INFO("SD is disable");
            }  
        }
        idle_state_handle();
    }

Thank !!

Parents
  • Hi,

    If softdevice have been enabled through the softdevice handler library with call to nrf_sdh_enable_request(), you should also make sure to disable it using the same API with nrf_sdh_disable_request(). Failing to do so will leave the softdevice handler in the wrong state and give you errors.

    Best regards,
    Jørgen

  • Hi ,

    I have a problem when try enable stack and reinit service.

    I follow ble_app_gzll, this my code : 

    void ble_stack_start(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        ASSERT(nrf_sdh_is_enabled());
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    static void ble_stack_stop(void)
    {
        uint32_t err_code;
    
        err_code = nrf_sdh_disable_request();
        APP_ERROR_CHECK(err_code);
    
        bool res = nrf_sdh_is_enabled();
        if(res)
        {
            NRF_LOG_INFO("SD enabled");
        }
        else{
            NRF_LOG_INFO("SD disabled");
        }
    }
    
    void ble_nus_start(void)
    {
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        advertising_start();
    }
    
    #define BLE_MODE  0
    #define NONE_MODE 1
    
    uint8_t running_mode = 0;
    uint8_t previous_mode  = 0;
    
    
    /**@brief Application main function.
     */
    int main(void)
    {
        bool erase_bonds;
    
        // Initialize.
        uart_init();
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
      
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
    
        // Start execution.
        printf("\r\nUART started.\r\n");
        NRF_LOG_INFO("Debug logging for UART over RTT started.");
        advertising_start();
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
            if (bsp_button_is_pressed(BLE_MODE))
            {
                running_mode  = BLE_MODE;
            }
            else if (bsp_button_is_pressed(NONE_MODE))
            {
                running_mode  = NONE_MODE;
            }     
            if(previous_mode != running_mode)
            {
                previous_mode = running_mode;
                if(running_mode == BLE_MODE)
                { 
                  NRF_LOG_INFO("BLE mode");
    
                  // Disable low frequency clock. Readying for softdevice startup.
                  nrf_drv_clock_lfclk_release();
    
                  // Clean up after Gazell.
                  NVIC_DisableIRQ(RADIO_IRQn);
                  NVIC_DisableIRQ(TIMER2_IRQn);
                  NVIC_DisableIRQ(SWI0_IRQn);
                  NVIC_ClearPendingIRQ(RADIO_IRQn);
                  NVIC_ClearPendingIRQ(TIMER2_IRQn);
                  NVIC_ClearPendingIRQ(SWI0_IRQn);
    
                  // Re-enable the softdevice stack.
                  ble_stack_start();
                  ble_nus_start();
                }
                else
                {
                  NRF_LOG_INFO("None mode");
    
                  // Disable the softdevice stack.
                  ble_stack_stop();
    
                  // Request Low frequency clock to re-enable the clock after the softdevice stops it.
                  nrf_drv_clock_lfclk_request(NULL);
                }
             }
        }
    }
    

    When I reinit, run to services_init(), I receiver error by funtion nrf_ble_qwr_init() return 

    if (MODULE_INITIALIZED)
    {
    return NRF_ERROR_INVALID_STATE;
    }

    because MODULE_INITIALIZED. So why ble_nus_init() not error but nrf_ble_qwr_init() return error. 

    Please show me a solution ?

    Thank!!

  • If you look in the ble_app_gzll example, they store a flag that say if Queued write module have been initialized. You will have to do something similar:

    // Flag that prevents from Queued Write module reinitialization.
    static bool        qwr_initialized = false;
    
    uint32_t           err_code;
    nrf_ble_qwr_init_t qwr_init = {0};
    
    if (!qwr_initialized)
    {
        // Initialize the Queued Write module.
        qwr_init.error_handler = nrf_qwr_error_handler;
    
        err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
        APP_ERROR_CHECK(err_code);
    
        qwr_initialized = true;
    }

  • I did. It worked. I want to ask in my code : 

                else if(running_mode == NONE_MODE)
                {
                  NRF_LOG_INFO("None mode");
                  bsp_indication_set(BSP_INDICATE_IDLE);
                  bsp_indication_set(BSP_INDICATE_CONNECTED);
                  // Stop any impending connection parameters update.
                  // Stop all timer use for update paramater of connection
                  uint32_t err_code = ble_conn_params_stop();
                  APP_ERROR_CHECK(err_code);
    
                  // Disable the softdevice stack.
                  ble_stack_stop();
    
                  // Request Low frequency clock to re-enable the clock after the softdevice stops it.
                  nrf_drv_clock_lfclk_request(NULL);
                }

    If I comment line : 

    uint32_t err_code = ble_conn_params_stop();
    APP_ERROR_CHECK(err_code);

    I will receiver many hardfault. Such as : 

    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);

    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);

    static void conn_params_error_handler(uint32_t nrf_error)
    {
    APP_ERROR_HANDLER(nrf_error);
    }

    So, can you tell me What happen ?

    Thank!!

  • I'm not sure I understand your question. If you disable the softdevice, you will get errors if you try to call softdevice API functions.

Reply Children
Related