nrf_sdh_enable_request() Error:4097 when switch from USBD or Gazell to BLE.

Good day, I am working on function to switch between USBD HID, Gazell and BLE HID with nrf52840 and SDK 17.1.0.

From the very beginning of program, USBD and BLE services are all initiated without any problem, and also no problem when switching between USBD HID and BLE HID.

as per below part coding, switch from USBD to Gazell, at the same time, ble services and ble stack stopped smoothly. but switch back to ble, RTT output unknow error, error no.4097 from nrf_sdh_enable_request(), pls see below part codes.

void set_output(uint8_t output) {
    static uint8_t last_output = OUTPUT_NONE;
    switch(output) {
        case OUTPUT_USB:
            switch (last_output) {
                case OUTPUT_BLE_HID:
                    if (nrf_sdh_is_enabled()) ble_disconnect();
                    break;
                case OUTPUT_GZLL:
                    nrf_drv_clock_lfclk_release();
                    gzll_kbd_device_stop();
                    break;
            }
            if (nrf_drv_usbd_is_enabled()) app_usbd_start();
            break;
        case OUTPUT_BLE_HID:
            switch (last_output) {
                case OUTPUT_GZLL:
                    nrf_drv_clock_lfclk_release();
                    gzll_kbd_device_stop();
                    break;
            }
            if (!nrf_sdh_is_enabled()) {
                ble_stack_init();
                ble_hid_service_start();
            }
            advertising_restart(false);
            break;
        case OUTPUT_GZLL:
            switch (last_output) {
                case OUTPUT_BLE_HID:
                    if (nrf_sdh_is_enabled()) {
                        ble_hid_service_stop();
                        ble_stack_stop();
                    }
            }
            nrf_drv_clock_lfclk_request(NULL);
            gzll_kbd_device_start();
            break;
    }
    last_output = output;
}

void ble_stack_stop(void)
{
    uint32_t err_code;

    err_code = nrf_sdh_disable_request();
    APP_ERROR_CHECK(err_code);

    ASSERT(!nrf_sdh_is_enabled());
}

void ble_stack_init(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);
}

void ble_hid_service_stop(void) {
    ret_code_t err_code;

    err_code = ble_conn_params_stop();
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_stop(m_battery_timer_id);
    APP_ERROR_CHECK(err_code);
}

void ble_hid_service_start(void) {
    // Initialize.
    timers_create();
    // ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();
    peer_manager_init();
    // Start execution.
    NRF_LOG_INFO("HID Keyboard example started.");
    timers_start();
    // advertising_restart(false);
}

Parents
  • Hello,

    Looks like the 4097 error is:

    #define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1)  ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).

    I assume the problem is that there are interrupts enabled that it don't expect, these seems to be the culpit:
    RE: SOFTDEVICE_HANDLER_INIT returning NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION   

    Kenneth

  • Hi, Kenneth

    yes, you are right. It did ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler); return error4097.

    but when I do single step debug, step in sd_softdevice_enable, then jumped to:

    SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));

    can not step further.

    At the same time, I looked though sdk_config.h, did not find any IRQ_Priority higher than 6.

    Pls help me that is there any other good way to debug out what's wrong exactly?

    Best regards.

  • I looked thought sdk_config.h, RTC0 disabled, TIMER0, disabled.

    Would you pls provide me some documents indicating what resources and interrupts related with softdevice?

    Best regards

  • Try something like this (copied from \examples\multiprotocol\ble_app_gzll\ble_app_gzll_device.c):

    void gzll_app_stop()
    {
        // Disable gazell.
        nrf_gzll_disable();

        // Wait for Gazell to shut down.
        while (nrf_gzll_is_enabled())
        {

        }

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

    }

  • Kenneth, thanks a lot, your remind me of above.

    But I am using makefile and armgcc. so I include below file:

    NRF_LDFLAGS += $(SDK_ROOT)/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.a \

    bss above user guide, there are two libraries: gzll_arm.lib and gzll_sd_resources_arm.lib.

    Can I say gzll_nrf52840_gcc.a corresponding to gzll_arm.lib and gzll_nrf52840_sd_resources_gcc.a coresponding to gzll_sd_resources_arm.lib?

    At the same time, I noticed that example of ble_app_gzll's makefile, including gzll_nrf52840_gcc.a, and below

    void gzll_app_stop()
    {
        // Disable gazell.
        nrf_gzll_disable();
    
        // Wait for Gazell to shut down.
        while (nrf_gzll_is_enabled())
        {
    
        }
    
        // 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);
    }

    In my makefile, I include gzll_nrf52840_sd_resources_gcc.a, bss above correspondingly, I should ammend above code as below?

    void gzll_app_stop()
    {
        // Disable gazell.
        nrf_gzll_disable();
    
        // Wait for Gazell to shut down.
        while (nrf_gzll_is_enabled())
        {
    
        }
        // Clean up after Gazell.
        NVIC_DisableIRQ(RADIO_IRQn);
        NVIC_DisableIRQ(TIMER0_IRQn);  //ammended
        NVIC_DisableIRQ(SWI0_IRQn);
        NVIC_ClearPendingIRQ(RADIO_IRQn);
        NVIC_ClearPendingIRQ(TIMER0_IRQn);//ammended
        NVIC_ClearPendingIRQ(SWI0_IRQn);
    }

    another questions: bss make file and armgcc, am I doing right of including  gzll_nrf52840_sd_resources_gcc.a?

  • I recommend to use the same library as the combined BLE and Gazell example use: gzll_arm.lib (in your case then I expect gzll_nrf52840_gcc.a).

    Kenneth

Reply Children
Related