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!!

  • 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.

  • Hi ,

    I have a trouble, In my project have DFU service and I want to disable SD and enable SD while chip running.

    But DFU have function : 

    static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
    {
    	NRF_LOG_INFO("System OFF");
       if (state == NRF_SDH_EVT_STATE_DISABLED)
       {
           // Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
           nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
    
           //Go to system off.
           nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
       }
    }
    

    And when I disable SD and want to enable SD after that. But my code will jump to above function and put chip to system off. And chip will not enable SD after that. 

    So How I can use both function disable SD for reset GATT table and use DFU. 

    Please show me a solution

    Thank you !!!

  • Thank for reply,

    I continue encounter other problem relate app_timer in below thread. Please read it. Thank !!

    https://devzone.nordicsemi.com/f/nordic-q-a/46455/app-timer-and-disable-softdevice-problems

Reply Children
No Data
Related