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 #include "NRF_RTC.h"
10 #include "NRF_PPI.h"
11 #include "NRF_CLOCK.h"
12 #include "NRF_HW_model_top.h"
13 #include "irq_ctrl.h"
14 #include "irq_sources.h"
15 #include "bs_tracing.h"
16 #include "time_machine_if.h"
17 
18 /*
19  * RTC — Real-time counter
20  *
21  * http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52840.ps/rtc.html?cp=2_0_0_23#concept_rvn_vkj_sr
22  */
23 
24 /* To simplify, so far it is only modeled what the current BLE controller uses
25  *
26  * NOT modelled:
27  *  * TICK events
28  *  * the delay in tasks or in the synchronization of configuration into the LF clock domain
29  *  * TRIGOVRFLW task or OVRFLW  event
30  *
31  * * Note: The COUNTER register is only updated when read with the proper function
32  *
33  * * Note: In this model all RTCs have 4 working CC registers (for simplicity)
34  *
35  * * Note: RTC2 cannot be used (it does not have an assigned interrupt)
36  */
37 
38 #define N_RTC 3
39 #define N_CC 4
40 
41 #define RTC_COUNTER_MASK 0xFFFFFF /*24 bits*/
42 NRF_RTC_Type NRF_RTC_regs[N_RTC];
43 
44 static bool RTC_Running[N_RTC] = {false};
45 static uint32_t RTC_INTEN[N_RTC] = {0};
46 
47 bs_time_t Timer_RTC = TIME_NEVER;
48 static bs_time_t cc_timers[N_RTC][N_CC] = {{TIME_NEVER}}; //when each CC will match (in microseconds)
49 
50 static bs_time_t RTC_counter_startT[N_RTC] = {TIME_NEVER}; //Time when the counter was "started" (really the time that would correspond to COUNTER = 0)
51 static uint32_t counter[N_RTC] = {0}; //Internal counter value when the counter was stopped
52 
53 static bs_time_t first_lf_tick_time = 0;
54 
nrf_rtc_init()55 void nrf_rtc_init() {
56   memset(NRF_RTC_regs, 0, sizeof(NRF_RTC_regs));
57   for (int i = 0; i < N_RTC ; i++) {
58     RTC_Running[i] = false;
59     RTC_INTEN[i] = 0;
60     counter[i] = 0;
61     RTC_counter_startT[i] = TIME_NEVER;
62     for (int j  = 0 ; j < N_CC ; j++) {
63       cc_timers[i][j] = TIME_NEVER;
64     }
65   }
66   Timer_RTC = TIME_NEVER;
67 }
68 
nrf_rtc_clean_up()69 void nrf_rtc_clean_up() {
70 
71 }
72 
nrf_rtc_notify_first_lf_tick()73 void nrf_rtc_notify_first_lf_tick() {
74   first_lf_tick_time = tm_get_hw_time();
75   bs_trace_raw_time(9, "RTC: First lf tick\n");
76 }
77 
78 
get_last_lf_tick_time()79 static bs_time_t get_last_lf_tick_time() {
80   bs_time_t now = tm_get_hw_time();
81 
82   if (now > TIME_NEVER>>9) {
83     bs_trace_error_time_line("Bummer, the RTC model only supports running for 1142 years\n");
84     /*If you really need this, generalize the calculation to more than 64 bits*/
85   }
86 
87   uint64_t lf_ticks = ((now - first_lf_tick_time)<<9) / LF_CLOCK_PERIOD; //floor()
88   bs_time_t last_tick_time = lf_ticks * LF_CLOCK_PERIOD >> 9;
89   last_tick_time += first_lf_tick_time;
90 
91   return last_tick_time;
92 }
93 
94 /**
95  * Convert a time delta in microseconds to the equivalent count accounting for the PRESCALER
96  * Note that the number is rounded down [floor()]
97  */
time_to_counter(bs_time_t delta,int rtc)98 static uint64_t time_to_counter(bs_time_t delta, int rtc) {
99   uint64_t ticks;
100   //Note: we add 1us, to account for the RTC ticks happening in the floor of the us
101   // as 1us is way smaller than the LF_CLOCK_PERIOD it will not cause an issue rounding the counter value up
102   ticks = ((delta + 1)<< 9) / ((uint64_t)LF_CLOCK_PERIOD * (NRF_RTC_regs[rtc].PRESCALER + 1));
103   return ticks;
104 }
105 
106 /**
107  * Convert a counter delta to microseconds accounting for the PRESCALER
108  * (the fractional number microseconds with 9 bit resolution, is stored in frac)
109  */
counter_to_time(uint64_t counter,int rtc,uint16_t * frac)110 static bs_time_t counter_to_time(uint64_t counter, int rtc, uint16_t *frac) {
111   bs_time_t Elapsed;
112   Elapsed = counter  * (uint64_t)LF_CLOCK_PERIOD * (NRF_RTC_regs[rtc].PRESCALER + 1);
113   if (frac != NULL){
114     *frac = Elapsed & 0x1FF;
115   }
116   return Elapsed >> 9;
117 }
118 
119 /**
120  * Return the time it takes for the COUNTER to do 1 wrap
121  *  The whole number of microseconds is stored in us, the fractional number of microseconds
122  *  with 9 bits resolution is stored in frac
123  */
time_of_1_counter_wrap(int rtc,bs_time_t * us,uint16_t * frac)124 static void time_of_1_counter_wrap(int rtc, bs_time_t *us, uint16_t *frac) {
125   *us = counter_to_time((uint64_t)RTC_COUNTER_MASK + 1, rtc, frac);
126 }
127 
update_master_timer()128 static void update_master_timer() {
129   Timer_RTC = TIME_NEVER;
130   for (int rtc = 0; rtc < N_RTC ; rtc++) {
131     if (RTC_Running[rtc] == false) {
132       continue;
133     }
134     for (int cc = 0 ; cc < N_CC ; cc++) {
135       if (cc_timers[rtc][cc] < Timer_RTC) {
136         Timer_RTC = cc_timers[rtc][cc];
137       }
138     }
139   }
140   nrf_hw_find_next_timer_to_trigger();
141 }
142 
143 /**
144  * Save in cc_timers[t][cc] the next time when this RTC will match the
145  * CC[cc] register
146  */
update_cc_timer(int rtc,int cc)147 static void update_cc_timer(int rtc, int cc) {
148   if (RTC_Running[rtc] == true) {
149     uint16_t next_match_frac;
150     bs_time_t next_match_us = RTC_counter_startT[rtc]
151                               + counter_to_time(NRF_RTC_regs[rtc].CC[cc], rtc, &next_match_frac);
152 
153     bs_time_t now = tm_get_hw_time();
154 
155     if (next_match_us <= now) {
156       bs_time_t t_us;
157       uint16_t t_frac;
158 
159       time_of_1_counter_wrap(rtc, &t_us, &t_frac);
160 
161       do {
162         next_match_us += t_us;
163         next_match_frac += t_frac;
164         if (next_match_frac >= 0x200){
165           next_match_frac -= 0x200;
166           next_match_us +=1;
167         }
168       } while (next_match_us <= now);
169 
170     }
171     cc_timers[rtc][cc] = next_match_us;
172   } else {
173     cc_timers[rtc][cc] = TIME_NEVER;
174   }
175 }
176 
update_all_cc_timers(int rtc)177 static void update_all_cc_timers(int rtc) {
178   for (int cc = 0 ; cc < N_CC; cc++){
179     update_cc_timer(rtc, cc);
180   }
181 }
182 
get_irq_t(int rtc)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;
198     }
199 
200     return irq_t;
201 }
202 
get_event(int rtc)203 static ppi_event_types_t get_event(int rtc)
204 {
205     ppi_event_types_t event = RTC0_EVENTS_COMPARE_0;
206     switch (rtc){
207     case 0:
208       event = RTC0_EVENTS_COMPARE_0;
209       break;
210     case 1:
211       event = RTC1_EVENTS_COMPARE_0;
212       break;
213     case 2:
214       event = RTC2_EVENTS_COMPARE_0;
215       break;
216     }
217 
218     return event;
219 }
220 
nrf_rtc_timer_triggered()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 
228     NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[rtc];
229 
230     uint32_t mask = RTC_EVTEN_COMPARE0_Msk;
231 
232     for ( int cc = 0 ; cc < N_CC ; cc++, event++, mask <<=1) {
233       if ( cc_timers[rtc][cc] == Timer_RTC ){ //This CC is matching now
234         update_cc_timer(rtc, cc); //Next time it will match
235 
236         bs_trace_raw_time(8, "RTC%i: CC%i matching now\n", rtc, cc);
237 
238         if ( ( RTC_regs->EVTEN | RTC_INTEN[rtc] ) & mask ) {
239           RTC_regs->EVENTS_COMPARE[cc] = 1;
240           if ( RTC_regs->EVTEN & mask ){
241             nrf_ppi_event(event);
242           }
243           if ( RTC_INTEN[rtc] & mask ){
244             hw_irq_ctrl_set_irq(get_irq_t(rtc));
245           }
246         }
247       } //if cc_timers[rtc][cc] == Timer_RTC
248     } //for cc
249   } //for rtc
250   update_master_timer();
251 }
252 
253 /**
254  * Check if an EVTEN or INTEN has the tick event set
255  */
check_not_supported_func(uint32_t i)256 static void check_not_supported_func(uint32_t i) {
257   if (i &  RTC_EVTEN_TICK_Msk) {
258     bs_trace_warning_line_time("RTC: The TICK functionality is not modelled\n");
259   }
260   if (i &  RTC_EVTEN_OVRFLW_Msk) {
261     bs_trace_warning_line_time("RTC: The OVERFLOW functionality is not modelled\n");
262   }
263 }
264 
265 
nrf_rtc_update_COUNTER(int rtc)266 void nrf_rtc_update_COUNTER(int rtc) {
267   if (RTC_Running[rtc] == true) {
268     uint64_t count;
269     count = time_to_counter(tm_get_hw_time() - RTC_counter_startT[rtc], rtc);
270     NRF_RTC_regs[rtc].COUNTER = count & RTC_COUNTER_MASK;
271   } else {
272     NRF_RTC_regs[rtc].COUNTER = counter[rtc] & RTC_COUNTER_MASK;
273   }
274 }
275 
276 /**
277  * TASK_START triggered handler
278  */
nrf_rtc_TASKS_START(int rtc)279 void nrf_rtc_TASKS_START(int rtc) {
280   if (RTC_Running[rtc] == true) {
281     return;
282   }
283   bs_trace_raw_time(5, "RTC%i: TASK_START\n", rtc);
284   RTC_Running[rtc] = true;
285   RTC_counter_startT[rtc] = get_last_lf_tick_time()
286                             - counter_to_time(counter[rtc], rtc, NULL); //If the counter is not zero at start, is like if the counter was started earlier
287   update_all_cc_timers(rtc);
288   update_master_timer();
289 }
290 
291 /**
292  * TASK_STOP triggered handler
293  */
nrf_rtc_TASKS_STOP(int rtc)294 void nrf_rtc_TASKS_STOP(int rtc) {
295   if (RTC_Running[rtc] == false) {
296     return;
297   }
298   bs_trace_raw_time(5, "RTC%i: TASK_STOP\n", rtc);
299   RTC_Running[rtc] = false;
300   counter[rtc] = time_to_counter(tm_get_hw_time() - RTC_counter_startT[rtc], rtc); //we save the value when the counter was stoped in case it is started again without clearing it
301   counter[rtc] &= RTC_COUNTER_MASK;
302   for (int cc = 0 ; cc < N_CC ; cc++){
303     cc_timers[rtc][cc] = TIME_NEVER;
304   }
305   update_master_timer();
306 }
307 
308 /**
309  * TASK_CLEAR triggered handler
310  */
nrf_rtc_TASKS_CLEAR(int rtc)311 void nrf_rtc_TASKS_CLEAR(int rtc) {
312   bs_trace_raw_time(5, "RTC%i: TASK_CLEAR\n", rtc);
313   NRF_RTC_regs[rtc].COUNTER = 0;
314   counter[rtc] = 0;
315   RTC_counter_startT[rtc] = get_last_lf_tick_time();
316   update_all_cc_timers(rtc);
317   update_master_timer();
318 }
319 
nrf_rtc0_TASKS_START()320 void nrf_rtc0_TASKS_START() { nrf_rtc_TASKS_START(0); }
nrf_rtc0_TASKS_STOP()321 void nrf_rtc0_TASKS_STOP()  { nrf_rtc_TASKS_STOP(0);  }
nrf_rtc0_TASKS_CLEAR()322 void nrf_rtc0_TASKS_CLEAR() { nrf_rtc_TASKS_CLEAR(0); }
nrf_rtc1_TASKS_START()323 void nrf_rtc1_TASKS_START() { nrf_rtc_TASKS_START(1); }
nrf_rtc1_TASKS_STOP()324 void nrf_rtc1_TASKS_STOP()  { nrf_rtc_TASKS_STOP(1);  }
nrf_rtc1_TASKS_CLEAR()325 void nrf_rtc1_TASKS_CLEAR() { nrf_rtc_TASKS_CLEAR(1); }
nrf_rtc2_TASKS_START()326 void nrf_rtc2_TASKS_START() { nrf_rtc_TASKS_START(2); }
nrf_rtc2_TASKS_STOP()327 void nrf_rtc2_TASKS_STOP()  { nrf_rtc_TASKS_STOP(2);  }
nrf_rtc2_TASKS_CLEAR()328 void nrf_rtc2_TASKS_CLEAR() { nrf_rtc_TASKS_CLEAR(2); }
329 
nrf_rtc_regw_sideeffect_TASKS_START(int i)330 void nrf_rtc_regw_sideeffect_TASKS_START(int i) {
331   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
332   if ( RTC_regs->TASKS_START ){
333     RTC_regs->TASKS_START = 0;
334     nrf_rtc_TASKS_START(i);
335   }
336 }
337 
nrf_rtc_regw_sideeffect_TASKS_STOP(int i)338 void nrf_rtc_regw_sideeffect_TASKS_STOP(int i) {
339   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
340   if ( RTC_regs->TASKS_STOP ){
341     NRF_RTC_regs[i].TASKS_STOP = 0;
342     nrf_rtc_TASKS_STOP(i);
343   }
344 }
345 
nrf_rtc_regw_sideeffect_TASKS_CLEAR(int i)346 void nrf_rtc_regw_sideeffect_TASKS_CLEAR(int i) {
347   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
348   if ( RTC_regs->TASKS_CLEAR ){
349     NRF_RTC_regs[i].TASKS_CLEAR = 0;
350     nrf_rtc_TASKS_CLEAR(i);
351   }
352 }
353 
nrf_rtc_regw_sideeffect_INTENSET(int i)354 void nrf_rtc_regw_sideeffect_INTENSET(int i) {
355   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
356   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 
361     RTC_INTEN[i] |= RTC_regs->INTENSET;
362     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 
369     check_not_supported_func(RTC_INTEN[i]);
370   }
371 }
372 
nrf_rtc_regw_sideeffect_INTENCLR(int i)373 void nrf_rtc_regw_sideeffect_INTENCLR(int i) {
374   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
375   if ( RTC_regs->INTENCLR ){
376     RTC_INTEN[i]  &= ~RTC_regs->INTENCLR;
377     RTC_regs->INTENSET = RTC_INTEN[i];
378     RTC_regs->INTENCLR = 0;
379   }
380 }
381 
nrf_rtc_regw_sideeffect_EVTENSET(int i)382 void nrf_rtc_regw_sideeffect_EVTENSET(int i) {
383   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
384   if ( RTC_regs->EVTENSET ){
385     RTC_regs->EVTEN |= RTC_regs->EVTENSET;
386     RTC_regs->EVTENSET = RTC_regs->EVTEN;
387     check_not_supported_func(RTC_regs->EVTEN);
388   }
389 }
390 
nrf_rtc_regw_sideeffect_EVTENCLR(int i)391 void nrf_rtc_regw_sideeffect_EVTENCLR(int i) {
392   NRF_RTC_Type *RTC_regs = &NRF_RTC_regs[i];
393   if ( RTC_regs->EVTENCLR ){
394     RTC_regs->EVTEN  &= ~RTC_regs->EVTENCLR;
395     RTC_regs->EVTENSET = RTC_regs->EVTEN;
396     RTC_regs->EVTENCLR = 0;
397   }
398 }
399 
nrf_rtc_regw_sideeffects_CC(int rtc,int cc_n)400 void nrf_rtc_regw_sideeffects_CC(int rtc, int cc_n) {
401   if (RTC_Running[rtc] == true) {
402     update_cc_timer(rtc, cc_n);
403     update_master_timer();
404   }
405 }
406 
407 /**
408  * Handle any register side effect (by inspecting the registers values)
409  * (deprecated)
410  */
nrf_rtc_regw_sideeffects(int i)411 void nrf_rtc_regw_sideeffects(int i){
412   nrf_rtc_regw_sideeffect_TASKS_START(i);
413 
414   nrf_rtc_regw_sideeffect_TASKS_STOP(i);
415 
416   nrf_rtc_regw_sideeffect_TASKS_CLEAR(i);
417 
418   nrf_rtc_regw_sideeffect_INTENSET(i);
419 
420   nrf_rtc_regw_sideeffect_INTENCLR(i);
421 
422   nrf_rtc_regw_sideeffect_EVTENSET(i);
423 
424   nrf_rtc_regw_sideeffect_EVTENCLR(i);
425 }
426 
nrf_rtc0_regw_sideeffects()427 void nrf_rtc0_regw_sideeffects(){ nrf_rtc_regw_sideeffects(0); }
nrf_rtc1_regw_sideeffects()428 void nrf_rtc1_regw_sideeffects(){ nrf_rtc_regw_sideeffects(1); }
nrf_rtc2_regw_sideeffects()429 void nrf_rtc2_regw_sideeffects(){ nrf_rtc_regw_sideeffects(2); }
430