1 /*
2  * Copyright (c) 2017 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <string.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 
10 #include "NRF_PPI.h"
11 #include "NRF_CLOCK.h"
12 #include "NRF_HW_model_top.h"
13 #include "irq_ctrl.h"
14 #include "bs_tracing.h"
15 #include "time_machine_if.h"
16 
17 /*
18  * RTC — Real-time counter
19  *
20  * https://infocenter.nordicsemi.com/topic/ps_nrf52833/rtc.html?cp=4_1_0_5_19
21  */
22 
23 /* To simplify, so far it is only modeled what the current BLE controller uses
24  *
25  * NOT modelled:
26  *  * TICK events
27  *  * the delay in tasks or in the synchronization of configuration into the LF clock domain
28  *
29  * * Note: The COUNTER register is only updated when read with the proper function
30  *
31  * * Note: In this model all RTCs have 4 working CC registers (for simplicity)
32  *
33  * * Note: RTC2 cannot be used (it does not have an assigned interrupt)
34  */
35 
36 #define N_RTC 3
37 #define N_CC 4
38 
39 #define RTC_COUNTER_MASK 0xFFFFFF /*24 bits*/
40 #define RTC_TRIGGER_OVERFLOW_COUNTER_VALUE 0xFFFFF0
41 
42 #define SUB_US_BITS 9 // Bits representing sub-microsecond units
43 
44 NRF_RTC_Type NRF_RTC_regs[N_RTC];
45 
46 static bool RTC_Running[N_RTC] = {false};
47 static uint32_t RTC_INTEN[N_RTC] = {0};
48 
49 bs_time_t Timer_RTC = TIME_NEVER;
50 static bs_time_t cc_timers[N_RTC][N_CC] = {{TIME_NEVER}}; //when each CC will match (in microseconds)
51 static bs_time_t overflow_timer[N_RTC] = {TIME_NEVER}; //when the timer will overflow (in microseconds)
52 
53 static uint64_t overflow_timer_sub_us[N_RTC] = {TIME_NEVER}; //when the timer will overflow (in sub-microsecond units)
54 static uint64_t RTC_counter_startT_sub_us[N_RTC] = {TIME_NEVER}; //Time when the counter was "started" (really the time that would correspond to COUNTER = 0)
55 static uint64_t RTC_counter_startT_negative_sub_us[N_RTC] = {0};
56 
57 static uint32_t counter[N_RTC] = {0}; //Internal counter value when the counter was stopped
58 
59 static uint64_t first_lf_tick_time_sub_us = 0;
60 
61 
62 static bs_time_t sub_us_time_to_us_time(uint64_t sub_us_time);
63 static uint64_t us_time_to_sub_us_time(bs_time_t us_time);
64 
65 /**
66  * Convert a time delta in sub-microseconds units to the equivalent time in microseconds.
67  * The value is always rounded UP. This is because otherwise the events would be registered
68  * in a time in microseconds before the event actually occured. This would lead to many imprecise
69  * event timings for example if the timing of an event would be calculated base on the last LF
70  * clock tick (which happens for example when triggering the CLEAR or TRIGGER_OVERFLOW tasks)
71  */
sub_us_time_to_us_time(uint64_t sub_us_time)72 static bs_time_t sub_us_time_to_us_time(uint64_t sub_us_time)
73 {
74   bs_time_t us_time = sub_us_time >> SUB_US_BITS;
75 
76   if(sub_us_time % (1U << SUB_US_BITS) != 0) //rounding up
77   {
78     us_time += 1;
79   }
80 
81   return us_time;
82 }
83 
84 /**
85  * Convert a time delta in microseconds to the equivalent time in sub-microseconds units
86  */
us_time_to_sub_us_time(bs_time_t us_time)87 static uint64_t us_time_to_sub_us_time(bs_time_t us_time)
88 {
89   return us_time << SUB_US_BITS;
90 }
91 
get_hw_time_sub_us()92 static uint64_t get_hw_time_sub_us()
93 {
94   bs_time_t now = tm_get_hw_time();
95 
96   if (now > sub_us_time_to_us_time(TIME_NEVER)) {
97     bs_trace_error_time_line("Bummer, the RTC model only supports running for 1142 years\n");
98     /*If you really need this, generalize the calculation to more than 64 bits*/
99   }
100 
101   return us_time_to_sub_us_time(now);
102 }
103 
get_last_lf_tick_time_sub_us()104 static uint64_t get_last_lf_tick_time_sub_us() {
105   uint64_t now_sub_us = get_hw_time_sub_us();
106 
107   uint64_t lf_ticks = (now_sub_us - first_lf_tick_time_sub_us) / LF_CLOCK_PERIOD; //floor()
108   uint64_t last_tick_time_sub_us = lf_ticks * LF_CLOCK_PERIOD;
109   last_tick_time_sub_us += first_lf_tick_time_sub_us;
110 
111   return last_tick_time_sub_us;
112 }
113 
114 /**
115  * Convert a time delta in sub-microsecond units to the equivalent count accounting for the PRESCALER
116  * Note that the number is rounded down [floor()]
117  */
time_sub_us_to_counter(uint64_t delta_sub_us,int rtc)118 static uint64_t time_sub_us_to_counter(uint64_t delta_sub_us, int rtc) {
119   uint64_t ticks;
120 
121   ticks = delta_sub_us / ((uint64_t)LF_CLOCK_PERIOD * (NRF_RTC_regs[rtc].PRESCALER + 1));
122   return ticks;
123 }
124 
125 /**
126  * Convert a counter delta to sub-microsecond units accounting for the PRESCALER
127  */
counter_to_time_sub_us(uint64_t counter,int rtc)128 static uint64_t counter_to_time_sub_us(uint64_t counter, int rtc) {
129   uint64_t Elapsed;
130 
131   Elapsed = counter  * (uint64_t)LF_CLOCK_PERIOD * (NRF_RTC_regs[rtc].PRESCALER + 1);
132 
133   return Elapsed;
134 }
135 
136 /**
137  * Return the time in sub-microsecond units it takes for the COUNTER to do 1 wrap
138  */
time_of_1_counter_wrap_sub_us(int rtc)139 static uint64_t time_of_1_counter_wrap_sub_us(int rtc) {
140   return counter_to_time_sub_us((uint64_t)RTC_COUNTER_MASK + 1, rtc);
141 }
142 
get_counter_match_time(uint64_t counter_match,int rtc,uint64_t * next_match_sub_us)143 static bs_time_t get_counter_match_time(uint64_t counter_match, int rtc, uint64_t* next_match_sub_us)
144 {
145   bs_time_t next_match_us = TIME_NEVER;
146   *next_match_sub_us = TIME_NEVER;
147 
148   if (RTC_Running[rtc] == true) {
149     uint64_t now_sub_us = get_hw_time_sub_us();
150     uint64_t counter_match_sub_us = counter_to_time_sub_us(counter_match, rtc);
151 
152     if(RTC_counter_startT_sub_us[rtc] > 0)
153     {
154       *next_match_sub_us = RTC_counter_startT_sub_us[rtc]
155                               + counter_match_sub_us;
156     }
157     else if (counter_match_sub_us > RTC_counter_startT_negative_sub_us[rtc])
158     {
159       *next_match_sub_us =  counter_match_sub_us - RTC_counter_startT_negative_sub_us[rtc];
160     }
161     else
162     {
163       *next_match_sub_us = time_of_1_counter_wrap_sub_us(rtc) + counter_match_sub_us - RTC_counter_startT_negative_sub_us[rtc];
164     }
165 
166     while(*next_match_sub_us <= now_sub_us)
167     {
168       *next_match_sub_us += time_of_1_counter_wrap_sub_us(rtc);
169     }
170 
171     next_match_us = sub_us_time_to_us_time(*next_match_sub_us);
172   }
173 
174   return next_match_us;
175 }
176 
update_master_timer()177 static void update_master_timer() {
178   Timer_RTC = TIME_NEVER;
179   for (int rtc = 0; rtc < N_RTC ; rtc++) {
180     if (RTC_Running[rtc] == false) {
181       continue;
182     }
183     for (int cc = 0 ; cc < N_CC ; cc++) {
184       if (cc_timers[rtc][cc] < Timer_RTC) {
185         Timer_RTC = cc_timers[rtc][cc];
186       }
187     }
188 
189     if (overflow_timer[rtc] < Timer_RTC) {
190       Timer_RTC = overflow_timer[rtc];
191     }
192   }
193   nrf_hw_find_next_timer_to_trigger();
194 }
195 
196 /**
197  * Save in cc_timers[t][cc] the next time when this RTC will match the
198  * CC[cc] register
199  */
update_cc_timer(int rtc,int cc)200 static void update_cc_timer(int rtc, int cc) {
201   uint64_t match_sub_us; // Only to comply to the interface
202   cc_timers[rtc][cc] = get_counter_match_time(NRF_RTC_regs[rtc].CC[cc], rtc, &match_sub_us);
203 }
204 
update_all_cc_timers(int rtc)205 static void update_all_cc_timers(int rtc) {
206   for (int cc = 0 ; cc < N_CC; cc++){
207     update_cc_timer(rtc, cc);
208   }
209 }
210 
update_overflow_timer(int rtc)211 static void update_overflow_timer(int rtc) {
212   overflow_timer[rtc] = get_counter_match_time(RTC_COUNTER_MASK + 1, rtc, &overflow_timer_sub_us[rtc]);
213 }
214 
update_timers(int rtc)215 static void update_timers(int rtc)
216 {
217   update_all_cc_timers(rtc);
218   update_overflow_timer(rtc);
219   update_master_timer();
220 }
221 
222 /**
223  * Sets the counter value to the specified value. This is done by setting the "counter start time"
224  * to an appropriate value, so that the time ellapsed from the counter start corresponds to the given
225  * counter value. Such virtual "counter start time" can be negative.
226  */
set_counter_to(uint64_t counter_val,int rtc)227 static void set_counter_to(uint64_t counter_val, int rtc)
228 {
229   counter_val &= RTC_COUNTER_MASK;
230   uint64_t counter_val_sub_us = counter_to_time_sub_us(counter_val, rtc);
231 
232   // All the functions which use this reset the <PRESC>, so it is like the counter was set
233   // on the last LF clock tick
234   uint64_t last_lf_tick_sub_us = get_last_lf_tick_time_sub_us();
235 
236   if(last_lf_tick_sub_us >= counter_val_sub_us)
237   {
238     RTC_counter_startT_sub_us[rtc] = last_lf_tick_sub_us - counter_val_sub_us;
239     RTC_counter_startT_negative_sub_us[rtc] = 0;
240   }
241   else
242   {
243     RTC_counter_startT_sub_us[rtc] = 0;
244     RTC_counter_startT_negative_sub_us[rtc] = counter_val_sub_us - last_lf_tick_sub_us;
245   }
246 
247   counter[rtc] = counter_val;
248   NRF_RTC_regs[rtc].COUNTER = counter_val;
249 
250   update_timers(rtc);
251 }
252 
get_irq_t(int rtc)253 static unsigned int get_irq_t(int rtc)
254 {
255     unsigned int irq_t = RTC0_IRQn;
256 
257     switch (rtc){
258     case 0:
259       irq_t = RTC0_IRQn;
260       break;
261     case 1:
262       irq_t = RTC1_IRQn;
263       break;
264     case 2:
265       irq_t = RTC2_IRQn;
266       bs_trace_error_line_time("There is no IRQ mapped for RTC2\n");
267       break;
268     }
269 
270     return irq_t;
271 }
272 
get_cc_event(int rtc)273 static ppi_event_types_t get_cc_event(int rtc)
274 {
275     ppi_event_types_t event = RTC0_EVENTS_COMPARE_0;
276     switch (rtc){
277     case 0:
278       event = RTC0_EVENTS_COMPARE_0;
279       break;
280     case 1:
281       event = RTC1_EVENTS_COMPARE_0;
282       break;
283     case 2:
284       event = RTC2_EVENTS_COMPARE_0;
285       break;
286     }
287 
288     return event;
289 }
get_overflow_event(int rtc)290 static ppi_event_types_t get_overflow_event(int rtc)
291 {
292     ppi_event_types_t event = RTC0_EVENTS_OVRFLW;
293     switch (rtc){
294     case 0:
295       event = RTC0_EVENTS_OVRFLW;
296       break;
297     case 1:
298       event = RTC1_EVENTS_OVRFLW;
299       break;
300     case 2:
301       event = RTC2_EVENTS_OVRFLW;
302       break;
303     }
304 
305     return event;
306 }
307 
handle_event(int rtc,ppi_event_types_t event,uint32_t mask)308 static void handle_event(int rtc, ppi_event_types_t event, uint32_t mask)
309 {
310   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[rtc];
311 
312   if ( ( RTC_regs->EVTEN | RTC_INTEN[rtc] ) & mask ) {
313     if ( RTC_regs->EVTEN & mask ){
314       nrf_ppi_event(event);
315     }
316     if ( RTC_INTEN[rtc] & mask ){
317       hw_irq_ctrl_set_irq(get_irq_t(rtc));
318     }
319   }
320 }
321 
handle_cc_event(int rtc,int cc)322 static void handle_cc_event(int rtc, int cc)
323 {
324   ppi_event_types_t event = get_cc_event(rtc) + cc;
325   uint32_t mask = RTC_EVTEN_COMPARE0_Msk << cc;
326   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[rtc];
327 
328   if ( cc_timers[rtc][cc] == Timer_RTC ){ //This CC is matching now
329     update_cc_timer(rtc, cc); //Next time it will match
330 
331     bs_trace_raw_time(8, "RTC%i: CC%i matching now\n", rtc, cc);
332 
333     RTC_regs->EVENTS_COMPARE[cc] = 1;
334     handle_event(rtc, event, mask);
335   }
336 }
337 
handle_overflow_event(int rtc)338 static void handle_overflow_event(int rtc)
339 {
340   ppi_event_types_t event = get_overflow_event(rtc);
341   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[rtc];
342 
343   if ( overflow_timer[rtc] ==  Timer_RTC ) //Overflow occured now
344   {
345     // The real time (in sub-microsecond units, not in microseconds)
346     // in which the current overflow event occurs.
347     // update_overflow_timer will overwrite overflow_timer_sub_us[rtc]
348     uint64_t current_overflow_event_sub_us = overflow_timer_sub_us[rtc];
349 
350     update_overflow_timer(rtc); //Next time it will overflow
351 
352     bs_trace_raw_time(8, "RTC%i: Timer overflow\n", rtc);
353 
354     RTC_regs->EVENTS_OVRFLW = 1;
355     handle_event(rtc, event, RTC_EVTEN_OVRFLW_Msk);
356 
357     RTC_counter_startT_sub_us[rtc] = current_overflow_event_sub_us;
358     RTC_counter_startT_negative_sub_us[rtc] = 0;
359   }
360 }
361 
362 
nrf_rtc_timer_triggered()363 void nrf_rtc_timer_triggered() {
364   for ( int rtc = 0; rtc < N_RTC-1/*the 3rd rtc does not have an int*/ ; rtc++ ){
365     if ( RTC_Running[rtc] == false ) {
366       continue;
367     }
368 
369     for ( int cc = 0 ; cc < N_CC ; cc++) {
370       handle_cc_event(rtc, cc);
371     }
372 
373     handle_overflow_event(rtc); // this must always be the last event, as it might update RTC_counter_startT_sub_us
374 
375   } //for rtc
376   update_master_timer();
377 }
378 
379 /**
380  * Check if an EVTEN or INTEN has the tick event set
381  */
check_not_supported_func(uint32_t i)382 static void check_not_supported_func(uint32_t i) {
383   if (i &  RTC_EVTEN_TICK_Msk) {
384     bs_trace_warning_line_time("RTC: The TICK functionality is not modelled\n");
385   }
386 }
387 
nrf_rtc_init()388 void nrf_rtc_init() {
389   memset(NRF_RTC_regs, 0, sizeof(NRF_RTC_regs));
390   for (int i = 0; i < N_RTC ; i++) {
391     RTC_Running[i] = false;
392     RTC_INTEN[i] = 0;
393     counter[i] = 0;
394     RTC_counter_startT_sub_us[i] = TIME_NEVER;
395     RTC_counter_startT_negative_sub_us[i] = 0;
396     for (int j  = 0 ; j < N_CC ; j++) {
397       cc_timers[i][j] = TIME_NEVER;
398     }
399     overflow_timer[i] = TIME_NEVER;
400     overflow_timer_sub_us[i] = TIME_NEVER;
401   }
402   Timer_RTC = TIME_NEVER;
403 }
404 
nrf_rtc_clean_up()405 void nrf_rtc_clean_up() {
406 
407 }
408 
nrf_rtc_notify_first_lf_tick()409 void nrf_rtc_notify_first_lf_tick() {
410   first_lf_tick_time_sub_us = get_hw_time_sub_us();
411   bs_trace_raw_time(9, "RTC: First lf tick\n");
412 }
413 
nrf_rtc_update_COUNTER(int rtc)414 void nrf_rtc_update_COUNTER(int rtc) {
415   if (RTC_Running[rtc] == true) {
416     uint64_t count;
417     count = time_sub_us_to_counter(get_hw_time_sub_us() - RTC_counter_startT_sub_us[rtc]
418                                                           + RTC_counter_startT_negative_sub_us[rtc], rtc);
419     NRF_RTC_regs[rtc].COUNTER = count & RTC_COUNTER_MASK;
420   } else {
421     NRF_RTC_regs[rtc].COUNTER = counter[rtc] & RTC_COUNTER_MASK;
422   }
423 }
424 
425 /**
426  * TASK_START triggered handler
427  */
nrf_rtc_TASKS_START(int rtc)428 void nrf_rtc_TASKS_START(int rtc) {
429   if (RTC_Running[rtc] == true) {
430     return;
431   }
432   bs_trace_raw_time(5, "RTC%i: TASK_START\n", rtc);
433   RTC_Running[rtc] = true;
434 
435   //If the counter is not zero at start, is like if the counter was started earlier
436   set_counter_to(counter[rtc], rtc);
437 }
438 
439 /**
440  * TASK_STOP triggered handler
441  */
nrf_rtc_TASKS_STOP(int rtc)442 void nrf_rtc_TASKS_STOP(int rtc) {
443   if (RTC_Running[rtc] == false) {
444     return;
445   }
446   bs_trace_raw_time(5, "RTC%i: TASK_STOP\n", rtc);
447   RTC_Running[rtc] = false;
448   counter[rtc] = time_sub_us_to_counter(get_hw_time_sub_us() - RTC_counter_startT_sub_us[rtc]
449                                         + RTC_counter_startT_negative_sub_us[rtc], rtc); //we save the value when the counter was stoped in case it is started again without clearing it
450   counter[rtc] &= RTC_COUNTER_MASK;
451   for (int cc = 0 ; cc < N_CC ; cc++){
452     cc_timers[rtc][cc] = TIME_NEVER;
453   }
454   overflow_timer[rtc] = TIME_NEVER;
455   update_master_timer();
456 }
457 
458 /**
459  * TASK_CLEAR triggered handler
460  */
nrf_rtc_TASKS_CLEAR(int rtc)461 void nrf_rtc_TASKS_CLEAR(int rtc) {
462   bs_trace_raw_time(5, "RTC%i: TASK_CLEAR\n", rtc);
463 
464   set_counter_to(0, rtc);
465 }
466 
467 /**
468  * TASK_TRIGGER_OVERFLOW triggered handler
469  */
nrf_rtc_TASKS_TRIGOVRFLW(int rtc)470 void nrf_rtc_TASKS_TRIGOVRFLW(int rtc) {
471 
472   bs_trace_raw_time(5, "RTC%i: TASK_TRIGGER_OVERFLOW\n", rtc);
473 
474   set_counter_to(RTC_TRIGGER_OVERFLOW_COUNTER_VALUE, rtc);
475 }
476 
nrf_rtc0_TASKS_START()477 void nrf_rtc0_TASKS_START()       { nrf_rtc_TASKS_START(0); }
nrf_rtc0_TASKS_STOP()478 void nrf_rtc0_TASKS_STOP()        { nrf_rtc_TASKS_STOP(0);  }
nrf_rtc0_TASKS_CLEAR()479 void nrf_rtc0_TASKS_CLEAR()       { nrf_rtc_TASKS_CLEAR(0); }
nrf_rtc0_TASKS_TRIGOVRFLW()480 void nrf_rtc0_TASKS_TRIGOVRFLW()  { nrf_rtc_TASKS_TRIGOVRFLW(0); }
nrf_rtc1_TASKS_START()481 void nrf_rtc1_TASKS_START()       { nrf_rtc_TASKS_START(1); }
nrf_rtc1_TASKS_STOP()482 void nrf_rtc1_TASKS_STOP()        { nrf_rtc_TASKS_STOP(1);  }
nrf_rtc1_TASKS_CLEAR()483 void nrf_rtc1_TASKS_CLEAR()       { nrf_rtc_TASKS_CLEAR(1); }
nrf_rtc1_TASKS_TRIGOVRFLW()484 void nrf_rtc1_TASKS_TRIGOVRFLW()  { nrf_rtc_TASKS_TRIGOVRFLW(1); }
nrf_rtc2_TASKS_START()485 void nrf_rtc2_TASKS_START()       { nrf_rtc_TASKS_START(2); }
nrf_rtc2_TASKS_STOP()486 void nrf_rtc2_TASKS_STOP()        { nrf_rtc_TASKS_STOP(2);  }
nrf_rtc2_TASKS_CLEAR()487 void nrf_rtc2_TASKS_CLEAR()       { nrf_rtc_TASKS_CLEAR(2); }
nrf_rtc2_TASKS_TRIGOVRFLW()488 void nrf_rtc2_TASKS_TRIGOVRFLW()  { nrf_rtc_TASKS_TRIGOVRFLW(2); }
489 
nrf_rtc_regw_sideeffect_TASKS_START(int i)490 void nrf_rtc_regw_sideeffect_TASKS_START(int i) {
491   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
492   if ( RTC_regs->TASKS_START ){
493     RTC_regs->TASKS_START = 0;
494     nrf_rtc_TASKS_START(i);
495   }
496 }
497 
nrf_rtc_regw_sideeffect_TASKS_STOP(int i)498 void nrf_rtc_regw_sideeffect_TASKS_STOP(int i) {
499   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
500   if ( RTC_regs->TASKS_STOP ){
501     NRF_RTC_regs[i].TASKS_STOP = 0;
502     nrf_rtc_TASKS_STOP(i);
503   }
504 }
505 
nrf_rtc_regw_sideeffect_TASKS_CLEAR(int i)506 void nrf_rtc_regw_sideeffect_TASKS_CLEAR(int i) {
507   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
508   if ( RTC_regs->TASKS_CLEAR ){
509     NRF_RTC_regs[i].TASKS_CLEAR = 0;
510     nrf_rtc_TASKS_CLEAR(i);
511   }
512 }
513 
nrf_rtc_regw_sideeffect_TASKS_TRIGOVRFLW(int i)514 void nrf_rtc_regw_sideeffect_TASKS_TRIGOVRFLW(int i) {
515   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
516   if ( RTC_regs->TASKS_TRIGOVRFLW ){
517     NRF_RTC_regs[i].TASKS_TRIGOVRFLW = 0;
518     nrf_rtc_TASKS_TRIGOVRFLW(i);
519   }
520 }
521 
nrf_rtc_regw_sideeffect_INTENSET(int i)522 void nrf_rtc_regw_sideeffect_INTENSET(int i) {
523   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
524   if ( RTC_regs->INTENSET ){
525     uint32_t new_interrupts = RTC_regs->INTENSET & ~RTC_INTEN[i];
526     unsigned int irq_t = get_irq_t(i);
527     uint32_t mask = RTC_EVTEN_COMPARE0_Msk;
528 
529     RTC_INTEN[i] |= RTC_regs->INTENSET;
530     RTC_regs->INTENSET = RTC_INTEN[i];
531     for ( int cc = 0 ; cc < N_CC ; cc++, mask <<=1) {
532       if (RTC_regs->EVENTS_COMPARE[cc] && (new_interrupts & mask)) {
533         hw_irq_ctrl_set_irq(irq_t);
534       }
535     }
536 
537     check_not_supported_func(RTC_INTEN[i]);
538   }
539 }
540 
nrf_rtc_regw_sideeffect_INTENCLR(int i)541 void nrf_rtc_regw_sideeffect_INTENCLR(int i) {
542   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
543   if ( RTC_regs->INTENCLR ){
544     RTC_INTEN[i]  &= ~RTC_regs->INTENCLR;
545     RTC_regs->INTENSET = RTC_INTEN[i];
546     RTC_regs->INTENCLR = 0;
547   }
548 }
549 
nrf_rtc_regw_sideeffect_EVTENSET(int i)550 void nrf_rtc_regw_sideeffect_EVTENSET(int i) {
551   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
552   if ( RTC_regs->EVTENSET ){
553     RTC_regs->EVTEN |= RTC_regs->EVTENSET;
554     RTC_regs->EVTENSET = RTC_regs->EVTEN;
555     check_not_supported_func(RTC_regs->EVTEN);
556   }
557 }
558 
nrf_rtc_regw_sideeffect_EVTENCLR(int i)559 void nrf_rtc_regw_sideeffect_EVTENCLR(int i) {
560   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
561   if ( RTC_regs->EVTENCLR ){
562     RTC_regs->EVTEN  &= ~RTC_regs->EVTENCLR;
563     RTC_regs->EVTENSET = RTC_regs->EVTEN;
564     RTC_regs->EVTENCLR = 0;
565   }
566 }
567 
nrf_rtc_regw_sideeffects_CC(int rtc,int cc_n)568 void nrf_rtc_regw_sideeffects_CC(int rtc, int cc_n) {
569   if (RTC_Running[rtc] == true) {
570     update_cc_timer(rtc, cc_n);
571     update_master_timer();
572   }
573 }
574 
575 /**
576  * Handle any register side effect (by inspecting the registers values)
577  * (deprecated)
578  */
nrf_rtc_regw_sideeffects(int i)579 void nrf_rtc_regw_sideeffects(int i){
580   nrf_rtc_regw_sideeffect_TASKS_START(i);
581 
582   nrf_rtc_regw_sideeffect_TASKS_STOP(i);
583 
584   nrf_rtc_regw_sideeffect_TASKS_CLEAR(i);
585 
586   nrf_rtc_regw_sideeffect_TASKS_TRIGOVRFLW(i);
587 
588   nrf_rtc_regw_sideeffect_INTENSET(i);
589 
590   nrf_rtc_regw_sideeffect_INTENCLR(i);
591 
592   nrf_rtc_regw_sideeffect_EVTENSET(i);
593 
594   nrf_rtc_regw_sideeffect_EVTENCLR(i);
595 }
596 
nrf_rtc0_regw_sideeffects()597 void nrf_rtc0_regw_sideeffects(){ nrf_rtc_regw_sideeffects(0); }
nrf_rtc1_regw_sideeffects()598 void nrf_rtc1_regw_sideeffects(){ nrf_rtc_regw_sideeffects(1); }
nrf_rtc2_regw_sideeffects()599 void nrf_rtc2_regw_sideeffects(){ nrf_rtc_regw_sideeffects(2); }
600