esb_disable() triggers ASSERT in nrfx_timer_uninit() and esb_ppi_deinit() on nRF54L15 (NCS v3.1.0)

Platform: nRF54L15, NCS v3.1.0, ESB using TIMER10 + DPPI10

Symptom: Calling esb_disable() during application shutdown triggers  ASSERT failures:

ASSERTION FAIL@WEST_TOPDIR/modules/hal/nordic/nrfx/drivers/src/nrfx_timer.c:188
[00:00:14.403,213] <err> os: esf_dump:r0/a1:Ox00000004 r1/a2:Ox000000bc r2/a3: Ox00000003
[00:00:14.403,218]<err> os: esf_dump:r3/a4:Ox0000004 r12/ip:Ox00000000 r14/lr:Ox000277ed
[00:00:14.403,223]<err> os:esf_dump: xpsr: Ox01000000
[00:00:14.403,228]<err>os: esf_dump: s[ 0]:0x00010813 s[1]:Ox5008a000 s[2]:0x00000000 s[3]:Ox20000c54
[00:00:14.403,233]<err>os: esf_dump: s[ 4]:0x00000010 s[5]:Ox00023c51 s[6]:0x00000000 s[7]:0x00000000
[00:00:14.403,238]<err>os: esf_dump: s[8]:0x00034b28 s[9]:0x00013a95 s[10]:Ox00000000 s[11]: Ox00000000
[00:00:14.403,243] <err>os:esf_dump:s[12]:0x00000000 s[13]:0x00000000 s[14]:Ox0000000 s[15]:Ox00000000
[00:00:14.403,258] <err> os: esf_dump: fpscr: Ox00000000
[00:00:14.403,263] <err> os: esf_dump: Faulting instruction address(r15/pc):Ox000308d2
[00:00:14.403,287] <err>os: zfatal_error:>>>ZEPHYR FATAL ERROR4:Kernel panic on CPU 0
[00:00:14.403,306]<err> os: z_fatal_error: Current thread:0x20001488(unknown)

Nordic Semiconductor AI has raised concerns about potential issues with esb.c, but I believe the version I am using has already been fixed:

void esb_disable(void)
{
on_radio_disabled = NULL;

esb_irq_disable();

nrf_radio_shorts_disable(NRF_RADIO, 0xFFFFFFFF);
nrf_radio_int_disable(NRF_RADIO, 0xFFFFFFFF);

nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);

while (!nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED)) {
/* wait for register to settle */
}

nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);

esb_ppi_disable_all();
esb_fem_reset();

sys_timer_deinit();
esb_ppi_deinit();

/* Radio ramp-up time to default mode */
nrf_radio_fast_ramp_up_enable_set(NRF_RADIO, false);

esb_state = ESB_STATE_IDLE;
errata216_off();
esb_initialized = false;

reset_fifos();

memset(rx_pipe_info, 0, sizeof(rx_pipe_info));
memset(pids, 0, sizeof(pids));
}

My deinitialize function:

void esb_deinitialize(void)
{
    tdma_running = false;
    k_timer_stop(&tx_timer);
    k_timer_stop(&heartbeat_timer);
    k_timer_stop(&quat_acc_timer);
    k_timer_stop(&quat_mag_timer);
    k_timer_stop(&registration_timer);
    k_timer_stop(&raw_data_timer);
    k_timer_stop(&phase_adjust_timer);

    struct k_work_sync sync = {0};
    k_work_cancel_sync(&tx_work, &sync);
    k_msgq_purge(&esb_tx_queue);

    esb_flush_tx();
    esb_flush_rx();
    LOG_INF("Waiting for ESB to be idle");
    while (!esb_is_idle())
    {
        k_yield(); // 让出 CPU,避免忙等待
    }

    esb_disable();

    if (nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_HFCLK, NULL))
    {
        nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
    }

    atomic_set(&esb_state, esb_idle);

    LOG_INF("ESB stopped");
}
MPSL is not enabled in the kconfig
Parents
  • Hi,

    Even though you are not directly using MPSL, it seems like ESB requires the MPSL library. Ant with the nRF54L series, TIMER10 is shared between ESB and MPSL.

    My guess is that ESB is not truly stopped yet when trying to disable it. Can you try this piece of code to ensure ESB is stopped before disabling?

    esb_stop_rx();
    while (!esb_is_idle()) {
        k_yield();
    }
    esb_disable();
    Can you also check if nothing else in your build is using TIMER10?

    Let me know if the assertion is still here after add that small snippet to your code

    Best regards,

    Simon D-M

Reply
  • Hi,

    Even though you are not directly using MPSL, it seems like ESB requires the MPSL library. Ant with the nRF54L series, TIMER10 is shared between ESB and MPSL.

    My guess is that ESB is not truly stopped yet when trying to disable it. Can you try this piece of code to ensure ESB is stopped before disabling?

    esb_stop_rx();
    while (!esb_is_idle()) {
        k_yield();
    }
    esb_disable();
    Can you also check if nothing else in your build is using TIMER10?

    Let me know if the assertion is still here after add that small snippet to your code

    Best regards,

    Simon D-M

Children
No Data
Related