diff --git a/examples/platforms/nrf52840/Makefile.am b/examples/platforms/nrf52840/Makefile.am index 5eadda777..0cb31eb1e 100644 --- a/examples/platforms/nrf52840/Makefile.am +++ b/examples/platforms/nrf52840/Makefile.am @@ -54,7 +54,8 @@ COMMONCPPFLAGS -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/common \ -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio \ -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/hal \ - -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal \ + -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch \ + -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal \ -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/power \ -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/systick \ -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/usbd \ @@ -100,7 +101,7 @@ SINGLEPHY_SOURCES @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_direct.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_direct.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_direct.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/rsch/raal/single_phy/single_phy.c \ $(NULL) SINGLEPHY_CPPFLAGS = \ @@ -115,11 +116,11 @@ SOFTDEVICE_SOURCES @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_swi.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c \ $(NULL) SOFTDEVICE_CPPFLAGS = \ - -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/softdevice \ + -I$(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice \ -I$(top_srcdir)/third_party/NordicSemiconductor/softdevice/s140/headers \ -DSOFTDEVICE_PRESENT \ -DS140 \ @@ -149,7 +150,6 @@ RADIO_DRIVER_SOURCES @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rssi.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c \ @@ -160,6 +160,8 @@ RADIO_DRIVER_SOURCES @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_802154_clock_sdk.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.c \ @top_builddir@/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c \ $(NULL) @@ -286,7 +288,6 @@ noinst_HEADERS $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.h \ - $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rssi.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.h \ @@ -302,9 +303,12 @@ noinst_HEADERS $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/temperature/nrf_802154_temperature.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h \ - $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_api.h \ - $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h \ - $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_wifi_coex.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_api.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_config.h \ + $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.h \ $(top_srcdir)/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h \ $(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error_weak.h \ $(top_srcdir)/third_party/NordicSemiconductor/libraries/app_error/app_error.h \ diff --git a/examples/platforms/nrf52840/platform-softdevice.h b/examples/platforms/nrf52840/platform-softdevice.h index c3262cd52..21b33b0f2 100644 --- a/examples/platforms/nrf52840/platform-softdevice.h +++ b/examples/platforms/nrf52840/platform-softdevice.h @@ -40,10 +40,10 @@ /** @brief RAAL Softdevice default parameters. */ #define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_LENGTH 6400 #define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS 5 -#define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN 91 +#define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN 126 #define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_TIMEOUT 6400 #define PLATFORM_SOFTDEVICE_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH 120000000 -#define PLATFORM_SOFTDEVICE_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM 25 +#define PLATFORM_SOFTDEVICE_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM 500 /** @brief RAAL Softdevice configuration parameters. */ typedef struct diff --git a/examples/platforms/nrf52840/radio.c b/examples/platforms/nrf52840/radio.c index f152c4560..ff219d22c 100644 --- a/examples/platforms/nrf52840/radio.c +++ b/examples/platforms/nrf52840/radio.c @@ -737,6 +737,7 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error) case NRF_802154_RX_ERROR_RUNTIME: case NRF_802154_RX_ERROR_TIMESLOT_ENDED: case NRF_802154_RX_ERROR_ABORTED: + case NRF_802154_RX_ERROR_INVALID_LENGTH: sReceiveError = OT_ERROR_FAILED; break; diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control.c b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control.c index 3b4d7f9ef..e2653ef32 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control.c +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control.c @@ -52,7 +52,7 @@ #if ENABLE_FEM -static nrf_fem_control_cfg_t m_nrf_fem_control_cfg; /**< FEM controller configuration. */ +static nrf_fem_control_cfg_t m_nrf_fem_control_cfg; /**< FEM controller configuration. */ /** Check whether pin is valid and enabled. */ static bool pin_is_enabled(nrf_fem_control_pin_t pin) @@ -102,14 +102,14 @@ static void gpiote_configure(void) nrf_gpiote_task_configure(m_nrf_fem_control_cfg.lna_gpiote_ch_id, m_nrf_fem_control_cfg.lna_cfg.gpio_pin, (nrf_gpiote_polarity_t)GPIOTE_CONFIG_POLARITY_None, - (nrf_gpiote_outinit_t)!m_nrf_fem_control_cfg.lna_cfg.active_high); + (nrf_gpiote_outinit_t) !m_nrf_fem_control_cfg.lna_cfg.active_high); nrf_gpiote_task_enable(m_nrf_fem_control_cfg.lna_gpiote_ch_id); nrf_gpiote_task_configure(m_nrf_fem_control_cfg.pa_gpiote_ch_id, m_nrf_fem_control_cfg.pa_cfg.gpio_pin, (nrf_gpiote_polarity_t)GPIOTE_CONFIG_POLARITY_None, - (nrf_gpiote_outinit_t)!m_nrf_fem_control_cfg.pa_cfg.active_high); + (nrf_gpiote_outinit_t) !m_nrf_fem_control_cfg.pa_cfg.active_high); nrf_gpiote_task_enable(m_nrf_fem_control_cfg.pa_gpiote_ch_id); } @@ -125,12 +125,12 @@ static void ppi_init(void) nrf_ppi_channel_and_fork_endpoint_setup( (nrf_ppi_channel_t)m_nrf_fem_control_cfg.ppi_ch_id_clr, (uint32_t)(&NRF_RADIO->EVENTS_DISABLED), - (m_nrf_fem_control_cfg.lna_cfg.active_high ? - (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.lna_gpiote_ch_id]) : - (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.lna_gpiote_ch_id])), - (m_nrf_fem_control_cfg.pa_cfg.active_high ? - (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.pa_gpiote_ch_id]) : - (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.pa_gpiote_ch_id]))); + (m_nrf_fem_control_cfg.lna_cfg.active_high ? + (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.lna_gpiote_ch_id]) : + (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.lna_gpiote_ch_id])), + (m_nrf_fem_control_cfg.pa_cfg.active_high ? + (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.pa_gpiote_ch_id]) : + (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.pa_gpiote_ch_id]))); } /** Setup PPI to set LNA pin on a timer event. */ @@ -141,8 +141,8 @@ static void ppi_lna_enable_setup(nrf_timer_cc_channel_t timer_cc_channel) (nrf_ppi_channel_t)m_nrf_fem_control_cfg.ppi_ch_id_set, (uint32_t)(&NRF_FEM_TIMER_INSTANCE->EVENTS_COMPARE[timer_cc_channel]), (m_nrf_fem_control_cfg.lna_cfg.active_high ? - (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.lna_gpiote_ch_id]) : - (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.lna_gpiote_ch_id]))); + (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.lna_gpiote_ch_id]) : + (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.lna_gpiote_ch_id]))); } /** Setup PPI to set PA pin on a timer event. */ @@ -153,8 +153,8 @@ static void ppi_pa_enable_setup(nrf_timer_cc_channel_t timer_cc_channel) (nrf_ppi_channel_t)m_nrf_fem_control_cfg.ppi_ch_id_set, (uint32_t)(&NRF_FEM_TIMER_INSTANCE->EVENTS_COMPARE[timer_cc_channel]), (m_nrf_fem_control_cfg.pa_cfg.active_high ? - (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.pa_gpiote_ch_id]) : - (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.pa_gpiote_ch_id]))); + (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.pa_gpiote_ch_id]) : + (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.pa_gpiote_ch_id]))); } /** @@ -258,23 +258,24 @@ void nrf_fem_control_pin_clear(void) if (pin_is_enabled(NRF_FEM_CONTROL_PA_PIN)) { nrf_gpiote_task_force(m_nrf_fem_control_cfg.pa_gpiote_ch_id, - (nrf_gpiote_outinit_t)!m_nrf_fem_control_cfg.pa_cfg.active_high); + (nrf_gpiote_outinit_t) !m_nrf_fem_control_cfg.pa_cfg.active_high); } if (pin_is_enabled(NRF_FEM_CONTROL_LNA_PIN)) { nrf_gpiote_task_force(m_nrf_fem_control_cfg.lna_gpiote_ch_id, - (nrf_gpiote_outinit_t)!m_nrf_fem_control_cfg.lna_cfg.active_high); + (nrf_gpiote_outinit_t) !m_nrf_fem_control_cfg.lna_cfg.active_high); } } -void nrf_fem_control_timer_set(nrf_fem_control_pin_t pin, +void nrf_fem_control_timer_set(nrf_fem_control_pin_t pin, nrf_timer_cc_channel_t timer_cc_channel, nrf_timer_short_mask_t short_mask) { if (pin_is_enabled(pin)) { uint32_t target_time = nrf_fem_control_delay_get(pin); + nrf_timer_shorts_enable(NRF_FEM_TIMER_INSTANCE, short_mask); nrf_timer_cc_write(NRF_FEM_TIMER_INSTANCE, timer_cc_channel, target_time); } @@ -333,11 +334,13 @@ void nrf_fem_control_ppi_pin_task_setup(nrf_ppi_channel_t ppi_channel, if ((lna_pin_set && m_nrf_fem_control_cfg.lna_cfg.active_high) || (!lna_pin_set && !m_nrf_fem_control_cfg.lna_cfg.active_high)) { - lna_task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.lna_gpiote_ch_id]); + lna_task_addr = + (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.lna_gpiote_ch_id]); } else { - lna_task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.lna_gpiote_ch_id]); + lna_task_addr = + (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.lna_gpiote_ch_id]); } } @@ -346,17 +349,20 @@ void nrf_fem_control_ppi_pin_task_setup(nrf_ppi_channel_t ppi_channel, if ((pa_pin_set && m_nrf_fem_control_cfg.pa_cfg.active_high) || (!pa_pin_set && !m_nrf_fem_control_cfg.pa_cfg.active_high)) { - pa_task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.pa_gpiote_ch_id]); + pa_task_addr = + (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_control_cfg.pa_gpiote_ch_id]); } else { - pa_task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.pa_gpiote_ch_id]); + pa_task_addr = + (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_control_cfg.pa_gpiote_ch_id]); } } if (lna_task_addr != 0 || pa_task_addr != 0) { - nrf_ppi_channel_and_fork_endpoint_setup(ppi_channel, event_addr, lna_task_addr, pa_task_addr); + nrf_ppi_channel_and_fork_endpoint_setup(ppi_channel, event_addr, lna_task_addr, + pa_task_addr); nrf_ppi_channel_enable(ppi_channel); } } diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h index 1653b89d9..1311e1db1 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h @@ -51,22 +51,22 @@ extern "C" { */ /** Default Power Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 26 +#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 15 /** Default Low Noise Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 27 +#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 16 /** Default PPI channel for pin setting. */ -#define NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL 15 +#define NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL 15 /** Default PPI channel for pin clearing. */ -#define NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL 16 +#define NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL 16 /** Default GPIOTE channel for FEM control. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL 6 +#define NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL 6 /** Default GPIOTE channel for FEM control. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL 7 +#define NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL 7 #if ENABLE_FEM @@ -75,9 +75,9 @@ extern "C" { */ typedef struct { - uint8_t enable :1; /**< Enable toggling for this amplifier */ - uint8_t active_high :1; /**< Set the pin to be active high */ - uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ + uint8_t enable : 1; /**< Enable toggling for this amplifier */ + uint8_t active_high : 1; /**< Set the pin to be active high */ + uint8_t gpio_pin : 6; /**< The GPIO pin to toggle for this amplifier */ } nrf_fem_control_pa_lna_cfg_t; /** @@ -94,12 +94,12 @@ typedef struct */ typedef struct { - nrf_fem_control_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ - nrf_fem_control_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ - uint8_t pa_gpiote_ch_id; /**< GPIOTE channel used for Power Amplifier pin toggling */ - uint8_t lna_gpiote_ch_id; /**< GPIOTE channel used for Low Noise Amplifier pin toggling */ - uint8_t ppi_ch_id_set; /**< PPI channel used for radio Power Amplifier and Low Noise Amplifier pins setting */ - uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + nrf_fem_control_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + nrf_fem_control_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + uint8_t pa_gpiote_ch_id; /**< GPIOTE channel used for Power Amplifier pin toggling */ + uint8_t lna_gpiote_ch_id; /**< GPIOTE channel used for Low Noise Amplifier pin toggling */ + uint8_t ppi_ch_id_set; /**< PPI channel used for radio Power Amplifier and Low Noise Amplifier pins setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ } nrf_fem_control_cfg_t; /** @@ -141,7 +141,7 @@ void nrf_fem_control_activate(void); void nrf_fem_control_deactivate(void); /**@brief Configure PPI to activate one of the Front End Module pins on an appropriate timer event. - * + * * @param[in] pin The Front End Module controlled pin to be connected to the PPI. * @param[in] timer_cc_channel Timer CC channel that triggers the @p pin activation through the PPI. * @@ -156,9 +156,9 @@ void nrf_fem_control_ppi_enable(nrf_fem_control_pin_t pin, nrf_timer_cc_channel_ void nrf_fem_control_ppi_disable(nrf_fem_control_pin_t pin); /**@brief Calculate target time for a timer, which activates one of the Front End Module pins. - * + * * @param[in] pin The Front End Module controlled pin to be activated. - * + * * @return @p pin activation delay in microseconds. * */ @@ -170,7 +170,7 @@ uint32_t nrf_fem_control_delay_get(nrf_fem_control_pin_t pin); void nrf_fem_control_pin_clear(void); /**@brief Configure and set a timer for one of the Front End Module pins activation. - * + * * @param[in] pin The Front End Module controlled pin to be activated. * @param[in] timer_cc_channel Timer CC channel to set. * @param[in] short_mask Mask of timer shortcuts to be enabled. @@ -181,7 +181,7 @@ void nrf_fem_control_timer_set(nrf_fem_control_pin_t pin, nrf_timer_short_mask_t short_mask); /**@brief Clear timer configuration after one of the Front End Module pins deactivation. - * + * * @param[in] pin The Front End Module controlled pin that was deactivated. * @param[in] short_mask Mask of timer shortcuts to be disabled. * @@ -189,7 +189,7 @@ void nrf_fem_control_timer_set(nrf_fem_control_pin_t pin, void nrf_fem_control_timer_reset(nrf_fem_control_pin_t pin, nrf_timer_short_mask_t short_mask); /**@brief Setup a PPI fork task necessary for one of the Front End Module pins. - * + * * @param[in] pin The Front End Module controlled pin that was deactivated. * @param[in] ppi_channel PPI channel to connect the fork task to. * @@ -199,7 +199,7 @@ void nrf_fem_control_ppi_fork_setup(nrf_fem_control_pin_t pin, uint32_t task_addr); /**@brief Setup a PPI task necessary for one of the Front End Module pins. - * + * * @param[in] pin The Front End Module controlled pin that was deactivated. * @param[in] ppi_channel PPI channel to connect the task to. * @param[in] event_addr Address of the event to be connected to the PPI. @@ -212,7 +212,7 @@ void nrf_fem_control_ppi_task_setup(nrf_fem_control_pin_t pin, uint32_t task_addr); /**@brief Clear a PPI fork task configuration for one of the Front End Module pins. - * + * * @param[in] pin The Front End Module controlled pin that was deactivated. * @param[in] ppi_channel PPI channel to disconnect the fork task from. * @@ -220,7 +220,7 @@ void nrf_fem_control_ppi_task_setup(nrf_fem_control_pin_t pin, void nrf_fem_control_ppi_fork_clear(nrf_fem_control_pin_t pin, nrf_ppi_channel_t ppi_channel); /**@brief Setup PPI task and fork that set or clear Front End Module pins on a given event. - * + * * @param[in] ppi_channel PPI channel to connect the task and fork to. * @param[in] event_addr Address of the event to be connected to the PPI. * @param[in] lna_pin_set If true, the Low Noise Amplifier pin will be set on the event @p event_addr. @@ -234,7 +234,7 @@ void nrf_fem_control_ppi_pin_task_setup(nrf_ppi_channel_t ppi_channel, bool lna_pin_set, bool pa_pin_set); -#else // ENABLE_FEM +#else // ENABLE_FEM #define nrf_fem_control_cfg_set(...) #define nrf_fem_control_cfg_get(...) @@ -242,7 +242,7 @@ void nrf_fem_control_ppi_pin_task_setup(nrf_ppi_channel_t ppi_channel, #define nrf_fem_control_deactivate(...) #define nrf_fem_control_ppi_enable(...) #define nrf_fem_control_ppi_disable(...) -#define nrf_fem_control_delay_get(...) 1 +#define nrf_fem_control_delay_get(...) 1 #define nrf_fem_control_pin_clear(...) #define nrf_fem_control_timer_set(...) #define nrf_fem_control_timer_reset(...) diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h index 87699a2e2..a4b84ed17 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_config.h @@ -40,10 +40,10 @@ extern "C" { */ /** Time in us when PA GPIO is activated before radio is ready for transmission. */ -#define NRF_FEM_PA_TIME_IN_ADVANCE 23 +#define NRF_FEM_PA_TIME_IN_ADVANCE 23 /** Time in us when LNA GPIO is activated before radio is ready for reception. */ -#define NRF_FEM_LNA_TIME_IN_ADVANCE 5 +#define NRF_FEM_LNA_TIME_IN_ADVANCE 5 #ifdef NRF52840_XXAA diff --git a/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h b/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h index adc3daecc..f44953fea 100644 --- a/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h +++ b/third_party/NordicSemiconductor/drivers/radio/hal/nrf_radio.h @@ -57,7 +57,8 @@ extern "C" { * @enum nrf_radio_task_t * @brief RADIO tasks. */ -typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +/*lint -save -e30 -esym(628,__INTADDR__) */ +typedef enum { NRF_RADIO_TASK_TXEN = offsetof(NRF_RADIO_Type, TASKS_TXEN), /**< Enable radio transmitter. */ NRF_RADIO_TASK_RXEN = offsetof(NRF_RADIO_Type, TASKS_RXEN), /**< Enable radio receiver. */ @@ -69,13 +70,13 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ NRF_RADIO_TASK_EDSTART = offsetof(NRF_RADIO_Type, TASKS_EDSTART), /**< Start Energy Detection procedure. */ NRF_RADIO_TASK_EDSTOP = offsetof(NRF_RADIO_Type, TASKS_EDSTOP), /**< Stop Energy Detection procedure. */ NRF_RADIO_TASK_RSSISTART = offsetof(NRF_RADIO_Type, TASKS_RSSISTART), /**< Start the RSSI and take one single sample of received signal strength. */ -} nrf_radio_task_t; /*lint -restore */ +} nrf_radio_task_t; /** * @enum nrf_radio_event_t * @brief RADIO events. */ -typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +typedef enum { NRF_RADIO_EVENT_READY = offsetof(NRF_RADIO_Type, EVENTS_READY), /**< Radio has ramped up and is ready to be started. */ NRF_RADIO_EVENT_ADDRESS = offsetof(NRF_RADIO_Type, EVENTS_ADDRESS), /**< Address sent or received. */ @@ -93,7 +94,8 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ NRF_RADIO_EVENT_RXREADY = offsetof(NRF_RADIO_Type, EVENTS_RXREADY), /**< Radio has ramped up and is ready to be started RX path. */ NRF_RADIO_EVENT_MHRMATCH = offsetof(NRF_RADIO_Type, EVENTS_MHRMATCH), /**< MAC Header match found. */ NRF_RADIO_EVENT_PHYEND = offsetof(NRF_RADIO_Type, EVENTS_PHYEND), /**< Generated in Ble_LR125Kbit, Ble_LR500Kbit and Ieee802154_250Kbit modes when last bit is sent on air. */ -} nrf_radio_event_t; /*lint -restore */ +} nrf_radio_event_t; +/*lint -restore */ /** * @enum nrf_radio_int_mask_t @@ -222,8 +224,8 @@ typedef enum */ typedef enum { - NRF_RADIO_RAMP_UP_MODE_DEFAULT = RADIO_MODECNF0_RU_Default, /**< Default ramp-up mode. */ - NRF_RADIO_RAMP_UP_MODE_FAST = RADIO_MODECNF0_RU_Fast /**< Fast ramp-up mode. */ + NRF_RADIO_RAMP_UP_MODE_DEFAULT = RADIO_MODECNF0_RU_Default, /**< Default ramp-up mode. */ + NRF_RADIO_RAMP_UP_MODE_FAST = RADIO_MODECNF0_RU_Fast /**< Fast ramp-up mode. */ } nrf_radio_ramp_up_mode_t; /** @@ -257,7 +259,7 @@ __STATIC_INLINE bool nrf_radio_int_get(nrf_radio_int_mask_t radio_int_mask); * * @param[in] radio_task Task. */ -__STATIC_INLINE uint32_t *nrf_radio_task_address_get(nrf_radio_task_t radio_task); +__STATIC_INLINE uint32_t * nrf_radio_task_address_get(nrf_radio_task_t radio_task); /** * @brief Function for setting a specific task. @@ -273,7 +275,7 @@ __STATIC_INLINE void nrf_radio_task_trigger(nrf_radio_task_t radio_task); * * @param[in] radio_event Event. */ -__STATIC_INLINE uint32_t *nrf_radio_event_address_get(nrf_radio_event_t radio_event); +__STATIC_INLINE uint32_t * nrf_radio_event_address_get(nrf_radio_event_t radio_event); /** * @brief Function for clearing a specific event. @@ -334,7 +336,7 @@ __STATIC_INLINE nrf_radio_state_t nrf_radio_state_get(void); * * @param[in] p_radio_packet_ptr Pointer to tx or rx packet buffer. */ -__STATIC_INLINE void nrf_radio_packet_ptr_set(const void *p_radio_packet_ptr); +__STATIC_INLINE void nrf_radio_packet_ptr_set(const void * p_radio_packet_ptr); /** * @brief Function for getting CRC status of last received packet. @@ -532,7 +534,6 @@ __STATIC_INLINE void nrf_radio_ed_loop_count_set(uint32_t radio_ed_loop_count); */ __STATIC_INLINE void nrf_radio_power_set(bool radio_power); - /** *@} **/ @@ -554,7 +555,7 @@ __STATIC_INLINE bool nrf_radio_int_get(nrf_radio_int_mask_t radio_int_mask) return (bool)(NRF_RADIO->INTENCLR & radio_int_mask); } -__STATIC_INLINE uint32_t *nrf_radio_task_address_get(nrf_radio_task_t radio_task) +__STATIC_INLINE uint32_t * nrf_radio_task_address_get(nrf_radio_task_t radio_task) { return (uint32_t *)((uint8_t *)NRF_RADIO + radio_task); } @@ -564,7 +565,7 @@ __STATIC_INLINE void nrf_radio_task_trigger(nrf_radio_task_t radio_task) *((volatile uint32_t *)((uint8_t *)NRF_RADIO + radio_task)) = NRF_RADIO_TASK_SET; } -__STATIC_INLINE uint32_t *nrf_radio_event_address_get(nrf_radio_event_t radio_event) +__STATIC_INLINE uint32_t * nrf_radio_event_address_get(nrf_radio_event_t radio_event) { return (uint32_t *)((uint8_t *)NRF_RADIO + radio_event); } @@ -574,13 +575,14 @@ __STATIC_INLINE void nrf_radio_event_clear(nrf_radio_event_t radio_event) *((volatile uint32_t *)((uint8_t *)NRF_RADIO + radio_event)) = NRF_RADIO_EVENT_CLEAR; #if __CORTEX_M == 0x04 volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_RADIO + radio_event)); + (void)dummy; #endif } __STATIC_INLINE bool nrf_radio_event_get(nrf_radio_event_t radio_event) { - return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_RADIO + radio_event)); + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_RADIO + radio_event)); } __STATIC_INLINE void nrf_radio_shorts_enable(uint32_t radio_short_mask) @@ -605,84 +607,85 @@ __STATIC_INLINE uint32_t nrf_radio_shorts_get(void) __STATIC_INLINE nrf_radio_state_t nrf_radio_state_get(void) { - return (nrf_radio_state_t) NRF_RADIO->STATE; + return (nrf_radio_state_t)NRF_RADIO->STATE; } -__STATIC_INLINE void nrf_radio_packet_ptr_set(const void *p_radio_packet_ptr) +__STATIC_INLINE void nrf_radio_packet_ptr_set(const void * p_radio_packet_ptr) { - NRF_RADIO->PACKETPTR = (uint32_t) p_radio_packet_ptr; + NRF_RADIO->PACKETPTR = (uint32_t)p_radio_packet_ptr; } __STATIC_INLINE nrf_radio_crc_status_t nrf_radio_crc_status_get(void) { - return (nrf_radio_crc_status_t) NRF_RADIO->CRCSTATUS; + return (nrf_radio_crc_status_t)NRF_RADIO->CRCSTATUS; } __STATIC_INLINE void nrf_radio_cca_mode_set(nrf_radio_cca_mode_t radio_cca_mode) { NRF_RADIO->CCACTRL &= (~RADIO_CCACTRL_CCAMODE_Msk); - NRF_RADIO->CCACTRL |= ((uint32_t) radio_cca_mode << RADIO_CCACTRL_CCAMODE_Pos); + NRF_RADIO->CCACTRL |= ((uint32_t)radio_cca_mode << RADIO_CCACTRL_CCAMODE_Pos); } __STATIC_INLINE void nrf_radio_cca_ed_threshold_set(uint8_t radio_cca_ed_threshold) { NRF_RADIO->CCACTRL &= (~RADIO_CCACTRL_CCAEDTHRES_Msk); - NRF_RADIO->CCACTRL |= ((uint32_t) radio_cca_ed_threshold << RADIO_CCACTRL_CCAEDTHRES_Pos); + NRF_RADIO->CCACTRL |= ((uint32_t)radio_cca_ed_threshold << RADIO_CCACTRL_CCAEDTHRES_Pos); } __STATIC_INLINE void nrf_radio_cca_corr_threshold_set(uint8_t radio_cca_corr_threshold_set) { NRF_RADIO->CCACTRL &= (~RADIO_CCACTRL_CCACORRTHRES_Msk); - NRF_RADIO->CCACTRL |= ((uint32_t) radio_cca_corr_threshold_set << RADIO_CCACTRL_CCACORRTHRES_Pos); + NRF_RADIO->CCACTRL |= + ((uint32_t)radio_cca_corr_threshold_set << RADIO_CCACTRL_CCACORRTHRES_Pos); } __STATIC_INLINE void nrf_radio_cca_corr_counter_set(uint8_t radio_cca_corr_counter_set) { NRF_RADIO->CCACTRL &= (~RADIO_CCACTRL_CCACORRCNT_Msk); - NRF_RADIO->CCACTRL |= ((uint32_t) radio_cca_corr_counter_set << RADIO_CCACTRL_CCACORRCNT_Pos); + NRF_RADIO->CCACTRL |= ((uint32_t)radio_cca_corr_counter_set << RADIO_CCACTRL_CCACORRCNT_Pos); } __STATIC_INLINE void nrf_radio_mode_set(nrf_radio_mode_t radio_mode) { - NRF_RADIO->MODE = ((uint32_t) radio_mode << RADIO_MODE_MODE_Pos); + NRF_RADIO->MODE = ((uint32_t)radio_mode << RADIO_MODE_MODE_Pos); } __STATIC_INLINE void nrf_radio_config_length_field_length_set(uint8_t radio_length_length) { NRF_RADIO->PCNF0 &= (~RADIO_PCNF0_LFLEN_Msk); - NRF_RADIO->PCNF0 |= ((uint32_t) radio_length_length << RADIO_PCNF0_LFLEN_Pos); + NRF_RADIO->PCNF0 |= ((uint32_t)radio_length_length << RADIO_PCNF0_LFLEN_Pos); } __STATIC_INLINE void nrf_radio_config_preamble_length_set( nrf_radio_preamble_length_t radio_preamble_length) { NRF_RADIO->PCNF0 &= (~RADIO_PCNF0_PLEN_Msk); - NRF_RADIO->PCNF0 |= ((uint32_t) radio_preamble_length << RADIO_PCNF0_PLEN_Pos); + NRF_RADIO->PCNF0 |= ((uint32_t)radio_preamble_length << RADIO_PCNF0_PLEN_Pos); } __STATIC_INLINE void nrf_radio_config_crc_included_set(bool radio_length_contains_crc) { NRF_RADIO->PCNF0 &= (~RADIO_PCNF0_CRCINC_Msk); - NRF_RADIO->PCNF0 |= ((uint32_t) radio_length_contains_crc << RADIO_PCNF0_CRCINC_Pos); + NRF_RADIO->PCNF0 |= ((uint32_t)radio_length_contains_crc << RADIO_PCNF0_CRCINC_Pos); } __STATIC_INLINE void nrf_radio_config_max_length_set(uint8_t radio_max_packet_length) { NRF_RADIO->PCNF1 &= (~RADIO_PCNF1_MAXLEN_Msk); - NRF_RADIO->PCNF1 |= ((uint32_t) radio_max_packet_length << RADIO_PCNF1_MAXLEN_Pos); + NRF_RADIO->PCNF1 |= ((uint32_t)radio_max_packet_length << RADIO_PCNF1_MAXLEN_Pos); } __STATIC_INLINE void nrf_radio_crc_length_set(uint8_t radio_crc_length) { NRF_RADIO->CRCCNF &= (~RADIO_CRCCNF_LEN_Msk); - NRF_RADIO->CRCCNF |= ((uint32_t) radio_crc_length << RADIO_CRCCNF_LEN_Pos); + NRF_RADIO->CRCCNF |= ((uint32_t)radio_crc_length << RADIO_CRCCNF_LEN_Pos); } __STATIC_INLINE void nrf_radio_crc_includes_address_set( nrf_radio_crc_includes_addr_t radio_crc_skip_address) { NRF_RADIO->CRCCNF &= (~RADIO_CRCCNF_SKIPADDR_Msk); - NRF_RADIO->CRCCNF |= ((uint32_t) radio_crc_skip_address << RADIO_CRCCNF_SKIPADDR_Pos); + NRF_RADIO->CRCCNF |= ((uint32_t)radio_crc_skip_address << RADIO_CRCCNF_SKIPADDR_Pos); } __STATIC_INLINE void nrf_radio_crc_polynominal_set(uint32_t radio_crc_polynominal) @@ -714,7 +717,7 @@ __STATIC_INLINE void nrf_radio_mhmu_pattern_mask_set(uint32_t radio_mhmu_pattern __STATIC_INLINE void nrf_radio_ramp_up_mode_set(nrf_radio_ramp_up_mode_t ramp_up_mode) { NRF_RADIO->MODECNF0 &= (~RADIO_MODECNF0_RU_Msk); - NRF_RADIO->MODECNF0 |= ((uint32_t) ramp_up_mode << RADIO_MODECNF0_RU_Pos); + NRF_RADIO->MODECNF0 |= ((uint32_t)ramp_up_mode << RADIO_MODECNF0_RU_Pos); } __STATIC_INLINE void nrf_radio_frequency_set(uint32_t radio_frequency) @@ -729,7 +732,7 @@ __STATIC_INLINE uint32_t nrf_radio_frequency_get(void) __STATIC_INLINE void nrf_radio_tx_power_set(int8_t radio_tx_power) { - NRF_RADIO->TXPOWER = (uint8_t) radio_tx_power; + NRF_RADIO->TXPOWER = (uint8_t)radio_tx_power; } __STATIC_INLINE void nrf_radio_ifs_set(uint32_t radio_ifs) @@ -754,7 +757,7 @@ __STATIC_INLINE uint32_t nrf_radio_bcc_get(void) __STATIC_INLINE uint8_t nrf_radio_ed_sample_get(void) { - return (uint8_t) NRF_RADIO->EDSAMPLE; + return (uint8_t)NRF_RADIO->EDSAMPLE; } __STATIC_INLINE void nrf_radio_ed_loop_count_set(uint32_t radio_ed_loop_count) @@ -764,7 +767,7 @@ __STATIC_INLINE void nrf_radio_ed_loop_count_set(uint32_t radio_ed_loop_count) __STATIC_INLINE void nrf_radio_power_set(bool radio_power) { - NRF_RADIO->POWER = (uint32_t) radio_power; + NRF_RADIO->POWER = (uint32_t)radio_power; } #endif /* SUPPRESS_INLINE_IMPLEMENTATION */ @@ -774,4 +777,3 @@ __STATIC_INLINE void nrf_radio_power_set(bool radio_power) #endif #endif /* NRF_RADIO_H__ */ - diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.c deleted file mode 100644 index 09ddc1737..000000000 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.c +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements ACK timeout procedure for the 802.15.4 driver. - * - */ - -#include "nrf_802154_ack_timeout.h" - -#include -#include -#include - -#include "nrf_802154_notification.h" -#include "nrf_802154_request.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" - -#define RETRY_DELAY 500 ///< Procedure is delayed by this time if cannot be performed at the moment. -#define MAX_RETRY_DELAY 1000000 ///< Maximal allowed delay of procedure retry. - -static void timeout_timer_retry(void); - -static uint32_t m_timeout = NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT; ///< ACK timeout in us. -static nrf_802154_timer_t m_timer; ///< Timer used to notify when we are waiting too long for ACK. -static volatile bool m_procedure_is_active; -static const uint8_t * mp_frame; - -static void notify_tx_error(bool result) -{ - if (result) - { - nrf_802154_notify_transmit_failed(mp_frame, NRF_802154_TX_ERROR_NO_ACK); - } -} - -static void timeout_timer_fired(void * p_context) -{ - (void)p_context; - - if (m_procedure_is_active) - { - if (nrf_802154_request_receive(NRF_802154_TERM_802154, - REQ_ORIG_ACK_TIMEOUT, - notify_tx_error, - false)) - { - m_procedure_is_active = false; - } - else - { - timeout_timer_retry(); - } - } -} - -static void timeout_timer_retry(void) -{ - m_timer.dt += RETRY_DELAY; - assert(m_timer.dt <= MAX_RETRY_DELAY); - - nrf_802154_timer_sched_add(&m_timer, true); -} - -static void timeout_timer_start(void) -{ - m_timer.callback = timeout_timer_fired; - m_timer.p_context = NULL; - m_timer.t0 = nrf_802154_timer_sched_time_get(); - m_timer.dt = m_timeout; - - m_procedure_is_active = true; - - nrf_802154_timer_sched_add(&m_timer, true); -} - -static void timeout_timer_stop(void) -{ - m_procedure_is_active = false; - - // To make sure `timeout_timer_fired()` detects that procedure is being stopped if it preempts - // this function. - __DMB(); - - nrf_802154_timer_sched_remove(&m_timer); -} - -void nrf_802154_ack_timeout_time_set(uint32_t time) -{ - m_timeout = time; -} - -bool nrf_802154_ack_timeout_tx_started_hook(const uint8_t * p_frame) -{ - mp_frame = p_frame; - timeout_timer_start(); - - return true; -} - -bool nrf_802154_ack_timeout_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) -{ - bool result; - - if (!m_procedure_is_active || req_orig == REQ_ORIG_ACK_TIMEOUT) - { - // Ignore if procedure is not running or self-request. - result = true; - } - else if (term_lvl >= NRF_802154_TERM_802154) - { - // Stop procedure only if termination level is high enough. - timeout_timer_stop(); - - result = true; - } - else - { - result = false; - } - - return result; -} - -void nrf_802154_ack_timeout_transmitted_hook(const uint8_t * p_frame) -{ - assert((p_frame == mp_frame) || (!m_procedure_is_active)); - - timeout_timer_stop(); -} - -bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_error_t error) -{ - (void)error; - assert((p_frame == mp_frame) || (!m_procedure_is_active)); - - timeout_timer_stop(); - - return true; -} diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h index 7712d0dfd..95102fc8a 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h @@ -46,7 +46,7 @@ /** * @brief Set timeout time for ACK timeout feature. - * + * * @param[in] time Timeout time in us. * Default value is defined in nrf_802154_config.h. */ @@ -83,7 +83,6 @@ void nrf_802154_ack_timeout_transmitted_hook(const uint8_t * p_frame); */ bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_error_t error); - /** * @brief Handler of TX started event. * diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c index 29fc0bf43..4c0f5a6f9 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c @@ -50,12 +50,12 @@ #if NRF_802154_CSMA_CA_ENABLED -static uint8_t m_nb; ///< The number of times the CSMA-CA algorithm was required to back off while attempting the current transmission. -static uint8_t m_be; ///< Backoff exponent, which is related to how many backoff periods a device shall wait before attempting to assess a channel. +static uint8_t m_nb; ///< The number of times the CSMA-CA algorithm was required to back off while attempting the current transmission. +static uint8_t m_be; ///< Backoff exponent, which is related to how many backoff periods a device shall wait before attempting to assess a channel. -static const uint8_t * mp_psdu; ///< Pointer to PSDU of the frame being transmitted. -static nrf_802154_timer_t m_timer; ///< Timer used to back off during CSMA-CA procedure. -static bool m_is_running; ///< Indicates if CSMA-CA procedure is running. +static const uint8_t * mp_psdu; ///< Pointer to PSDU of the frame being transmitted. +static nrf_802154_timer_t m_timer; ///< Timer used to back off during CSMA-CA procedure. +static bool m_is_running; ///< Indicates if CSMA-CA procedure is running. /** * @brief Perform appropriate actions for busy channel conditions. diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.c index fb5e34f8d..11bd191c5 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.c @@ -47,30 +47,55 @@ #include "nrf_802154_procedures_duration.h" #include "nrf_802154_request.h" #include "nrf_802154_rsch.h" +#include "timer_scheduler/nrf_802154_timer_sched.h" -#define TX_SETUP_TIME 190 ///< Time [us] needed to change channel, stop rx and setup tx procedure. +#define TX_SETUP_TIME 190u ///< Time [us] needed to change channel, stop rx and setup tx procedure. +#define RX_SETUP_TIME 190u ///< Time [us] needed to change channel, stop tx and setup rx procedure. -static const uint8_t * mp_tx_psdu; ///< Pointer to PHR + PSDU of the frame requested to transmit. -static bool m_tx_cca; ///< If CCA should be performed prior to transmission. -static uint8_t m_tx_channel; ///< Channel number on which transmission should be performed. +static const uint8_t * mp_tx_psdu; ///< Pointer to PHR + PSDU of the frame requested to transmit. +static bool m_tx_cca; ///< If CCA should be performed prior to transmission. +static uint8_t m_tx_channel; ///< Channel number on which transmission should be performed. + +static nrf_802154_timer_t m_timeout_timer; ///< Timer for delayed RX timeout handling. +static uint8_t m_rx_channel; ///< Channel number on which reception should be performed. + +static bool m_dly_op_in_progress[RSCH_DLY_TS_NUM]; ///< Status of delayed operation. /** - * Check if delayed transmission procedure is in progress. + * Start delayed timeslot operation. * - * @retval true Delayed transmission is in progress (waiting or transmitting). - * @retval false Delayed transmission is not in progress. + * @param[in] dly_ts_id Delayed timeslot ID. */ -static bool tx_is_in_progress(void) +static void dly_op_start(rsch_dly_ts_id_t dly_ts_id) { - return mp_tx_psdu != NULL; + assert(dly_ts_id < RSCH_DLY_TS_NUM); + + m_dly_op_in_progress[dly_ts_id] = true; } /** - * Mark that delayed transmission procedure has stopped. + * Stop delayed timeslot operation. + * + * @param[in] dly_ts_id Delayed timeslot ID. */ -static void tx_stop(void) +static void dly_op_stop(rsch_dly_ts_id_t dly_ts_id) { - mp_tx_psdu = NULL; + assert(dly_ts_id < RSCH_DLY_TS_NUM); + + m_dly_op_in_progress[dly_ts_id] = false; +} + +/** + * Check if delayed operation is in progress. + * + * @retval true Delayed operation is in progress (waiting or ongoing). + * @retval false Delayed operation is not in progress. + */ +bool dly_op_is_in_progress(rsch_dly_ts_id_t dly_ts_id) +{ + assert(dly_ts_id < RSCH_DLY_TS_NUM); + + return m_dly_op_in_progress[dly_ts_id]; } /** @@ -86,6 +111,98 @@ static void notify_tx_timeslot_denied(bool result) } } +/** + * Notify MAC layer that requested timeslot is not granted if rx request failed. + * + * @param[in] result Result of RX request. + */ +static void notify_rx_timeslot_denied(bool result) +{ + if (!result) + { + nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED); + } +} + +/** + * Notify MAC layer that no frame was received before timeout. + * + * @param[in] p_context Not used. + */ +static void notify_rx_timeout(void * p_context) +{ + (void)p_context; + + dly_op_stop(RSCH_DLY_RX); + nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_DELAYED_TIMEOUT); +} + +/** + * Handle TX timeslot start. + */ +static void nrf_802154_rsch_delayed_tx_timeslot_started(void) +{ + bool result; + + assert(dly_op_is_in_progress(RSCH_DLY_TX)); + + nrf_802154_pib_channel_set(m_tx_channel); + result = nrf_802154_request_channel_update(); + + if (result) + { + result = nrf_802154_request_transmit(NRF_802154_TERM_802154, + REQ_ORIG_DELAYED_TRX, + mp_tx_psdu, + m_tx_cca, + true, + notify_tx_timeslot_denied); + (void)result; + } + else + { + notify_tx_timeslot_denied(result); + } + + dly_op_stop(RSCH_DLY_TX); +} + +/** + * Handle RX timeslot start. + */ +static void nrf_802154_rsch_delayed_rx_timeslot_started(void) +{ + bool result; + + assert(dly_op_is_in_progress(RSCH_DLY_RX)); + + nrf_802154_pib_channel_set(m_rx_channel); + result = nrf_802154_request_channel_update(); + + if (result) + { + result = nrf_802154_request_receive(NRF_802154_TERM_802154, + REQ_ORIG_DELAYED_TRX, + notify_rx_timeslot_denied, + true); + if (result) + { + m_timeout_timer.t0 = nrf_802154_timer_sched_time_get(); + + nrf_802154_timer_sched_add(&m_timeout_timer, true); + } + else + { + dly_op_stop(RSCH_DLY_RX); + } + } + else + { + notify_rx_timeslot_denied(result); + dly_op_stop(RSCH_DLY_RX); + } +} + bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, bool cca, uint32_t t0, @@ -95,7 +212,7 @@ bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, bool result = true; uint16_t timeslot_length; - if (tx_is_in_progress()) + if (dly_op_is_in_progress(RSCH_DLY_TX)) { result = false; } @@ -118,50 +235,131 @@ bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, cca, p_data[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT); - result = nrf_802154_rsch_delayed_timeslot_request(t0, dt, timeslot_length); + dly_op_start(RSCH_DLY_TX); + result = nrf_802154_rsch_delayed_timeslot_request(t0, + dt, + timeslot_length, + RSCH_PRIO_MAX, + RSCH_DLY_TX); if (!result) { notify_tx_timeslot_denied(result); - tx_stop(); + dly_op_stop(RSCH_DLY_TX); } } return result; } -void nrf_802154_rsch_delayed_timeslot_started(void) +bool nrf_802154_delayed_trx_receive(uint32_t t0, + uint32_t dt, + uint32_t timeout, + uint8_t channel) { bool result; - assert(tx_is_in_progress()); - - nrf_802154_pib_channel_set(m_tx_channel); - result = nrf_802154_request_channel_update(); + result = !dly_op_is_in_progress(RSCH_DLY_RX); if (result) { - result = nrf_802154_request_transmit(NRF_802154_TERM_802154, - REQ_ORIG_DELAYED_TRX, - mp_tx_psdu, - m_tx_cca, - true, - notify_tx_timeslot_denied); - (void)result; + dt -= RX_SETUP_TIME; + dt -= RX_RAMP_UP_TIME; + + dly_op_start(RSCH_DLY_RX); + result = nrf_802154_rsch_delayed_timeslot_request(t0, + dt, + timeout + + nrf_802154_rx_duration_get(MAX_PACKET_SIZE, + true), + RSCH_PRIO_MAX, + RSCH_DLY_RX); + + if (result) + { + m_timeout_timer.dt = timeout; + m_timeout_timer.callback = notify_rx_timeout; + m_timeout_timer.p_context = NULL; + + m_rx_channel = channel; + + } + else + { + notify_rx_timeslot_denied(result); + dly_op_stop(RSCH_DLY_RX); + } + } + + return result; +} + +void nrf_802154_rsch_delayed_timeslot_started(rsch_dly_ts_id_t dly_ts_id) +{ + switch (dly_ts_id) + { + case RSCH_DLY_TX: + nrf_802154_rsch_delayed_tx_timeslot_started(); + break; + + case RSCH_DLY_RX: + nrf_802154_rsch_delayed_rx_timeslot_started(); + break; + + default: + assert(false); + } +} + +void nrf_802154_rsch_delayed_timeslot_failed(rsch_dly_ts_id_t dly_ts_id) +{ + assert(dly_ts_id < RSCH_DLY_TS_NUM); + assert(dly_op_is_in_progress(dly_ts_id)); + + if (RSCH_DLY_TX == dly_ts_id) + { + notify_tx_timeslot_denied(false); } else { - notify_tx_timeslot_denied(result); + notify_rx_timeslot_denied(false); } - tx_stop(); + dly_op_stop(dly_ts_id); } -void nrf_802154_rsch_delayed_timeslot_failed(void) +bool nrf_802154_delayed_trx_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) { - assert(tx_is_in_progress()); + bool result = true; - notify_tx_timeslot_denied(false); + if (!dly_op_is_in_progress(RSCH_DLY_RX)) + { + // No active procedures, just return true. + } + else if ((REQ_ORIG_HIGHER_LAYER == req_orig) || (term_lvl >= NRF_802154_TERM_802154)) + { + nrf_802154_timer_sched_remove(&m_timeout_timer); + dly_op_stop(RSCH_DLY_RX); + } + else + { + result = false; + } - tx_stop(); + return result; +} + +void nrf_802154_delayed_trx_rx_started_hook(void) +{ + if (dly_op_is_in_progress(RSCH_DLY_RX)) + { + if (nrf_802154_timer_sched_remaining_time_get(&m_timeout_timer) + < nrf_802154_rx_duration_get(MAX_PACKET_SIZE, true)) + { + m_timeout_timer.t0 = nrf_802154_timer_sched_time_get(); + m_timeout_timer.dt = nrf_802154_rx_duration_get(MAX_PACKET_SIZE, true); + + nrf_802154_timer_sched_add(&m_timeout_timer, true); + } + } } diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.h index aebc5df07..f88d93ef1 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.h @@ -60,8 +60,8 @@ * * @param[in] p_data Pointer to array containing data to transmit (PHR + PSDU). * @param[in] cca If the driver should perform CCA procedure before transmission. - * @param[in] t0 Base of delay time. - * @param[in] dt Delta of delay time from @p t0. + * @param[in] t0 Base of delay time [us]. + * @param[in] dt Delta of delay time from @p t0 [us]. * @param[in] channel Number of channel on which the frame should be transmitted. */ bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, @@ -70,6 +70,47 @@ bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, uint32_t dt, uint8_t channel); +/** + *@} + **/ + +/** + * @brief Request reception of a frame at given time. + * + * If the requested is accepted and a frame is received during defined time slot + * @ref nrf_802154_received is called. If the request is rejected due to denied timeslot request + * or reception timeout expired the @ref nrf_802154_receive_failed function is called. + * + * @param[in] t0 Base of delay time [us]. + * @param[in] dt Delta of delay time from @p t0 [us]. + * @param[in] timeout Reception timeout (counted from @p t0 + @p dt) [us]. + * @param[in] channel Number of channel on which the frame should be received. + */ +bool nrf_802154_delayed_trx_receive(uint32_t t0, + uint32_t dt, + uint32_t timeout, + uint8_t channel); + +/** + * @brief Abort started delayed transmit/receive procedure. + * + * @param[in] term_lvl Termination level set by request aborting ongoing operation. + * @param[in] req_orig Module that originates this request. + * + * If delayed transmit/receive procedure are not running during call, this function does nothing. + * + * @retval true transmit/receive procedures have been stopped. + */ +bool nrf_802154_delayed_trx_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig); + +/** + * @brief Extends timeout timer when reception start is detected and there is not enough time + * left for delayed RX operation. + * + * If delayed transmit/receive procedure are not running during call, this function does nothing. + */ +void nrf_802154_delayed_trx_rx_started_hook(void); + /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c index 87b75ea41..5fc56d1d5 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c @@ -153,12 +153,12 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006(const uint8_t * { case DEST_ADDR_TYPE_SHORT: *p_num_bytes = SHORT_ADDR_CHECK_OFFSET; - result = NRF_802154_RX_ERROR_NONE; + result = NRF_802154_RX_ERROR_NONE; break; case DEST_ADDR_TYPE_EXTENDED: *p_num_bytes = EXTENDED_ADDR_CHECK_OFFSET; - result = NRF_802154_RX_ERROR_NONE; + result = NRF_802154_RX_ERROR_NONE; break; case DEST_ADDR_TYPE_NONE: @@ -168,12 +168,12 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006(const uint8_t * { case SRC_ADDR_TYPE_SHORT: *p_num_bytes = SHORT_ADDR_CHECK_OFFSET; - result = NRF_802154_RX_ERROR_NONE; + result = NRF_802154_RX_ERROR_NONE; break; case SRC_ADDR_TYPE_EXTENDED: *p_num_bytes = EXTENDED_ADDR_CHECK_OFFSET; - result = NRF_802154_RX_ERROR_NONE; + result = NRF_802154_RX_ERROR_NONE; break; default: @@ -363,7 +363,7 @@ static bool dst_short_addr_check(const uint8_t * p_psdu) * @retval true Destination address of incoming frame allows further processing of the frame. * @retval false Destination address of incoming frame does not allow further processing. */ -static bool dst_extended_addr_check(const uint8_t *p_psdu) +static bool dst_extended_addr_check(const uint8_t * p_psdu) { bool result; @@ -400,8 +400,7 @@ nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8 { if (p_psdu[0] < IMM_ACK_LENGTH || p_psdu[0] > MAX_PACKET_SIZE) { - // Frame length is invalid - result = NRF_802154_RX_ERROR_INVALID_FRAME; + result = NRF_802154_RX_ERROR_INVALID_LENGTH; break; } @@ -432,7 +431,7 @@ nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8 } result = dst_short_addr_check(p_psdu) ? NRF_802154_RX_ERROR_NONE : - NRF_802154_RX_ERROR_INVALID_DEST_ADDR; + NRF_802154_RX_ERROR_INVALID_DEST_ADDR; break; case EXTENDED_ADDR_CHECK_OFFSET: @@ -443,7 +442,7 @@ nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8 } result = dst_extended_addr_check(p_psdu) ? NRF_802154_RX_ERROR_NONE : - NRF_802154_RX_ERROR_INVALID_DEST_ADDR; + NRF_802154_RX_ERROR_INVALID_DEST_ADDR; break; default: diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.h index 434d3247b..639a98486 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.h @@ -48,7 +48,6 @@ * @brief Procedures used to discard incoming frames that contain unexpected data in PHR or MHR. */ - /** * @brief Verify if given part of the frame is valid. * @@ -75,4 +74,3 @@ nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8_t * p_num_bytes); #endif /* NRF_802154_FILTER_H_ */ - diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c index 79d75b223..ca7383db7 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c @@ -45,13 +45,13 @@ #include "nrf_802154_request.h" #include "timer_scheduler/nrf_802154_timer_sched.h" -#define RETRY_DELAY 500 ///< Procedure is delayed by this time if it cannot be performed at the moment [us]. -#define MAX_RETRY_DELAY 1000000 ///< Maximum allowed delay of procedure retry [us]. +#define RETRY_DELAY 500 ///< Procedure is delayed by this time if it cannot be performed at the moment [us]. +#define MAX_RETRY_DELAY 1000000 ///< Maximum allowed delay of procedure retry [us]. static void timeout_timer_retry(void); -static uint32_t m_timeout = NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT; ///< ACK timeout in us. -static nrf_802154_timer_t m_timer; ///< Timer used to notify when the ACK frama is not received for too long. +static uint32_t m_timeout = NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT; ///< ACK timeout in us. +static nrf_802154_timer_t m_timer; ///< Timer used to notify when the ACK frama is not received for too long. static volatile bool m_procedure_is_active; static const uint8_t * mp_frame; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c index ab1eecf86..4cc86b40a 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c @@ -54,6 +54,7 @@ #include "nrf_802154_request.h" #include "nrf_802154_revision.h" #include "nrf_802154_rsch.h" +#include "nrf_802154_rsch_crit_sect.h" #include "nrf_802154_rssi.h" #include "nrf_802154_rx_buffer.h" #include "nrf_802154_timer_coord.h" @@ -97,6 +98,7 @@ static void tx_buffer_fill(const uint8_t * p_data, uint8_t length) m_tx_buffer[RAW_LENGTH_OFFSET] = length + FCS_SIZE; memcpy(&m_tx_buffer[RAW_PAYLOAD_OFFSET], p_data, length); } + #endif // !NRF_802154_USE_RAW_API /** @@ -129,7 +131,7 @@ static uint32_t last_rx_frame_timestamp_get(void) return timestamp; #else // NRF_802154_FRAME_TIMESTAMP_ENABLED return NRF_802154_NO_TIMESTAMP; -#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED +#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED } void nrf_802154_channel_set(uint8_t channel) @@ -192,6 +194,7 @@ uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm) uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t psdu_length) { uint32_t frame_symbols = PHY_SHR_SYMBOLS; + frame_symbols += (PHR_SIZE + psdu_length) * PHY_SYMBOLS_PER_OCTET; return end_timestamp - (frame_symbols * PHY_US_PER_SYMBOL); @@ -210,6 +213,7 @@ void nrf_802154_init(void) nrf_802154_priority_drop_init(); nrf_802154_request_init(); nrf_802154_revision_init(); + nrf_802154_rsch_crit_sect_init(); nrf_802154_rsch_init(); nrf_802154_rx_buffer_init(); nrf_802154_temperature_init(); @@ -233,6 +237,7 @@ void nrf_802154_radio_irq_handler(void) { nrf_802154_core_irq_handler(); } + #endif // !NRF_802154_INTERNAL_RADIO_IRQ_HANDLING #if ENABLE_FEM @@ -245,33 +250,34 @@ void nrf_802154_fem_control_cfg_get(nrf_802154_fem_control_cfg_t * p_cfg) { nrf_fem_control_cfg_get(p_cfg); } + #endif // ENABLE_FEM nrf_802154_state_t nrf_802154_state_get(void) { switch (nrf_802154_core_state_get()) { - case RADIO_STATE_SLEEP: - case RADIO_STATE_FALLING_ASLEEP: - return NRF_802154_STATE_SLEEP; + case RADIO_STATE_SLEEP: + case RADIO_STATE_FALLING_ASLEEP: + return NRF_802154_STATE_SLEEP; - case RADIO_STATE_RX: - case RADIO_STATE_TX_ACK: - return NRF_802154_STATE_RECEIVE; + case RADIO_STATE_RX: + case RADIO_STATE_TX_ACK: + return NRF_802154_STATE_RECEIVE; - case RADIO_STATE_CCA_TX: - case RADIO_STATE_TX: - case RADIO_STATE_RX_ACK: - return NRF_802154_STATE_TRANSMIT; + case RADIO_STATE_CCA_TX: + case RADIO_STATE_TX: + case RADIO_STATE_RX_ACK: + return NRF_802154_STATE_TRANSMIT; - case RADIO_STATE_ED: - return NRF_802154_STATE_ENERGY_DETECTION; + case RADIO_STATE_ED: + return NRF_802154_STATE_ENERGY_DETECTION; - case RADIO_STATE_CCA: - return NRF_802154_STATE_CCA; + case RADIO_STATE_CCA: + return NRF_802154_STATE_CCA; - case RADIO_STATE_CONTINUOUS_CARRIER: - return NRF_802154_STATE_CONTINUOUS_CARRIER; + case RADIO_STATE_CONTINUOUS_CARRIER: + return NRF_802154_STATE_CONTINUOUS_CARRIER; } return NRF_802154_STATE_INVALID; @@ -280,6 +286,7 @@ nrf_802154_state_t nrf_802154_state_get(void) bool nrf_802154_sleep(void) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_SLEEP); result = nrf_802154_request_sleep(NRF_802154_TERM_802154); @@ -291,10 +298,13 @@ bool nrf_802154_sleep(void) nrf_802154_sleep_error_t nrf_802154_sleep_if_idle(void) { nrf_802154_sleep_error_t result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_SLEEP); - - result = nrf_802154_request_sleep(NRF_802154_TERM_NONE) ? NRF_802154_SLEEP_ERROR_NONE : NRF_802154_SLEEP_ERROR_BUSY; - + + result = + nrf_802154_request_sleep(NRF_802154_TERM_NONE) ? NRF_802154_SLEEP_ERROR_NONE : + NRF_802154_SLEEP_ERROR_BUSY; + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_SLEEP); return result; } @@ -302,6 +312,7 @@ nrf_802154_sleep_error_t nrf_802154_sleep_if_idle(void) bool nrf_802154_receive(void) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RECEIVE); result = nrf_802154_request_receive(NRF_802154_TERM_802154, REQ_ORIG_HIGHER_LAYER, NULL, true); @@ -314,6 +325,7 @@ bool nrf_802154_receive(void) bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT); result = nrf_802154_request_transmit(NRF_802154_TERM_NONE, @@ -332,6 +344,7 @@ bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca) bool nrf_802154_transmit(const uint8_t * p_data, uint8_t length, bool cca) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT); tx_buffer_fill(p_data, length); @@ -355,6 +368,7 @@ bool nrf_802154_transmit_raw_at(const uint8_t * p_data, uint8_t channel) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT_AT); result = nrf_802154_delayed_trx_transmit(p_data, cca, t0, dt, channel); @@ -363,9 +377,25 @@ bool nrf_802154_transmit_raw_at(const uint8_t * p_data, return result; } +bool nrf_802154_receive_at(uint32_t t0, + uint32_t dt, + uint32_t timeout, + uint8_t channel) +{ + bool result; + + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RECEIVE_AT); + + result = nrf_802154_delayed_trx_receive(t0, dt, timeout, channel); + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RECEIVE_AT); + return result; +} + bool nrf_802154_energy_detection(uint32_t time_us) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_ENERGY_DETECTION); result = nrf_802154_request_energy_detection(NRF_802154_TERM_NONE, time_us); @@ -377,6 +407,7 @@ bool nrf_802154_energy_detection(uint32_t time_us) bool nrf_802154_cca(void) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CCA); result = nrf_802154_request_cca(NRF_802154_TERM_NONE); @@ -388,6 +419,7 @@ bool nrf_802154_cca(void) bool nrf_802154_continuous_carrier(void) { bool result; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CONTINUOUS_CARRIER); result = nrf_802154_request_continuous_carrier(NRF_802154_TERM_NONE); @@ -470,11 +502,11 @@ bool nrf_802154_buffer_free_immediately(uint8_t * p_data) int8_t nrf_802154_rssi_last_get(void) { - uint8_t minus_dbm = nrf_radio_rssi_sample_get(); + uint8_t negative_dbm = nrf_radio_rssi_sample_get(); - minus_dbm = nrf_802154_rssi_sample_corrected_get(minus_dbm); + negative_dbm = nrf_802154_rssi_sample_corrected_get(negative_dbm); - return - (int8_t)minus_dbm; + return -(int8_t)negative_dbm; } bool nrf_802154_promiscuous_get(void) @@ -619,6 +651,7 @@ __WEAK void nrf_802154_received_timestamp(uint8_t * p_data, nrf_802154_buffer_free(p_data); } + #endif // !NRF_802154_USE_RAW_API __WEAK void nrf_802154_receive_failed(nrf_802154_rx_error_t error) @@ -690,8 +723,8 @@ __WEAK void nrf_802154_transmitted_timestamp(const uint8_t * p_frame, nrf_802154_buffer_free(p_ack); } } -#endif // NRF_802154_USE_RAW_API +#endif // NRF_802154_USE_RAW_API __WEAK void nrf_802154_transmit_failed(const uint8_t * p_frame, nrf_802154_tx_error_t error) { diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h index 9f18775de..691f4488b 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h @@ -128,22 +128,22 @@ int8_t nrf_802154_tx_power_get(void); typedef nrf_fem_control_cfg_t nrf_802154_fem_control_cfg_t; /** Macro with default configuration of the FEM module. */ -#define NRF_802154_FEM_DEFAULT_SETTINGS \ - ((nrf_802154_fem_control_cfg_t) { \ - .pa_cfg = { \ - .enable = 1, \ - .active_high = 1, \ - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_PA_PIN, \ - }, \ - .lna_cfg = { \ - .enable = 1, \ - .active_high = 1, \ - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_LNA_PIN, \ - }, \ - .pa_gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL, \ - .lna_gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL, \ - .ppi_ch_id_set = NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL, \ - .ppi_ch_id_clr = NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL, \ +#define NRF_802154_FEM_DEFAULT_SETTINGS \ + ((nrf_802154_fem_control_cfg_t) { \ + .pa_cfg = { \ + .enable = 1, \ + .active_high = 1, \ + .gpio_pin = NRF_FEM_CONTROL_DEFAULT_PA_PIN, \ + }, \ + .lna_cfg = { \ + .enable = 1, \ + .active_high = 1, \ + .gpio_pin = NRF_FEM_CONTROL_DEFAULT_LNA_PIN, \ + }, \ + .pa_gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL, \ + .lna_gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL, \ + .ppi_ch_id_set = NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL, \ + .ppi_ch_id_clr = NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL, \ }) /** @@ -166,9 +166,8 @@ void nrf_802154_fem_control_cfg_get(nrf_802154_fem_control_cfg_t * p_cfg); #endif // ENABLE_FEM - /** - * @} + * @} * @defgroup nrf_802154_addresses Setting addresses and PAN ID of the device * @{ */ @@ -180,7 +179,7 @@ void nrf_802154_fem_control_cfg_get(nrf_802154_fem_control_cfg_t * p_cfg); * * This function makes a copy of the PAN ID. */ -void nrf_802154_pan_id_set(const uint8_t *p_pan_id); +void nrf_802154_pan_id_set(const uint8_t * p_pan_id); /** * @brief Set the extended address of the device. @@ -189,7 +188,7 @@ void nrf_802154_pan_id_set(const uint8_t *p_pan_id); * * This function makes a copy of the address. */ -void nrf_802154_extended_address_set(const uint8_t *p_extended_address); +void nrf_802154_extended_address_set(const uint8_t * p_extended_address); /** * @brief Set the short address of the device. @@ -198,8 +197,7 @@ void nrf_802154_extended_address_set(const uint8_t *p_extended_address); * * This function makes a copy of the address. */ -void nrf_802154_short_address_set(const uint8_t *p_short_address); - +void nrf_802154_short_address_set(const uint8_t * p_short_address); /** * @} @@ -236,7 +234,6 @@ uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm); */ uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t psdu_length); - /** * @} * @defgroup nrf_802154_transitions Functions to request FSM transitions and check current state @@ -290,11 +287,36 @@ nrf_802154_sleep_error_t nrf_802154_sleep_if_idle(void); */ bool nrf_802154_receive(void); +/** + * @brief Request reception at specified time. + * + * This function works as delayed version of the @sref nrf_802154_receive. It is not + * blocking, but queues delayed reception using Radio Scheduler module. If delayed reception + * cannot be performed (the @ref nrf_802154_receive_at would return false) or requested + * reception timeslot is denied, the @ref nrf_drv_radio802154_receive_failed with the + * @ref NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED argument is called. + * + * If the requested reception time is in the past, the function returns false and does not + * schedule reception. + * + * @param[in] t0 Base of delay time - absolute time used by the Timer Scheduler [us]. + * @param[in] dt Delta of delay time from @p t0 [us]. + * @param[in] timeout Reception timeout (counted from @p t0 + @p dt) [us]. + * @param[in] channel Radio channel on which the frame should be received. + * + * @retval true If the transmission procedure was scheduled. + * @retval false If the driver could not schedule the transmission procedure. + */ +bool nrf_802154_receive_at(uint32_t t0, + uint32_t dt, + uint32_t timeout, + uint8_t channel); + #if NRF_802154_USE_RAW_API /** * @brief Change radio state to transmit. * - * @note If the CPU is halted or interrupted while this function is executed, + * @note If the CPU is halted or interrupted while this function is executed, * @ref nrf_802154_transmitted or @ref nrf_802154_transmit_failed may be called before this * function returns a result. * @note This function is implemented in zero-copy fashion. It passes the given buffer pointer to @@ -334,7 +356,7 @@ bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca); /** * @brief Change radio state to transmit. * - * @note If the CPU is halted or interrupted while this function is executed, + * @note If the CPU is halted or interrupted while this function is executed, * @ref nrf_802154_transmitted or @ref nrf_802154_transmit_failed must be called before this * function returns a result. * @note This function copies the given buffer. It maintains an internal buffer, which is used to @@ -455,7 +477,6 @@ bool nrf_802154_cca(void); */ bool nrf_802154_continuous_carrier(void); - /** * @} * @defgroup nrf_802154_calls Calls to higher layer @@ -586,7 +607,7 @@ extern void nrf_802154_receive_failed(nrf_802154_rx_error_t error); * @brief Notify that transmitting a frame has started. * * @note Usually, @ref nrf_802154_transmitted is called shortly after this function. - * However, if the transmit procedure is interrupted, it might happen that + * However, if the transmit procedure is interrupted, it might happen that * @ref nrf_802154_transmitted is not called. * @note This function should be very short to prevent dropping frames by the driver. * @@ -694,7 +715,7 @@ extern void nrf_802154_transmitted(const uint8_t * p_frame, * * @param[in] p_frame Pointer to the buffer containing PSDU of the transmitted frame. * @param[in] p_ack Pointer to the buffer containing the received ACK payload (PHR excluding FCS). - * If ACK was not requested, @p p_ack is set to NULL. + * If ACK was not requested, @p p_ack is set to NULL. * @param[in] length Length of the received ACK payload. * @param[in] power RSSI of received frame or 0 if ACK was not requested. * @param[in] lqi LQI of received frame or 0 if ACK was not requested. @@ -753,7 +774,6 @@ extern void nrf_802154_cca_done(bool channel_free); */ extern void nrf_802154_cca_failed(nrf_802154_cca_error_t error); - /** * @} * @defgroup nrf_802154_memman Driver memory management @@ -822,7 +842,6 @@ bool nrf_802154_buffer_free_immediately(uint8_t * p_data); #endif // NRF_802154_USE_RAW_API - /** * @} * @defgroup nrf_802154_rssi RSSI measurement function @@ -846,7 +865,6 @@ void nrf_802154_rssi_measure(void); */ int8_t nrf_802154_rssi_last_get(void); - /** * @} * @defgroup nrf_802154_prom Promiscuous mode @@ -876,7 +894,6 @@ void nrf_802154_promiscuous_set(bool enabled); */ bool nrf_802154_promiscuous_get(void); - /** * @} * @defgroup nrf_802154_autoack Auto ACK management @@ -958,7 +975,7 @@ void nrf_802154_auto_pending_bit_set(bool enabled); * @retval True If the address is successfully added to the list. * @retval False If there is not enough memory to store the address in the list. */ -bool nrf_802154_pending_bit_for_addr_set(const uint8_t *p_addr, bool extended); +bool nrf_802154_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended); /** * @brief Remove address of a peer node for which there is no more pending data in the buffer. @@ -969,7 +986,7 @@ bool nrf_802154_pending_bit_for_addr_set(const uint8_t *p_addr, bool extended); * @retval True If the address is successfully removed from the list. * @retval False If there is no such address in the list. */ -bool nrf_802154_pending_bit_for_addr_clear(const uint8_t *p_addr, bool extended); +bool nrf_802154_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended); /** * @brief Remove all addresses of a given type from the pending bit list. @@ -1063,9 +1080,9 @@ void nrf_802154_transmit_csma_ca(const uint8_t * p_data, uint8_t length); /** * @brief Set timeout for the ACK timeout feature. - * + * * A timeout is notified by @ref nrf_802154_transmit_failed. - * + * * @param[in] time Timeout in us. * A default value is defined in nrf_802154_config.h. */ diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c index b02083550..79d20b787 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c @@ -50,9 +50,9 @@ /// Maximum number of Extended Addresses of nodes for which there is pending data in buffer. #define NUM_PENDING_EXTENDED_ADDRESSES NRF_802154_PENDING_EXTENDED_ADDRESSES /// Value used to mark Short Address as unused. -#define UNUSED_PENDING_SHORT_ADDRESS ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff}) +#define UNUSED_PENDING_SHORT_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff}) /// Value used to mark Extended Address as unused. -#define UNUSED_PENDING_EXTENDED_ADDRESS ((uint8_t [EXTENDED_ADDRESS_SIZE]) {0}) +#define UNUSED_PENDING_EXTENDED_ADDRESS ((uint8_t[EXTENDED_ADDRESS_SIZE]) {0}) /// If pending bit in ACK frame should be set to valid or default value. static bool m_setting_pending_bit_enabled; @@ -139,7 +139,9 @@ static int8_t short_addr_compare(const uint8_t * p_first_addr, const uint8_t * p * @retval 0 First address is equal to the second address. * @retval 1 First address is greater than the second address. */ -static int8_t addr_compare(const uint8_t * p_first_addr, const uint8_t * p_second_addr, bool extended) +static int8_t addr_compare(const uint8_t * p_first_addr, + const uint8_t * p_second_addr, + bool extended) { if (extended) { @@ -258,12 +260,15 @@ static bool addr_index_find(const uint8_t * p_addr, */ static bool addr_add(const uint8_t * p_addr, uint8_t location, bool extended) { - uint8_t * p_addr_array = extended ? (uint8_t *)m_pending_extended : - (uint8_t *)m_pending_short; - uint8_t max_addr_array_len = extended ? NUM_PENDING_EXTENDED_ADDRESSES : - NUM_PENDING_SHORT_ADDRESSES; - uint8_t * p_addr_array_len = extended ? &m_num_of_pending_extended : &m_num_of_pending_short; - uint8_t entry_size = extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE; + uint8_t * p_addr_array; + uint8_t max_addr_array_len; + uint8_t * p_addr_array_len; + uint8_t entry_size; + + p_addr_array = extended ? (uint8_t *)m_pending_extended : (uint8_t *)m_pending_short; + max_addr_array_len = extended ? NUM_PENDING_EXTENDED_ADDRESSES : NUM_PENDING_SHORT_ADDRESSES; + p_addr_array_len = extended ? &m_num_of_pending_extended : &m_num_of_pending_short; + entry_size = extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE; if (*p_addr_array_len == max_addr_array_len) { @@ -292,10 +297,13 @@ static bool addr_add(const uint8_t * p_addr, uint8_t location, bool extended) */ static bool addr_remove(uint8_t location, bool extended) { - uint8_t * p_addr_array = extended ? (uint8_t *)m_pending_extended : - (uint8_t *)m_pending_short; - uint8_t * p_addr_array_len = extended ? &m_num_of_pending_extended : &m_num_of_pending_short; - uint8_t entry_size = extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE; + uint8_t * p_addr_array; + uint8_t * p_addr_array_len; + uint8_t entry_size; + + p_addr_array = extended ? (uint8_t *)m_pending_extended : (uint8_t *)m_pending_short; + p_addr_array_len = extended ? &m_num_of_pending_extended : &m_num_of_pending_short; + entry_size = extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE; if (*p_addr_array_len == 0) { diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h index 459bf558f..a773a7553 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.h @@ -108,4 +108,3 @@ bool nrf_802154_ack_pending_bit_should_be_set(const uint8_t * p_psdu); #endif #endif /* NRF_802154_ACK_PENDING_BIT_H_ */ - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h index 640d939b2..8a81452f9 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h @@ -60,7 +60,7 @@ extern "C" { * */ #ifndef NRF_802154_CCA_MODE_DEFAULT -#define NRF_802154_CCA_MODE_DEFAULT NRF_RADIO_CCA_MODE_ED +#define NRF_802154_CCA_MODE_DEFAULT NRF_RADIO_CCA_MODE_ED #endif /** @@ -70,7 +70,7 @@ extern "C" { * */ #ifndef NRF_802154_CCA_ED_THRESHOLD_DEFAULT -#define NRF_802154_CCA_ED_THRESHOLD_DEFAULT 0x14 +#define NRF_802154_CCA_ED_THRESHOLD_DEFAULT 0x14 #endif /** @@ -80,7 +80,7 @@ extern "C" { * */ #ifndef NRF_802154_CCA_CORR_THRESHOLD_DEFAULT -#define NRF_802154_CCA_CORR_THRESHOLD_DEFAULT 0x14 +#define NRF_802154_CCA_CORR_THRESHOLD_DEFAULT 0x14 #endif /** @@ -90,7 +90,7 @@ extern "C" { * */ #ifndef NRF_802154_CCA_CORR_LIMIT_DEFAULT -#define NRF_802154_CCA_CORR_LIMIT_DEFAULT 0x02 +#define NRF_802154_CCA_CORR_LIMIT_DEFAULT 0x02 #endif /** @@ -103,11 +103,11 @@ extern "C" { #ifndef NRF_802154_INTERNAL_RADIO_IRQ_HANDLING -#if RAAL_SOFTDEVICE +#if RAAL_SOFTDEVICE || RAAL_REM #define NRF_802154_INTERNAL_RADIO_IRQ_HANDLING 0 -#else // RAAL_SOFTDEVICE +#else // RAAL_SOFTDEVICE || RAAL_REM #define NRF_802154_INTERNAL_RADIO_IRQ_HANDLING 1 -#endif // RAAL_SOFTDEVICE +#endif // RAAL_SOFTDEVICE || RAAL_REM #endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING @@ -120,7 +120,7 @@ extern "C" { * */ #ifndef NRF_802154_IRQ_PRIORITY -#define NRF_802154_IRQ_PRIORITY 0 +#define NRF_802154_IRQ_PRIORITY 0 #endif /** @@ -213,7 +213,7 @@ extern "C" { * */ #ifndef NRF_802154_PENDING_SHORT_ADDRESSES -#define NRF_802154_PENDING_SHORT_ADDRESSES 10 +#define NRF_802154_PENDING_SHORT_ADDRESSES 10 #endif /** @@ -223,7 +223,7 @@ extern "C" { * */ #ifndef NRF_802154_PENDING_EXTENDED_ADDRESSES -#define NRF_802154_PENDING_EXTENDED_ADDRESSES 10 +#define NRF_802154_PENDING_EXTENDED_ADDRESSES 10 #endif /** @@ -233,7 +233,7 @@ extern "C" { * */ #ifndef NRF_802154_RX_BUFFERS -#define NRF_802154_RX_BUFFERS 16 +#define NRF_802154_RX_BUFFERS 16 #endif /** @@ -256,7 +256,7 @@ extern "C" { * */ #ifndef NRF_802154_NOTIFY_CRCERROR -#define NRF_802154_NOTIFY_CRCERROR 1 +#define NRF_802154_NOTIFY_CRCERROR 1 #endif /** @@ -330,7 +330,7 @@ extern "C" { * */ #ifndef NRF_802154_RTC_IRQ_PRIORITY -#define NRF_802154_RTC_IRQ_PRIORITY 6 +#define NRF_802154_RTC_IRQ_PRIORITY 6 #endif /** @@ -343,7 +343,7 @@ extern "C" { * */ #ifndef NRF_802154_RTC_INSTANCE -#define NRF_802154_RTC_INSTANCE NRF_RTC2 +#define NRF_802154_RTC_INSTANCE NRF_RTC2 #endif /** @@ -356,10 +356,9 @@ extern "C" { * */ #ifndef NRF_802154_RTC_IRQ_HANDLER -#define NRF_802154_RTC_IRQ_HANDLER RTC2_IRQHandler +#define NRF_802154_RTC_IRQ_HANDLER RTC2_IRQHandler #endif - /** * @def NRF_802154_RTC_IRQN * @@ -370,10 +369,9 @@ extern "C" { * */ #ifndef NRF_802154_RTC_IRQN -#define NRF_802154_RTC_IRQN RTC2_IRQn +#define NRF_802154_RTC_IRQN RTC2_IRQn #endif - /** * @} * @defgroup nrf_802154_config_csma CSMA/CA procedure configuration diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h index 2d0aca2a6..7d59a6419 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h @@ -39,77 +39,77 @@ #include #include "nrf_802154_config.h" -#define ACK_HEADER_WITH_PENDING 0x12 ///< First byte of ACK frame containing pending bit. -#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< First byte of ACK frame without pending bit. +#define ACK_HEADER_WITH_PENDING 0x12 ///< First byte of ACK frame containing pending bit. +#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< First byte of ACK frame without pending bit. -#define ACK_REQUEST_OFFSET 1 ///< Byte containing Ack request bit (+1 for frame length byte). -#define ACK_REQUEST_BIT (1 << 5) ///< Ack request bit. +#define ACK_REQUEST_OFFSET 1 ///< Byte containing Ack request bit (+1 for frame length byte). +#define ACK_REQUEST_BIT (1 << 5) ///< Ack request bit. -#define DEST_ADDR_TYPE_OFFSET 2 ///< Byte containing destination address type (+1 for frame length byte). -#define DEST_ADDR_TYPE_MASK 0x0c ///< Mask of bits containing destination address type. -#define DEST_ADDR_TYPE_EXTENDED 0x0c ///< Bits containing extended destination address type. -#define DEST_ADDR_TYPE_NONE 0x00 ///< Bits containing not present destination address type. -#define DEST_ADDR_TYPE_SHORT 0x08 ///< Bits containing short destination address type. -#define DEST_ADDR_OFFSET 6 ///< Offset of destination address in Data frame (+1 for frame length byte). +#define DEST_ADDR_TYPE_OFFSET 2 ///< Byte containing destination address type (+1 for frame length byte). +#define DEST_ADDR_TYPE_MASK 0x0c ///< Mask of bits containing destination address type. +#define DEST_ADDR_TYPE_EXTENDED 0x0c ///< Bits containing extended destination address type. +#define DEST_ADDR_TYPE_NONE 0x00 ///< Bits containing not present destination address type. +#define DEST_ADDR_TYPE_SHORT 0x08 ///< Bits containing short destination address type. +#define DEST_ADDR_OFFSET 6 ///< Offset of destination address in Data frame (+1 for frame length byte). -#define DSN_OFFSET 3 ///< Byte containing DSN value (+1 for frame length byte). +#define DSN_OFFSET 3 ///< Byte containing DSN value (+1 for frame length byte). -#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte). -#define FRAME_PENDING_BIT (1 << 4) ///< Pending bit. +#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte). +#define FRAME_PENDING_BIT (1 << 4) ///< Pending bit. -#define FRAME_TYPE_OFFSET 1 ///< Byte containing frame type bits (+1 for frame length byte). -#define FRAME_TYPE_MASK 0x07 ///< Mask of bits containing frame type. -#define FRAME_TYPE_ACK 0x02 ///< Bits containing ACK frame type. -#define FRAME_TYPE_BEACON 0x00 ///< Bits containing Beacon frame type. -#define FRAME_TYPE_COMMAND 0x03 ///< Bits containing Command frame type. -#define FRAME_TYPE_DATA 0x01 ///< Bits containing Data frame type. -#define FRAME_TYPE_EXTENDED 0x07 ///< Bits containing Extended frame type. -#define FRAME_TYPE_FRAGMENT 0x06 ///< Bits containing Fragment or Frak frame type. -#define FRAME_TYPE_MULTIPURPOSE 0x05 ///< Bits containing Multipurpose frame type. +#define FRAME_TYPE_OFFSET 1 ///< Byte containing frame type bits (+1 for frame length byte). +#define FRAME_TYPE_MASK 0x07 ///< Mask of bits containing frame type. +#define FRAME_TYPE_ACK 0x02 ///< Bits containing ACK frame type. +#define FRAME_TYPE_BEACON 0x00 ///< Bits containing Beacon frame type. +#define FRAME_TYPE_COMMAND 0x03 ///< Bits containing Command frame type. +#define FRAME_TYPE_DATA 0x01 ///< Bits containing Data frame type. +#define FRAME_TYPE_EXTENDED 0x07 ///< Bits containing Extended frame type. +#define FRAME_TYPE_FRAGMENT 0x06 ///< Bits containing Fragment or Frak frame type. +#define FRAME_TYPE_MULTIPURPOSE 0x05 ///< Bits containing Multipurpose frame type. -#define FRAME_VERSION_OFFSET 2 ///< Byte containing frame version bits (+1 for frame length byte). -#define FRAME_VERSION_MASK 0x30 ///< Mask of bits containing frame version. -#define FRAME_VERSION_0 0x00 ///< Bits containing frame version 0b00. -#define FRAME_VERSION_1 0x10 ///< Bits containing frame version 0b01. -#define FRAME_VERSION_2 0x20 ///< Bits containing frame version 0b10. -#define FRAME_VERSION_3 0x30 ///< Bits containing frame version 0b11. +#define FRAME_VERSION_OFFSET 2 ///< Byte containing frame version bits (+1 for frame length byte). +#define FRAME_VERSION_MASK 0x30 ///< Mask of bits containing frame version. +#define FRAME_VERSION_0 0x00 ///< Bits containing frame version 0b00. +#define FRAME_VERSION_1 0x10 ///< Bits containing frame version 0b01. +#define FRAME_VERSION_2 0x20 ///< Bits containing frame version 0b10. +#define FRAME_VERSION_3 0x30 ///< Bits containing frame version 0b11. -#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing Pan Id compression bit (+1 for frame length byte). -#define PAN_ID_COMPR_MASK 0x40 ///< Pan Id compression bit. +#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing Pan Id compression bit (+1 for frame length byte). +#define PAN_ID_COMPR_MASK 0x40 ///< Pan Id compression bit. -#define PAN_ID_OFFSET 4 ///< Offset of Pan Id in Data frame (+1 for frame length byte). +#define PAN_ID_OFFSET 4 ///< Offset of Pan Id in Data frame (+1 for frame length byte). -#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing extended source address type. -#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing not present source address type. -#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing source address type. -#define SRC_ADDR_TYPE_OFFSET 2 ///< Byte containing source address type (+1 for frame length byte). -#define SRC_ADDR_TYPE_SHORT 0x80 ///< Bits containing short source address type. +#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing extended source address type. +#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing not present source address type. +#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing source address type. +#define SRC_ADDR_TYPE_OFFSET 2 ///< Byte containing source address type (+1 for frame length byte). +#define SRC_ADDR_TYPE_SHORT 0x80 ///< Bits containing short source address type. -#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of source address in Data frame if destination address is short. -#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of source address in Data frame if destination address is extended. +#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of source address in Data frame if destination address is short. +#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of source address in Data frame if destination address is extended. -#define PHR_SIZE 1 ///< Size of PHR field. -#define FCF_SIZE 2 ///< Size of FCF field. -#define PAN_ID_SIZE 2 ///< Size of Pan Id. -#define SHORT_ADDRESS_SIZE 2 ///< Size of Short Mac Address. -#define EXTENDED_ADDRESS_SIZE 8 ///< Size of Extended Mac Address. -#define FCS_SIZE 2 ///< Size of FCS field. -#define IMM_ACK_LENGTH 5 ///< Length of ACK frame. -#define MAX_PACKET_SIZE 127 ///< Maximum size of radio packet. +#define PHR_SIZE 1 ///< Size of PHR field. +#define FCF_SIZE 2 ///< Size of FCF field. +#define PAN_ID_SIZE 2 ///< Size of Pan Id. +#define SHORT_ADDRESS_SIZE 2 ///< Size of Short Mac Address. +#define EXTENDED_ADDRESS_SIZE 8 ///< Size of Extended Mac Address. +#define FCS_SIZE 2 ///< Size of FCS field. +#define IMM_ACK_LENGTH 5 ///< Length of ACK frame. +#define MAX_PACKET_SIZE 127 ///< Maximum size of radio packet. -#define TURNAROUND_TIME 192UL ///< aTurnaroundTime [us]. -#define CCA_TIME 128UL ///< aCcaTime [us]. -#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< aUnitBackoffPeriod [us]. +#define TURNAROUND_TIME 192UL ///< aTurnaroundTime [us]. +#define CCA_TIME 128UL ///< aCcaTime [us]. +#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< aUnitBackoffPeriod [us]. -#define PHY_US_PER_SYMBOL 16 ///< Duration of a single symbol in microseconds [us]. -#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet). -#define PHY_SHR_SYMBOLS 10 ///< Number of symbols in Synchronization Header (SHR). +#define PHY_US_PER_SYMBOL 16 ///< Duration of a single symbol in microseconds [us]. +#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet). +#define PHY_SHR_SYMBOLS 10 ///< Number of symbols in Synchronization Header (SHR). -#define ED_MIN_DBM (-94) ///< dBm value corresponding to value 0 in EDSAMPLE register. -#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate ED result based on data from RADIO peripheral. -#define ED_RESULT_MAX 0xff ///< Maximal ED result. +#define ED_MIN_DBM (-94) ///< dBm value corresponding to value 0 in EDSAMPLE register. +#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate ED result based on data from RADIO peripheral. +#define ED_RESULT_MAX 0xff ///< Maximal ED result. -#define BROADCAST_ADDRESS ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast Short Address. +#define BROADCAST_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast Short Address. typedef enum { diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c index 155b11830..e9306418e 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c @@ -49,10 +49,8 @@ #include "nrf_802154_debug.h" #include "nrf_802154_notification.h" #include "nrf_802154_pib.h" -#include "nrf_802154_priority_drop.h" #include "nrf_802154_procedures_duration.h" #include "nrf_802154_revision.h" -#include "nrf_802154_rsch.h" #include "nrf_802154_rssi.h" #include "nrf_802154_rx_buffer.h" #include "nrf_802154_timer_coord.h" @@ -62,35 +60,37 @@ #include "hal/nrf_ppi.h" #include "hal/nrf_radio.h" #include "hal/nrf_timer.h" +#include "mac_features/nrf_802154_delayed_trx.h" #include "mac_features/nrf_802154_filter.h" +#include "rsch/nrf_802154_rsch.h" +#include "rsch/nrf_802154_rsch_crit_sect.h" #include "nrf_802154_core_hooks.h" +#define EGU_EVENT NRF_EGU_EVENT_TRIGGERED15 +#define EGU_TASK NRF_EGU_TASK_TRIGGER15 +#define PPI_CH0 NRF_PPI_CHANNEL6 +#define PPI_CH1 NRF_PPI_CHANNEL7 +#define PPI_CH2 NRF_PPI_CHANNEL8 +#define PPI_CH3 NRF_PPI_CHANNEL9 +#define PPI_CH4 NRF_PPI_CHANNEL10 +#define PPI_CH5 NRF_PPI_CHANNEL11 +#define PPI_CH6 NRF_PPI_CHANNEL12 +#define PPI_CHGRP0 NRF_PPI_CHANNEL_GROUP0 ///< PPI group used to disable self-disabling PPIs +#define PPI_CHGRP0_DIS_TASK NRF_PPI_TASK_CHG0_DIS ///< PPI task used to disable self-disabling PPIs -#define EGU_EVENT NRF_EGU_EVENT_TRIGGERED15 -#define EGU_TASK NRF_EGU_TASK_TRIGGER15 -#define PPI_CH0 NRF_PPI_CHANNEL6 -#define PPI_CH1 NRF_PPI_CHANNEL7 -#define PPI_CH2 NRF_PPI_CHANNEL8 -#define PPI_CH3 NRF_PPI_CHANNEL9 -#define PPI_CH4 NRF_PPI_CHANNEL10 -#define PPI_CH5 NRF_PPI_CHANNEL11 -#define PPI_CH6 NRF_PPI_CHANNEL12 -#define PPI_CHGRP0 NRF_PPI_CHANNEL_GROUP0 ///< PPI group used to disable self-disabling PPIs -#define PPI_CHGRP0_DIS_TASK NRF_PPI_TASK_CHG0_DIS - -#define PPI_DISABLED_EGU PPI_CH0 ///< PPI that connects RADIO DISABLED event with EGU task -#define PPI_EGU_RAMP_UP PPI_CH1 ///< PPI that connects EGU event with RADIO TXEN or RXEN task -#define PPI_EGU_TIMER_START PPI_CH2 ///< PPI that connects EGU event with TIMER START task -#define PPI_CRCERROR_CLEAR PPI_CH3 ///< PPI that connects RADIO CRCERROR event with TIMER CLEAR task -#define PPI_CCAIDLE_FEM PPI_CH3 ///< PPI that connects RADIO CCAIDLE event with GPIOTE tasks used by FEM -#define PPI_TIMER_TX_ACK PPI_CH3 ///< PPI that connects TIMER COMPARE event with RADIO TXEN task -#define PPI_CRCOK_DIS_PPI PPI_CH4 ///< PPI that connects RADIO CRCOK event with task that disables PPI group +#define PPI_DISABLED_EGU PPI_CH0 ///< PPI that connects RADIO DISABLED event with EGU task +#define PPI_EGU_RAMP_UP PPI_CH1 ///< PPI that connects EGU event with RADIO TXEN or RXEN task +#define PPI_EGU_TIMER_START PPI_CH2 ///< PPI that connects EGU event with TIMER START task +#define PPI_CRCERROR_CLEAR PPI_CH3 ///< PPI that connects RADIO CRCERROR event with TIMER CLEAR task +#define PPI_CCAIDLE_FEM PPI_CH3 ///< PPI that connects RADIO CCAIDLE event with GPIOTE tasks used by FEM +#define PPI_TIMER_TX_ACK PPI_CH3 ///< PPI that connects TIMER COMPARE event with RADIO TXEN task +#define PPI_CRCOK_DIS_PPI PPI_CH4 ///< PPI that connects RADIO CRCOK event with task that disables PPI group #if NRF_802154_DISABLE_BCC_MATCHING -#define PPI_ADDRESS_COUNTER_COUNT PPI_CH5 ///< PPI that connects RADIO ADDRESS event with TIMER COUNT task -#define PPI_CRCERROR_COUNTER_CLEAR PPI_CH6 ///< PPI that connects RADIO CRCERROR event with TIMER CLEAR task -#endif // NRF_802154_DISABLE_BCC_MATCHING +#define PPI_ADDRESS_COUNTER_COUNT PPI_CH5 ///< PPI that connects RADIO ADDRESS event with TIMER COUNT task +#define PPI_CRCERROR_COUNTER_CLEAR PPI_CH6 ///< PPI that connects RADIO CRCERROR event with TIMER CLEAR task +#endif // NRF_802154_DISABLE_BCC_MATCHING /// Workaround for missing PHYEND event in older chip revision. static inline uint32_t short_phyend_disable_mask_get(void) @@ -104,77 +104,78 @@ static inline uint32_t short_phyend_disable_mask_get(void) } #if NRF_802154_DISABLE_BCC_MATCHING -#define SHORT_ADDRESS_BCSTART 0UL +#define SHORT_ADDRESS_BCSTART 0UL #else // NRF_802154_DISABLE_BCC_MATCHING -#define SHORT_ADDRESS_BCSTART NRF_RADIO_SHORT_ADDRESS_BCSTART_MASK -#endif // NRF_802154_DISABLE_BCC_MATCHING +#define SHORT_ADDRESS_BCSTART NRF_RADIO_SHORT_ADDRESS_BCSTART_MASK +#endif // NRF_802154_DISABLE_BCC_MATCHING /// Value set to SHORTS register when no shorts should be enabled. -#define SHORTS_IDLE 0 +#define SHORTS_IDLE 0 /// Value set to SHORTS register for RX operation. -#define SHORTS_RX (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ - NRF_RADIO_SHORT_END_DISABLE_MASK | \ - SHORT_ADDRESS_BCSTART) +#define SHORTS_RX (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ + NRF_RADIO_SHORT_END_DISABLE_MASK | \ + SHORT_ADDRESS_BCSTART) -#define SHORTS_RX_FREE_BUFFER (NRF_RADIO_SHORT_RXREADY_START_MASK) +#define SHORTS_RX_FREE_BUFFER (NRF_RADIO_SHORT_RXREADY_START_MASK) -#define SHORTS_TX_ACK (NRF_RADIO_SHORT_TXREADY_START_MASK | \ - short_phyend_disable_mask_get()) +#define SHORTS_TX_ACK (NRF_RADIO_SHORT_TXREADY_START_MASK | \ + short_phyend_disable_mask_get()) -#define SHORTS_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ - NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK | \ - NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK | \ - NRF_RADIO_SHORT_TXREADY_START_MASK | \ - short_phyend_disable_mask_get()) +#define SHORTS_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ + NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK | \ + NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK | \ + NRF_RADIO_SHORT_TXREADY_START_MASK | \ + short_phyend_disable_mask_get()) -#define SHORTS_TX (NRF_RADIO_SHORT_TXREADY_START_MASK | \ - short_phyend_disable_mask_get()) +#define SHORTS_TX (NRF_RADIO_SHORT_TXREADY_START_MASK | \ + short_phyend_disable_mask_get()) -#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ - NRF_RADIO_SHORT_END_DISABLE_MASK) +#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ + NRF_RADIO_SHORT_END_DISABLE_MASK) -#define SHORTS_ED (NRF_RADIO_SHORT_READY_EDSTART_MASK) +#define SHORTS_ED (NRF_RADIO_SHORT_READY_EDSTART_MASK) -#define SHORTS_CCA (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ - NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK) +#define SHORTS_CCA (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ + NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK) /// Delay before first check of received frame: 24 bits is PHY header and MAC Frame Control field. -#define BCC_INIT (3 * 8) +#define BCC_INIT (3 * 8) /// Duration of single iteration of Energy Detection procedure -#define ED_ITER_DURATION 128U +#define ED_ITER_DURATION 128U /// Overhead of hardware preparation for ED procedure (aTurnaroundTime) [number of iterations] -#define ED_ITERS_OVERHEAD 2U +#define ED_ITERS_OVERHEAD 2U -#define CRC_LENGTH 2 ///< Length of CRC in 802.15.4 frames [bytes] -#define CRC_POLYNOMIAL 0x011021 ///< Polynomial used for CRC calculation in 802.15.4 frames +#define CRC_LENGTH 2 ///< Length of CRC in 802.15.4 frames [bytes] +#define CRC_POLYNOMIAL 0x011021 ///< Polynomial used for CRC calculation in 802.15.4 frames -#define MHMU_MASK 0xff000700 ///< Mask of known bytes in ACK packet -#define MHMU_PATTERN 0x00000200 ///< Values of known bytes in ACK packet -#define MHMU_PATTERN_DSN_OFFSET 24 ///< Offset of DSN in MHMU_PATTER [bits] +#define MHMU_MASK 0xff000700 ///< Mask of known bytes in ACK packet +#define MHMU_PATTERN 0x00000200 ///< Values of known bytes in ACK packet +#define MHMU_PATTERN_DSN_OFFSET 24 ///< Offset of DSN in MHMU_PATTER [bits] -#define ACK_IFS TURNAROUND_TIME ///< Ack Inter Frame Spacing [us] - delay between last symbol of received frame and first symbol of transmitted Ack -#define TXRU_TIME 40 ///< Transmitter ramp up time [us] -#define EVENT_LAT 23 ///< END event latency [us] +#define ACK_IFS TURNAROUND_TIME ///< Ack Inter Frame Spacing [us] - delay between last symbol of received frame and first symbol of transmitted Ack +#define TXRU_TIME 40 ///< Transmitter ramp up time [us] +#define EVENT_LAT 23 ///< END event latency [us] -#define MAX_CRIT_SECT_TIME 60 ///< Maximal time that the driver spends in single critical section. - -#define LQI_VALUE_FACTOR 4 ///< Factor needed to calculate LQI value based on data from RADIO peripheral -#define LQI_MAX 0xff ///< Maximal LQI value +#define MAX_CRIT_SECT_TIME 60 ///< Maximal time that the driver spends in single critical section. +#define LQI_VALUE_FACTOR 4 ///< Factor needed to calculate LQI value based on data from RADIO peripheral +#define LQI_MAX 0xff ///< Maximal LQI value /** Get LQI of given received packet. If CRC is calculated by hardware LQI is included instead of CRC * in the frame. Length is stored in byte with index 0; CRC is 2 last bytes. */ -#define RX_FRAME_LQI(psdu) ((psdu)[(psdu)[0] - 1]) +#define RX_FRAME_LQI(psdu) ((psdu)[(psdu)[0] - 1]) #if NRF_802154_RX_BUFFERS > 1 /// Pointer to currently used receive buffer. static rx_buffer_t * mp_current_rx_buffer; + #else /// If there is only one buffer use const pointer to the receive buffer. static rx_buffer_t * const mp_current_rx_buffer = &nrf_802154_rx_buffers[0]; + #endif static uint8_t m_ack_psdu[IMM_ACK_LENGTH + 1]; ///< ACK frame buffer. @@ -182,22 +183,25 @@ static const uint8_t * mp_tx_data; ///< Pointer to the data static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us]. static uint8_t m_ed_result; ///< Result of the current energy detection procedure. -static volatile radio_state_t m_state; ///< State of the radio driver. +static volatile radio_state_t m_state; ///< State of the radio driver. typedef struct { - bool frame_filtered :1; ///< If frame being received passed filtering operation. - bool rx_timeslot_requested :1; ///< If timeslot for the frame being received is already requested. -#if !NRF_802154_DISABLE_BCC_MATCHING - bool psdu_being_received :1; ///< If PSDU is currently being received. -#endif // !NRF_802154_DISABLE_BCC_MATCHING -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - bool tx_started :1; ///< If requested transmission has started. -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED -} nrf_802154_flags_t; -static nrf_802154_flags_t m_flags; ///< Flags used to store current driver state. + bool frame_filtered : 1; ///< If frame being received passed filtering operation. + bool rx_timeslot_requested : 1; ///< If timeslot for the frame being received is already requested. -static volatile bool m_rsch_timeslot_is_granted; ///< State of the RSCH timeslot. +#if !NRF_802154_DISABLE_BCC_MATCHING + bool psdu_being_received : 1; ///< If PSDU is currently being received. + +#endif // !NRF_802154_DISABLE_BCC_MATCHING +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + bool tx_started : 1; ///< If requested transmission has started. + +#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED +} nrf_802154_flags_t; +static nrf_802154_flags_t m_flags; ///< Flags used to store current driver state. + +static volatile bool m_rsch_timeslot_is_granted; ///< State of the RSCH timeslot. /*************************************************************************************************** * @section Common core operations @@ -220,7 +224,7 @@ static void rx_flags_clear(void) m_flags.frame_filtered = false; m_flags.rx_timeslot_requested = false; #if !NRF_802154_DISABLE_BCC_MATCHING - m_flags.psdu_being_received = false; + m_flags.psdu_being_received = false; #endif // !NRF_802154_DISABLE_BCC_MATCHING } @@ -247,7 +251,7 @@ static uint8_t lqi_get(const uint8_t * p_data) { uint32_t lqi = RX_FRAME_LQI(p_data); - lqi = nrf_802154_rssi_lqi_corrected_get(lqi); + lqi = nrf_802154_rssi_lqi_corrected_get(lqi); lqi *= LQI_VALUE_FACTOR; if (lqi > LQI_MAX) @@ -260,9 +264,9 @@ static uint8_t lqi_get(const uint8_t * p_data) static void received_frame_notify(uint8_t * p_psdu) { - nrf_802154_notify_received(p_psdu, // data - rssi_last_measurement_get(), // rssi - lqi_get(p_psdu)); // lqi + nrf_802154_notify_received(p_psdu, // data + rssi_last_measurement_get(), // rssi + lqi_get(p_psdu)); // lqi } /** Allow nesting critical sections and notify MAC layer that a frame was received. */ @@ -297,6 +301,15 @@ static void transmit_started_notify(void) } +#if !NRF_802154_DISABLE_BCC_MATCHING +/** Notify that reception of a frame has started. */ +static void receive_started_notify(void) +{ + nrf_802154_core_hooks_rx_started(); +} + +#endif + /** Notify MAC layer that a frame was transmitted. */ static void transmitted_frame_notify(uint8_t * p_ack, int8_t power, int8_t lqi) { @@ -359,7 +372,7 @@ static void cca_configuration_update(void) nrf_802154_pib_cca_cfg_get(&cca_cfg); nrf_radio_cca_mode_set(cca_cfg.mode); nrf_radio_cca_ed_threshold_set( - nrf_802154_rssi_cca_ed_threshold_corrected_get(cca_cfg.ed_threshold)); + nrf_802154_rssi_cca_ed_threshold_corrected_get(cca_cfg.ed_threshold)); nrf_radio_cca_corr_threshold_set(cca_cfg.corr_threshold); nrf_radio_cca_corr_counter_set(cca_cfg.corr_limit); } @@ -371,7 +384,8 @@ static void cca_configuration_update(void) static bool psdu_is_being_received(void) { #if NRF_802154_DISABLE_BCC_MATCHING - nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, nrf_timer_capture_task_get(NRF_TIMER_CC_CHANNEL0)); + nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, + nrf_timer_capture_task_get(NRF_TIMER_CC_CHANNEL0)); uint32_t counter = nrf_timer_cc_read(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0); assert(counter <= 1); @@ -379,7 +393,7 @@ static bool psdu_is_being_received(void) return counter > 0; #else // NRF_802154_DISABLE_BCC_MATCHING return m_flags.psdu_being_received; -#endif // NRF_802154_DISABLE_BCC_MATCHING +#endif // NRF_802154_DISABLE_BCC_MATCHING } /** Check if requested transmission has already started. @@ -393,7 +407,7 @@ static bool transmission_has_started(void) return m_flags.tx_started; #else // NRF_802154_TX_STARTED_NOTIFY_ENABLED return nrf_radio_event_get(NRF_RADIO_EVENT_ADDRESS); -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED +#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED } /** Check if timeslot is currently granted. @@ -419,7 +433,7 @@ static void rx_buffer_in_use_set(rx_buffer_t * p_rx_buffer) #if NRF_802154_RX_BUFFERS > 1 mp_current_rx_buffer = p_rx_buffer; #else - (void) p_rx_buffer; + (void)p_rx_buffer; #endif } @@ -500,7 +514,7 @@ static void ack_matching_enable(void) { nrf_radio_event_clear(NRF_RADIO_EVENT_MHRMATCH); nrf_radio_mhmu_search_pattern_set(MHMU_PATTERN | - ((uint32_t) mp_tx_data[DSN_OFFSET] << + ((uint32_t)mp_tx_data[DSN_OFFSET] << MHMU_PATTERN_DSN_OFFSET)); } @@ -519,7 +533,7 @@ static void ack_matching_disable(void) static bool ack_is_matched(void) { return (nrf_radio_event_get(NRF_RADIO_EVENT_MHRMATCH)) && - (nrf_radio_crc_status_get() == NRF_RADIO_CRC_STATUS_OK); + (nrf_radio_crc_status_get() == NRF_RADIO_CRC_STATUS_OK); } /*************************************************************************************************** @@ -579,7 +593,6 @@ static void irq_deinit(void) __ISB(); } - /*************************************************************************************************** * @section TIMER peripheral management **************************************************************************************************/ @@ -610,7 +623,7 @@ static uint8_t ed_result_get(void) { uint32_t result = m_ed_result; - result = nrf_802154_rssi_ed_corrected_get(result); + result = nrf_802154_rssi_ed_corrected_get(result); result *= ED_RESULT_FACTOR; if (result > ED_RESULT_MAX) @@ -666,7 +679,6 @@ static bool ed_iter_setup(uint32_t time_us) } } - /*************************************************************************************************** * @section FSM transition request sub-procedures **************************************************************************************************/ @@ -728,26 +740,26 @@ static void ppis_for_egu_and_ramp_up_set(nrf_radio_task_t ramp_up_task, bool sel { nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_RAMP_UP, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_radio_task_address_get(ramp_up_task), (uint32_t)nrf_ppi_task_address_get( - PPI_CHGRP0_DIS_TASK)); + PPI_CHGRP0_DIS_TASK)); } else { nrf_ppi_channel_endpoint_setup(PPI_EGU_RAMP_UP, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_radio_task_address_get(ramp_up_task)); } nrf_ppi_channel_endpoint_setup(PPI_DISABLED_EGU, (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_DISABLED), (uint32_t)nrf_egu_task_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_TASK)); + NRF_802154_SWI_EGU_INSTANCE, + EGU_TASK)); if (self_disabling) { @@ -767,8 +779,8 @@ static void fem_for_lna_set(nrf_timer_cc_channel_t cc_channel, nrf_fem_control_ppi_task_setup(NRF_FEM_CONTROL_LNA_PIN, PPI_EGU_TIMER_START, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_timer_task_address_get( NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START)); @@ -845,8 +857,8 @@ static void fem_for_tx_reset(bool disable_ppi_egu_timer_start) { nrf_fem_control_ppi_disable(NRF_FEM_CONTROL_ANY_PIN); nrf_fem_control_timer_reset(NRF_FEM_CONTROL_ANY_PIN, - (nrf_timer_short_mask_t) (NRF_TIMER_SHORT_COMPARE0_STOP_MASK | - NRF_TIMER_SHORT_COMPARE1_STOP_MASK)); + (nrf_timer_short_mask_t)(NRF_TIMER_SHORT_COMPARE0_STOP_MASK | + NRF_TIMER_SHORT_COMPARE1_STOP_MASK)); nrf_fem_control_ppi_fork_clear(NRF_FEM_CONTROL_ANY_PIN, PPI_CCAIDLE_FEM); nrf_ppi_channel_disable(PPI_CCAIDLE_FEM); @@ -891,7 +903,7 @@ static void rx_restart(bool set_shorts) // Prepare the timer coordinator to get a precise timestamp of the CRCOK event. nrf_802154_timer_coord_timestamp_prepare( - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); + (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); if (!ppi_egu_worked()) { @@ -947,8 +959,7 @@ static void falling_asleep_terminate(void) /** Terminate Sleep procedure. */ static void sleep_terminate(void) { - nrf_802154_priority_drop_timeslot_exit_terminate(); - nrf_802154_rsch_continuous_mode_enter(); + nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_MAX); } /** Terminate RX procedure. */ @@ -974,11 +985,13 @@ static void rx_terminate(void) nrf_ppi_fork_endpoint_setup(PPI_EGU_TIMER_START, 0); #else // NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0); -#endif // NRF_802154_DISABLE_BCC_MATCHING +#endif // NRF_802154_DISABLE_BCC_MATCHING // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK | NRF_TIMER_SHORT_COMPARE2_STOP_MASK); + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK | + NRF_TIMER_SHORT_COMPARE2_STOP_MASK); #if NRF_802154_DISABLE_BCC_MATCHING // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. @@ -1023,7 +1036,9 @@ static void tx_ack_terminate(void) // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK | NRF_TIMER_SHORT_COMPARE2_STOP_MASK); + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK | + NRF_TIMER_SHORT_COMPARE2_STOP_MASK); #if NRF_802154_DISABLE_BCC_MATCHING // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. @@ -1034,7 +1049,7 @@ static void tx_ack_terminate(void) if (timeslot_is_granted()) { ints_to_disable = nrf_802154_revision_has_phyend_event() ? - NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK; + NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK; #if NRF_802154_TX_STARTED_NOTIFY_ENABLED ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; #endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED @@ -1061,7 +1076,7 @@ static void tx_terminate(void) if (timeslot_is_granted()) { ints_to_disable = nrf_802154_revision_has_phyend_event() ? - NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK; + NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK; ints_to_disable |= NRF_RADIO_INT_CCABUSY_MASK; #if NRF_802154_TX_STARTED_NOTIFY_ENABLED ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; @@ -1090,7 +1105,7 @@ static void rx_ack_terminate(void) nrf_radio_int_disable(NRF_RADIO_INT_END_MASK); nrf_radio_shorts_set(SHORTS_IDLE); nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - + ack_matching_disable(); } } @@ -1153,7 +1168,7 @@ static void continuous_carrier_terminate(void) * * This function is called when MAC layer requests transition to another operation. * - * After calling this function RADIO should enter DISABLED state and Radio Scheduler + * After calling this function RADIO should enter DISABLED state and Radio Scheduler * should be in continuous mode. * * @param[in] term_lvl Termination level of this request. Selects procedures to abort. @@ -1312,7 +1327,7 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl, /** Enter Sleep state. */ static void sleep_init(void) { - nrf_802154_priority_drop_timeslot_exit(); + nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_IDLE); m_rsch_timeslot_is_granted = false; nrf_802154_timer_coord_stop(); } @@ -1415,64 +1430,64 @@ static void rx_init(bool disabled_was_triggered) #if NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_channel_endpoint_setup(PPI_EGU_RAMP_UP, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_radio_task_address_get(NRF_RADIO_TASK_RXEN)); nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_TIMER_START, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_START), + NRF_802154_TIMER_INSTANCE, + NRF_TIMER_TASK_START), (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_START)); + NRF_802154_COUNTER_TIMER_INSTANCE, + NRF_TIMER_TASK_START)); // Anomaly 78: use SHUTDOWN instead of CLEAR. nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_CLEAR, (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCERROR), (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_SHUTDOWN)); + NRF_802154_TIMER_INSTANCE, + NRF_TIMER_TASK_SHUTDOWN)); nrf_ppi_channel_endpoint_setup(PPI_CRCOK_DIS_PPI, (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK), (uint32_t)nrf_ppi_task_address_get(PPI_CHGRP0_DIS_TASK)); #else // NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_RAMP_UP, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_radio_task_address_get( - NRF_RADIO_TASK_RXEN), + NRF_RADIO_TASK_RXEN), (uint32_t)nrf_ppi_task_address_get( - PPI_CHGRP0_DIS_TASK)); + PPI_CHGRP0_DIS_TASK)); nrf_ppi_channel_endpoint_setup(PPI_EGU_TIMER_START, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_START)); + NRF_802154_TIMER_INSTANCE, + NRF_TIMER_TASK_START)); #endif // NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_channel_include_in_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); nrf_ppi_channel_endpoint_setup(PPI_DISABLED_EGU, (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_DISABLED), (uint32_t)nrf_egu_task_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_TASK)); + NRF_802154_SWI_EGU_INSTANCE, + EGU_TASK)); #if NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_channel_endpoint_setup(PPI_ADDRESS_COUNTER_COUNT, (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_ADDRESS), (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_COUNT)); + NRF_802154_COUNTER_TIMER_INSTANCE, + NRF_TIMER_TASK_COUNT)); // Anomaly 78: use SHUTDOWN instead of CLEAR. nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_COUNTER_CLEAR, (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCERROR), (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_SHUTDOWN)); + NRF_802154_COUNTER_TIMER_INSTANCE, + NRF_TIMER_TASK_SHUTDOWN)); #endif // NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_channel_enable(PPI_EGU_RAMP_UP); @@ -1487,7 +1502,7 @@ static void rx_init(bool disabled_was_triggered) // Configure the timer coordinator to get a timestamp of the CRCOK event. nrf_802154_timer_coord_timestamp_prepare( - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); + (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); // Start procedure if necessary if (!disabled_was_triggered || !ppi_egu_worked()) @@ -1550,7 +1565,7 @@ static bool tx_init(const uint8_t * p_data, bool cca, bool disabled_was_triggere nrf_radio_event_clear(NRF_RADIO_EVENT_ADDRESS); #if NRF_802154_TX_STARTED_NOTIFY_ENABLED - ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; + ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; m_flags.tx_started = false; #endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED @@ -1658,17 +1673,15 @@ static void continuous_carrier_init(bool disabled_was_triggered) } } - - /*************************************************************************************************** * @section Radio Scheduler notification handlers **************************************************************************************************/ -void nrf_802154_critical_section_rsch_prec_approved(void) +static void cont_prec_approved(void) { nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TIMESLOT_STARTED); - if (remaining_timeslot_time_is_enough_for_crit_sect()) + if (remaining_timeslot_time_is_enough_for_crit_sect() && !timeslot_is_granted()) { nrf_radio_reset(); nrf_radio_init(); @@ -1721,69 +1734,84 @@ void nrf_802154_critical_section_rsch_prec_approved(void) nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TIMESLOT_STARTED); } -void nrf_802154_critical_section_rsch_prec_denied(void) +static void cont_prec_denied(void) { bool result; nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TIMESLOT_ENDED); - irq_deinit(); - nrf_radio_reset(); - nrf_fem_control_pin_clear(); - - m_rsch_timeslot_is_granted = false; - nrf_802154_timer_coord_stop(); - - result = current_operation_terminate(NRF_802154_TERM_802154, REQ_ORIG_RSCH, false); - assert(result); - (void)result; - - switch (m_state) + if (timeslot_is_granted()) { - case RADIO_STATE_SLEEP: - // Intentionally empty. - // Ignore this notification if continuous mode was not requested. - break; + irq_deinit(); + nrf_radio_reset(); + nrf_fem_control_pin_clear(); - case RADIO_STATE_FALLING_ASLEEP: - state_set(RADIO_STATE_SLEEP); - sleep_init(); - break; + m_rsch_timeslot_is_granted = false; + nrf_802154_timer_coord_stop(); - case RADIO_STATE_RX: - if (psdu_is_being_received()) - { - receive_failed_notify(NRF_802154_RX_ERROR_TIMESLOT_ENDED); - } + result = current_operation_terminate(NRF_802154_TERM_802154, REQ_ORIG_RSCH, false); + assert(result); + (void)result; - break; + switch (m_state) + { + case RADIO_STATE_SLEEP: + // Intentionally empty. + // Ignore this notification if continuous mode was not requested. + break; - case RADIO_STATE_TX_ACK: - state_set(RADIO_STATE_RX); - mp_current_rx_buffer->free = false; - received_frame_notify_and_nesting_allow(mp_current_rx_buffer->psdu); - break; + case RADIO_STATE_FALLING_ASLEEP: + state_set(RADIO_STATE_SLEEP); + sleep_init(); + break; - case RADIO_STATE_CCA_TX: - case RADIO_STATE_TX: - case RADIO_STATE_RX_ACK: - state_set(RADIO_STATE_RX); - transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_TIMESLOT_ENDED); - break; + case RADIO_STATE_RX: + if (psdu_is_being_received()) + { + receive_failed_notify(NRF_802154_RX_ERROR_TIMESLOT_ENDED); + } - case RADIO_STATE_ED: - case RADIO_STATE_CCA: - case RADIO_STATE_CONTINUOUS_CARRIER: - // Intentionally empty. - break; + break; - default: - assert(false); + case RADIO_STATE_TX_ACK: + state_set(RADIO_STATE_RX); + mp_current_rx_buffer->free = false; + received_frame_notify_and_nesting_allow(mp_current_rx_buffer->psdu); + break; + + case RADIO_STATE_CCA_TX: + case RADIO_STATE_TX: + case RADIO_STATE_RX_ACK: + state_set(RADIO_STATE_RX); + transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_TIMESLOT_ENDED); + break; + + case RADIO_STATE_ED: + case RADIO_STATE_CCA: + case RADIO_STATE_CONTINUOUS_CARRIER: + // Intentionally empty. + break; + + default: + assert(false); + } } nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TIMESLOT_ENDED); } +void nrf_802154_rsch_crit_sect_prio_changed(rsch_prio_t prio) +{ + if (prio > RSCH_PRIO_IDLE) + { + cont_prec_approved(); + } + else + { + cont_prec_denied(); + nrf_802154_rsch_continuous_ended(); + } +} /*************************************************************************************************** * @section RADIO interrupt handler @@ -1828,7 +1856,8 @@ static void irq_bcmatch_state_rx(void) if (!m_flags.frame_filtered) { m_flags.psdu_being_received = true; - filter_result = nrf_802154_filter_frame_part(mp_current_rx_buffer->psdu, &num_psdu_bytes); + filter_result = nrf_802154_filter_frame_part(mp_current_rx_buffer->psdu, + &num_psdu_bytes); if (filter_result == NRF_802154_RX_ERROR_NONE) { @@ -1841,7 +1870,7 @@ static void irq_bcmatch_state_rx(void) m_flags.frame_filtered = true; } } - else if ((filter_result == NRF_802154_RX_ERROR_INVALID_FRAME) || + else if ((filter_result == NRF_802154_RX_ERROR_INVALID_LENGTH) || (!nrf_802154_pib_promiscuous_get())) { rx_terminate(); @@ -1864,10 +1893,12 @@ static void irq_bcmatch_state_rx(void) if ((!m_flags.rx_timeslot_requested) && (frame_accepted)) { if (nrf_802154_rsch_timeslot_request(nrf_802154_rx_duration_get( - mp_current_rx_buffer->psdu[0], - ack_is_requested(mp_current_rx_buffer->psdu)))) + mp_current_rx_buffer->psdu[0], + ack_is_requested(mp_current_rx_buffer->psdu)))) { m_flags.rx_timeslot_requested = true; + + receive_started_notify(); } else { @@ -1878,25 +1909,28 @@ static void irq_bcmatch_state_rx(void) } } } -#endif //!NRF_802154_DISABLE_BCC_MATCHING + +#endif // !NRF_802154_DISABLE_BCC_MATCHING #if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR static void irq_crcerror_state_rx(void) { #if !NRF_802154_DISABLE_BCC_MATCHING rx_restart(false); -#endif //!NRF_802154_DISABLE_BCC_MATCHING +#endif // !NRF_802154_DISABLE_BCC_MATCHING #if NRF_802154_NOTIFY_CRCERROR receive_failed_notify(NRF_802154_RX_ERROR_INVALID_FCS); -#endif //NRF_802154_NOTIFY_CRCERROR +#endif // NRF_802154_NOTIFY_CRCERROR } -#endif //!NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR + +#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR static void irq_crcok_state_rx(void) { uint8_t * p_received_psdu = mp_current_rx_buffer->psdu; uint32_t ints_to_disable = 0; uint32_t ints_to_enable = 0; + #if NRF_802154_DISABLE_BCC_MATCHING uint8_t num_psdu_bytes = PHR_SIZE + FCF_SIZE; uint8_t prev_num_psdu_bytes = 0; @@ -1974,10 +2008,10 @@ static void irq_crcok_state_rx(void) // Set PPIs nrf_ppi_channel_endpoint_setup(PPI_TIMER_TX_ACK, (uint32_t)nrf_timer_event_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_EVENT_COMPARE1), + NRF_802154_TIMER_INSTANCE, + NRF_TIMER_EVENT_COMPARE1), (uint32_t)nrf_radio_task_address_get( - NRF_RADIO_TASK_TXEN)); + NRF_RADIO_TASK_TXEN)); #if !NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_channel_enable(PPI_TIMER_TX_ACK); @@ -2111,7 +2145,7 @@ static void irq_crcok_state_rx(void) } #else // NRF_802154_DISABLE_BCC_MATCHING receive_failed_notify(NRF_802154_RX_ERROR_RUNTIME); -#endif // NRF_802154_DISABLE_BCC_MATCHING +#endif // NRF_802154_DISABLE_BCC_MATCHING } } @@ -2136,7 +2170,7 @@ static void irq_phyend_state_tx_ack(void) #endif // !NRF_802154_DISABLE_BCC_MATCHING ints_to_disable = nrf_802154_revision_has_phyend_event() ? - NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK; + NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK; #if NRF_802154_TX_STARTED_NOTIFY_ENABLED ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; @@ -2172,16 +2206,16 @@ static void irq_phyend_state_tx_ack(void) nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_CLEAR, (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCERROR), (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_SHUTDOWN)); + NRF_802154_TIMER_INSTANCE, + NRF_TIMER_TASK_SHUTDOWN)); nrf_ppi_fork_endpoint_setup(PPI_EGU_TIMER_START, (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_START)); + NRF_802154_COUNTER_TIMER_INSTANCE, + NRF_TIMER_TASK_START)); #else // NRF_802154_DISABLE_BCC_MATCHING nrf_ppi_channel_disable(PPI_TIMER_TX_ACK); -#endif // NRF_802154_DISABLE_BCC_MATCHING +#endif // NRF_802154_DISABLE_BCC_MATCHING // Enable PPI disabled by CRCOK nrf_ppi_channel_enable(PPI_EGU_RAMP_UP); @@ -2196,7 +2230,7 @@ static void irq_phyend_state_tx_ack(void) // Prepare the timer coordinator to get a precise timestamp of the CRCOK event. nrf_802154_timer_coord_timestamp_prepare( - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); + (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); if (!ppi_egu_worked()) { @@ -2240,7 +2274,7 @@ static void irq_phyend_state_tx_frame(void) { bool rx_buffer_free = rx_buffer_is_available(); uint32_t shorts = rx_buffer_free ? - (SHORTS_RX_ACK | SHORTS_RX_FREE_BUFFER) : SHORTS_RX_ACK; + (SHORTS_RX_ACK | SHORTS_RX_FREE_BUFFER) : SHORTS_RX_ACK; // Disable EGU PPI to prevent unsynchronized PPIs nrf_ppi_channel_disable(PPI_DISABLED_EGU); @@ -2272,12 +2306,12 @@ static void irq_phyend_state_tx_frame(void) nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_RAMP_UP, (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), + NRF_802154_SWI_EGU_INSTANCE, + EGU_EVENT), (uint32_t)nrf_radio_task_address_get( - NRF_RADIO_TASK_RXEN), + NRF_RADIO_TASK_RXEN), (uint32_t)nrf_ppi_task_address_get( - PPI_CHGRP0_DIS_TASK)); + PPI_CHGRP0_DIS_TASK)); nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); @@ -2329,7 +2363,7 @@ static void irq_end_state_rx_ack(void) if (ack_match) { - p_ack_buffer = mp_current_rx_buffer; + p_ack_buffer = mp_current_rx_buffer; mp_current_rx_buffer->free = false; } @@ -2339,9 +2373,9 @@ static void irq_end_state_rx_ack(void) if (ack_match) { - transmitted_frame_notify(p_ack_buffer->psdu, // psdu - rssi_last_measurement_get(), // rssi - lqi_get(p_ack_buffer->psdu)); // lqi; + transmitted_frame_notify(p_ack_buffer->psdu, // psdu + rssi_last_measurement_get(), // rssi + lqi_get(p_ack_buffer->psdu)); // lqi; } else { @@ -2388,7 +2422,8 @@ static void irq_ccabusy_state_cca(void) static void irq_edend_state_ed(void) { uint32_t result = nrf_radio_ed_sample_get(); - m_ed_result = result > m_ed_result ? result : m_ed_result; + + m_ed_result = result > m_ed_result ? result : m_ed_result; if (m_ed_time_left) { @@ -2519,8 +2554,8 @@ static void irq_handler(void) switch (m_state) { case RADIO_STATE_TX_ACK: - irq_phyend_state_tx_ack(); - break; + irq_phyend_state_tx_ack(); + break; case RADIO_STATE_CCA_TX: case RADIO_STATE_TX: @@ -2656,7 +2691,6 @@ static void irq_handler(void) nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_IRQ_HANDLER); } - /*************************************************************************************************** * @section API functions **************************************************************************************************/ @@ -2664,9 +2698,11 @@ static void irq_handler(void) void nrf_802154_core_init(void) { const uint8_t ack_psdu[] = {0x05, ACK_HEADER_WITH_PENDING, 0x00, 0x00, 0x00, 0x00}; + memcpy(m_ack_psdu, ack_psdu, sizeof(ack_psdu)); - m_state = RADIO_STATE_SLEEP; + m_state = RADIO_STATE_SLEEP; + m_rsch_timeslot_is_granted = false; nrf_timer_init(); } @@ -2677,10 +2713,10 @@ void nrf_802154_core_deinit(void) { nrf_radio_reset(); } - + nrf_fem_control_pin_clear(); nrf_fem_control_deactivate(); - + irq_deinit(); } @@ -2950,7 +2986,8 @@ bool nrf_802154_core_channel_update(void) channel_set(nrf_802154_pib_channel_get()); } - term_result = current_operation_terminate(NRF_802154_TERM_NONE, REQ_ORIG_CORE, true); + term_result = + current_operation_terminate(NRF_802154_TERM_NONE, REQ_ORIG_CORE, true); if (term_result) { @@ -3015,7 +3052,7 @@ bool nrf_802154_core_cca_cfg_update(void) void RADIO_IRQHandler(void) #else // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING void nrf_802154_core_irq_handler(void) -#endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING +#endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING { irq_handler(); } diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.h index 87001e769..ce4b89eaf 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.h @@ -239,4 +239,3 @@ void nrf_802154_core_irq_handler(void); #endif #endif /* NRF_802154_CORE_H_ */ - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c index b80d73ba7..325cc3aa4 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c @@ -43,14 +43,15 @@ #include "mac_features/nrf_802154_ack_timeout.h" #include "mac_features/nrf_802154_csma_ca.h" +#include "mac_features/nrf_802154_delayed_trx.h" #include "nrf_802154_config.h" #include "nrf_802154_types.h" - typedef bool (* abort_hook)(nrf_802154_term_t term_lvl, req_originator_t req_orig); typedef void (* transmitted_hook)(const uint8_t * p_frame); typedef bool (* tx_failed_hook)(const uint8_t * p_frame, nrf_802154_tx_error_t error); typedef bool (* tx_started_hook)(const uint8_t * p_frame); +typedef void (* rx_started_hook)(void); /* Since some compilers do not allow empty initializers for arrays with unspecified bounds, * NULL pointer is appended to below arrays if the compiler used is not GCC. It is intentionally @@ -67,6 +68,10 @@ static const abort_hook m_abort_hooks[] = nrf_802154_ack_timeout_abort, #endif +#if NRF_802154_DELAYED_TRX_ENABLED + nrf_802154_delayed_trx_abort, +#endif + NULL, }; @@ -105,6 +110,15 @@ static const tx_started_hook m_tx_started_hooks[] = NULL, }; +static const rx_started_hook m_rx_started_hooks[] = +{ +#if NRF_802154_DELAYED_TRX_ENABLED + nrf_802154_delayed_trx_rx_started_hook, +#endif + + NULL, +}; + bool nrf_802154_core_hooks_terminate(nrf_802154_term_t term_lvl, req_originator_t req_orig) { bool result = true; @@ -183,3 +197,16 @@ bool nrf_802154_core_hooks_tx_started(const uint8_t * p_frame) return result; } + +void nrf_802154_core_hooks_rx_started(void) +{ + for (uint32_t i = 0; i < sizeof(m_rx_started_hooks) / sizeof(m_rx_started_hooks[0]); i++) + { + if (m_rx_started_hooks[i] == NULL) + { + break; + } + + m_rx_started_hooks[i](); + } +} diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h index 1f7bdc148..8a14fdecd 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.h @@ -88,6 +88,11 @@ bool nrf_802154_core_hooks_tx_failed(const uint8_t * p_frame, nrf_802154_tx_erro */ bool nrf_802154_core_hooks_tx_started(const uint8_t * p_frame); +/** + * @brief Process hooks for the RX started event. + */ +void nrf_802154_core_hooks_rx_started(void); + /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.c index 1b504fa9d..c3ce8600b 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.c @@ -47,103 +47,13 @@ #include -#define CMSIS_IRQ_NUM_VECTACTIVE_DIFF 16 +#define CMSIS_IRQ_NUM_VECTACTIVE_DIFF 16 #define NESTED_CRITICAL_SECTION_ALLOWED_PRIORITY_NONE (-1) -static volatile uint8_t m_critical_section_monitor; ///< Monitors each critical section enter operation -static volatile uint8_t m_nested_critical_section_counter; ///< Counter of nested critical sections -static volatile int8_t m_nested_critical_section_allowed_priority; ///< Indicator if nested critical sections are currently allowed - -typedef enum -{ - RSCH_EVT_NONE, - RSCH_EVT_STARTED, - RSCH_EVT_ENDED, -} rsch_evt_t; - -static volatile uint8_t m_rsch_pending_evt; ///< Indicator of pending RSCH event. - - -/*************************************************************************************************** - * @section RSCH pending events management - **************************************************************************************************/ - -static void rsch_pending_evt_set(rsch_evt_t evt) -{ - rsch_evt_t curr_evt; - rsch_evt_t new_evt; - uint8_t evt_value; - - do - { - evt_value = __LDREXB(&m_rsch_pending_evt); - curr_evt = (rsch_evt_t)evt_value; - - switch (curr_evt) - { - case RSCH_EVT_NONE: - new_evt = evt; - break; - - case RSCH_EVT_ENDED: - assert(evt == RSCH_EVT_STARTED); - new_evt = RSCH_EVT_NONE; - break; - - case RSCH_EVT_STARTED: - assert(evt == RSCH_EVT_ENDED); - new_evt = RSCH_EVT_NONE; - break; - - default: - assert(false); - } - - evt_value = (uint8_t)new_evt; - } while (__STREXB(evt_value, &m_rsch_pending_evt)); -} - -static rsch_evt_t rsch_pending_evt_clear(void) -{ - rsch_evt_t evt; - uint8_t evt_value; - - do - { - evt_value = __LDREXB(&m_rsch_pending_evt); - evt = (rsch_evt_t)evt_value; - - evt_value = RSCH_EVT_NONE; - } while (__STREXB(evt_value, &m_rsch_pending_evt)); - - return evt; -} - -static bool rsch_pending_evt_is_none(void) -{ - return (rsch_evt_t)m_rsch_pending_evt == RSCH_EVT_NONE; -} - -static void rsch_evt_process(rsch_evt_t evt) -{ - switch (evt) - { - case RSCH_EVT_NONE: - break; - - case RSCH_EVT_STARTED: - nrf_802154_critical_section_rsch_prec_approved(); - break; - - case RSCH_EVT_ENDED: - nrf_802154_critical_section_rsch_prec_denied(); - break; - - default: - assert(false); - } -} +static volatile uint8_t m_critical_section_monitor; ///< Monitors each critical section enter operation +static volatile uint8_t m_nested_critical_section_counter; ///< Counter of nested critical sections +static volatile int8_t m_nested_critical_section_allowed_priority; ///< Indicator if nested critical sections are currently allowed /*************************************************************************************************** * @section Critical sections management @@ -156,7 +66,7 @@ static void rsch_evt_process(rsch_evt_t evt) */ static void radio_critical_section_enter(void) { - if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL)) + if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL, RSCH_PRIO_MIN_APPROVED)) { NVIC_DisableIRQ(RADIO_IRQn); } @@ -169,7 +79,7 @@ static void radio_critical_section_enter(void) */ static void radio_critical_section_exit(void) { - if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL)) + if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL, RSCH_PRIO_MIN_APPROVED)) { NVIC_EnableIRQ(RADIO_IRQn); } @@ -194,8 +104,7 @@ static int8_t active_priority_convert(uint32_t active_priority) static bool nested_critical_section_is_allowed_in_this_context(void) { return m_nested_critical_section_allowed_priority == - active_priority_convert( - nrf_802154_critical_section_active_vector_priority_get()); + active_priority_convert(nrf_802154_critical_section_active_vector_priority_get()); } static bool critical_section_enter(bool forced) @@ -215,6 +124,7 @@ static bool critical_section_enter(bool forced) } while (__STREXB(cnt + 1, &m_nested_critical_section_counter)); + nrf_802154_critical_section_rsch_enter(); nrf_802154_lp_timer_critical_section_enter(); radio_critical_section_enter(); __DSB(); @@ -230,8 +140,7 @@ static bool critical_section_enter(bool forced) static void critical_section_exit(void) { - uint8_t cnt = m_nested_critical_section_counter; - rsch_evt_t rsch_evt = RSCH_EVT_NONE; + uint8_t cnt = m_nested_critical_section_counter; uint8_t monitor; uint8_t atomic_cnt; static bool exiting_crit_sect; @@ -239,11 +148,6 @@ static void critical_section_exit(void) assert(cnt > 0); - if (cnt == 1) - { - rsch_evt = rsch_pending_evt_clear(); - } - do { monitor = m_critical_section_monitor; @@ -255,7 +159,7 @@ static void critical_section_exit(void) (void)exiting_crit_sect; exiting_crit_sect = true; - rsch_evt_process(rsch_evt); + nrf_802154_critical_section_rsch_exit(); radio_critical_section_exit(); nrf_802154_lp_timer_critical_section_exit(); @@ -273,10 +177,9 @@ static void critical_section_exit(void) // change of state or critical section was visited by higher priority IRQ meantime. if (cnt == 1) { - rsch_evt = rsch_pending_evt_clear(); - // Check if critical section must be exited again. - if ((rsch_evt != RSCH_EVT_NONE) || (monitor != m_critical_section_monitor)) + if (nrf_802154_critical_section_rsch_event_is_pending() || + (monitor != m_critical_section_monitor)) { result = critical_section_enter(false); assert(result); @@ -341,11 +244,11 @@ void nrf_802154_critical_section_exit(void) void nrf_802154_critical_section_nesting_allow(void) { assert(m_nested_critical_section_allowed_priority == - NESTED_CRITICAL_SECTION_ALLOWED_PRIORITY_NONE); + NESTED_CRITICAL_SECTION_ALLOWED_PRIORITY_NONE); assert(m_nested_critical_section_counter >= 1); m_nested_critical_section_allowed_priority = active_priority_convert( - nrf_802154_critical_section_active_vector_priority_get()); + nrf_802154_critical_section_active_vector_priority_get()); } void nrf_802154_critical_section_nesting_deny(void) @@ -380,46 +283,3 @@ uint32_t nrf_802154_critical_section_active_vector_priority_get(void) return active_priority; } - -/*************************************************************************************************** - * @section RSCH callbacks - **************************************************************************************************/ - -void nrf_802154_rsch_prec_approved(void) -{ - bool crit_sect_success = critical_section_enter(false); - - if (crit_sect_success && rsch_pending_evt_is_none()) - { - nrf_802154_critical_section_rsch_prec_approved(); - } - else - { - rsch_pending_evt_set(RSCH_EVT_STARTED); - } - - if (crit_sect_success) - { - critical_section_exit(); - } -} - -void nrf_802154_rsch_prec_denied(void) -{ - bool crit_sect_success = critical_section_enter(false); - - if (crit_sect_success && rsch_pending_evt_is_none()) - { - nrf_802154_critical_section_rsch_prec_denied(); - } - else - { - rsch_pending_evt_set(RSCH_EVT_ENDED); - } - - if (crit_sect_success) - { - critical_section_exit(); - } -} - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.h index 9a94eaab6..d017e9522 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.h @@ -104,24 +104,20 @@ bool nrf_802154_critical_section_is_nested(void); */ uint32_t nrf_802154_critical_section_active_vector_priority_get(void); +/** + * @brief Function called to enter critical section in the RSCH module. + */ +extern void nrf_802154_critical_section_rsch_enter(void); /** - * @brief The critical section module calls this function to notify the core that all RSCH - * preconditions are met. - * - * @note This function is called from critical section context and does not preempt other critical - * sections. + * @brief Function called to exit critical section in the RSCH module. */ -extern void nrf_802154_critical_section_rsch_prec_approved(void); +extern void nrf_802154_critical_section_rsch_exit(void); /** - * @brief The critical section module calls this function to notify the core that any of RSCH - * preconditions is not met anymore. - * - * @note This function is called from critical section context and does not preempt other critical - * sections. + * @brief Check if there is pending event in the RSCH critical section. */ -extern void nrf_802154_critical_section_rsch_prec_denied(void); +extern bool nrf_802154_critical_section_rsch_event_is_pending(void); /** *@} diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c index 7fcda41c8..aa6c6ebfb 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c @@ -48,6 +48,7 @@ volatile uint32_t nrf_802154_debug_log_buffer[NRF_802154_DEBUG_LOG_BUFFER_LEN]; /// Index of the log buffer pointing to the element that should be filled with next log message. volatile uint32_t nrf_802154_debug_log_ptr = 0; + #endif #if ENABLE_DEBUG_GPIO @@ -63,12 +64,30 @@ static void radio_event_gpio_toggle_init(void) nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_EDEND); nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_PHYEND); - nrf_gpiote_task_configure(0, PIN_DBG_RADIO_EVT_END, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(1, PIN_DBG_RADIO_EVT_DISABLED, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(2, PIN_DBG_RADIO_EVT_READY, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(3, PIN_DBG_RADIO_EVT_FRAMESTART, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(4, PIN_DBG_RADIO_EVT_EDEND, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(5, PIN_DBG_RADIO_EVT_PHYEND, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(0, + PIN_DBG_RADIO_EVT_END, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(1, + PIN_DBG_RADIO_EVT_DISABLED, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(2, + PIN_DBG_RADIO_EVT_READY, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(3, + PIN_DBG_RADIO_EVT_FRAMESTART, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(4, + PIN_DBG_RADIO_EVT_EDEND, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(5, + PIN_DBG_RADIO_EVT_PHYEND, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); nrf_gpiote_task_enable(0); nrf_gpiote_task_enable(1); @@ -77,12 +96,24 @@ static void radio_event_gpio_toggle_init(void) nrf_gpiote_task_enable(4); nrf_gpiote_task_enable(5); - nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL0, (uint32_t) &NRF_RADIO->EVENTS_END, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0)); - nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL1, (uint32_t) &NRF_RADIO->EVENTS_DISABLED, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1)); - nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL2, (uint32_t) &NRF_RADIO->EVENTS_READY, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2)); - nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL3, (uint32_t) &NRF_RADIO->EVENTS_FRAMESTART, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3)); - nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL4, (uint32_t) &NRF_RADIO->EVENTS_EDEND, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_4)); - nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, (uint32_t) &NRF_RADIO->EVENTS_PHYEND, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL0, + (uint32_t)&NRF_RADIO->EVENTS_END, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL1, + (uint32_t)&NRF_RADIO->EVENTS_DISABLED, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL2, + (uint32_t)&NRF_RADIO->EVENTS_READY, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL3, + (uint32_t)&NRF_RADIO->EVENTS_FRAMESTART, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL4, + (uint32_t)&NRF_RADIO->EVENTS_EDEND, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_4)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, + (uint32_t)&NRF_RADIO->EVENTS_PHYEND, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5)); nrf_ppi_channel_enable(NRF_PPI_CHANNEL0); nrf_ppi_channel_enable(NRF_PPI_CHANNEL1); @@ -118,15 +149,21 @@ static void raal_softdevice_event_gpio_toggle_init(void) nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_BLOCKED); nrf_gpio_cfg_output(PIN_DBG_RTC0_EVT_REM); - nrf_gpiote_task_configure(5, PIN_DBG_RTC0_EVT_REM, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(5, + PIN_DBG_RTC0_EVT_REM, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); nrf_gpiote_task_enable(5); - nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, (uint32_t) &NRF_RTC0->EVENTS_COMPARE[1], nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5)); + nrf_ppi_channel_endpoint_setup(NRF_PPI_CHANNEL5, + (uint32_t)&NRF_RTC0->EVENTS_COMPARE[1], + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_5)); nrf_ppi_channel_enable(NRF_PPI_CHANNEL5); #endif // RAAL_SOFTDEVICE } + #endif // ENABLE_DEBUG_GPIO void nrf_802154_debug_init(void) @@ -139,15 +176,17 @@ void nrf_802154_debug_init(void) } #if ENABLE_DEBUG_ASSERT -void __assert_func(const char *file, int line, const char *func, const char *cond) +void __assert_func(const char * file, int line, const char * func, const char * cond) { - (void) file; - (void) line; - (void) func; - (void) cond; + (void)file; + (void)line; + (void)func; + (void)cond; __disable_irq(); - while (1); + while (1) + ; } + #endif // ENABLE_DEBUG_ASSERT diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h index 60e93c041..33a503669 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.h @@ -42,7 +42,7 @@ extern "C" { #endif -#define NRF_802154_DEBUG_LOG_BUFFER_LEN 1024 +#define NRF_802154_DEBUG_LOG_BUFFER_LEN 1024 #define EVENT_TRACE_ENTER 0x0001UL #define EVENT_TRACE_EXIT 0x0002UL @@ -60,6 +60,7 @@ extern "C" { #define FUNCTION_CONTINUOUS_CARRIER 0x0007UL #define FUNCTION_CSMACA 0x0008UL #define FUNCTION_TRANSMIT_AT 0x0009UL +#define FUNCTION_RECEIVE_AT 0x000AUL #define FUNCTION_IRQ_HANDLER 0x0100UL #define FUNCTION_EVENT_FRAMESTART 0x0101UL @@ -96,21 +97,22 @@ extern "C" { #define FUNCTION_RAAL_EVT_BLOCKED 0x0408UL #define FUNCTION_RAAL_EVT_SESSION_IDLE 0x0409UL #define FUNCTION_RAAL_EVT_HFCLK_READY 0x040AUL +#define FUNCTION_RAAL_SIG_EVENT_MARGIN_MOVE 0x040BUL -#define FUNCTION_RSCH_CONTINUOUS_ENTER 0x040BUL -#define FUNCTION_RSCH_CONTINUOUS_EXIT 0x040CUL -#define FUNCTION_RSCH_CRITICAL_SECTION_ENTER 0x040DUL -#define FUNCTION_RSCH_CRITICAL_SECTION_EXIT 0x040EUL -#define FUNCTION_RSCH_TIMESLOT_STARTED 0x040FUL -#define FUNCTION_RSCH_TIMESLOT_ENDED 0x0410UL -#define FUNCTION_RSCH_PEND_GRANTED 0x0411UL -#define FUNCTION_RSCH_PEND_REVOKED 0x0412UL -#define FUNCTION_RSCH_NOTIFY_GRANTED 0x0413UL -#define FUNCTION_RSCH_NOTIFY_REVOKED 0x0414UL -#define FUNCTION_RSCH_NOTIFY_IF_PENDING 0x0415UL -#define FUNCTION_RSCH_DELAYED_TIMESLOT_REQ 0x0416UL -#define FUNCTION_RSCH_TIMER_DELAYED_PREC 0x0417UL -#define FUNCTION_RSCH_TIMER_DELAYED_START 0x0418UL +#define FUNCTION_RSCH_CONTINUOUS_ENTER 0x0480UL +#define FUNCTION_RSCH_CONTINUOUS_EXIT 0x0481UL +#define FUNCTION_RSCH_CRITICAL_SECTION_ENTER 0x0482UL +#define FUNCTION_RSCH_CRITICAL_SECTION_EXIT 0x0483UL +#define FUNCTION_RSCH_TIMESLOT_STARTED 0x0484UL +#define FUNCTION_RSCH_TIMESLOT_ENDED 0x0485UL +#define FUNCTION_RSCH_PEND_GRANTED 0x0486UL +#define FUNCTION_RSCH_PEND_REVOKED 0x0487UL +#define FUNCTION_RSCH_NOTIFY_GRANTED 0x0488UL +#define FUNCTION_RSCH_NOTIFY_REVOKED 0x0489UL +#define FUNCTION_RSCH_NOTIFY_IF_PENDING 0x048AUL +#define FUNCTION_RSCH_DELAYED_TIMESLOT_REQ 0x048BUL +#define FUNCTION_RSCH_TIMER_DELAYED_PREC 0x048CUL +#define FUNCTION_RSCH_TIMER_DELAYED_START 0x048DUL #define FUNCTION_CSMA_ABORT 0x0500UL #define FUNCTION_CSMA_TX_FAILED 0x0501UL @@ -140,16 +142,19 @@ extern "C" { #if ENABLE_DEBUG_LOG extern volatile uint32_t nrf_802154_debug_log_buffer[ - NRF_802154_DEBUG_LOG_BUFFER_LEN]; + NRF_802154_DEBUG_LOG_BUFFER_LEN]; extern volatile uint32_t nrf_802154_debug_log_ptr; -#define nrf_802154_log(EVENT_CODE, EVENT_ARG) \ - do { \ - uint32_t ptr = nrf_802154_debug_log_ptr; \ - nrf_802154_debug_log_buffer[ptr] = ((EVENT_CODE) | ((EVENT_ARG) << 16)); \ - nrf_802154_debug_log_ptr = \ - ptr < (NRF_802154_DEBUG_LOG_BUFFER_LEN - 1) ? ptr + 1 : 0; \ - } while (0) +#define nrf_802154_log(EVENT_CODE, EVENT_ARG) \ + do \ + { \ + uint32_t ptr = nrf_802154_debug_log_ptr; \ + \ + nrf_802154_debug_log_buffer[ptr] = ((EVENT_CODE) | ((EVENT_ARG) << 16)); \ + nrf_802154_debug_log_ptr = \ + ptr < (NRF_802154_DEBUG_LOG_BUFFER_LEN - 1) ? ptr + 1 : 0; \ + } \ + while (0) #else // ENABLE_DEBUG_LOG @@ -161,10 +166,15 @@ extern volatile uint32_t nrf_802154_debug_log_ptr; #define nrf_802154_pin_set(pin) NRF_P0->OUTSET = (1UL << (pin)) #define nrf_802154_pin_clr(pin) NRF_P0->OUTCLR = (1UL << (pin)) -#define nrf_802154_pin_tgl(pin) do { volatile uint32_t ps = NRF_P0->OUT; \ - NRF_P0->OUTSET = (~ps & (1UL << (pin))); \ - NRF_P0->OUTCLR = (ps & (1UL << (pin))); \ - } while(0); +#define nrf_802154_pin_tgl(pin) \ + do \ + { \ + volatile uint32_t ps = NRF_P0->OUT; \ + \ + NRF_P0->OUTSET = (~ps & (1UL << (pin))); \ + NRF_P0->OUTCLR = (ps & (1UL << (pin))); \ + } \ + while (0); #else // ENABLE_DEBUG_GPIO diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification.h index 9425486bb..7bb3cad05 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification.h @@ -55,7 +55,7 @@ extern "C" { * * @param[in] result If called request succeeded. */ -typedef void (*nrf_802154_notification_func_t)(bool result); +typedef void (* nrf_802154_notification_func_t)(bool result); /** * @brief Initialize notification module. diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_direct.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_direct.c index 1f92d6a26..ad35b6c2c 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_direct.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_direct.c @@ -56,7 +56,7 @@ void nrf_802154_notify_received(uint8_t * p_data, int8_t power, int8_t lqi) nrf_802154_received_raw(p_data, power, lqi); #else // NRF_802154_USE_RAW_API nrf_802154_received(p_data + RAW_PAYLOAD_OFFSET, p_data[RAW_LENGTH_OFFSET], power, lqi); -#endif // NRF_802154_USE_RAW_API +#endif // NRF_802154_USE_RAW_API } void nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error) @@ -86,7 +86,7 @@ void nrf_802154_notify_transmit_failed(const uint8_t * p_frame, nrf_802154_tx_er nrf_802154_transmit_failed(p_frame, error); #else // NRF_802154_USE_RAW_API nrf_802154_transmit_failed(p_frame + RAW_PAYLOAD_OFFSET, error); -#endif // NRF_802154_USE_RAW_API +#endif // NRF_802154_USE_RAW_API } void nrf_802154_notify_energy_detected(uint8_t result) diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_swi.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_swi.c index 1719a5930..aab450884 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_swi.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_notification_swi.c @@ -89,4 +89,3 @@ void nrf_802154_notify_cca_failed(nrf_802154_cca_error_t error) { nrf_802154_swi_notify_cca_failed(error); } - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c index 21d4f74fd..71590655f 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c @@ -46,18 +46,19 @@ typedef struct { - int8_t tx_power; ///< Transmit power. - uint8_t pan_id[PAN_ID_SIZE]; ///< Pan Id of this node. - uint8_t short_addr[SHORT_ADDRESS_SIZE]; ///< Short Address of this node. - uint8_t extended_addr[EXTENDED_ADDRESS_SIZE]; ///< Extended Address of this node. - nrf_802154_cca_cfg_t cca; ///< CCA mode and thresholds. - bool promiscuous :1; ///< Indicating if radio is in promiscuous mode. - bool auto_ack :1; ///< Indicating if auto ACK procedure is enabled. - bool pan_coord :1; ///< Indicating if radio is configured as the PAN coordinator. - uint8_t channel :5; ///< Channel on which the node receives messages. + int8_t tx_power; ///< Transmit power. + uint8_t pan_id[PAN_ID_SIZE]; ///< Pan Id of this node. + uint8_t short_addr[SHORT_ADDRESS_SIZE]; ///< Short Address of this node. + uint8_t extended_addr[EXTENDED_ADDRESS_SIZE]; ///< Extended Address of this node. + nrf_802154_cca_cfg_t cca; ///< CCA mode and thresholds. + bool promiscuous : 1; ///< Indicating if radio is in promiscuous mode. + bool auto_ack : 1; ///< Indicating if auto ACK procedure is enabled. + bool pan_coord : 1; ///< Indicating if radio is configured as the PAN coordinator. + uint8_t channel : 5; ///< Channel on which the node receives messages. } nrf_802154_pib_data_t; -static nrf_802154_pib_data_t m_data; ///< Buffer containing PIB data. +// Static variables. +static nrf_802154_pib_data_t m_data; ///< Buffer containing PIB data. void nrf_802154_pib_init(void) { @@ -125,7 +126,9 @@ int8_t nrf_802154_pib_tx_power_get(void) void nrf_802154_pib_tx_power_set(int8_t dbm) { const int8_t allowed_values[] = {-40, -20, -16, -12, -8, -4, 0, 2, 3, 4, 5, 6, 7, 8}; - const int8_t highest_value = allowed_values[(sizeof(allowed_values) / sizeof(allowed_values[0])) - 1]; + const int8_t highest_value = + allowed_values[(sizeof(allowed_values) / sizeof(allowed_values[0])) - 1]; + if (dbm > highest_value) { dbm = highest_value; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.h index 95bdc0544..3a390b695 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.h @@ -95,7 +95,6 @@ bool nrf_802154_pib_pan_coord_get(void); */ void nrf_802154_pib_pan_coord_set(bool enabled); - /** * @brief Get currently used channel. * @@ -191,4 +190,3 @@ void nrf_802154_pib_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg); #endif #endif /* NRF_802154_PIB_H_ */ - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop.h index 14de19f08..13d2d0244 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop.h @@ -49,20 +49,21 @@ extern "C" { void nrf_802154_priority_drop_init(void); /** - * @brief Request discarding of the timeslot. + * @brief Request stop of the high frequency clock. * - * @note This function should be called through this module to prevent calling it from arbiter context. + * @note This function should be called through this module to prevent calling it from the arbiter + * context. */ -void nrf_802154_priority_drop_timeslot_exit(void); +void nrf_802154_priority_drop_hfclk_stop(void); /** - * @brief Terminate requesting of timeslot discarding. + * @brief Terminate requesting of high frequency clock stop. * - * Function used to to terminate timeslot exit procedure requested by previous call to - * @rev nrf_802154_priority_drop_timeslot_exit. Timeslot discarding is terminated only if it has + * Function used to to terminate HFClk stop procedure requested by previous call to + * @rev nrf_802154_priority_drop_hfclk_stop. The HFClk stop procedure is terminated only if it has * not been started. */ -void nrf_802154_priority_drop_timeslot_exit_terminate(void); +void nrf_802154_priority_drop_hfclk_stop_terminate(void); /** *@} @@ -73,4 +74,3 @@ void nrf_802154_priority_drop_timeslot_exit_terminate(void); #endif #endif // NRF_802154_PRIORITY_DROP_H__ - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_direct.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_direct.c index 486312fd1..fe79f0a25 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_direct.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_direct.c @@ -37,21 +37,20 @@ #include "nrf_802154_priority_drop.h" -#include "nrf_802154_rsch.h" +#include "platform/clock/nrf_802154_clock.h" void nrf_802154_priority_drop_init(void) { // Intentionally empty } -void nrf_802154_priority_drop_timeslot_exit(void) +void nrf_802154_priority_drop_hfclk_stop(void) { - nrf_802154_rsch_continuous_mode_exit(); + nrf_802154_clock_hfclk_stop(); } -void nrf_802154_priority_drop_timeslot_exit_terminate(void) +void nrf_802154_priority_drop_hfclk_stop_terminate(void) { // Intentionally empty: - // nrf_802154_priority_drop_timeslot_exit is synchronous and cannot be terminated. + // nrf_802154_priority_drop_hfclk_stop is synchronous and cannot be terminated. } - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_swi.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_swi.c index e6e36bcfa..ae2a31c02 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_swi.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_priority_drop_swi.c @@ -44,13 +44,12 @@ void nrf_802154_priority_drop_init(void) nrf_802154_swi_init(); } -void nrf_802154_priority_drop_timeslot_exit(void) +void nrf_802154_priority_drop_hfclk_stop(void) { - nrf_802154_swi_timeslot_exit(); + nrf_802154_swi_hfclk_stop(); } -void nrf_802154_priority_drop_timeslot_exit_terminate(void) +void nrf_802154_priority_drop_hfclk_stop_terminate(void) { - nrf_802154_swi_timeslot_exit_terminate(); + nrf_802154_swi_hfclk_stop_terminate(); } - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h index 94a75306b..8d209d4ef 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h @@ -42,25 +42,26 @@ #include "nrf_802154_const.h" -#define TX_RAMP_UP_TIME 40 // us -#define RX_RAMP_UP_TIME 40 // us -#define RX_RAMP_DOWN_TIME 0 // us -#define MAX_RAMP_DOWN_TIME 6 // us -#define RX_TX_TURNAROUND_TIME 20 // us +#define TX_RAMP_UP_TIME 40 // us +#define RX_RAMP_UP_TIME 40 // us +#define RX_RAMP_DOWN_TIME 0 // us +#define MAX_RAMP_DOWN_TIME 6 // us +#define RX_TX_TURNAROUND_TIME 20 // us -#define A_CCA_DURATION_SYMBOLS 8 // sym -#define A_TURNAROUND_TIME_SYMBOLS 12 // sym -#define A_UNIT_BACKOFF_SYMBOLS 20 // sym +#define A_CCA_DURATION_SYMBOLS 8 // sym +#define A_TURNAROUND_TIME_SYMBOLS 12 // sym +#define A_UNIT_BACKOFF_SYMBOLS 20 // sym #define PHY_SYMBOLS_FROM_OCTETS(octets) ((octets) * PHY_SYMBOLS_PER_OCTET) #define PHY_US_TIME_FROM_SYMBOLS(symbols) ((symbols) * PHY_US_PER_SYMBOL) -#define IMM_ACK_SYMBOLS (PHY_SHR_SYMBOLS + PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE)) -#define IMM_ACK_DURATION (PHY_US_TIME_FROM_SYMBOLS(IMM_ACK_SYMBOLS)) +#define IMM_ACK_SYMBOLS (PHY_SHR_SYMBOLS + \ + PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE)) +#define IMM_ACK_DURATION (PHY_US_TIME_FROM_SYMBOLS(IMM_ACK_SYMBOLS)) -#define MAC_IMM_ACK_WAIT_SYMBOLS (A_UNIT_BACKOFF_SYMBOLS + \ - A_TURNAROUND_TIME_SYMBOLS + \ - IMM_ACK_SYMBOLS) +#define MAC_IMM_ACK_WAIT_SYMBOLS (A_UNIT_BACKOFF_SYMBOLS + \ + A_TURNAROUND_TIME_SYMBOLS + \ + IMM_ACK_SYMBOLS) __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, bool cca, @@ -101,7 +102,10 @@ __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, // if CCA: + RX ramp up + CCA + RX ramp down // + TX ramp up + SHR + PHR + PSDU // if ACK: + macAckWaitDuration - uint16_t us_time = MAX_RAMP_DOWN_TIME + TX_RAMP_UP_TIME + nrf_802154_frame_duration_get(psdu_length, true, true); + uint16_t us_time = MAX_RAMP_DOWN_TIME + TX_RAMP_UP_TIME + nrf_802154_frame_duration_get( + psdu_length, + true, + true); if (ack_requested) { @@ -110,7 +114,8 @@ __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, if (cca) { - us_time += RX_RAMP_UP_TIME + RX_RAMP_DOWN_TIME + PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS); + us_time += RX_RAMP_UP_TIME + RX_RAMP_DOWN_TIME + PHY_US_TIME_FROM_SYMBOLS( + A_CCA_DURATION_SYMBOLS); } return us_time; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_direct.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_direct.c index 4ee9e8f01..93d414c84 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_direct.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_direct.c @@ -42,14 +42,13 @@ #include "nrf_802154_core.h" #include "hal/nrf_radio.h" -#define REQUEST_FUNCTION(func_core, ...) \ - bool result; \ - \ - result = func_core(__VA_ARGS__); \ - \ +#define REQUEST_FUNCTION(func_core, ...) \ + bool result; \ + \ + result = func_core(__VA_ARGS__); \ + \ return result; - void nrf_802154_request_init(void) { // Intentionally empty @@ -75,7 +74,13 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl, bool immediate, nrf_802154_notification_func_t notify_function) { - REQUEST_FUNCTION(nrf_802154_core_transmit, term_lvl, req_orig, p_data, cca, immediate, notify_function) + REQUEST_FUNCTION(nrf_802154_core_transmit, + term_lvl, + req_orig, + p_data, + cca, + immediate, + notify_function) } bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us) diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c index de45decc8..d37160cf3 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c @@ -57,34 +57,34 @@ static inline void assert_interrupt_status(void) assert(nrf_is_nvic_irq_enabled(NRF_802154_SWI_IRQN)); } -#define REQUEST_FUNCTION(func_core, func_swi, ...) \ - bool result = false; \ - \ - if (active_vector_priority_is_high()) \ - { \ - result = func_core(__VA_ARGS__); \ - } \ - else \ - { \ - assert_interrupt_status(); \ - func_swi(__VA_ARGS__, &result); \ - } \ - \ +#define REQUEST_FUNCTION(func_core, func_swi, ...) \ + bool result = false; \ + \ + if (active_vector_priority_is_high()) \ + { \ + result = func_core(__VA_ARGS__); \ + } \ + else \ + { \ + assert_interrupt_status(); \ + func_swi(__VA_ARGS__, &result); \ + } \ + \ return result; -#define REQUEST_FUNCTION_NO_ARGS(func_core, func_swi) \ - bool result = false; \ - \ - if (active_vector_priority_is_high()) \ - { \ - result = func_core(); \ - } \ - else \ - { \ - assert_interrupt_status(); \ - func_swi(&result); \ - } \ - \ +#define REQUEST_FUNCTION_NO_ARGS(func_core, func_swi) \ + bool result = false; \ + \ + if (active_vector_priority_is_high()) \ + { \ + result = func_core(); \ + } \ + else \ + { \ + assert_interrupt_status(); \ + func_swi(&result); \ + } \ + \ return result; /** Check if active vector priority is high enough to call requests directly. @@ -154,7 +154,8 @@ bool nrf_802154_request_cca(nrf_802154_term_t term_lvl) bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, nrf_802154_swi_continuous_carrier, term_lvl) + REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, nrf_802154_swi_continuous_carrier, + term_lvl) } bool nrf_802154_request_buffer_free(uint8_t * p_data) @@ -171,4 +172,3 @@ bool nrf_802154_request_cca_cfg_update(void) { REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update, nrf_802154_swi_cca_cfg_update) } - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c index 473b49dfc..733739937 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c @@ -115,17 +115,17 @@ bool nrf_802154_revision_has_phyend_event(void) switch (m_nrf52840_revision) { - case NRF52840_REVISION_AAAA: - result = false; - break; + case NRF52840_REVISION_AAAA: + result = false; + break; - case NRF52840_REVISION_AABA: - case NRF52840_REVISION_UNKNOWN: - result = true; - break; + case NRF52840_REVISION_AABA: + case NRF52840_REVISION_UNKNOWN: + result = true; + break; - default: - assert(false); + default: + assert(false); } return result; diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.c deleted file mode 100644 index f65594ac8..000000000 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.c +++ /dev/null @@ -1,466 +0,0 @@ -#include "nrf_802154_rsch.h" - -#include -#include -#include - -#include "nrf_802154_debug.h" -#include "platform/clock/nrf_802154_clock.h" -#include "raal/nrf_raal_api.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" - -#define PREC_RAMP_UP_TIME 300 ///< Ramp-up time of preconditions [us]. 300 is worst case for HFclock - -typedef enum -{ - RSCH_PREC_STATE_IDLE, - RSCH_PREC_STATE_REQUESTED, - RSCH_PREC_STATE_APPROVED, -} rsch_prec_state_t; - -static volatile uint8_t m_mutex; ///< Mutex for notyfying core. -static volatile uint8_t m_mutex_monitor; ///< Mutex monitor, incremented every failed mutex lock. -static volatile bool m_last_notified_approved; ///< Last reported state was approved. -static volatile rsch_prec_state_t m_prec_states[RSCH_PREC_CNT]; ///< State of all preconditions. -static bool m_in_cont_mode; ///< If RSCH operates in continuous mode. - -static bool m_delayed_timeslot_is_scheduled; ///< If delayed timeslot is scheduled at the moment. -static uint32_t m_delayed_timeslot_t0; ///< Time base of the delayed timeslot trigger time. -static uint32_t m_delayed_timeslot_dt; ///< Time delta of the delayed timeslot trigger time. -static nrf_802154_timer_t m_timer; ///< Timer used to trigger delayed timeslot. - -/** @brief Non-blocking mutex for notifying core. - * - * @retval true Mutex was acquired. - * @retval false Mutex could not be acquired. - */ -static inline bool mutex_trylock(void) -{ - do - { - uint8_t mutex_value = __LDREXB(&m_mutex); - - if (mutex_value) - { - __CLREX(); - - m_mutex_monitor++; - return false; - } - } while (__STREXB(1, &m_mutex)); - - __DMB(); - - return true; -} - -/** @brief Release mutex. */ -static inline void mutex_unlock(void) -{ - __DMB(); - m_mutex = 0; -} - -/** @brief Check if any precondition should be requested at the moment for delayed timeslot. - * - * To meet delayed timeslot timing requirements there is a time window in which radio - * preconditions should be requested. This function is used to prevent releasing preconditions - * in this time window. - * - * @retval true A precondition should be requested at the moment for delayed timeslot feature. - * @retval false None of preconditions should be requested at the moment for delayed timeslot. - */ -static bool any_prec_should_be_requested_for_delayed_timeslot(void) -{ - uint32_t now = nrf_802154_timer_sched_time_get(); - uint32_t t0 = m_delayed_timeslot_t0; - uint32_t dt = m_delayed_timeslot_dt - PREC_RAMP_UP_TIME - - nrf_802154_timer_sched_granularity_get(); - - return (m_delayed_timeslot_is_scheduled && - !nrf_802154_timer_sched_time_is_in_future(now, t0, dt)); -} - -/** @brief Set RSCH_PREC_STATE_APPROVED state on given precondition @p prec only if - * its current state is other than RSCH_PREC_STATE_IDLE. - * - * @param[in] prec Precondition which state will be changed. - */ -static inline void prec_approve(rsch_prec_t prec) -{ - do - { - rsch_prec_state_t old_state = (rsch_prec_state_t) __LDREXB((uint8_t*)&m_prec_states[prec]); - - assert(old_state != RSCH_PREC_STATE_APPROVED); - - if (old_state == RSCH_PREC_STATE_IDLE) - { - __CLREX(); - return; - } - } while (__STREXB((uint8_t)RSCH_PREC_STATE_APPROVED, (uint8_t*)&m_prec_states[prec])); -} - -/** @brief Set RSCH_PREC_STATE_REQUESTED state on given precondition @p prec only if - * its current state is RSCH_PREC_STATE_APPROVED. - * - * @param[in] prec Precondition which state will be changed. - */ -static inline void prec_deny(rsch_prec_t prec) -{ - do - { - rsch_prec_state_t old_state = (rsch_prec_state_t) __LDREXB((uint8_t*)&m_prec_states[prec]); - - assert(old_state != RSCH_PREC_STATE_REQUESTED); - - if (old_state != RSCH_PREC_STATE_APPROVED) - { - __CLREX(); - return; - } - } while (__STREXB((uint8_t)RSCH_PREC_STATE_REQUESTED, (uint8_t*)&m_prec_states[prec])); -} - -/** @brief Set RSCH_PREC_STATE_REQUESTED state on given precondition @p prec only if - * its current state is RSCH_PREC_STATE_IDLE. - * - * @param[in] prec Precondition which state will be changed. - * - * @retval true Precondition changed state to requested. - * @retval false Precondition cannot change state to requested due to invalid state. - */ -static inline bool prec_request(rsch_prec_t prec) -{ - do - { - rsch_prec_state_t old_state = (rsch_prec_state_t) __LDREXB((uint8_t*)&m_prec_states[prec]); - - if (old_state != RSCH_PREC_STATE_IDLE) - { - __CLREX(); - return false; - } - } while (__STREXB((uint8_t)RSCH_PREC_STATE_REQUESTED, (uint8_t*)&m_prec_states[prec])); - - return true; -} - -/** @brief Set RSCH_PREC_STATE_IDLE state on given precondition @p prec. - * - * @param[in] prec Precondition which state will be changed. - */ -static inline void prec_release(rsch_prec_t prec) -{ - assert(m_prec_states[prec] != RSCH_PREC_STATE_IDLE); - m_prec_states[prec] = RSCH_PREC_STATE_IDLE; - __CLREX(); -} - -/** @brief Request all preconditions. - */ -static inline void all_prec_request(void) -{ - if (prec_request(RSCH_PREC_HFCLK)) - { - nrf_802154_clock_hfclk_start(); - } - - if (prec_request(RSCH_PREC_RAAL)) - { - nrf_raal_continuous_mode_enter(); - } -} - -/** @brief Release all preconditions if not needed. - * - * If RSCH is not in continuous mode and delayed timeslot is not expected all preconditions are - * released. - */ -static inline void all_prec_release(void) -{ - if (!m_in_cont_mode && !any_prec_should_be_requested_for_delayed_timeslot()) - { - prec_release(RSCH_PREC_HFCLK); - nrf_802154_clock_hfclk_stop(); - - prec_release(RSCH_PREC_RAAL); - nrf_raal_continuous_mode_exit(); - } -} - -/** @brief Check if all preconditions are met. - * - * @retval true All preconditions are met. - * @retval false At least one precondition is not met. - */ -static inline bool all_prec_are_approved(void) -{ - for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) - { - if (m_prec_states[i] != RSCH_PREC_STATE_APPROVED) - { - return false; - } - } - - return true; -} - -/** @brief Check if all preconditions are requested or met. - * - * @retval true All preconditions are requested or met. - * @retval false At least one precondition is idle. - */ -static inline bool all_prec_are_requested(void) -{ - for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) - { - if (m_prec_states[i] == RSCH_PREC_STATE_IDLE) - { - return false; - } - } - - return true; -} - - -/** @brief Notify core if preconditions are approved or denied if current state differs from last reported. - */ -static inline void notify_core(void) -{ - bool notify_approved; - uint8_t temp_mon; - - do - { - if (!mutex_trylock()) - { - return; - } - - /* It is possible that preemption is not detected (m_mutex_monitor is read after acquiring mutex). - * It is not a problem because we will call proper handler function requested by preempting context. - * Avoiding this race would generate one additional iteration without any effect. - */ - temp_mon = m_mutex_monitor; - notify_approved = all_prec_are_approved(); - - if (m_in_cont_mode && (m_last_notified_approved != notify_approved)) - { - m_last_notified_approved = notify_approved; - - if (notify_approved) - { - nrf_802154_rsch_prec_approved(); - } - else - { - nrf_802154_rsch_prec_denied(); - } - } - - mutex_unlock(); - } while(temp_mon != m_mutex_monitor); -} - -/** Timer callback used to trigger delayed timeslot. - * - * @param[in] p_context Unused parameter. - */ -static void delayed_timeslot_start(void * p_context) -{ - (void)p_context; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMER_DELAYED_START); - - m_delayed_timeslot_is_scheduled = false; - - if (all_prec_are_approved()) - { - nrf_802154_rsch_delayed_timeslot_started(); - } - else - { - nrf_802154_rsch_delayed_timeslot_failed(); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMER_DELAYED_START); -} - -/** Timer callback used to request preconditions for delayed timeslot. - * - * @param[in] p_context Unused parameter. - */ -static void delayed_timeslot_prec_request(void * p_context) -{ - (void)p_context; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMER_DELAYED_PREC); - - all_prec_request(); - - m_timer.t0 = m_delayed_timeslot_t0; - m_timer.dt = m_delayed_timeslot_dt; - m_timer.callback = delayed_timeslot_start; - m_timer.p_context = NULL; - - nrf_802154_timer_sched_add(&m_timer, true); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMER_DELAYED_PREC); -} - -/*************************************************************************************************** - * Public API - **************************************************************************************************/ - -void nrf_802154_rsch_init(void) -{ - nrf_raal_init(); - - m_mutex = 0; - m_last_notified_approved = false; - m_in_cont_mode = false; - m_delayed_timeslot_is_scheduled = false; - - for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) - { - m_prec_states[i] = RSCH_PREC_STATE_IDLE; - } -} - -void nrf_802154_rsch_uninit(void) -{ - nrf_802154_timer_sched_remove(&m_timer); - - nrf_raal_uninit(); -} - -void nrf_802154_rsch_continuous_mode_enter(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_CONTINUOUS_ENTER); - - m_in_cont_mode = true; - __DMB(); - - all_prec_request(); - notify_core(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_CONTINUOUS_ENTER); -} - -void nrf_802154_rsch_continuous_mode_exit(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_CONTINUOUS_EXIT); - - __DMB(); - m_in_cont_mode = false; - - all_prec_release(); - notify_core(); - m_last_notified_approved = false; - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_CONTINUOUS_EXIT); -} - -bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec) -{ - assert(prec < RSCH_PREC_CNT); - return m_prec_states[prec] == RSCH_PREC_STATE_APPROVED; -} - -bool nrf_802154_rsch_timeslot_request(uint32_t length_us) -{ - return nrf_raal_timeslot_request(length_us); -} - -bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0, uint32_t dt, uint32_t length) -{ - (void)length; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_DELAYED_TIMESLOT_REQ); - - uint32_t now = nrf_802154_timer_sched_time_get(); - uint32_t req_dt = dt - PREC_RAMP_UP_TIME; - bool result; - - assert(!nrf_802154_timer_sched_is_running(&m_timer)); - assert(!m_delayed_timeslot_is_scheduled); - - if (nrf_802154_timer_sched_time_is_in_future(now, t0, req_dt)) - { - m_delayed_timeslot_is_scheduled = true; - m_delayed_timeslot_t0 = t0; - m_delayed_timeslot_dt = dt; - - m_timer.t0 = t0; - m_timer.dt = req_dt; - m_timer.callback = delayed_timeslot_prec_request; - m_timer.p_context = NULL; - - nrf_802154_timer_sched_add(&m_timer, false); - - result = true; - } - else if (all_prec_are_requested() && nrf_802154_timer_sched_time_is_in_future(now, t0, dt)) - { - m_delayed_timeslot_is_scheduled = true; - m_delayed_timeslot_t0 = t0; - m_delayed_timeslot_dt = dt; - - m_timer.t0 = t0; - m_timer.dt = dt; - m_timer.callback = delayed_timeslot_start; - m_timer.p_context = NULL; - - nrf_802154_timer_sched_add(&m_timer, true); - - result = true; - } - else - { - result = false; - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_DELAYED_TIMESLOT_REQ); - - return result; -} - -uint32_t nrf_802154_rsch_timeslot_us_left_get(void) -{ - return nrf_raal_timeslot_us_left_get(); -} - -// External handlers - -void nrf_raal_timeslot_started(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMESLOT_STARTED); - - prec_approve(RSCH_PREC_RAAL); - - notify_core(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMESLOT_STARTED); -} - -void nrf_raal_timeslot_ended(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMESLOT_ENDED); - - prec_deny(RSCH_PREC_RAAL); - - notify_core(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMESLOT_ENDED); -} - -void nrf_802154_clock_hfclk_ready(void) -{ - prec_approve(RSCH_PREC_HFCLK); - - notify_core(); -} diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.h index f3d94cb27..41fe5c768 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.h @@ -51,7 +51,7 @@ extern "C" { typedef struct { uint8_t psdu[MAX_PACKET_SIZE + 1]; - bool free; // If this buffer is free or contains a frame. + bool free; // If this buffer is free or contains a frame. } rx_buffer_t; /** @@ -80,4 +80,3 @@ rx_buffer_t * nrf_802154_rx_buffer_free_find(void); #endif #endif /* NRF_802154_RX_BUFFER_H_ */ - diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.c index fff23f07a..5b9ff3f8a 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.c @@ -43,38 +43,37 @@ #include "nrf_802154.h" #include "nrf_802154_config.h" #include "nrf_802154_core.h" -#include "nrf_802154_rsch.h" #include "nrf_802154_rx_buffer.h" #include "hal/nrf_egu.h" - +#include "platform/clock/nrf_802154_clock.h" /** Size of notification queue. * * One slot for each receive buffer, one for transmission, one for busy channel and one for energy * detection. */ -#define NTF_QUEUE_SIZE (NRF_802154_RX_BUFFERS + 3) +#define NTF_QUEUE_SIZE (NRF_802154_RX_BUFFERS + 3) /** Size of requests queue. * * Two is minimal queue size. It is not expected in current implementation to queue a few requests. */ -#define REQ_QUEUE_SIZE 2 +#define REQ_QUEUE_SIZE 2 -#define SWI_EGU NRF_802154_SWI_EGU_INSTANCE ///< Label of SWI peripheral. -#define SWI_IRQn NRF_802154_SWI_IRQN ///< Symbol of SWI IRQ number. -#define SWI_IRQHandler NRF_802154_SWI_IRQ_HANDLER ///< Symbol of SWI IRQ handler. +#define SWI_EGU NRF_802154_SWI_EGU_INSTANCE ///< Label of SWI peripheral. +#define SWI_IRQn NRF_802154_SWI_IRQN ///< Symbol of SWI IRQ number. +#define SWI_IRQHandler NRF_802154_SWI_IRQ_HANDLER ///< Symbol of SWI IRQ handler. -#define NTF_INT NRF_EGU_INT_TRIGGERED0 ///< Label of notification interrupt. -#define NTF_TASK NRF_EGU_TASK_TRIGGER0 ///< Label of notification task. -#define NTF_EVENT NRF_EGU_EVENT_TRIGGERED0 ///< Label of notification event. +#define NTF_INT NRF_EGU_INT_TRIGGERED0 ///< Label of notification interrupt. +#define NTF_TASK NRF_EGU_TASK_TRIGGER0 ///< Label of notification task. +#define NTF_EVENT NRF_EGU_EVENT_TRIGGERED0 ///< Label of notification event. -#define TIMESLOT_EXIT_INT NRF_EGU_INT_TRIGGERED1 ///< Label of timeslot exit interrupt. -#define TIMESLOT_EXIT_TASK NRF_EGU_TASK_TRIGGER1 ///< Label of timeslot exit task. -#define TIMESLOT_EXIT_EVENT NRF_EGU_EVENT_TRIGGERED1 ///< Label of timeslot exit event. +#define HFCLK_STOP_INT NRF_EGU_INT_TRIGGERED1 ///< Label of HFClk stop interrupt. +#define HFCLK_STOP_TASK NRF_EGU_TASK_TRIGGER1 ///< Label of HFClk stop task. +#define HFCLK_STOP_EVENT NRF_EGU_EVENT_TRIGGERED1 ///< Label of HFClk stop event. -#define REQ_INT NRF_EGU_INT_TRIGGERED2 ///< Label of request interrupt. -#define REQ_TASK NRF_EGU_TASK_TRIGGER2 ///< Label of request task. -#define REQ_EVENT NRF_EGU_EVENT_TRIGGERED2 ///< Label of request event. +#define REQ_INT NRF_EGU_INT_TRIGGERED2 ///< Label of request interrupt. +#define REQ_TASK NRF_EGU_TASK_TRIGGER2 ///< Label of request task. +#define REQ_EVENT NRF_EGU_EVENT_TRIGGERED2 ///< Label of request event. #define RAW_LENGTH_OFFSET 0 #define RAW_PAYLOAD_OFFSET 1 @@ -82,68 +81,69 @@ /// Types of notifications in notification queue. typedef enum { - NTF_TYPE_RECEIVED, ///< Frame received - NTF_TYPE_RECEIVE_FAILED, ///< Frame reception failed - NTF_TYPE_TRANSMITTED, ///< Frame transmitted - NTF_TYPE_TRANSMIT_FAILED, ///< Frame transmission failure - NTF_TYPE_ENERGY_DETECTED, ///< Energy detection procedure ended - NTF_TYPE_ENERGY_DETECTION_FAILED, ///< Energy detection procedure failed - NTF_TYPE_CCA, ///< CCA procedure ended - NTF_TYPE_CCA_FAILED, ///< CCA procedure failed + NTF_TYPE_RECEIVED, ///< Frame received + NTF_TYPE_RECEIVE_FAILED, ///< Frame reception failed + NTF_TYPE_TRANSMITTED, ///< Frame transmitted + NTF_TYPE_TRANSMIT_FAILED, ///< Frame transmission failure + NTF_TYPE_ENERGY_DETECTED, ///< Energy detection procedure ended + NTF_TYPE_ENERGY_DETECTION_FAILED, ///< Energy detection procedure failed + NTF_TYPE_CCA, ///< CCA procedure ended + NTF_TYPE_CCA_FAILED, ///< CCA procedure failed } nrf_802154_ntf_type_t; /// Notification data in the notification queue. typedef struct { - nrf_802154_ntf_type_t type; ///< Notification type. + nrf_802154_ntf_type_t type; ///< Notification type. + union { struct { - uint8_t * p_psdu; ///< Pointer to received frame PSDU. - int8_t power; ///< RSSI of received frame. - int8_t lqi; ///< LQI of received frame. - } received; ///< Received frame details. + uint8_t * p_psdu; ///< Pointer to received frame PSDU. + int8_t power; ///< RSSI of received frame. + int8_t lqi; ///< LQI of received frame. + } received; ///< Received frame details. struct { - nrf_802154_rx_error_t error; ///< An error code that indicates reason of the failure. + nrf_802154_rx_error_t error; ///< An error code that indicates reason of the failure. } receive_failed; struct { - const uint8_t * p_frame; ///< Pointer to frame that was transmitted. - uint8_t * p_psdu; ///< Pointer to received ACK PSDU or NULL. - int8_t power; ///< RSSI of received ACK or 0. - int8_t lqi; ///< LQI of received ACK or 0. - } transmitted; ///< Transmitted frame details. + const uint8_t * p_frame; ///< Pointer to frame that was transmitted. + uint8_t * p_psdu; ///< Pointer to received ACK PSDU or NULL. + int8_t power; ///< RSSI of received ACK or 0. + int8_t lqi; ///< LQI of received ACK or 0. + } transmitted; ///< Transmitted frame details. struct { - const uint8_t * p_frame; ///< Pointer to frame that was requested to be transmitted, but failed. - nrf_802154_tx_error_t error; ///< An error code that indicates reason of the failure. + const uint8_t * p_frame; ///< Pointer to frame that was requested to be transmitted, but failed. + nrf_802154_tx_error_t error; ///< An error code that indicates reason of the failure. } transmit_failed; struct { - int8_t result; ///< Energy detection result. - } energy_detected; ///< Energy detection details. + int8_t result; ///< Energy detection result. + } energy_detected; ///< Energy detection details. struct { - nrf_802154_ed_error_t error; ///< An error code that indicates reason of the failure. - } energy_detection_failed; ///< Energy detection failure details. + nrf_802154_ed_error_t error; ///< An error code that indicates reason of the failure. + } energy_detection_failed; ///< Energy detection failure details. struct { - bool result; ///< CCA result. - } cca; ///< CCA details. + bool result; ///< CCA result. + } cca; ///< CCA details. struct { - nrf_802154_cca_error_t error; ///< An error code that indicates reason of the failure. - } cca_failed; ///< CCA failure details. - } data; ///< Notification data depending on it's type. + nrf_802154_cca_error_t error; ///< An error code that indicates reason of the failure. + } cca_failed; ///< CCA failure details. + } data; ///< Notification data depending on it's type. } nrf_802154_ntf_data_t; /// Type of requests in request queue. @@ -163,79 +163,80 @@ typedef enum /// Request data in request queue. typedef struct { - nrf_802154_req_type_t type; ///< Type of the request. + nrf_802154_req_type_t type; ///< Type of the request. + union { struct { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< Sleep request result. - } sleep; ///< Sleep request details. + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< Sleep request result. + } sleep; ///< Sleep request details. struct { - nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. - nrf_802154_term_t term_lvl; ///< Request priority. - req_originator_t req_orig; ///< Request originator. - bool notif_abort; ///< If function termination should be notified. - bool * p_result; ///< Receive request result. - } receive; ///< Receive request details. + nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. + nrf_802154_term_t term_lvl; ///< Request priority. + req_originator_t req_orig; ///< Request originator. + bool notif_abort; ///< If function termination should be notified. + bool * p_result; ///< Receive request result. + } receive; ///< Receive request details. struct { - nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. - nrf_802154_term_t term_lvl; ///< Request priority. - req_originator_t req_orig; ///< Request originator. - const uint8_t * p_data; ///< Pointer to PSDU to transmit. - bool cca; ///< If CCA was requested prior to transmission. - bool immediate; ///< If TX procedure must be performed immediately. - bool * p_result; ///< Transmit request result. - } transmit; ///< Transmit request details. + nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. + nrf_802154_term_t term_lvl; ///< Request priority. + req_originator_t req_orig; ///< Request originator. + const uint8_t * p_data; ///< Pointer to PSDU to transmit. + bool cca; ///< If CCA was requested prior to transmission. + bool immediate; ///< If TX procedure must be performed immediately. + bool * p_result; ///< Transmit request result. + } transmit; ///< Transmit request details. struct { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< Energy detection request result. - uint32_t time_us; ///< Requested time of energy detection procedure. - } energy_detection; ///< Energy detection request details. + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< Energy detection request result. + uint32_t time_us; ///< Requested time of energy detection procedure. + } energy_detection; ///< Energy detection request details. struct { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< CCA request result. - } cca; ///< CCA request details. + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< CCA request result. + } cca; ///< CCA request details. struct { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< Continuous carrier request result. - } continuous_carrier; ///< Continuous carrier request details. + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< Continuous carrier request result. + } continuous_carrier; ///< Continuous carrier request details. struct { - uint8_t * p_data; ///< Pointer to receive buffer to free. - bool * p_result; ///< Buffer free request result. - } buffer_free; ///< Buffer free request details. + uint8_t * p_data; ///< Pointer to receive buffer to free. + bool * p_result; ///< Buffer free request result. + } buffer_free; ///< Buffer free request details. struct { - bool * p_result; ///< Channel update request result. - } channel_update; ///< Channel update request details. + bool * p_result; ///< Channel update request result. + } channel_update; ///< Channel update request details. struct { - bool * p_result; ///< CCA config update request result. - } cca_cfg_update; ///< CCA config update request details. - } data; ///< Request data depending on it's type. + bool * p_result; ///< CCA config update request result. + } cca_cfg_update; ///< CCA config update request details. + } data; ///< Request data depending on it's type. } nrf_802154_req_data_t; -static nrf_802154_ntf_data_t m_ntf_queue[NTF_QUEUE_SIZE]; ///< Notification queue. -static uint8_t m_ntf_r_ptr; ///< Notification queue read index. -static uint8_t m_ntf_w_ptr; ///< Notification queue write index. +static nrf_802154_ntf_data_t m_ntf_queue[NTF_QUEUE_SIZE]; ///< Notification queue. +static uint8_t m_ntf_r_ptr; ///< Notification queue read index. +static uint8_t m_ntf_w_ptr; ///< Notification queue write index. -static nrf_802154_req_data_t m_req_queue[REQ_QUEUE_SIZE]; ///< Request queue. -static uint8_t m_req_r_ptr; ///< Request queue read index. -static uint8_t m_req_w_ptr; ///< Request queue write index. +static nrf_802154_req_data_t m_req_queue[REQ_QUEUE_SIZE]; ///< Request queue. +static uint8_t m_req_r_ptr; ///< Request queue read index. +static uint8_t m_req_w_ptr; ///< Request queue write index. /** * Increment given index for any queue. @@ -431,7 +432,7 @@ void nrf_802154_swi_init(void) m_ntf_r_ptr = 0; m_ntf_w_ptr = 0; - nrf_egu_int_enable(SWI_EGU, NTF_INT | TIMESLOT_EXIT_INT | REQ_INT); + nrf_egu_int_enable(SWI_EGU, NTF_INT | HFCLK_STOP_INT | REQ_INT); NVIC_SetPriority(SWI_IRQn, NRF_802154_SWI_PRIORITY); NVIC_ClearPendingIRQ(SWI_IRQn); @@ -527,16 +528,16 @@ void nrf_802154_swi_notify_cca_failed(nrf_802154_cca_error_t error) ntf_exit(); } -void nrf_802154_swi_timeslot_exit(void) +void nrf_802154_swi_hfclk_stop(void) { - assert(!nrf_egu_event_check(SWI_EGU, TIMESLOT_EXIT_EVENT)); + assert(!nrf_egu_event_check(SWI_EGU, HFCLK_STOP_EVENT)); - nrf_egu_task_trigger(SWI_EGU, TIMESLOT_EXIT_TASK); + nrf_egu_task_trigger(SWI_EGU, HFCLK_STOP_TASK); } -void nrf_802154_swi_timeslot_exit_terminate(void) +void nrf_802154_swi_hfclk_stop_terminate(void) { - nrf_egu_event_clear(SWI_EGU, TIMESLOT_EXIT_EVENT); + nrf_egu_event_clear(SWI_EGU, HFCLK_STOP_EVENT); } void nrf_802154_swi_sleep(nrf_802154_term_t term_lvl, bool * p_result) @@ -695,7 +696,7 @@ void SWI_IRQHandler(void) #else // NRF_802154_USE_RAW_API nrf_802154_transmitted(p_slot->data.transmitted.p_frame + RAW_PAYLOAD_OFFSET, p_slot->data.transmitted.p_psdu == NULL ? NULL : - p_slot->data.transmitted.p_psdu + RAW_PAYLOAD_OFFSET, + p_slot->data.transmitted.p_psdu + RAW_PAYLOAD_OFFSET, p_slot->data.transmitted.p_psdu[RAW_LENGTH_OFFSET], p_slot->data.transmitted.power, p_slot->data.transmitted.lqi); @@ -707,8 +708,9 @@ void SWI_IRQHandler(void) nrf_802154_transmit_failed(p_slot->data.transmit_failed.p_frame, p_slot->data.transmit_failed.error); #else // NRF_802154_USE_RAW_API - nrf_802154_transmit_failed(p_slot->data.transmit_failed.p_frame + RAW_PAYLOAD_OFFSET, - p_slot->data.transmit_failed.error); + nrf_802154_transmit_failed( + p_slot->data.transmit_failed.p_frame + RAW_PAYLOAD_OFFSET, + p_slot->data.transmit_failed.error); #endif break; @@ -718,7 +720,7 @@ void SWI_IRQHandler(void) case NTF_TYPE_ENERGY_DETECTION_FAILED: nrf_802154_energy_detection_failed( - p_slot->data.energy_detection_failed.error); + p_slot->data.energy_detection_failed.error); break; case NTF_TYPE_CCA: @@ -737,11 +739,11 @@ void SWI_IRQHandler(void) } } - if (nrf_egu_event_check(SWI_EGU, TIMESLOT_EXIT_EVENT)) + if (nrf_egu_event_check(SWI_EGU, HFCLK_STOP_EVENT)) { - nrf_802154_rsch_continuous_mode_exit(); + nrf_802154_clock_hfclk_stop(); - nrf_egu_event_clear(SWI_EGU, TIMESLOT_EXIT_EVENT); + nrf_egu_event_clear(SWI_EGU, HFCLK_STOP_EVENT); } if (nrf_egu_event_check(SWI_EGU, REQ_EVENT)) @@ -756,32 +758,32 @@ void SWI_IRQHandler(void) { case REQ_TYPE_SLEEP: *(p_slot->data.sleep.p_result) = - nrf_802154_core_sleep(p_slot->data.sleep.term_lvl); + nrf_802154_core_sleep(p_slot->data.sleep.term_lvl); break; case REQ_TYPE_RECEIVE: *(p_slot->data.receive.p_result) = - nrf_802154_core_receive(p_slot->data.receive.term_lvl, - p_slot->data.receive.req_orig, - p_slot->data.receive.notif_func, - p_slot->data.receive.notif_abort); + nrf_802154_core_receive(p_slot->data.receive.term_lvl, + p_slot->data.receive.req_orig, + p_slot->data.receive.notif_func, + p_slot->data.receive.notif_abort); break; case REQ_TYPE_TRANSMIT: *(p_slot->data.transmit.p_result) = - nrf_802154_core_transmit(p_slot->data.transmit.term_lvl, - p_slot->data.transmit.req_orig, - p_slot->data.transmit.p_data, - p_slot->data.transmit.cca, - p_slot->data.transmit.immediate, - p_slot->data.transmit.notif_func); + nrf_802154_core_transmit(p_slot->data.transmit.term_lvl, + p_slot->data.transmit.req_orig, + p_slot->data.transmit.p_data, + p_slot->data.transmit.cca, + p_slot->data.transmit.immediate, + p_slot->data.transmit.notif_func); break; case REQ_TYPE_ENERGY_DETECTION: *(p_slot->data.energy_detection.p_result) = - nrf_802154_core_energy_detection( - p_slot->data.energy_detection.term_lvl, - p_slot->data.energy_detection.time_us); + nrf_802154_core_energy_detection( + p_slot->data.energy_detection.term_lvl, + p_slot->data.energy_detection.time_us); break; case REQ_TYPE_CCA: @@ -790,13 +792,13 @@ void SWI_IRQHandler(void) case REQ_TYPE_CONTINUOUS_CARRIER: *(p_slot->data.continuous_carrier.p_result) = - nrf_802154_core_continuous_carrier( - p_slot->data.continuous_carrier.term_lvl); + nrf_802154_core_continuous_carrier( + p_slot->data.continuous_carrier.term_lvl); break; case REQ_TYPE_BUFFER_FREE: *(p_slot->data.buffer_free.p_result) = - nrf_802154_core_notify_buffer_free(p_slot->data.buffer_free.p_data); + nrf_802154_core_notify_buffer_free(p_slot->data.buffer_free.p_data); break; case REQ_TYPE_CHANNEL_UPDATE: diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.h index 775a90fff..f3cad1cb5 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_swi.h @@ -121,18 +121,19 @@ void nrf_802154_swi_notify_cca(bool channel_free); void nrf_802154_swi_notify_cca_failed(nrf_802154_cca_error_t error); /** - * @brief Request discarding of the timeslot from SWI priority level. + * @brief Request stop of the HF clock from the SWI priority level. * - * @note This function should be called through notification module to prevent calling it from arbiter context. + * @note This function should be called through notification module to prevent calling it from + * the arbiter context. */ -void nrf_802154_swi_timeslot_exit(void); +void nrf_802154_swi_hfclk_stop(void); /** - * @brief Terminate discarding of the timeslot. + * @brief Terminate stopping of the HF clock. * - * @note This function terminates discrading of timeslot only if it has not been performed. + * @note This function terminates stopping of the HF clock only if it has not been performed. */ -void nrf_802154_swi_timeslot_exit_terminate(void); +void nrf_802154_swi_hfclk_stop_terminate(void); /** * @brief Request entering sleep state from SWI priority. diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c index 225b07b22..7b636a423 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c @@ -45,23 +45,24 @@ #include "platform/hp_timer/nrf_802154_hp_timer.h" #include "platform/lp_timer/nrf_802154_lp_timer.h" -#define DIV_ROUND_POSITIVE(n, d) (((n) + (d)/2)/(d)) -#define DIV_ROUND_NEGATIVE(n, d) (((n) - (d)/2)/(d)) -#define DIV_ROUND(n, d) ((((n) < 0) ^ ((d) < 0)) ? DIV_ROUND_NEGATIVE(n, d) : DIV_ROUND_POSITIVE(n, d)) +#define DIV_ROUND_POSITIVE(n, d) (((n) + (d) / 2) / (d)) +#define DIV_ROUND_NEGATIVE(n, d) (((n) - (d) / 2) / (d)) +#define DIV_ROUND(n, d) ((((n) < 0) ^ ((d) < 0)) ? \ + DIV_ROUND_NEGATIVE(n, d) : \ + DIV_ROUND_POSITIVE(n, d)) +#define TIME_BASE (1UL << 22) ///< Unit used to calculate PPTB (Point per Time Base). It is not equal million to speed up computations and increase precision. +#define FIRST_RESYNC_TIME TIME_BASE ///< Delay of the first resynchronization. The first resynchronization is needed to measure timers drift. +#define RESYNC_TIME (64 * TIME_BASE) ///< Delay of following resynchronizations. +#define EWMA_COEF (8) ///< Weight used in the EWMA algorithm. -#define TIME_BASE (1UL << 22) ///< Unit used to calculate PPTB (Point per Time Base). It is not equal million to speed up computations and increase precision. -#define FIRST_RESYNC_TIME TIME_BASE ///< Delay of the first resynchronization. The first resynchronization is needed to measure timers drift. -#define RESYNC_TIME (64 * TIME_BASE) ///< Delay of following resynchronizations. -#define EWMA_COEF (8) ///< Weight used in the EWMA algorithm. +#define PPI_CH0 NRF_PPI_CHANNEL13 +#define PPI_CH1 NRF_PPI_CHANNEL14 +#define PPI_CHGRP0 NRF_PPI_CHANNEL_GROUP1 -#define PPI_CH0 NRF_PPI_CHANNEL13 -#define PPI_CH1 NRF_PPI_CHANNEL14 -#define PPI_CHGRP0 NRF_PPI_CHANNEL_GROUP1 - -#define PPI_SYNC PPI_CH0 -#define PPI_TIMESTAMP PPI_CH1 -#define PPI_TIMESTAMP_GROUP PPI_CHGRP0 +#define PPI_SYNC PPI_CH0 +#define PPI_TIMESTAMP PPI_CH1 +#define PPI_TIMESTAMP_GROUP PPI_CHGRP0 #if NRF_802154_FRAME_TIMESTAMP_ENABLED // Structure holding common timepoint from both timers. @@ -71,6 +72,7 @@ typedef struct uint32_t hp_timer_time; ///< HP Timer time of common timepoint. } common_timepoint_t; +// Static variables. static common_timepoint_t m_last_sync; ///< Common timepoint of last synchronization event. static volatile bool m_synchronized; ///< If timers were synchronized since last start. static bool m_drift_known; ///< If timer drift value is known. @@ -125,7 +127,8 @@ void nrf_802154_timer_coord_timestamp_prepare(uint32_t event_addr) nrf_ppi_channel_and_fork_endpoint_setup(PPI_TIMESTAMP, event_addr, nrf_802154_hp_timer_timestamp_task_get(), - (uint32_t)nrf_ppi_task_group_disable_address_get(PPI_TIMESTAMP_GROUP)); + (uint32_t)nrf_ppi_task_group_disable_address_get( + PPI_TIMESTAMP_GROUP)); nrf_ppi_group_enable(PPI_TIMESTAMP_GROUP); } diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.h index 06c2eae62..45b9c6ea9 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.h @@ -67,7 +67,7 @@ void nrf_802154_timer_coord_uninit(void); /** * @brief Start the Timer Coordinator. - * + * * This function starts the HP timer and synchronizes it with the LP timer. * * Started Timer Coordinator resynchronizes automatically in constant interval. diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h index 67a39db64..93f566b86 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h @@ -47,63 +47,66 @@ */ typedef uint8_t nrf_802154_state_t; -#define NRF_802154_STATE_INVALID 0x01 //!< Radio in an invalid state. -#define NRF_802154_STATE_SLEEP 0x02 //!< Radio in sleep state. -#define NRF_802154_STATE_RECEIVE 0x03 //!< Radio in receive state. -#define NRF_802154_STATE_TRANSMIT 0x04 //!< Radio in transmit state. -#define NRF_802154_STATE_ENERGY_DETECTION 0x05 //!< Radio in energy detection state. -#define NRF_802154_STATE_CCA 0x06 //!< Radio in CCA state. -#define NRF_802154_STATE_CONTINUOUS_CARRIER 0x07 //!< Radio in continuous carrier state. +#define NRF_802154_STATE_INVALID 0x01 // !< Radio in an invalid state. +#define NRF_802154_STATE_SLEEP 0x02 // !< Radio in sleep state. +#define NRF_802154_STATE_RECEIVE 0x03 // !< Radio in receive state. +#define NRF_802154_STATE_TRANSMIT 0x04 // !< Radio in transmit state. +#define NRF_802154_STATE_ENERGY_DETECTION 0x05 // !< Radio in energy detection state. +#define NRF_802154_STATE_CCA 0x06 // !< Radio in CCA state. +#define NRF_802154_STATE_CONTINUOUS_CARRIER 0x07 // !< Radio in continuous carrier state. /** * @brief Errors reported during frame transmission. */ typedef uint8_t nrf_802154_tx_error_t; -#define NRF_802154_TX_ERROR_NONE 0x00 //!< There is no transmit error. -#define NRF_802154_TX_ERROR_BUSY_CHANNEL 0x01 //!< CCA reported busy channel prior to transmission. -#define NRF_802154_TX_ERROR_INVALID_ACK 0x02 //!< Received ACK frame is other than expected. -#define NRF_802154_TX_ERROR_NO_MEM 0x03 //!< No receive buffer is available to receive an ACK. -#define NRF_802154_TX_ERROR_TIMESLOT_ENDED 0x04 //!< Radio timeslot ended during transmission procedure. -#define NRF_802154_TX_ERROR_NO_ACK 0x05 //!< ACK frame was not received during timeout period. -#define NRF_802154_TX_ERROR_ABORTED 0x06 //!< Procedure was aborted by another driver operation with FORCE priority. -#define NRF_802154_TX_ERROR_TIMESLOT_DENIED 0x07 //!< Transmission did not start due to denied timeslot request. +#define NRF_802154_TX_ERROR_NONE 0x00 // !< There is no transmit error. +#define NRF_802154_TX_ERROR_BUSY_CHANNEL 0x01 // !< CCA reported busy channel prior to transmission. +#define NRF_802154_TX_ERROR_INVALID_ACK 0x02 // !< Received ACK frame is other than expected. +#define NRF_802154_TX_ERROR_NO_MEM 0x03 // !< No receive buffer is available to receive an ACK. +#define NRF_802154_TX_ERROR_TIMESLOT_ENDED 0x04 // !< Radio timeslot ended during transmission procedure. +#define NRF_802154_TX_ERROR_NO_ACK 0x05 // !< ACK frame was not received during timeout period. +#define NRF_802154_TX_ERROR_ABORTED 0x06 // !< Procedure was aborted by another driver operation with FORCE priority. +#define NRF_802154_TX_ERROR_TIMESLOT_DENIED 0x07 // !< Transmission did not start due to denied timeslot request. /** * @brief Possible errors during frame reception. */ typedef uint8_t nrf_802154_rx_error_t; -#define NRF_802154_RX_ERROR_NONE 0x00 //!< There is no receive error. -#define NRF_802154_RX_ERROR_INVALID_FRAME 0x01 //!< Received a malformed frame. -#define NRF_802154_RX_ERROR_INVALID_FCS 0x02 //!< Received a frame with invalid checksum. -#define NRF_802154_RX_ERROR_INVALID_DEST_ADDR 0x03 //!< Received a frame with mismatched destination address. -#define NRF_802154_RX_ERROR_RUNTIME 0x04 //!< A runtime error occurred (for example, CPU was held for too long). -#define NRF_802154_RX_ERROR_TIMESLOT_ENDED 0x05 //!< Radio timeslot ended during frame reception. -#define NRF_802154_RX_ERROR_ABORTED 0x06 //!< Procedure was aborted by another driver operation with FORCE priority. +#define NRF_802154_RX_ERROR_NONE 0x00 // !< There is no receive error. +#define NRF_802154_RX_ERROR_INVALID_FRAME 0x01 // !< Received a malformed frame. +#define NRF_802154_RX_ERROR_INVALID_FCS 0x02 // !< Received a frame with invalid checksum. +#define NRF_802154_RX_ERROR_INVALID_DEST_ADDR 0x03 // !< Received a frame with mismatched destination address. +#define NRF_802154_RX_ERROR_RUNTIME 0x04 // !< A runtime error occurred (for example, CPU was held for too long). +#define NRF_802154_RX_ERROR_TIMESLOT_ENDED 0x05 // !< Radio timeslot ended during frame reception. +#define NRF_802154_RX_ERROR_ABORTED 0x06 // !< Procedure was aborted by another driver operation with FORCE priority. +#define NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED 0x07 // !< Delayed reception request was rejected due to denied timeslot request. +#define NRF_802154_RX_ERROR_DELAYED_TIMEOUT 0x08 // !< Frame not received during delayed reception time slot. +#define NRF_802154_RX_ERROR_INVALID_LENGTH 0x09 // !< Received a frame with invalid length. /** * @brief Possible errors during energy detection. */ typedef uint8_t nrf_802154_ed_error_t; -#define NRF_802154_ED_ERROR_ABORTED 0x01 //!< Procedure was aborted by another driver operation with FORCE priority. +#define NRF_802154_ED_ERROR_ABORTED 0x01 // !< Procedure was aborted by another driver operation with FORCE priority. /** * @brief Possible errors during CCA procedure. */ typedef uint8_t nrf_802154_cca_error_t; -#define NRF_802154_CCA_ERROR_ABORTED 0x01 //!< Procedure was aborted by another driver operation with FORCE priority. +#define NRF_802154_CCA_ERROR_ABORTED 0x01 // !< Procedure was aborted by another driver operation with FORCE priority. /** * @brief Possible errors during sleep procedure call. */ typedef uint8_t nrf_802154_sleep_error_t; -#define NRF_802154_SLEEP_ERROR_NONE 0x00 //!< There is no error. -#define NRF_802154_SLEEP_ERROR_BUSY 0x01 //!< The driver cannot enter sleep state due to ongoing operation. - +#define NRF_802154_SLEEP_ERROR_NONE 0x00 // !< There is no error. +#define NRF_802154_SLEEP_ERROR_BUSY 0x01 // !< The driver cannot enter sleep state due to ongoing operation. + /** * @brief Termination level selected for a particular request. * @@ -112,18 +115,18 @@ typedef uint8_t nrf_802154_sleep_error_t; */ typedef uint8_t nrf_802154_term_t; -#define NRF_802154_TERM_NONE 0x00 //!< Request is skipped if another operation is ongoing. -#define NRF_802154_TERM_802154 0x01 //!< Request terminates ongoing 802.15.4 operation. +#define NRF_802154_TERM_NONE 0x00 // !< Request is skipped if another operation is ongoing. +#define NRF_802154_TERM_802154 0x01 // !< Request terminates ongoing 802.15.4 operation. /** * @brief Structure for configuring CCA. */ typedef struct { - nrf_radio_cca_mode_t mode; //!< CCA mode. - uint8_t ed_threshold; //!< CCA energy busy threshold. Not used in NRF_RADIO_CCA_MODE_CARRIER. - uint8_t corr_threshold; //!< CCA correlator busy threshold. Not used in NRF_RADIO_CCA_MODE_ED. - uint8_t corr_limit; //!< Limit of occurrences above CCA correlator busy threshold. Not used in NRF_RADIO_CCA_MODE_ED. + nrf_radio_cca_mode_t mode; // !< CCA mode. + uint8_t ed_threshold; // !< CCA energy busy threshold. Not used in NRF_RADIO_CCA_MODE_CARRIER. + uint8_t corr_threshold; // !< CCA correlator busy threshold. Not used in NRF_RADIO_CCA_MODE_ED. + uint8_t corr_limit; // !< Limit of occurrences above CCA correlator busy threshold. Not used in NRF_RADIO_CCA_MODE_ED. } nrf_802154_cca_cfg_t; /** diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h index 713d6cd45..7e6696ed7 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h @@ -43,26 +43,25 @@ */ /**@brief RTC clock frequency. */ -#define NRF_802154_RTC_FREQUENCY 32768UL +#define NRF_802154_RTC_FREQUENCY 32768UL /**@brief Defines number of microseconds in one second. */ -#define NRF_802154_US_PER_S 1000000ULL +#define NRF_802154_US_PER_S 1000000ULL /**@brief Number of microseconds in one RTC tick. (rounded up) */ -#define NRF_802154_US_PER_TICK NRF_802154_RTC_TICKS_TO_US(1) +#define NRF_802154_US_PER_TICK NRF_802154_RTC_TICKS_TO_US(1) /**@brief Number of bits to shift RTC_FREQUENCY and US_PER_S to achieve division by greatest common divisor. */ -#define NRF_802154_FREQUENCY_US_PER_S_GCD_BITS 6 - +#define NRF_802154_FREQUENCY_US_PER_S_GCD_BITS 6 /**@brief Ceil division helper */ -#define NRF_802154_DIVIDE_AND_CEIL(A, B) (((A) + (B) - 1) / (B)) +#define NRF_802154_DIVIDE_AND_CEIL(A, B) (((A) + (B)-1) / (B)) /**@brief RTC ticks to us conversion. */ -#define NRF_802154_RTC_TICKS_TO_US(ticks) \ - NRF_802154_DIVIDE_AND_CEIL( \ - (ticks) * (NRF_802154_US_PER_S >> NRF_802154_FREQUENCY_US_PER_S_GCD_BITS), \ - (NRF_802154_RTC_FREQUENCY >> NRF_802154_FREQUENCY_US_PER_S_GCD_BITS)) +#define NRF_802154_RTC_TICKS_TO_US(ticks) \ + NRF_802154_DIVIDE_AND_CEIL( \ + (ticks) * (NRF_802154_US_PER_S >> NRF_802154_FREQUENCY_US_PER_S_GCD_BITS), \ + (NRF_802154_RTC_FREQUENCY >> NRF_802154_FREQUENCY_US_PER_S_GCD_BITS)) static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) { @@ -101,11 +100,11 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) There is a possible loss of precision so that t1 will be up to 93*15625 _smaller_ than the accurate number. This is taken into account in the next step. - */ + */ - t1 = ((time >> 13) * 0x8637bd0) >> 28; // ((time >> 13) * (2^41 / 15625)) >> (41 - 13) + t1 = ((time >> 13) * 0x8637bd0) >> 28; // ((time >> 13) * (2^41 / 15625)) >> (41 - 13) result = t1 * 512; - t1 = time - t1 * 15625; + t1 = time - t1 * 15625; /* This second step of the calculation is to find out how many RTC units there are still left in the remaining microseconds. @@ -130,9 +129,9 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) // ceil((time * (2^56 / 15625)) >> (56 - 9)) assert(t1 <= 1453125); - u1 = (t1 * 0x431bde82d7b); // (time * (2^56 / 15625)) - u1 += 0x7fffffffffff; // round up - u1 >>= 47; // ceil(u1 >> (56 - 9)) + u1 = (t1 * 0x431bde82d7b); // (time * (2^56 / 15625)) + u1 += 0x7fffffffffff; // round up + u1 >>= 47; // ceil(u1 >> (56 - 9)) result += u1; @@ -149,7 +148,8 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) */ static inline uint32_t nrf_is_nvic_irq_enabled(IRQn_Type IRQn) { - return (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)]) & ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)]) & + ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); } /** diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c b/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c index ca78f1ce4..8d82e7679 100644 --- a/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c +++ b/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c @@ -49,20 +49,20 @@ #include "nrf_802154_config.h" /**@brief Timer instance. */ -#define TIMER NRF_TIMER0 +#define TIMER NRF_TIMER0 /**@brief Timer compare channel definitions. */ -#define TIMER_CC_CAPTURE NRF_TIMER_CC_CHANNEL1 -#define TIMER_CC_CAPTURE_TASK NRF_TIMER_TASK_CAPTURE1 +#define TIMER_CC_CAPTURE NRF_TIMER_CC_CHANNEL1 +#define TIMER_CC_CAPTURE_TASK NRF_TIMER_TASK_CAPTURE1 -#define TIMER_CC_SYNC NRF_TIMER_CC_CHANNEL2 -#define TIMER_CC_SYNC_TASK NRF_TIMER_TASK_CAPTURE2 -#define TIMER_CC_SYNC_EVENT NRF_TIMER_EVENT_COMPARE2 -#define TIMER_CC_SYNC_INT NRF_TIMER_INT_COMPARE2_MASK +#define TIMER_CC_SYNC NRF_TIMER_CC_CHANNEL2 +#define TIMER_CC_SYNC_TASK NRF_TIMER_TASK_CAPTURE2 +#define TIMER_CC_SYNC_EVENT NRF_TIMER_EVENT_COMPARE2 +#define TIMER_CC_SYNC_INT NRF_TIMER_INT_COMPARE2_MASK -#define TIMER_CC_EVT NRF_TIMER_CC_CHANNEL3 -#define TIMER_CC_EVT_TASK NRF_TIMER_TASK_CAPTURE3 -#define TIMER_CC_EVT_INT NRF_TIMER_INT_COMPARE3_MASK +#define TIMER_CC_EVT NRF_TIMER_CC_CHANNEL3 +#define TIMER_CC_EVT_TASK NRF_TIMER_TASK_CAPTURE3 +#define TIMER_CC_EVT_INT NRF_TIMER_INT_COMPARE3_MASK /**@brief Unexpected value in the sync compare channel. */ static uint32_t m_unexpected_sync; @@ -139,4 +139,3 @@ uint32_t nrf_802154_hp_timer_timestamp_get(void) { return nrf_timer_cc_read(TIMER, TIMER_CC_EVT); } - diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.h b/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.h index ea561a682..770c7b37e 100644 --- a/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.h +++ b/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.h @@ -134,7 +134,6 @@ uint32_t nrf_802154_hp_timer_timestamp_task_get(void); */ uint32_t nrf_802154_hp_timer_timestamp_get(void); - /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h b/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h index 26ef993a6..e5522fc32 100644 --- a/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h +++ b/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer.h @@ -146,22 +146,22 @@ bool nrf_802154_lp_timer_is_running(void); /** * @brief Start one-shot synchronization timer that expires at nearest possible timepoint. - * + * * On timer expiration @ref nrf_802154_lp_timer_synchronized function will be called and * event returned by @ref nrf_802154_lp_timer_sync_event_get will be triggered. - * + * * @note @ref nrf_802154_lp_timer_synchronized may be called multiple times. */ void nrf_802154_lp_timer_sync_start_now(void); /** * @brief Start one-shot synchronization timer that expires at specified time. - * + * * Start one-shot synchronization timer that will expire @p dt microseconds after @p t0 time. - * + * * On timer expiration @ref nrf_802154_lp_timer_synchronized function will be called and * event returned by @ref nrf_802154_lp_timer_sync_event_get will be triggered. - * + * * @param[in] t0 Number of microseconds representing timer start time. * @param[in] dt Time of timer expiration as time elapsed from @p t0 [us]. */ @@ -174,7 +174,7 @@ void nrf_802154_lp_timer_sync_stop(void); /** * @brief Get event used to synchronize this timer with HP Timer - * + * * @return Address of the peripheral register corresponding to the event that * should be used for timers synchronization. */ diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c b/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c index 05884044f..47a9b399b 100644 --- a/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c +++ b/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c @@ -57,13 +57,12 @@ #define RTC_SYNC_COMPARE_EVENT NRF_RTC_EVENT_COMPARE_1 #define RTC_SYNC_COMPARE_EVENT_MASK RTC_EVTEN_COMPARE1_Msk -#define US_PER_OVERFLOW (512UL * NRF_802154_US_PER_S) ///< Time that has passed between overflow events. On full RTC speed, it occurs every 512 s. -#define MIN_RTC_COMPARE_EVENT_DT (2 * NRF_802154_US_PER_TICK) ///< Minimum time delta from now before RTC compare event is guaranteed to fire. +#define US_PER_OVERFLOW (512UL * NRF_802154_US_PER_S) ///< Time that has passed between overflow events. On full RTC speed, it occurs every 512 s. +#define MIN_RTC_COMPARE_EVENT_DT (2 * NRF_802154_US_PER_TICK) ///< Minimum time delta from now before RTC compare event is guaranteed to fire. #define EPOCH_32BIT_US (1ULL << 32) #define EPOCH_FROM_TIME(time) ((time) & ((uint64_t)UINT32_MAX << 32)) - // Struct holding information about compare channel. typedef struct { @@ -86,8 +85,7 @@ static const compare_channel_descriptor_t m_cmp_ch[CHANNEL_CNT] = {{RTC_LP_TIMER RTC_SYNC_COMPARE_EVENT, RTC_SYNC_COMPARE_EVENT_MASK}}; -static uint64_t m_target_times[CHANNEL_CNT]; ///< Target time of given channel [us]. - +static uint64_t m_target_times[CHANNEL_CNT]; ///< Target time of given channel [us]. static volatile uint32_t m_offset_counter; ///< Counter of RTC overflows, incremented by 2 on each OVERFLOW event. static volatile uint8_t m_mutex; ///< Mutex for write access to @ref m_offset_counter. @@ -276,7 +274,8 @@ static uint32_t overflow_counter_get(void) else { // Failed to acquire mutex. - if (nrf_rtc_event_pending(NRF_802154_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW) || (m_offset_counter & 0x01)) + if (nrf_rtc_event_pending(NRF_802154_RTC_INSTANCE, + NRF_RTC_EVENT_OVERFLOW) || (m_offset_counter & 0x01)) { // Lower priority context is currently incrementing m_offset_counter variable. offset = (m_offset_counter + 2) / 2; @@ -340,6 +339,7 @@ static uint64_t round_up_to_timer_ticks_multiply(uint64_t time) { uint64_t ticks = time_to_ticks(time); uint64_t result = ticks_to_time(ticks); + return result; } @@ -396,7 +396,10 @@ void nrf_802154_lp_timer_init(void) // Setup low frequency clock. nrf_802154_clock_lfclk_start(); - while (!m_clock_ready) { } + while (!m_clock_ready) + { + // Intentionally empty + } // Setup RTC timer. NVIC_SetPriority(NRF_802154_RTC_IRQN, NRF_802154_RTC_IRQ_PRIORITY); @@ -517,7 +520,8 @@ void nrf_802154_lp_timer_sync_start_now(void) offset_and_counter_get(&offset, &counter); now = time_get(offset, counter); timer_sync_start_at((uint32_t)now, MIN_RTC_COMPARE_EVENT_DT, &now); - } while (counter_get() != counter); + } + while (counter_get() != counter); } void nrf_802154_lp_timer_sync_start_at(uint32_t t0, uint32_t dt) @@ -536,7 +540,8 @@ void nrf_802154_lp_timer_sync_stop(void) uint32_t nrf_802154_lp_timer_sync_event_get(void) { - return (uint32_t)nrf_rtc_event_address_get(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].event); + return (uint32_t)nrf_rtc_event_address_get(NRF_802154_RTC_INSTANCE, + m_cmp_ch[SYNC_CHANNEL].event); } uint32_t nrf_802154_lp_timer_sync_time_get(void) diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/temperature/nrf_802154_temperature_none.c b/third_party/NordicSemiconductor/drivers/radio/platform/temperature/nrf_802154_temperature_none.c index dc56c27be..f6590b3b8 100644 --- a/third_party/NordicSemiconductor/drivers/radio/platform/temperature/nrf_802154_temperature_none.c +++ b/third_party/NordicSemiconductor/drivers/radio/platform/temperature/nrf_802154_temperature_none.c @@ -57,4 +57,3 @@ int8_t nrf_802154_temperature_get(void) { return DEFAULT_TEMPERATURE; } - diff --git a/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.c b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.c new file mode 100644 index 000000000..eaf98fc95 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.c @@ -0,0 +1,456 @@ +#include "nrf_802154_rsch.h" + +#include +#include +#include + +#include "nrf_802154_debug.h" +#include "nrf_802154_priority_drop.h" +#include "platform/clock/nrf_802154_clock.h" +#include "raal/nrf_raal_api.h" +#include "timer_scheduler/nrf_802154_timer_sched.h" + +#define PREC_RAMP_UP_TIME 300 ///< Ramp-up time of preconditions [us]. 300 is worst case for HFclock + +static volatile uint8_t m_ntf_mutex; ///< Mutex for notyfying core. +static volatile uint8_t m_ntf_mutex_monitor; ///< Mutex monitor, incremented every failed ntf mutex lock. +static volatile uint8_t m_req_mutex; ///< Mutex for requesting preconditions. +static volatile uint8_t m_req_mutex_monitor; ///< Mutex monitor, incremented every failed req mutex lock. +static volatile rsch_prio_t m_last_notified_prio; ///< Last reported approved priority level. +static volatile rsch_prio_t m_approved_prios[RSCH_PREC_CNT]; ///< Priority levels approved by each precondition. +static rsch_prio_t m_requested_prio; ///< Priority requested from all preconditions. +static rsch_prio_t m_cont_mode_prio; ///< Continuous mode priority level. If continuous mode is not requested equal to @ref RSCH_PRIO_IDLE. + +typedef struct +{ + rsch_prio_t prio; ///< Delayed timeslot priority level. If delayed timeslot is not scheduled equal to @ref RSCH_PRIO_IDLE. + uint32_t t0; ///< Time base of the delayed timeslot trigger time. + uint32_t dt; ///< Time delta of the delayed timeslot trigger time. + nrf_802154_timer_t timer; ///< Timer used to trigger delayed timeslot. +} dly_ts_t; + +static dly_ts_t m_dly_ts[RSCH_DLY_TS_NUM]; + +/** @brief Non-blocking mutex for notifying core. + * + * @param[inout] p_mutex Pointer to the mutex data. + * @param[inout] p_mutex_monitor Pointer to the mutex monitor counter. + * + * @retval true Mutex was acquired. + * @retval false Mutex could not be acquired. + */ +static inline bool mutex_trylock(volatile uint8_t * p_mutex, volatile uint8_t * p_mutex_monitor) +{ + do + { + uint8_t mutex_value = __LDREXB(p_mutex); + + if (mutex_value) + { + __CLREX(); + + (*p_mutex_monitor)++; + return false; + } + } + while (__STREXB(1, p_mutex)); + + __DMB(); + + return true; +} + +/** @brief Release mutex. */ +static inline void mutex_unlock(volatile uint8_t * p_mutex) +{ + __DMB(); + *p_mutex = 0; +} + +/** @brief Check maximal priority level required by any of delayed timeslots at the moment. + * + * To meet delayed timeslot timing requirements there is a time window in which radio + * preconditions should be requested. This function is used to prevent releasing preconditions + * in this time window. + * + * @return Maximal priority level required by delayed timeslots. + */ +static rsch_prio_t max_prio_for_delayed_timeslot_get(void) +{ + rsch_prio_t result = RSCH_PRIO_IDLE; + uint32_t now = nrf_802154_timer_sched_time_get(); + + for (uint32_t i = 0; i < RSCH_DLY_TS_NUM; i++) + { + dly_ts_t * p_dly_ts = &m_dly_ts[i]; + uint32_t t0 = p_dly_ts->t0; + uint32_t dt = p_dly_ts->dt - PREC_RAMP_UP_TIME - + nrf_802154_timer_sched_granularity_get(); + + if ((p_dly_ts->prio > result) && !nrf_802154_timer_sched_time_is_in_future(now, t0, dt)) + { + result = p_dly_ts->prio; + } + } + + return result; +} + +static rsch_prio_t required_prio_lvl_get(void) +{ + rsch_prio_t result = max_prio_for_delayed_timeslot_get(); + + if (m_cont_mode_prio > result) + { + result = m_cont_mode_prio; + } + + return result; +} + +/** @brief Set approved priority level @p prio on given precondition @p prec. + * + * When requested priority level equals to the @ref RSCH_PRIO_IDLE this function will approve only + * the @ref RSCH_PRIO_IDLE priority level and drop other approved levels silently. + * + * @param[in] prec Precondition which state will be changed. + * @param[in] prio Approved priority level for given precondition. + */ +static inline void prec_approved_prio_set(rsch_prec_t prec, rsch_prio_t prio) +{ + assert(prec <= RSCH_PREC_CNT); + + if ((m_requested_prio == RSCH_PRIO_IDLE) && (prio != RSCH_PRIO_IDLE)) + { + // Ignore approved precondition - it was not requested. + return; + } + + assert((m_approved_prios[prec] != prio) || (prio == RSCH_PRIO_IDLE)); + + m_approved_prios[prec] = prio; +} + +/** @brief Request all preconditions. + */ +static inline void all_prec_update(void) +{ + rsch_prio_t prev_prio; + rsch_prio_t new_prio; + uint8_t monitor; + + do + { + if (!mutex_trylock(&m_req_mutex, &m_req_mutex_monitor)) + { + return; + } + + monitor = m_req_mutex_monitor; + prev_prio = m_requested_prio; + new_prio = required_prio_lvl_get(); + + if (prev_prio != new_prio) + { + m_requested_prio = new_prio; + + if (new_prio == RSCH_PRIO_IDLE) + { + nrf_802154_priority_drop_hfclk_stop(); + prec_approved_prio_set(RSCH_PREC_HFCLK, RSCH_PRIO_IDLE); + + nrf_raal_continuous_mode_exit(); + prec_approved_prio_set(RSCH_PREC_RAAL, RSCH_PRIO_IDLE); + } + else + { + nrf_802154_priority_drop_hfclk_stop_terminate(); + nrf_802154_clock_hfclk_start(); + nrf_raal_continuous_mode_enter(); + } + } + + mutex_unlock(&m_req_mutex); + } + while (monitor != m_req_mutex_monitor); +} + +/** @brief Get currently approved priority level. + * + * @return Maximal priority level approved by all radio preconditions. + */ +static inline rsch_prio_t approved_prio_lvl_get(void) +{ + rsch_prio_t result = RSCH_PRIO_MAX; + + for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) + { + if (m_approved_prios[i] < result) + { + result = m_approved_prios[i]; + } + } + + return result; +} + +/** @brief Check if all preconditions are requested or met at given priority level or higher. + * + * @param[in] prio Minimal priority level requested from preconditions. + * + * @retval true All preconditions are requested or met at given or higher level. + * @retval false At least one precondition is requested at lower level than required. + */ +static inline bool requested_prio_lvl_is_at_least(rsch_prio_t prio) +{ + return m_requested_prio >= prio; +} + +/** @brief Notify core if preconditions are approved or denied if current state differs from last reported. + */ +static inline void notify_core(void) +{ + rsch_prio_t approved_prio_lvl; + uint8_t temp_mon; + + do + { + if (!mutex_trylock(&m_ntf_mutex, &m_ntf_mutex_monitor)) + { + return; + } + + /* It is possible that preemption is not detected (m_ntf_mutex_monitor is read after + * acquiring mutex). It is not a problem because we will call proper handler function + * requested by preempting context. Avoiding this race would generate one additional + * iteration without any effect. + */ + temp_mon = m_ntf_mutex_monitor; + approved_prio_lvl = approved_prio_lvl_get(); + + if ((m_cont_mode_prio > RSCH_PRIO_IDLE) && (m_last_notified_prio != approved_prio_lvl)) + { + m_last_notified_prio = approved_prio_lvl; + + nrf_802154_rsch_continuous_prio_changed(approved_prio_lvl); + } + + mutex_unlock(&m_ntf_mutex); + } + while (temp_mon != m_ntf_mutex_monitor); +} + +/** Timer callback used to trigger delayed timeslot. + * + * @param[in] p_context Index of the delayed timeslot operation (TX or RX). + */ +static void delayed_timeslot_start(void * p_context) +{ + rsch_dly_ts_id_t dly_ts_id = (rsch_dly_ts_id_t)(uint32_t)p_context; + dly_ts_t * p_dly_ts = &m_dly_ts[dly_ts_id]; + rsch_prio_t req_prio_lvl; + + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMER_DELAYED_START); + + req_prio_lvl = p_dly_ts->prio; + p_dly_ts->prio = RSCH_PRIO_IDLE; + + if (approved_prio_lvl_get() >= req_prio_lvl) + { + nrf_802154_rsch_delayed_timeslot_started(dly_ts_id); + } + else + { + nrf_802154_rsch_delayed_timeslot_failed(dly_ts_id); + } + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMER_DELAYED_START); +} + +/** Timer callback used to request preconditions for delayed timeslot. + * + * @param[in] p_context Index of the delayed timeslot operation (TX or RX). + */ +static void delayed_timeslot_prec_request(void * p_context) +{ + rsch_dly_ts_id_t dly_ts_id = (rsch_dly_ts_id_t)(uint32_t)p_context; + dly_ts_t * p_dly_ts = &m_dly_ts[dly_ts_id]; + + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMER_DELAYED_PREC); + + all_prec_update(); + + p_dly_ts->timer.t0 = p_dly_ts->t0; + p_dly_ts->timer.dt = p_dly_ts->dt; + p_dly_ts->timer.callback = delayed_timeslot_start; + p_dly_ts->timer.p_context = p_context; + + nrf_802154_timer_sched_add(&p_dly_ts->timer, true); + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMER_DELAYED_PREC); +} + +/*************************************************************************************************** + * Public API + **************************************************************************************************/ + +void nrf_802154_rsch_init(void) +{ + nrf_raal_init(); + + m_ntf_mutex = 0; + m_req_mutex = 0; + m_last_notified_prio = RSCH_PRIO_IDLE; + m_cont_mode_prio = RSCH_PRIO_IDLE; + m_requested_prio = RSCH_PRIO_IDLE; + + for (uint32_t i = 0; i < RSCH_DLY_TS_NUM; i++) + { + m_dly_ts[i].prio = RSCH_PRIO_IDLE; + } + + for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) + { + m_approved_prios[i] = RSCH_PRIO_IDLE; + } +} + +void nrf_802154_rsch_uninit(void) +{ + for (uint32_t i = 0; i < RSCH_DLY_TS_NUM; i++) + { + nrf_802154_timer_sched_remove(&m_dly_ts[i].timer); + } + + nrf_raal_uninit(); +} + +void nrf_802154_rsch_continuous_mode_priority_set(rsch_prio_t prio) +{ + nrf_802154_log(EVENT_TRACE_ENTER, (prio > RSCH_PRIO_IDLE) ? FUNCTION_RSCH_CONTINUOUS_ENTER : + FUNCTION_RSCH_CONTINUOUS_EXIT); + + m_cont_mode_prio = prio; + __DMB(); + + all_prec_update(); + notify_core(); + + if (prio == RSCH_PRIO_IDLE) + { + m_last_notified_prio = RSCH_PRIO_IDLE; + } + + nrf_802154_log(EVENT_TRACE_EXIT, (prio > RSCH_PRIO_IDLE) ? FUNCTION_RSCH_CONTINUOUS_ENTER : + FUNCTION_RSCH_CONTINUOUS_EXIT); +} + +void nrf_802154_rsch_continuous_ended(void) +{ + nrf_raal_continuous_ended(); +} + +bool nrf_802154_rsch_timeslot_request(uint32_t length_us) +{ + return nrf_raal_timeslot_request(length_us); +} + +bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0, + uint32_t dt, + uint32_t length, + rsch_prio_t prio, + rsch_dly_ts_id_t dly_ts_id) +{ + (void)length; + + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_DELAYED_TIMESLOT_REQ); + assert(dly_ts_id < RSCH_DLY_TS_NUM); + + dly_ts_t * p_dly_ts = &m_dly_ts[dly_ts_id]; + uint32_t now = nrf_802154_timer_sched_time_get(); + uint32_t req_dt = dt - PREC_RAMP_UP_TIME; + bool result; + + assert(!nrf_802154_timer_sched_is_running(&p_dly_ts->timer)); + assert(p_dly_ts->prio == RSCH_PRIO_IDLE); + assert(prio != RSCH_PRIO_IDLE); + + if (nrf_802154_timer_sched_time_is_in_future(now, t0, req_dt)) + { + p_dly_ts->prio = prio; + p_dly_ts->t0 = t0; + p_dly_ts->dt = dt; + + p_dly_ts->timer.t0 = t0; + p_dly_ts->timer.dt = req_dt; + p_dly_ts->timer.callback = delayed_timeslot_prec_request; + p_dly_ts->timer.p_context = (void *)dly_ts_id; + + nrf_802154_timer_sched_add(&p_dly_ts->timer, false); + + result = true; + } + else if (requested_prio_lvl_is_at_least(RSCH_PRIO_MAX) && + nrf_802154_timer_sched_time_is_in_future(now, t0, dt)) + { + p_dly_ts->prio = prio; + p_dly_ts->t0 = t0; + p_dly_ts->dt = dt; + + p_dly_ts->timer.t0 = t0; + p_dly_ts->timer.dt = dt; + p_dly_ts->timer.callback = delayed_timeslot_start; + p_dly_ts->timer.p_context = (void *)dly_ts_id; + + nrf_802154_timer_sched_add(&p_dly_ts->timer, true); + + result = true; + } + else + { + result = false; + } + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_DELAYED_TIMESLOT_REQ); + + return result; +} + +bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec, rsch_prio_t prio) +{ + assert(prec < RSCH_PREC_CNT); + return m_approved_prios[prec] >= prio; +} + +uint32_t nrf_802154_rsch_timeslot_us_left_get(void) +{ + return nrf_raal_timeslot_us_left_get(); +} + +// External handlers + +void nrf_raal_timeslot_started(void) +{ + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMESLOT_STARTED); + + prec_approved_prio_set(RSCH_PREC_RAAL, RSCH_PRIO_MAX); + notify_core(); + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMESLOT_STARTED); +} + +void nrf_raal_timeslot_ended(void) +{ + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMESLOT_ENDED); + + prec_approved_prio_set(RSCH_PREC_RAAL, RSCH_PRIO_IDLE); + notify_core(); + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMESLOT_ENDED); +} + +void nrf_802154_clock_hfclk_ready(void) +{ + prec_approved_prio_set(RSCH_PREC_HFCLK, RSCH_PRIO_MAX); + notify_core(); +} diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.h b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.h similarity index 64% rename from third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.h rename to third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.h index 3c9c0f109..1fde3a2c2 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.h +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch.h @@ -67,6 +67,32 @@ typedef enum RSCH_PREC_CNT, } rsch_prec_t; +/** + * @brief Priorities of the 802.15.4 radio operations. + */ +typedef enum +{ + RSCH_PRIO_IDLE, ///< Priority used in the sleep state. With this priority RSCH releases all preconditions. + RSCH_PRIO_IDLE_LISTENING, ///< Priority used during the idle listening procedure. + RSCH_PRIO_RX, ///< Priority used when a frame is being received. + RSCH_PRIO_DETECT, ///< Priority used to detect channel conditions (CCA, ED). + RSCH_PRIO_TX, ///< Priority used to transmit a frame. + + RSCH_PRIO_MIN_APPROVED = RSCH_PRIO_IDLE_LISTENING, ///< Minimal priority indicating that given precondition is approved. + RSCH_PRIO_MAX = RSCH_PRIO_TX, ///< Maximal priority available in the RSCH module. +} rsch_prio_t; + +/** + * @brief Enumeration of delayed timeslots ids. + */ +typedef enum +{ + RSCH_DLY_TX, ///< Timeslot for delayed tx operation. + RSCH_DLY_RX, ///< Timeslot for delayed rx operation. + + RSCH_DLY_TS_NUM, ///< Number of delayed timeslots. +} rsch_dly_ts_id_t; + /** * @brief Initialize Radio Scheduler. * @@ -87,25 +113,28 @@ void nrf_802154_rsch_init(void); void nrf_802154_rsch_uninit(void); /** - * @brief Enter continuous radio mode. + * @brief Set priority for the continuous radio mode. * * In the continuous mode the radio scheduler should try to satisfy all preconditions as long as * possible in order to give to the radio driver core as much radio time as possible while * disturbing the other activities as little as possible. * * @note The start of a timeslot will be indicated by @ref nrf_802154_rsch_prec_approved call. + * @note To disable the continuous radio mode, the @ref RSCH_PRIO_IDLE should be used. + * + * @param[in] prio Priority level used in the continuous radio mode. * */ -void nrf_802154_rsch_continuous_mode_enter(void); +void nrf_802154_rsch_continuous_mode_priority_set(rsch_prio_t prio); /** - * @brief Exit continuous radio mode. + * @brief Confirm that current part of continuous timeslot is ended by the core. * - * In this mode the radio scheduler should not try to satisfy any of radio activity preconditions - * unless it was requested by other functionalities of this module. + * This confirmation is used by the core to synchronize ending of continuous timeslot parts with + * the RSCH module. * */ -void nrf_802154_rsch_continuous_mode_exit(void); +void nrf_802154_rsch_continuous_ended(void); /** * @brief Request timeslot for radio communication immediately. @@ -135,21 +164,28 @@ bool nrf_802154_rsch_timeslot_request(uint32_t length_us); * @param[in] t0 Base time of the timestamp of the timeslot start [us]. * @param[in] dt Time delta between @p t0 and the timestamp of the timeslot start [us]. * @param[in] length Requested radio timeslot length [us]. + * @param[in] prio Priority level required for the delayed timeslot. + * @param[in] dly_ts Type of the requested timeslot. * * @retval true Requested timeslot has been scheduled. * @retval false Requested timeslot cannot be scheduled and will not be granted. */ -bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0, uint32_t dt, uint32_t length); +bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0, + uint32_t dt, + uint32_t length, + rsch_prio_t prio, + rsch_dly_ts_id_t dly_ts); /** * @brief Check if the RSCH precondition is satisfied. * * @param[in] prec RSCH precondition to be checked. - * + * @param[in] prio Minimal required priority level of given precondition. + * * @retval true Precondition @p prec is currently granted. * @retval false Precondition @p prec is not currently granted. */ -bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec); +bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec, rsch_prio_t prio); /** * @brief Get left time of currently granted timeslot [us]. @@ -159,50 +195,33 @@ bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec); uint32_t nrf_802154_rsch_timeslot_us_left_get(void); /** - * @brief The Radio Scheduler calls this function to notify the core - * about granting all preconditions. + * @brief This function is called to notify the core about changes of approved priority level. * - * The radio driver now has exclusive access to the peripherals until - * @ref nrf_802154_rsch_prec_denied is called. + * If the @p prio is greater than @ref RSCH_PRIO_IDLE, the radio driver has exclusive access to the + * peripherals until this function is called with the @p prio equal to @ref RSCH_PRIO_IDLE. * - * @note The end of the timeslot will be indicated by @ref nrf_802154_rsch_prec_denied function. + * @note The end of the timeslot is indicated by @p prio equal to the @ref RSCH_PRIO_IDLE. * + * @param[in] prio Currently approved priority level. */ -extern void nrf_802154_rsch_prec_approved(void); - -/** - * @brief The Radio Scheduler calls this function to notify the core - * about denial of one or all preconditions. - * - * Depending on the preconditions configuration, radio driver has NRF_RAAL_MAX_CLEAN_UP_TIME_US - * microseconds to do any clean-up actions on RADIO peripheral and stop using it completely. - * Thus the Radio Scheduler has to call this function NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds - * before the timeslot is finished. - * - * If the Radio Scheduler is in the continuous mode, the next timeslot will be indicated again by - * the @ref nrf_802154_rsch_prec_approved. - * - * @note Because the radio driver core needs to stop any operation on the RADIO peripheral within - * NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds, this function should be called with high - * interrupt priority level to avoid unwanted delays. - * - * @note This function may be called after @ref nrf_802154_rsch_continuous_mode_exit is called. - * - */ -extern void nrf_802154_rsch_prec_denied(void); +extern void nrf_802154_rsch_continuous_prio_changed(rsch_prio_t prio); /** * @brief Notification that previously requested delayed timeslot has started just now. + * + * @param[in] dly_ts_id Type of the started timeslot. */ -extern void nrf_802154_rsch_delayed_timeslot_started(void); +extern void nrf_802154_rsch_delayed_timeslot_started(rsch_dly_ts_id_t dly_ts_id); /** * @brief Notification that previously requested delayed timeslot cannot be started. * * This function may be called when any of radio activity precondition is not satisfied at the * time when the timeslot should start. + * + * @param[in] dly_ts_id Type of the failed timeslot. */ -extern void nrf_802154_rsch_delayed_timeslot_failed(void); +extern void nrf_802154_rsch_delayed_timeslot_failed(rsch_dly_ts_id_t dly_ts_id); /** *@} diff --git a/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.c b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.c new file mode 100644 index 000000000..da8dcf2e5 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.c @@ -0,0 +1,154 @@ +/* Copyright (c) 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * @file + * This file implements critical sections for the RSCH module. + * + */ + +#include "nrf_802154_rsch_crit_sect.h" + +#include +#include +#include + +#include "nrf_802154_critical_section.h" +#include "nrf_802154_rsch.h" + +#include + +#define RSCH_EVT_NONE (rsch_prio_t)UINT8_MAX + +static volatile uint8_t m_rsch_pending_evt; ///< Indicator of pending RSCH event. + +/*************************************************************************************************** + * @section RSCH pending events management + **************************************************************************************************/ + +static void rsch_pending_evt_set(rsch_prio_t prio) +{ + volatile uint8_t rsch_pending_evt; // Dummy variable to prevent compilers from removing ldrex + + do + { + rsch_pending_evt = __LDREXB(&m_rsch_pending_evt); + (void)rsch_pending_evt; + } + while (__STREXB((uint8_t)prio, &m_rsch_pending_evt)); +} + +static rsch_prio_t rsch_pending_evt_clear(void) +{ + uint8_t evt_value; + + do + { + evt_value = __LDREXB(&m_rsch_pending_evt); + } + while (__STREXB(RSCH_EVT_NONE, &m_rsch_pending_evt)); + + return (rsch_prio_t)evt_value; +} + +static bool rsch_pending_evt_is_none(void) +{ + return m_rsch_pending_evt == (uint8_t)RSCH_EVT_NONE; +} + +static void rsch_evt_process(rsch_prio_t evt) +{ + if (evt != RSCH_EVT_NONE) + { + nrf_802154_rsch_crit_sect_prio_changed(evt); + } +} + +/*************************************************************************************************** + * @section Public API + **************************************************************************************************/ + +void nrf_802154_rsch_crit_sect_init(void) +{ + m_rsch_pending_evt = RSCH_EVT_NONE; +} + +void nrf_802154_rsch_crit_sect_prio_request(rsch_prio_t prio) +{ + nrf_802154_rsch_continuous_mode_priority_set(prio); +} + +/*************************************************************************************************** + * @section RSCH callbacks + **************************************************************************************************/ + +void nrf_802154_rsch_continuous_prio_changed(rsch_prio_t prio) +{ + bool crit_sect_success = false; + + crit_sect_success = nrf_802154_critical_section_enter(); + + // If we managed to enter critical section, but there is already a pending event, + // it means that the Critical Section module is about to make one more iteration of the + // critical section exit procedure. To prevent race in continuous mode priorities notification, + // we do not notify directly, but just update the pending event. + if (crit_sect_success && rsch_pending_evt_is_none()) + { + nrf_802154_rsch_crit_sect_prio_changed(prio); + } + else + { + rsch_pending_evt_set(prio); + } + + if (crit_sect_success) + { + nrf_802154_critical_section_exit(); + } +} + +/*************************************************************************************************** + * @section Critical section callbacks + **************************************************************************************************/ + +void nrf_802154_critical_section_rsch_enter(void) +{ + // Intentionally empty +} + +void nrf_802154_critical_section_rsch_exit(void) +{ + rsch_evt_process(rsch_pending_evt_clear()); +} + +bool nrf_802154_critical_section_rsch_event_is_pending(void) +{ + return !rsch_pending_evt_is_none(); +} diff --git a/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.h b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.h new file mode 100644 index 000000000..75563e3fa --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_rsch_crit_sect.h @@ -0,0 +1,71 @@ +/* Copyright (c) 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NRF_802154_RSCH_CRIT_SECT_H__ +#define NRF_802154_RSCH_CRIT_SECT_H__ + +#include + +#include "nrf_802154_rsch.h" + +/** + * @defgroup nrf_802154_rsch_crit_sect RSCH event queue used during critical sections + * @{ + * @ingroup nrf_802154_rsch + * @brief Critical section implementation for the RSCH module. + */ + +/** + * @brief Initialize the RSCH critical section module. + */ +void nrf_802154_rsch_crit_sect_init(void); + +/** + * @brief Request priority level from RSCH through the critical section module. + * + * @param[in] prio Requested priority level. + */ +void nrf_802154_rsch_crit_sect_prio_request(rsch_prio_t prio); + +/** + * @brief This function is called to notify the core that approved RSCH priority has changed. + * + * @note This function is called from critical section context and does not preempt other critical + * sections. + * + * @param[in] prio Approved priority level. + */ +extern void nrf_802154_rsch_crit_sect_prio_changed(rsch_prio_t prio); + +/** + *@} + **/ + +#endif // NRF_802154_RSCH_CRIT_SECT_H__ diff --git a/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_wifi_coex.h b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_wifi_coex.h new file mode 100644 index 000000000..130189db5 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/nrf_802154_wifi_coex.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * @brief This module defines the Wifi coexistence module. + * + */ + +#ifndef NRF_802154_WIFI_COEX_H_ +#define NRF_802154_WIFI_COEX_H_ + +#include "nrf_802154_rsch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_wifi_coex Wifi Coexistence + * @{ + * @ingroup nrf_802154 + * @brief Wifi Coexistence module. + * + * Wifi Coexistence module is a client of the PTA (defined in the 802.15.2). It manages GPIO + * to assert pins and respond to pin state changes. + */ + +/** + * @brief Initialize the Wifi Coexistence module. + * + * @note This function shall be called once, before any other function from this module. + * + */ +void nrf_802154_wifi_coex_init(void); + +/** + * @brief Uninitialize the Wifi Coexistence module. + * + */ +void nrf_802154_wifi_coex_uninit(void); + +/** + * @brief Request given priority from the Wifi Coexistence module. + * + * @note The approval of requested priority is notified asynchronously by the + * @ref nrf_802154_wifi_coex_prio_changed call. + * + * @param[in] priority Requested priority level. + * + */ +void nrf_802154_wifi_coex_prio_req(rsch_prio_t priority); + +/** + * @brief Get priority denial event address. + * + * Get an address of a hardware event that notifies about denial of the previously approved + * priority. + * + * @return Address of a priority denial event. + */ +void * nrf_802154_wifi_coex_deny_event_addr_get(void); + +/** + * @biref Approved priority change notification. + * + * The Wifi Coexistence module calls this function to notify the RSCH of currently approved + * priority level. + * + * @param[in] priority Approved priority level. + */ +extern void nrf_802154_wifi_coex_prio_changed(rsch_prio_t priority); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_802154_WIFI_COEX_H_ */ diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_api.h b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_api.h similarity index 95% rename from third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_api.h rename to third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_api.h index 82573c22a..474b4159f 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_api.h +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_api.h @@ -85,13 +85,20 @@ void nrf_raal_uninit(void); void nrf_raal_continuous_mode_enter(void); /** - * @brief Exit arbiter from continous mode. + * @brief Exit arbiter from continuous mode. * * In this mode radio arbiter will not extend or allocate any more timeslots for radio driver. * */ void nrf_raal_continuous_mode_exit(void); +/** + * @brief Confirm to RAAL that current part of the continuous timeslot is ended. + * + * The core cannot use the RADIO peripheral after this call until the timeslot is started again. + */ +void nrf_raal_continuous_ended(void); + /** * @brief Request timeslot for radio communication. * diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_config.h similarity index 98% rename from third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h rename to third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_config.h index 1da120485..986a06100 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/nrf_raal_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/nrf_raal_config.h @@ -56,7 +56,7 @@ extern "C" { * */ #ifndef NRF_RAAL_MAX_CLEAN_UP_TIME_US -#define NRF_RAAL_MAX_CLEAN_UP_TIME_US 91 +#define NRF_RAAL_MAX_CLEAN_UP_TIME_US 91 #endif /** diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/simulator/nrf_raal_simulator.c b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/simulator/nrf_raal_simulator.c similarity index 95% rename from third_party/NordicSemiconductor/drivers/radio/raal/simulator/nrf_raal_simulator.c rename to third_party/NordicSemiconductor/drivers/radio/rsch/raal/simulator/nrf_raal_simulator.c index dae0438b5..b27026996 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/simulator/nrf_raal_simulator.c +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/simulator/nrf_raal_simulator.c @@ -95,11 +95,11 @@ void nrf_raal_init(void) NVIC_ClearPendingIRQ(MWU_IRQn); NVIC_EnableIRQ(MWU_IRQn); - NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; - NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_24Bit; - NRF_TIMER0->PRESCALER = 4; - NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk; - NRF_TIMER0->CC[0] = m_started_timestamp; + NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; + NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_24Bit; + NRF_TIMER0->PRESCALER = 4; + NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk; + NRF_TIMER0->CC[0] = m_started_timestamp; NVIC_SetPriority(TIMER0_IRQn, 1); NVIC_ClearPendingIRQ(TIMER0_IRQn); @@ -155,6 +155,11 @@ void nrf_raal_continuous_mode_exit(void) nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_EXIT); } +void nrf_raal_continuous_ended(void) +{ + // Intentionally empty. +} + bool nrf_raal_timeslot_request(uint32_t length_us) { uint32_t timer; diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/single_phy/single_phy.c similarity index 96% rename from third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c rename to third_party/NordicSemiconductor/drivers/radio/rsch/raal/single_phy/single_phy.c index 2067586b2..a27e98749 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/single_phy/single_phy.c +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/single_phy/single_phy.c @@ -69,9 +69,14 @@ void nrf_raal_continuous_mode_exit(void) m_continuous = false; } +void nrf_raal_continuous_ended(void) +{ + // Intentionally empty. +} + bool nrf_raal_timeslot_request(uint32_t length_us) { - (void) length_us; + (void)length_us; assert(m_continuous); @@ -82,4 +87,3 @@ uint32_t nrf_raal_timeslot_us_left_get(void) { return UINT32_MAX; } - diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c similarity index 60% rename from third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c rename to third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c index bbdc1aae2..14fec32f6 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.c +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.c @@ -45,46 +45,69 @@ #include #include #include +#include #include +#include +#include #if defined(__GNUC__) - _Pragma("GCC diagnostic push") - _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") - _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") - _Pragma("GCC diagnostic ignored \"-Wpedantic\"") +_Pragma("GCC diagnostic push") +_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") +_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") +_Pragma("GCC diagnostic ignored \"-Wpedantic\"") #endif +#include +#include +#include #include #if defined(__GNUC__) - _Pragma("GCC diagnostic pop") +_Pragma("GCC diagnostic pop") #endif /*************************************************************************************************** * @section Defines and typedefs. **************************************************************************************************/ +/* + * @brief Defines the minimum version of the SoftDevice that supports configuration of BLE advertising + * role scheduling. + * + * The first SoftDevice that supports this option is S140 6.1.1 (6001001). The full version + * number for the SoftDevice binary is a decimal number in the form Mmmmbbb, where: + * - M is major version (one or more digits) + * - mmm is minor version (three digits) + * - bbb is bugfix version (three digits). + */ +#define BLE_ADV_SCHED_CFG_SUPPORT_MIN_SD_VERSION (6001001) + /**@brief Enable Request and End on timeslot safety interrupt. */ -#define ENABLE_REQUEST_AND_END_ON_TIMESLOT_END 0 +#define ENABLE_REQUEST_AND_END_ON_TIMESLOT_END 0 /**@brief RAAL Timer instance. */ -#define RAAL_TIMER NRF_TIMER0 +#define RAAL_TIMER NRF_TIMER0 /**@brief RAAL Timer interrupt number. */ -#define RAAL_TIMER_IRQn TIMER0_IRQn +#define RAAL_TIMER_IRQn TIMER0_IRQn -/**@brief Maximum jitter relative to the start time of START and TIMER0 (safety margin) events . */ -#define TIMER_TO_SIGNAL_JITTER_US NRF_RADIO_START_JITTER_US + 6 +/**@brief Minimum time prior safe margin reached by RTC when TIMER reports reached margin in microseconds. */ +#define MIN_TIME_PRIOR_MARGIN_IS_REACHED_US 31 /**@brief Timer compare channel definitions. */ -#define TIMER_CC_ACTION NRF_TIMER_CC_CHANNEL0 -#define TIMER_CC_ACTION_EVENT NRF_TIMER_EVENT_COMPARE0 -#define TIMER_CC_ACTION_INT NRF_TIMER_INT_COMPARE0_MASK +#define TIMER_CC_ACTION NRF_TIMER_CC_CHANNEL0 +#define TIMER_CC_ACTION_EVENT NRF_TIMER_EVENT_COMPARE0 +#define TIMER_CC_ACTION_INT NRF_TIMER_INT_COMPARE0_MASK -#define TIMER_CC_CAPTURE NRF_TIMER_CC_CHANNEL1 -#define TIMER_CC_CAPTURE_TASK NRF_TIMER_TASK_CAPTURE1 +#define TIMER_CC_CAPTURE NRF_TIMER_CC_CHANNEL1 +#define TIMER_CC_CAPTURE_TASK NRF_TIMER_TASK_CAPTURE1 -#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_TICKS NRF_802154_US_TO_RTC_TICKS(NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US) +#define MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_TICKS NRF_802154_US_TO_RTC_TICKS( \ + NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US) + +/**@brief PPM constants. */ +#define PPM_UNIT 1000000UL +#define MAX_HFCLK_PPM 40 /**@brief Defines states of timeslot. */ typedef enum @@ -129,9 +152,31 @@ static timer_action_t m_timer_action; /**@brief Current timeslot length. */ static uint16_t m_timeslot_length; +/**@brief Previously granted timeslot length. */ +static uint16_t m_prev_timeslot_length; + +/**@brief Interval between successive timeslot extensions. */ +static uint16_t m_extension_interval; + /**@brief Number of already performed extentions tries on failed event. */ static volatile uint16_t m_timeslot_extend_tries; +/*************************************************************************************************** + * @section Drift calculations + **************************************************************************************************/ + +static uint32_t time_corrected_for_drift_get(uint32_t time) +{ + uint32_t ppm = m_config.lf_clk_accuracy_ppm + MAX_HFCLK_PPM; + + return time - NRF_802154_DIVIDE_AND_CEIL(time * ppm, PPM_UNIT); +} + +static void calculate_config(void) +{ + m_extension_interval = time_corrected_for_drift_get(m_config.timeslot_length); +} + /*************************************************************************************************** * @section Operations on RAAL TIMER. **************************************************************************************************/ @@ -185,7 +230,7 @@ static inline uint32_t ticks_to_timeslot_end_get(void) static inline uint32_t safe_time_to_timeslot_end_get(void) { - uint32_t margin = m_config.timeslot_safe_margin + TIMER_TO_SIGNAL_JITTER_US; + uint32_t margin = m_config.timeslot_safe_margin + NRF_RADIO_START_JITTER_US; uint32_t timeslot_end = NRF_802154_RTC_TICKS_TO_US(ticks_to_timeslot_end_get()); if (timeslot_end > margin) @@ -201,7 +246,10 @@ static inline uint32_t safe_time_to_timeslot_end_get(void) /**@brief Get timeslot margin. */ static uint32_t timer_get_cc_margin(void) { - return timer_time_get() + safe_time_to_timeslot_end_get(); + uint32_t corrected_time_to_margin = time_corrected_for_drift_get( + safe_time_to_timeslot_end_get()); + + return timer_time_get() + corrected_time_to_margin; } /**@brief Set timer action to the timeslot margin. */ @@ -219,7 +267,8 @@ static inline void timer_to_margin_set(void) /**@brief Check if margin is already reached. */ static inline bool timer_is_margin_reached(void) { - return timer_is_set_to_margin() && nrf_timer_event_check(RAAL_TIMER, TIMER_CC_ACTION_EVENT); + return timer_is_set_to_margin() && nrf_timer_event_check(RAAL_TIMER, TIMER_CC_ACTION_EVENT) && + safe_time_to_timeslot_end_get() <= MIN_TIME_PRIOR_MARGIN_IS_REACHED_US; } /**@brief Set timer on extend event. */ @@ -230,13 +279,18 @@ static void timer_on_extend_update(void) if (timer_is_set_to_margin()) { uint32_t margin_cc = nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_ACTION); + margin_cc += m_timeslot_length; nrf_timer_cc_write(RAAL_TIMER, TIMER_CC_ACTION, margin_cc); } else { + uint16_t extension_interval = (m_prev_timeslot_length == m_config.timeslot_length) ? + m_extension_interval : + time_corrected_for_drift_get(m_prev_timeslot_length); + nrf_timer_cc_write(RAAL_TIMER, TIMER_CC_ACTION, - nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_ACTION) + m_timeslot_length); + nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_ACTION) + extension_interval); nrf_timer_int_enable(RAAL_TIMER, TIMER_CC_ACTION_INT); } } @@ -355,27 +409,30 @@ static void timer_irq_handle(void) { if (timer_is_set_to_margin()) { - // Safe margin exceeded. - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_MARGIN); + if (timer_is_margin_reached()) + { + // Safe margin exceeded. + nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_MARGIN); - m_timeslot_state = TIMESLOT_STATE_IDLE; - timeslot_ended_notify(); + m_timeslot_state = TIMESLOT_STATE_IDLE; + timeslot_ended_notify(); - // Ignore any other events. - timer_reset(); + // Ignore any other events. + timer_reset(); - #if (ENABLE_REQUEST_AND_END_ON_TIMESLOT_END == 1) - timeslot_data_init(); - timeslot_request_prepare(); - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END; - m_ret_param.params.request.p_next = &m_request; - #else - // Return and wait for NRF_EVT_RADIO_SESSION_IDLE event. - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; - #endif + // Return and wait for NRF_EVT_RADIO_SESSION_IDLE event. + m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_MARGIN); + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_MARGIN); + } + else + { + // Move safety margin a little further to suppress clocks drift + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_MARGIN_MOVE); + timer_to_margin_set(); + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_MARGIN_MOVE); + } } else { @@ -387,7 +444,7 @@ static void timer_irq_handle(void) if (m_continuous && (nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_ACTION) + - m_config.timeslot_length < m_config.timeslot_max_length)) + m_config.timeslot_length < m_config.timeslot_max_length)) { // Try to extend timeslot. timeslot_extend(m_config.timeslot_length); @@ -415,7 +472,7 @@ static void timer_irq_handle(void) **************************************************************************************************/ /**@brief Signal handler. */ -static nrf_radio_signal_callback_return_param_t *signal_handler(uint8_t signal_type) +static nrf_radio_signal_callback_return_param_t * signal_handler(uint8_t signal_type) { nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_HANDLER); @@ -427,7 +484,7 @@ static nrf_radio_signal_callback_return_param_t *signal_handler(uint8_t signal_t nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_ENDED); - m_timeslot_state = TIMESLOT_STATE_IDLE; + m_timeslot_state = TIMESLOT_STATE_IDLE; // TODO: Change to NRF_RADIO_SIGNAL_CALLBACK_ACTION_END (KRKNWK-937) m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; @@ -440,97 +497,107 @@ static nrf_radio_signal_callback_return_param_t *signal_handler(uint8_t signal_t switch (signal_type) { - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START: /**< This signal indicates the start of the radio timeslot. */ - { - nrf_802154_pin_set(PIN_DBG_TIMESLOT_ACTIVE); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_START); - - assert(m_timeslot_state == TIMESLOT_STATE_REQUESTED); - - m_timeslot_state = TIMESLOT_STATE_GRANTED; - - // Set up timer first with requested timeslot length. - timer_start(); - - // Re-initialize timeslot data for future extensions. - timeslot_data_init(); - - timeslot_started_notify(); - - // Try to extend right after start. - timeslot_extend(m_timeslot_length); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_START); - break; - } - - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0: /**< This signal indicates the TIMER0 interrupt. */ - timer_irq_handle(); - break; - - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO: /**< This signal indicates the NRF_RADIO interrupt. */ - nrf_802154_pin_set(PIN_DBG_TIMESLOT_RADIO_IRQ); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_RADIO); - - if (timeslot_is_granted()) + case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START: /**< This signal indicates the start of the radio timeslot. */ { - if (!timer_is_margin_reached()) - { - nrf_802154_radio_irq_handler(); - } - else - { - // Handle margin exceeded event. - timer_irq_handle(); - } - } - else - { - NVIC_DisableIRQ(RADIO_IRQn); - } + nrf_802154_pin_set(PIN_DBG_TIMESLOT_ACTIVE); + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_START); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_RADIO); - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_RADIO_IRQ); - break; + assert(m_timeslot_state == TIMESLOT_STATE_REQUESTED); - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED: /**< This signal indicates extend action failed. */ - nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_FAILED); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL); + // Set up timer first with requested timeslot length. + timer_start(); - if (!timer_is_set_to_margin()) - { - timer_to_margin_set(); - } + // Re-initialize timeslot data for future extensions. + m_prev_timeslot_length = m_timeslot_length; + timeslot_data_init(); - timeslot_next_extend(); + // Try to extend right after start. + timeslot_extend(m_timeslot_length); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL); - break; + // Do not notify started timeslot here. Notify after successful extend to make sure + // enough timeslot length is available before notification. - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED: /**< This signal indicates extend action succeeded. */ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS); - - if ((!timer_is_set_to_margin()) && (ticks_to_timeslot_end_get() < NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_TICKS)) - { - timer_to_margin_set(); - - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_START); break; } - timer_on_extend_update(); + case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0: /**< This signal indicates the TIMER0 interrupt. */ + timer_irq_handle(); + break; + + case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO: /**< This signal indicates the NRF_RADIO interrupt. */ + nrf_802154_pin_set(PIN_DBG_TIMESLOT_RADIO_IRQ); + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_RADIO); + + if (timeslot_is_granted()) + { + if (!timer_is_margin_reached()) + { + nrf_802154_radio_irq_handler(); + } + else + { + // Handle margin exceeded event. + timer_irq_handle(); + } + } + else + { + NVIC_DisableIRQ(RADIO_IRQn); + } + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_RADIO); + nrf_802154_pin_clr(PIN_DBG_TIMESLOT_RADIO_IRQ); + break; + + case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED: /**< This signal indicates extend action failed. */ + nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_FAILED); + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL); + + if (!timer_is_set_to_margin()) + { + timer_to_margin_set(); + } - // Request futher extension only if any of previous one failed. - if (m_timeslot_extend_tries != 0) - { timeslot_next_extend(); - } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS); - break; + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL); + break; - default: - break; + case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED: /**< This signal indicates extend action succeeded. */ + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS); + + if ((!timer_is_set_to_margin()) && + (ticks_to_timeslot_end_get() < + MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_TICKS)) + { + timer_to_margin_set(); + + m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; + } + else + { + timer_on_extend_update(); + m_prev_timeslot_length = m_timeslot_length; + + // Request further extension only if any of previous one failed. + if (m_timeslot_extend_tries != 0) + { + timeslot_next_extend(); + } + } + + if (!timeslot_is_granted()) + { + m_timeslot_state = TIMESLOT_STATE_GRANTED; + timeslot_started_notify(); + } + + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS); + break; + + default: + break; } nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_HANDLER); @@ -542,55 +609,55 @@ void nrf_raal_softdevice_soc_evt_handler(uint32_t evt_id) { switch (evt_id) { - case NRF_EVT_RADIO_BLOCKED: - case NRF_EVT_RADIO_CANCELED: - { - nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_BLOCKED); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_EVT_BLOCKED); - - assert(!timeslot_is_granted()); - - m_timeslot_state = TIMESLOT_STATE_IDLE; - - if (m_continuous) + case NRF_EVT_RADIO_BLOCKED: + case NRF_EVT_RADIO_CANCELED: { - if (m_timeslot_extend_tries < m_config.timeslot_alloc_iters) + nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_BLOCKED); + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_EVT_BLOCKED); + + assert(!timeslot_is_granted()); + + m_timeslot_state = TIMESLOT_STATE_IDLE; + + if (m_continuous) { - timeslot_length_decrease(); + if (m_timeslot_extend_tries < m_config.timeslot_alloc_iters) + { + timeslot_length_decrease(); + } + + timeslot_request(); } - timeslot_request(); + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_EVT_BLOCKED); + + break; } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_EVT_BLOCKED); + case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN: + assert(false); + break; - break; - } + case NRF_EVT_RADIO_SESSION_IDLE: - case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN: - assert(false); - break; + nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_EVT_SESSION_IDLE); + nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_SESSION_IDLE); - case NRF_EVT_RADIO_SESSION_IDLE: + if (m_continuous && timeslot_is_idle()) + { + timeslot_data_init(); + timeslot_request(); + } - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_EVT_SESSION_IDLE); - nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_SESSION_IDLE); + nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_EVT_SESSION_IDLE); - if (m_continuous && timeslot_is_idle()) - { - timeslot_data_init(); - timeslot_request(); - } + break; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_EVT_SESSION_IDLE); + case NRF_EVT_RADIO_SESSION_CLOSED: + break; - break; - - case NRF_EVT_RADIO_SESSION_CLOSED: - break; - - default: - break; + default: + break; } } @@ -605,25 +672,48 @@ void nrf_raal_softdevice_config(const nrf_raal_softdevice_cfg_t * p_cfg) assert(p_cfg); m_config = *p_cfg; + + calculate_config(); } void nrf_raal_init(void) { assert(!m_initialized); - m_continuous = false; - m_timeslot_state = TIMESLOT_STATE_IDLE; + m_continuous = false; + m_timeslot_state = TIMESLOT_STATE_IDLE; m_config.timeslot_length = NRF_RAAL_TIMESLOT_DEFAULT_LENGTH; m_config.timeslot_alloc_iters = NRF_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS; m_config.timeslot_safe_margin = NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN; m_config.timeslot_max_length = NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH; m_config.timeslot_timeout = NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT; + m_config.lf_clk_accuracy_ppm = NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM; + + calculate_config(); uint32_t err_code = sd_radio_session_open(signal_handler); + assert(err_code == NRF_SUCCESS); (void)err_code; +#if (SD_VERSION >= BLE_ADV_SCHED_CFG_SUPPORT_MIN_SD_VERSION) + // Ensure that correct SoftDevice version is flashed. + if (SD_VERSION_GET(MBR_SIZE) >= BLE_ADV_SCHED_CFG_SUPPORT_MIN_SD_VERSION) + { + // Use improved Advertiser Role Scheduling configuration. + ble_opt_t opt; + + memset(&opt, 0, sizeof(opt)); + opt.common_opt.adv_sched_cfg.sched_cfg = ADV_SCHED_CFG_IMPROVED; + + err_code = sd_ble_opt_set(BLE_COMMON_OPT_ADV_SCHED_CFG, &opt); + + assert(err_code == NRF_SUCCESS); + (void)err_code; + } +#endif + m_initialized = true; } @@ -632,11 +722,12 @@ void nrf_raal_uninit(void) assert(m_initialized); uint32_t err_code = sd_radio_session_close(); + assert(err_code == NRF_SUCCESS); (void)err_code; - m_continuous = false; - m_timeslot_state = TIMESLOT_STATE_IDLE; + m_continuous = false; + m_timeslot_state = TIMESLOT_STATE_IDLE; nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); } @@ -677,14 +768,26 @@ void nrf_raal_continuous_mode_exit(void) nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_EXIT); } +void nrf_raal_continuous_ended(void) +{ + // Intentionally empty. +} + bool nrf_raal_timeslot_request(uint32_t length_us) { + uint32_t us_left; + if (!m_continuous || !timeslot_is_granted()) { return false; } - return length_us < nrf_raal_timeslot_us_left_get(); + us_left = nrf_raal_timeslot_us_left_get(); + + assert((us_left >= nrf_802154_rx_duration_get(MAX_PACKET_SIZE, + true)) || timer_is_set_to_margin()); + + return length_us < us_left; } uint32_t nrf_raal_timeslot_us_left_get(void) diff --git a/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.h similarity index 69% rename from third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h rename to third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.h index 8095ffbee..106fcdf10 100644 --- a/third_party/NordicSemiconductor/drivers/radio/raal/softdevice/nrf_raal_softdevice.h +++ b/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice/nrf_raal_softdevice.h @@ -46,30 +46,35 @@ extern "C" { #endif /** @brief RAAL Softdevice default parameters. */ -#define NRF_RAAL_TIMESLOT_DEFAULT_LENGTH 6400 -#define NRF_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS 5 -#define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN nrf_raal_softdevice_safe_margin_calc(NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM) -#define NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT 6400 -#define NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH 120000000 -#define NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM 500 +#define NRF_RAAL_TIMESLOT_DEFAULT_LENGTH 6400 +#define NRF_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS 5 +#define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN nrf_raal_softdevice_safe_margin_calc( \ + NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM) +#define NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT 4500 +#define NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH 120000000 +#define NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM 500 #define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_LFRC_TICKS 4 #define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_CRYSTAL_TICKS 3 #define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_US 3 -#define NRF_RAAL_PPM_THRESHOLD 500 +#define NRF_RAAL_PPM_THRESHOLD 500 -#define NRF_RAAL_TIMESLOT_SAFE_MARGIN_TICKS(ppm) ((ppm >= NRF_RAAL_PPM_THRESHOLD) ? \ - NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_LFRC_TICKS : \ - NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_CRYSTAL_TICKS) +#define NRF_RAAL_TIMESLOT_SAFE_MARGIN_TICKS(ppm) ((ppm >= NRF_RAAL_PPM_THRESHOLD) ? \ + NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_LFRC_TICKS \ + : \ + NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_CRYSTAL_TICKS) /** * @brief Function used to calculate safe margin from LF clock accuracy in ppm unit. * * @param[in] ppm LF clock accuracy in ppm unit. */ -#define nrf_raal_softdevice_safe_margin_calc(ppm) (NRF_802154_RTC_TICKS_TO_US(NRF_RAAL_TIMESLOT_SAFE_MARGIN_TICKS(ppm)) \ - + NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_US) +#define nrf_raal_softdevice_safe_margin_calc(ppm) (NRF_802154_RTC_TICKS_TO_US( \ + NRF_RAAL_TIMESLOT_SAFE_MARGIN_TICKS( \ + ppm)) \ + + \ + NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_US) /** @brief RAAL Softdevice configuration parameters. */ typedef struct @@ -99,12 +104,10 @@ typedef struct * @ref nrf_raal_softdevice_safe_margin_calc can be used to calculate proper value based on clock accuracy. * This value can also be selected experimentally. */ - uint16_t timeslot_safe_margin; + uint16_t timeslot_safe_margin; /** - * @brief @deprecated Clock accuracy in ppm unit. - * This value is not used anymore. - * Clock accuracy is embedded into timeslot_safe_margin. + * @brief Clock accuracy in ppm unit. */ uint16_t lf_clk_accuracy_ppm; } nrf_raal_softdevice_cfg_t; diff --git a/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c b/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c index 1f23d774d..00378bf25 100644 --- a/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c +++ b/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c @@ -51,7 +51,7 @@ #include "platform/lp_timer/nrf_802154_lp_timer.h" #if defined(__ICCARM__) - _Pragma("diag_suppress=Pe167") +_Pragma("diag_suppress=Pe167") #endif static volatile uint8_t m_timer_mutex; ///< Mutex for starting the timer. @@ -75,7 +75,8 @@ static inline bool mutex_trylock(volatile uint8_t * p_mutex) __CLREX(); return false; } - } while (__STREXB(1, p_mutex)); + } + while (__STREXB(1, p_mutex)); __DMB(); @@ -97,7 +98,8 @@ static inline void queue_cntr_bump(void) do { cntr = __LDREXB(&m_queue_changed_cntr); - } while (__STREXB(cntr + 1, &m_queue_changed_cntr)); + } + while (__STREXB(cntr + 1, &m_queue_changed_cntr)); __DMB(); } @@ -165,7 +167,8 @@ static inline void handle_timer(void) mutex_unlock(&m_timer_mutex); } - } while (queue_cntr != m_queue_changed_cntr); + } + while (queue_cntr != m_queue_changed_cntr); } /** @@ -259,7 +262,8 @@ static bool timer_remove(nrf_802154_timer_t * p_timer) // This assignment is used to prevent compiler from removing exclusive load during optimization (IAR). temp = __LDREXW((uint32_t *)&p_cur->p_next); assert((void *)temp != p_cur); - } while (__STREXW(temp, (uint32_t *)&p_cur->p_next)); + } + while (__STREXW(temp, (uint32_t *)&p_cur->p_next)); } return (timer_start || timer_stop); @@ -298,6 +302,24 @@ bool nrf_802154_timer_sched_time_is_in_future(uint32_t now, uint32_t t0, uint32_ return difference > 0; } +uint32_t nrf_802154_timer_sched_remaining_time_get(const nrf_802154_timer_t * p_timer) +{ + assert(p_timer != NULL); + + uint32_t now = nrf_802154_lp_timer_time_get(); + uint32_t expiration = p_timer->t0 + p_timer->dt; + int32_t remaining = expiration - now; + + if (remaining > 0) + { + return (uint32_t)remaining; + } + else + { + return 0ul; + } +} + void nrf_802154_timer_sched_add(nrf_802154_timer_t * p_timer, bool round_up) { nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TSCH_ADD); @@ -316,7 +338,7 @@ void nrf_802154_timer_sched_add(nrf_802154_timer_t * p_timer, bool round_up) } nrf_802154_timer_t ** pp_item; - nrf_802154_timer_t * p_next; + nrf_802154_timer_t * p_next; uint8_t queue_cntr; while (true) @@ -402,7 +424,8 @@ bool nrf_802154_timer_sched_is_running(nrf_802154_timer_t * p_timer) break; } } - } while (queue_cntr != m_queue_changed_cntr); + } + while (queue_cntr != m_queue_changed_cntr); return result; } @@ -413,7 +436,7 @@ void nrf_802154_lp_timer_fired(void) if (mutex_trylock(&m_fired_mutex)) { - nrf_802154_timer_t * p_timer = (nrf_802154_timer_t *) mp_head; + nrf_802154_timer_t * p_timer = (nrf_802154_timer_t *)mp_head; if (p_timer != NULL) { diff --git a/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h b/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h index dc2d9bae5..4889aa09c 100644 --- a/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h +++ b/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.h @@ -76,11 +76,11 @@ typedef struct nrf_802154_timer_s nrf_802154_timer_t; */ struct nrf_802154_timer_s { - uint32_t t0; ///< Base time of the timer [us] - uint32_t dt; ///< Timer expiration delta from @p t0 [us] - nrf_802154_timer_callback_t callback; ///< Callback function called when timer expires - void * p_context; ///< User-defined context passed to callback function - nrf_802154_timer_t * p_next; ///< A pointer to the next running timer + uint32_t t0; ///< Base time of the timer [us] + uint32_t dt; ///< Timer expiration delta from @p t0 [us] + nrf_802154_timer_callback_t callback; ///< Callback function called when timer expires + void * p_context; ///< User-defined context passed to callback function + nrf_802154_timer_t * p_next; ///< A pointer to the next running timer }; /** @@ -121,6 +121,15 @@ uint32_t nrf_802154_timer_sched_granularity_get(void); */ bool nrf_802154_timer_sched_time_is_in_future(uint32_t now, uint32_t t0, uint32_t dt); +/** + * @brief Get timer time remaining to expiration. + * + * @param[in] p_timer Pointer to the timer to check remaining time. + * + * @retval remaining time [us] or 0 if timer has already expired. + */ +uint32_t nrf_802154_timer_sched_remaining_time_get(const nrf_802154_timer_t * p_timer); + /** * @brief Start given timer and add it to the scheduler. *