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