diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 87d8a6d0c7a..87d961d6fb3 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -58,7 +58,11 @@ config SOC_NRF53_RTC_PRETICK select ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK if SOC_NRF5340_CPUNET help Indicates that the pre-tick workaround for the anomaly 165 that affects - the nRF5340 SoC should be applied. + the nRF5340 SoC should be applied. The workaround applies to wake ups caused + by EVENTS_COMPARE and EVENTS_OVRFLW on RTC0 and RTC1 for which interrupts are + enabled through INTENSET register. The case when these events are generated + by EVTEN but without interrupts enabled through INTENSET is not handled. + The EVENTS_TICK event is not handled. if SOC_NRF53_RTC_PRETICK diff --git a/soc/arm/nordic_nrf/nrf53/soc.c b/soc/arm/nordic_nrf/nrf53/soc.c index c18228ac4fa..396ce79f49e 100644 --- a/soc/arm/nordic_nrf/nrf53/soc.c +++ b/soc/arm/nordic_nrf/nrf53/soc.c @@ -224,6 +224,15 @@ static bool cpu_idle_prepare_monitor_end(void) return __STREXB(0U, &cpu_idle_prepare_monitor_dummy); } +static void rtc_pretick_finish_previous(void) +{ + NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= + ~IPC_PUBLISH_RECEIVE_EN_Msk; + + nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); +} + + void z_arm_on_enter_cpu_idle_prepare(void) { bool ok_to_sleep = true; @@ -263,6 +272,7 @@ void z_arm_on_enter_cpu_idle_prepare(void) if (rtc_pretick_cc_val != nrf_rtc_cc_get(NRF_RTC1, RTC1_PRETICK_CC_CHAN)) { /* The CC for pretick needs to be updated. */ + rtc_pretick_finish_previous(); nrf_rtc_cc_set(NRF_RTC1, RTC1_PRETICK_CC_CHAN, rtc_pretick_cc_val); if (rtc_ticks_to_next_event >= NRF_RTC_COUNTER_MAX/2) { @@ -406,22 +416,14 @@ static int rtc_pretick_cpuapp_init(void) } #else /* CONFIG_SOC_NRF5340_CPUNET */ -static void rtc_pretick_rtc_isr_hook(void) -{ - NRF_IPC->PUBLISH_RECEIVE[CONFIG_SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET] &= - ~IPC_PUBLISH_RECEIVE_EN_Msk; - - nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_CHANNEL_EVENT_ADDR(RTC1_PRETICK_CC_CHAN)); -} - void rtc_pretick_rtc0_isr_hook(void) { - rtc_pretick_rtc_isr_hook(); + rtc_pretick_finish_previous(); } void rtc_pretick_rtc1_isr_hook(void) { - rtc_pretick_rtc_isr_hook(); + rtc_pretick_finish_previous(); } static int rtc_pretick_cpunet_init(void)