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

Unable to call sd_ble_gap_addr_get after calling sd_radio_request??

S140, nrf52840, as long as I call sd_radio_request before calling sd_ble_gap_addr_get, the program will crash and enter a default error handler, it's not the case if the sequence was reversed.

Upon reading the API tech docs for sd_radio_request, I noticed that:

NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is guaranteed to be clocked from the external crystal.

I've been having some problem with timers before, namely if I don't call this function:

APP_TIMER_INIT ,

the sd_ble_gap_addr_get will return a 0x3001 (certain feature) uninitialized error.

APP_TIMER_INIT is a macro function, which I replicated from the hrs example, and it calls another function app_timer_init, shown below:

uint32_t app_timer_init(uint32_t                      prescaler,
                    uint8_t                       op_queue_size,
                    void *                        p_buffer,
                    app_timer_evt_schedule_func_t evt_schedule_func)
{
// Check that buffer is correctly aligned
if (!is_word_aligned(p_buffer))
{
    return NRF_ERROR_INVALID_PARAM;
}
// Check for NULL buffer
if (p_buffer == NULL)
{
    return NRF_ERROR_INVALID_PARAM;
}

// Stop RTC to prevent any running timers from expiring (in case of reinitialization)
rtc1_stop();

m_evt_schedule_func = evt_schedule_func;

// Initialize operation queue
m_op_queue.first           = 0;
m_op_queue.last            = 0;
m_op_queue.size            = op_queue_size;
m_op_queue.p_user_op_queue = p_buffer;

mp_timer_id_head            = NULL;
m_ticks_elapsed_q_read_ind  = 0;
m_ticks_elapsed_q_write_ind = 0;

#if APP_TIMER_WITH_PROFILER
m_max_user_op_queue_utilization   = 0;
#endif

NVIC_ClearPendingIRQ(SWI_IRQn);
NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI);
NVIC_EnableIRQ(SWI_IRQn);

rtc1_init(prescaler);

m_ticks_latest = rtc1_counter_get();

return NRF_SUCCESS;
}

By skimming through this function I decided that it has more to do with RTC than TMR0, my initial hypothesis was that by calling sd_radio_request, TMR0 will be immediately reset which interfere with the sd_ble_gap_addr_get function, now that it seems they run on different clock source (I could be wrong).

Could it be that right after sd_radio_request ordering a timeslot, one should expect a lot of functions unavailable, until the ordered timeslot expires or manually terminated? I think that is highly unlikely, but if that were the case, what did I do wrong?

So... what is more like that case:

timer conflict,

or

exclusive nature of the timeslot, meaning a lot of functions will be unavailable after sd_radio_request was called?

  • Hello Mitch 996

    Regarding the timers, TIMER0 is a dedicated hardware timer, while app_timer is a library that uses the real time clock (RTC) to create multiple timer instances.

    I find it strange you have encountered the 0x3001 error coming from sd_ble_gap_addr_get as should be incapable of returning that error. According to ble_gap.h line 1274 it can only return NRF_SUCCESS (err code 0) or NRF_ERROR_INVALID_ADDR (error code 0x10).

    The 0x3001 error is defined at line 63 in ble_err.h as

    #define BLE_ERROR_NOT_ENABLED            (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
    

    When it comes to the sd_ble_gap_addr_get leading to a crash, have you ensured you are in the correct interrupt level? Please see section 17.2 page 71 of the S132 specification. The s132 and S140 functions identically with respect to this.

    Handlers running at a priority level higher than 4 (lower numerical priority value) have neither access to SoftDevice functions nor to application specific SVCs or RTOS functions running at lower priority levels (higher numerical priority values).

    It would otherwise be helpful to know what part of our code leads to the crash.

    Best regards

    Jørn Frøysa

Related