Hi Friend,
We have a project using SDK16 and softdevice S140. We want to generate a looping output of 60ms 2.4GHz OOK and 500ms BLE scan. Ported 2.4GHz OOK from radio_test project.
Now I get an error message BLE_ERROR_NOT_ENABLED. Is it because BLE is not properly enabled? But I have called ble_stack_init in the resume_ble function, I don't know why the enable is not successful? I trace program ble_stack_init and found the program execute to nrf_sdh_enable_request to softdevices_evt_irq_enable(); program will execute nrf_sdh_ble_evts_poll() and cause ret_code == BLE_ERROR_NOT_ENABLED and crash.
1: Is this the remaining MESSAGE of RF switching BLE STACK and OOK? (Because it alternates between enabling and disabling.) so after softdevices_evt_irq_enable, execute nrf_sdh_ble_evts_poll. Is there a function to clear the remaining MESSAGE before ble_stack_init?
2: Or other reasons?
How to solve it? Can anyone help me? Thank you in advance.
Best wishes
Ted Wu
main.c
static void ble_stack_init(void)
{
ret_code_t err_code;
err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);
// 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_app_stop(void)
{
uint32_t err_code;
// Stop any impending connection parameters update.
err_code = ble_conn_params_stop();
APP_ERROR_CHECK(err_code);
}
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_app_start(void)
{
ble_stack_init();
scan_init();
db_discovery_init();
gap_params_init();
gatt_init();
nus_c_init();
buffer_init();
conn_params_init();
peer_manager_init();
services_init();
advertising_init();
}
void resume_ble(void)
{
if(ble_enable_flag == false)
{
ble_enable_flag = true;
ble_app_start();
APP_ERROR_CHECK(nrf_ble_scan_start(&m_scan));
}
}
void ook_start(void)
{
if(ble_enable_flag == true)
{
ble_enable_flag = false;
// Stop scanning.
nrf_ble_scan_stop();
ble_app_stop();
ble_stack_stop();
// Use 32MHz from external crystal
// This could be customized for RC/Xtal, or even to use a 32 kHz crystal
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
{
// Do nothing while waiting for the clock to start
}
}
manchester_data_frame(&RfTriggerCmdBuf[1], RfTriggerCmdBuf[0]);
}
nrf_sdh.c
ret_code_t nrf_sdh_enable_request(void)
{
ret_code_t ret_code;
if (m_nrf_sdh_enabled)
{
return NRF_ERROR_INVALID_STATE;
}
m_nrf_sdh_continue = true;
// Notify observers about SoftDevice enable request.
if (sdh_request_observer_notify(NRF_SDH_EVT_ENABLE_REQUEST) == NRF_ERROR_BUSY)
{
// Enable process was stopped.
return NRF_SUCCESS;
}
// Notify observers about starting SoftDevice enable process.
sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLE_PREPARE);
nrf_clock_lf_cfg_t const clock_lf_cfg =
{
.source = NRF_SDH_CLOCK_LF_SRC,
.rc_ctiv = NRF_SDH_CLOCK_LF_RC_CTIV,
.rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
.accuracy = NRF_SDH_CLOCK_LF_ACCURACY
};
CRITICAL_REGION_ENTER();
#ifdef ANT_LICENSE_KEY
ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler, ANT_LICENSE_KEY);
#else
ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);
#endif
m_nrf_sdh_enabled = (ret_code == NRF_SUCCESS);
CRITICAL_REGION_EXIT();
if (ret_code != NRF_SUCCESS)
{
return ret_code;
}
m_nrf_sdh_continue = false;
m_nrf_sdh_suspended = false;
// Enable event interrupt.
// Interrupt priority has already been set by the stack.
softdevices_evt_irq_enable();
// Notify observers about a finished SoftDevice enable process.
sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLED);
return NRF_SUCCESS;
}
nrf_sdh_ble.c
static void nrf_sdh_ble_evts_poll(void * p_context)
{
UNUSED_VARIABLE(p_context);
ret_code_t ret_code;
if (!m_stack_is_enabled)
{
return;
}
while (true)
{
/*lint -save -e(587) */
__ALIGN(4) uint8_t evt_buffer[NRF_SDH_BLE_EVT_BUF_SIZE];
/*lint -restore */
ble_evt_t * p_ble_evt;
uint16_t evt_len = (uint16_t)sizeof(evt_buffer);
ret_code = sd_ble_evt_get(evt_buffer, &evt_len);
if (ret_code != NRF_SUCCESS)
{
break;
}
p_ble_evt = (ble_evt_t *)evt_buffer;
NRF_LOG_DEBUG("BLE event: 0x%x.", p_ble_evt->header.evt_id);
// Forward the event to BLE observers.
nrf_section_iter_t iter;
for (nrf_section_iter_init(&iter, &sdh_ble_observers);
nrf_section_iter_get(&iter) != NULL;
nrf_section_iter_next(&iter))
{
nrf_sdh_ble_evt_observer_t * p_observer;
nrf_sdh_ble_evt_handler_t handler;
p_observer = (nrf_sdh_ble_evt_observer_t *)nrf_section_iter_get(&iter);
handler = p_observer->handler;
handler(p_ble_evt, p_observer->p_context);
}
}
if (ret_code != NRF_ERROR_NOT_FOUND)
{
APP_ERROR_HANDLER(ret_code);
}
}