nrf53: fix RTC pretick for RTC rescheduling by other interrupts

It might happen that while some interrupt handler other than for RTC0
or RTC1 (e.g. for RADIO) is executed, the scheduled pretick CC triggers.
This starts pretick pulses due to the loop through IPC. The change
in pretick schedule did not stop the pretick pulses going through IPC
loop, what caused heavy increase in power consumption.

This commit fixes this behavior.
Added also clarifications for Kconfig option `SOC_NRF53_RTC_PRETICK`.

Signed-off-by: Andrzej Kuroś <andrzej.kuros@nordicsemi.no>
This commit is contained in:
Andrzej Kuros 2023-10-10 16:14:14 +02:00 committed by Carles Cufí
commit 3eef769209
2 changed files with 17 additions and 11 deletions

View file

@ -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

View file

@ -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)