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
Related