Skip to content
This repository was archived by the owner on Oct 23, 2025. It is now read-only.

Commit a47e326

Browse files
nordic-krchaescolar
authored andcommitted
HW_models: NRF_RTC: Fix compare event missed when interrupt disabled
If compare event interrupt was disabled and event occurred then that interrupt was not triggered after interrupt re-enabling. Added checking if there are pending events for interrupt which are reenabled. Interrupt is triggered then. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent 4e11816 commit a47e326

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

src/HW_models/NRF_RTC.c

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,29 +180,51 @@ static void update_all_cc_timers(int rtc) {
180180
}
181181
}
182182

183-
void nrf_rtc_timer_triggered() {
184-
for ( int rtc = 0; rtc < N_RTC-1/*the 3rd rtc does not have an int*/ ; rtc++ ){
185-
if ( RTC_Running[rtc] == false ) {
186-
continue;
183+
static unsigned int get_irq_t(int rtc)
184+
{
185+
unsigned int irq_t = NRF5_IRQ_RTC0_IRQn;
186+
187+
switch (rtc){
188+
case 0:
189+
irq_t = NRF5_IRQ_RTC0_IRQn;
190+
break;
191+
case 1:
192+
irq_t = NRF5_IRQ_RTC1_IRQn;
193+
break;
194+
case 2:
195+
irq_t = NRF5_IRQ_RTC1_IRQn;
196+
bs_trace_error_line_time("There is no IRQ mapped for RTC2\n");
197+
break;
187198
}
199+
200+
return irq_t;
201+
}
202+
203+
static ppi_event_types_t get_event(int rtc)
204+
{
188205
ppi_event_types_t event = RTC0_EVENTS_COMPARE_0;
189-
unsigned int irq_t = NRF5_IRQ_RTC0_IRQn;
190206
switch (rtc){
191207
case 0:
192208
event = RTC0_EVENTS_COMPARE_0;
193-
irq_t = NRF5_IRQ_RTC0_IRQn;
194209
break;
195210
case 1:
196211
event = RTC1_EVENTS_COMPARE_0;
197-
irq_t = NRF5_IRQ_RTC1_IRQn;
198212
break;
199213
case 2:
200214
event = RTC2_EVENTS_COMPARE_0;
201-
irq_t = NRF5_IRQ_RTC1_IRQn;
202-
bs_trace_error_line_time("There is no IRQ mapped for RTC2\n");
203215
break;
204216
}
205217

218+
return event;
219+
}
220+
221+
void nrf_rtc_timer_triggered() {
222+
for ( int rtc = 0; rtc < N_RTC-1/*the 3rd rtc does not have an int*/ ; rtc++ ){
223+
if ( RTC_Running[rtc] == false ) {
224+
continue;
225+
}
226+
ppi_event_types_t event = get_event(rtc);
227+
206228
NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[rtc];
207229

208230
uint32_t mask = RTC_EVTEN_COMPARE0_Msk;
@@ -219,7 +241,7 @@ void nrf_rtc_timer_triggered() {
219241
nrf_ppi_event(event);
220242
}
221243
if ( RTC_INTEN[rtc] & mask ){
222-
hw_irq_ctrl_set_irq(irq_t);
244+
hw_irq_ctrl_set_irq(get_irq_t(rtc));
223245
}
224246
}
225247
} //if cc_timers[rtc][cc] == Timer_RTC
@@ -332,8 +354,18 @@ void nrf_rtc_regw_sideeffect_TASKS_CLEAR(int i) {
332354
void nrf_rtc_regw_sideeffect_INTENSET(int i) {
333355
NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
334356
if ( RTC_regs->INTENSET ){
357+
uint32_t new_interrupts = RTC_regs->INTENSET & ~RTC_INTEN[i];
358+
unsigned int irq_t = get_irq_t(i);
359+
uint32_t mask = RTC_EVTEN_COMPARE0_Msk;
360+
335361
RTC_INTEN[i] |= RTC_regs->INTENSET;
336362
RTC_regs->INTENSET = RTC_INTEN[i];
363+
for ( int cc = 0 ; cc < N_CC ; cc++, mask <<=1) {
364+
if (RTC_regs->EVENTS_COMPARE[cc] && (new_interrupts & mask)) {
365+
hw_irq_ctrl_set_irq(irq_t);
366+
}
367+
}
368+
337369
check_not_supported_func(RTC_INTEN[i]);
338370
}
339371
}

0 commit comments

Comments
 (0)