@@ -333,37 +333,81 @@ static void timer_frequency_set_1mhz(void)
333333 nrf_timer_prescaler_set (NRF_802154_TIMER_INSTANCE , prescaler );
334334}
335335
336+ /** Disables the radio no matter its state. */
337+ static void radio_force_disable (void )
338+ {
339+ /* Radio cannot be disabled if EVENT_DISABLED is set. Clear it first. */
340+ nrf_radio_event_clear (NRF_RADIO , NRF_RADIO_EVENT_DISABLED );
341+ nrf_radio_task_trigger (NRF_RADIO , NRF_RADIO_TASK_DISABLE );
342+ }
343+
344+ /** Robustly disable the radio peripheral based on the radio state. */
345+ static void radio_robust_disable (void )
346+ {
347+ nrf_radio_state_t radio_state = nrf_radio_state_get (NRF_RADIO );
348+
349+ if ((radio_state == NRF_RADIO_STATE_RXDISABLE ) || (radio_state == NRF_RADIO_STATE_TXDISABLE ))
350+ {
351+ /* RADIO is in an unstable state that should resolve to DISABLED. Do nothing. */
352+ }
353+ else
354+ {
355+ /* RADIO is in a stable state and needs to be transitioned to DISABLED manually. */
356+ radio_force_disable ();
357+ }
358+ }
359+
336360static inline void wait_until_radio_is_disabled (void )
337361{
338362 nrf_802154_log_function_enter (NRF_802154_LOG_VERBOSITY_HIGH );
339363
340364 bool radio_is_disabled = false;
365+ bool repeat = false;
366+
367+ do
368+ {
369+ /* RADIO should enter DISABLED state after no longer than RX ramp-down time or TX ramp-down
370+ * time, depending on its initial state before TASK_DISABLE was triggered. The loop below busy
371+ * waits for the state transition to complete. To prevent the CPU from spinning in an endless
372+ * loop, the maximum allowed number of loop cycles is limited. The limit's intention is not to
373+ * approximate the expected maximum time the transition might actually take, which is generally
374+ * very short, but to act as a safeguard against obviously incorrect and unexpected behaviors.
375+ * In practice, in most cases the radio will have already changed state to DISABLED before this
376+ * function starts. In the remaining cases several cycles of the loop should be sufficient for
377+ * the transition to complete.
378+ */
379+ for (uint32_t i = 0 ; i < MAX_RAMPDOWN_CYCLES ; i ++ )
380+ {
381+ if (nrf_radio_state_get (NRF_RADIO ) == NRF_RADIO_STATE_DISABLED )
382+ {
383+ radio_is_disabled = true;
384+ break ;
385+ }
386+ #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX )
387+ nrf_802154_delay_us (1 );
388+ /* In this simulated board, and in general in the POSIX ARCH,
389+ * code takes 0 simulated time to execute.
390+ * Let's hold for 1 microsecond to allow the RADIO HW to clear the state
391+ */
392+ #endif
393+ }
341394
342- /* RADIO should enter DISABLED state after no longer than RX ramp-down time or TX ramp-down
343- * time, depending on its initial state before TASK_DISABLE was triggered. The loop below busy
344- * waits for the state transition to complete. To prevent the CPU from spinning in an endless
345- * loop, the maximum allowed number of loop cycles is limited. The limit's intention is not to
346- * approximate the expected maximum time the transition might actually take, which is generally
347- * very short, but to act as a safeguard against obviously incorrect and unexpected behaviors.
348- * In practice, in most cases the radio will have already changed state to DISABLED before this
349- * function starts. In the remaining cases several cycles of the loop should be sufficient for
350- * the transition to complete.
351- */
352- for (uint32_t i = 0 ; i < MAX_RAMPDOWN_CYCLES ; i ++ )
353- {
354- if (nrf_radio_state_get (NRF_RADIO ) == NRF_RADIO_STATE_DISABLED )
395+ #ifdef NRF54L_SERIES
396+ if (!radio_is_disabled && !repeat )
397+ {
398+ /* Radio still not in disabled state.
399+ * Manually disable the radio and repeat the loop once as a last resort.
400+ */
401+ radio_force_disable ();
402+ repeat = true;
403+ }
404+ else
355405 {
356- radio_is_disabled = true;
357406 break ;
358407 }
359- #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX )
360- nrf_802154_delay_us (1 );
361- /* In this simulated board, and in general in the POSIX ARCH,
362- * code takes 0 simulated time to execute.
363- * Let's hold for 1 microsecond to allow the RADIO HW to clear the state
364- */
365408#endif
366409 }
410+ while (repeat );
367411
368412 NRF_802154_ASSERT (radio_is_disabled );
369413 (void )radio_is_disabled ;
@@ -525,24 +569,6 @@ static void nrf_radio_reset(void)
525569 nrf_802154_log_function_exit (NRF_802154_LOG_VERBOSITY_LOW );
526570}
527571
528- /** Robustly disable the radio peripheral. */
529- static void radio_robust_disable (void )
530- {
531- nrf_radio_state_t radio_state = nrf_radio_state_get (NRF_RADIO );
532-
533- if ((radio_state == NRF_RADIO_STATE_RXDISABLE ) || (radio_state == NRF_RADIO_STATE_TXDISABLE ))
534- {
535- /* RADIO is in an unstable state that should resolve to DISABLED. Do nothing. */
536- }
537- else
538- {
539- /* RADIO is in a stable state and needs to be transitioned to DISABLED manually.
540- * It cannot be disabled if EVENT_DISABLED is set. Clear it first. */
541- nrf_radio_event_clear (NRF_RADIO , NRF_RADIO_EVENT_DISABLED );
542- nrf_radio_task_trigger (NRF_RADIO , NRF_RADIO_TASK_DISABLE );
543- }
544- }
545-
546572static void channel_set (uint8_t channel )
547573{
548574 NRF_802154_ASSERT (channel >= 11U && channel <= 26U );
0 commit comments