1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "plat_addr_map.h"
16 #ifdef CMU_FREE_TIMER
17 #include CHIP_SPECIFIC_HDR(reg_aoncmu)
18 #endif
19 #include "cmsis_nvic.h"
20 #include "hal_cmu.h"
21 #include "hal_location.h"
22 #define IGNORE_HAL_TIMER_RAW_API_CHECK
23 #include "hal_timer_raw.h"
24 #include "hal_timer_fast_irq.h"
25 #include "hal_timer_user_irq.h"
26 #include "hal_timer.h"
27 #include "reg_timer.h"
28 #include "hal_trace.h"
29
30 #if defined(CHIP_BEST3001) || defined(CHIP_BEST3003) || defined(CHIP_BEST3005) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402)
31 #define CLOCK_SYNC_WORKAROUND
32 #endif
33
34 #if defined(TIMER1_BASE) && defined(LOW_SYS_FREQ) && defined(LOW_SYS_FREQ_6P5M)
35 #if defined(CHIP_BEST1305) || defined(CHIP_BEST1501) || \
36 defined(CHIP_BEST2001) || defined(CHIP_BEST2003) || \
37 defined(CHIP_BEST2300A) || defined(CHIP_BEST2300P)
38 #define FAST_TIMER_WORKAROUND
39 #endif
40 #endif
41
42 #if !(defined(__FPU_USED) && (__FPU_USED == 1))
43 #undef TIMER_USE_FPU
44 #endif
45
46 #ifndef SLOW_TIMER_SUB_ID_WITH_IRQ
47 #define SLOW_TIMER_SUB_ID_WITH_IRQ 1
48 #endif
49
50 #define SLOW_TIMER_VAL_DELTA 1
51 #define SLOW_TIMER_VAL_DELTA_SLEEP 10
52 #define FAST_TIMER_VAL_DELTA 20
53
54 #ifdef CALIB_SLOW_TIMER
55 #define MAX_CALIB_SYSTICK_HZ (CONFIG_SYSTICK_HZ_NOMINAL * 2)
56
57 #define MIN_CALIB_TICKS (30 * (CONFIG_SYSTICK_HZ_NOMINAL / 1000))
58
59 #define MAX_CALIB_TICKS (30 * CONFIG_SYSTICK_HZ_NOMINAL)
60
61 static
62 #ifdef TIMER_USE_FPU
63 float
64 #else
65 uint32_t
66 #endif
67 BOOT_DATA_LOC sys_tick_hz = CONFIG_SYSTICK_HZ_NOMINAL;
68 static uint32_t BOOT_BSS_LOC slow_val;
69 static uint32_t BOOT_BSS_LOC fast_val;
70 #endif
71
72 #ifdef FAST_TIMER_COMPENSATE
73 #ifndef TIMER1_BASE
74 #error "FAST_TIMER_COMPENSATE need timer1"
75 #endif
76 #if !(defined(__FPU_USED) && (__FPU_USED == 1))
77 #error "FAST_TIMER_COMPENSATE need FPU"
78 #endif
79 #ifdef FAST_TIMER_WORKAROUND
80 #error "FAST_TIMER_COMPENSATE conflicts with FAST_TIMER_WORKAROUND"
81 #endif
82 #define FAST_TICK_RATIO_NUM 3
83 static float BOOT_BSS_LOC fast_tick_ratio_avg;
84 static float BOOT_BSS_LOC fast_tick_ratio[FAST_TICK_RATIO_NUM];
85 #endif
86
87 static struct DUAL_TIMER_T * const BOOT_RODATA_SRAM_LOC dual_timer[] = {
88 (struct DUAL_TIMER_T *)TIMER0_BASE,
89 #ifdef TIMER1_BASE
90 (struct DUAL_TIMER_T *)TIMER1_BASE,
91 #endif
92 #ifdef TIMER2_BASE
93 (struct DUAL_TIMER_T *)TIMER2_BASE,
94 #endif
95 };
96
97 #ifdef CMU_FREE_TIMER
98 #ifndef TIMER1_BASE
99 #error "CMU_FREE_TIMER should work with TIMER1_BASE"
100 #endif
101 #ifdef CLOCK_SYNC_WORKAROUND
102 #error "CMU_FREE_TIMER conflicts with CLOCK_SYNC_WORKAROUND"
103 #endif
104 #ifdef FAST_TIMER_WORKAROUND
105 #error "CMU_FREE_TIMER conflicts with FAST_TIMER_WORKAROUND"
106 #endif
107 static struct AONCMU_T * const aoncmu = (struct AONCMU_T *)AON_CMU_BASE;
108 #endif
109
110 static IRQn_Type irq_num[ARRAY_SIZE(dual_timer)][2] = {
111 { TIMER00_IRQn, TIMER01_IRQn, },
112 #ifdef TIMER1_BASE
113 { INVALID_IRQn, TIMER11_IRQn, },
114 #endif
115 #ifdef TIMER2_BASE
116 #if defined(ASIC_SIMU)
117 { INVALID_IRQn, INVALID_IRQn, },
118 #else
119 { TIMER20_IRQn, TIMER21_IRQn, },
120 #endif
121 #endif
122 };
123
124 static HAL_TIMER_IRQ_HANDLER_T irq_handler[ARRAY_SIZE(dual_timer)][2];
125
126 static uint32_t start_time[ARRAY_SIZE(dual_timer)][2];
127
128 static uint32_t hal_timer_common_get_elapsed_time(uint32_t id, uint32_t sub_id);
129 static int hal_timer_common_irq_pending(uint32_t id, uint32_t sub_id);
130
get_timer_value(struct TIMER_T * timer,uint32_t delta)131 __STATIC_FORCEINLINE uint32_t get_timer_value(struct TIMER_T *timer, uint32_t delta)
132 {
133 #ifdef CLOCK_SYNC_WORKAROUND
134 uint32_t lock;
135 uint32_t v1, v2;
136
137 lock = int_lock();
138 do {
139 v1 = timer->Value;
140 v2 = timer->Value;
141 } while ((v1 < v2) || (v1 > v2 + delta));
142 int_unlock(lock);
143
144 return v2;
145 #else
146 return timer->Value;
147 #endif
148 }
149
clear_timer_irq(struct TIMER_T * timer)150 __STATIC_FORCEINLINE void clear_timer_irq(struct TIMER_T *timer)
151 {
152 #ifdef CLOCK_SYNC_WORKAROUND
153 do {
154 timer->IntClr = 1;
155 } while (timer->RIS & TIMER_RIS_RIS);
156 #else
157 timer->IntClr = 1;
158 #endif
159 }
160
set_timer_load(struct TIMER_T * timer,uint32_t load,uint32_t delta)161 __STATIC_FORCEINLINE void set_timer_load(struct TIMER_T *timer, uint32_t load, uint32_t delta)
162 {
163 #ifdef CLOCK_SYNC_WORKAROUND
164 uint32_t lock;
165 uint32_t val;
166
167 lock = int_lock();
168 do {
169 timer->Load = load;
170 val = timer->Value;
171 } while ((load < val) || (load > val + delta));
172 int_unlock(lock);
173 #else
174 timer->Load = load;
175 #endif
176 }
177
fast_sys_timer_open(void)178 __STATIC_FORCEINLINE void fast_sys_timer_open(void)
179 {
180 #ifdef CMU_FREE_TIMER
181 hal_cmu_fast_timer_init();
182 #endif
183 #ifdef TIMER1_BASE
184 hal_cmu_timer1_select_fast();
185 dual_timer[1]->timer[0].Control = TIMER_CTRL_EN | TIMER_CTRL_PRESCALE_DIV_1 | TIMER_CTRL_SIZE_32_BIT;
186 #endif
187 #ifdef TIMER2_BASE
188 hal_cmu_timer2_select_fast();
189 #endif
190 }
191
hal_sys_timer_open(void)192 void BOOT_TEXT_FLASH_LOC hal_sys_timer_open(void)
193 {
194 #ifndef CMU_FREE_TIMER
195 hal_cmu_timer0_select_slow();
196 dual_timer[0]->timer[0].Control = TIMER_CTRL_EN | TIMER_CTRL_PRESCALE_DIV_1 | TIMER_CTRL_SIZE_32_BIT;
197 #endif
198 fast_sys_timer_open();
199 #if defined(ASIC_SIMU)
200 #if defined(TIMER2_BASE)
201 dual_timer[2]->timer[0].Control = TIMER_CTRL_EN | TIMER_CTRL_PRESCALE_DIV_1 | TIMER_CTRL_SIZE_32_BIT;
202 #endif
203 #endif
204 }
205
206 #ifdef CORE_SLEEP_POWER_DOWN
hal_sys_timer_wakeup(void)207 void SRAM_TEXT_LOC hal_sys_timer_wakeup(void)
208 {
209 fast_sys_timer_open();
210 }
211 #endif
212
hal_sys_timer_get(void)213 uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_get(void)
214 {
215 #ifdef CMU_FREE_TIMER
216 return aoncmu->FREE_TIMER;
217 #else
218 return -get_timer_value(&dual_timer[0]->timer[0], SLOW_TIMER_VAL_DELTA);
219 #endif
220 }
221
hal_aco_timer_get(void)222 uint32_t BOOT_TEXT_SRAM_LOC hal_aco_timer_get(void)
223 {
224 #if defined(TIMER2_BASE)
225 return -get_timer_value(&dual_timer[2]->timer[0], SLOW_TIMER_VAL_DELTA);
226 #else
227 return hal_sys_timer_get();
228 #endif
229 }
230
231 #ifdef CLOCK_SYNC_WORKAROUND
hal_sys_timer_get_in_sleep(void)232 uint32_t SRAM_TEXT_LOC hal_sys_timer_get_in_sleep(void)
233 {
234 return -get_timer_value(&dual_timer[0]->timer[0], SLOW_TIMER_VAL_DELTA_SLEEP);
235 }
236 #else
237 uint32_t hal_sys_timer_get_in_sleep(void) __attribute__((alias("hal_sys_timer_get")));
238 #endif
239
flash_hal_sys_timer_get(void)240 uint32_t BOOT_TEXT_FLASH_LOC flash_hal_sys_timer_get(void)
241 {
242 #ifdef CMU_FREE_TIMER
243 return aoncmu->FREE_TIMER;
244 #else
245 return -get_timer_value(&dual_timer[0]->timer[0], SLOW_TIMER_VAL_DELTA);
246 #endif
247 }
248
hal_sys_ms_get(void)249 uint32_t BOOT_TEXT_SRAM_LOC hal_sys_ms_get(void)
250 {
251 return GET_CURRENT_MS();
252 }
253
254 #ifdef TIMER1_BASE
_real_fast_sys_timer_get(void)255 __STATIC_FORCEINLINE uint32_t BOOT_TEXT_SRAM_LOC _real_fast_sys_timer_get(void)
256 {
257 return -get_timer_value(&dual_timer[1]->timer[0], FAST_TIMER_VAL_DELTA);
258 }
259 #endif
260
hal_fast_sys_timer_get(void)261 uint32_t BOOT_TEXT_SRAM_LOC hal_fast_sys_timer_get(void)
262 {
263 #ifdef FAST_TIMER_WORKAROUND
264 #ifdef TIMER_USE_FPU
265 return (uint32_t)(hal_sys_timer_get() * ((float)CONFIG_FAST_SYSTICK_HZ / CONFIG_SYSTICK_HZ));
266 #else
267 return (uint32_t)(hal_sys_timer_get() * (uint64_t)CONFIG_FAST_SYSTICK_HZ / CONFIG_SYSTICK_HZ);
268 #endif
269 #elif defined(TIMER1_BASE)
270 return _real_fast_sys_timer_get();
271 #else
272 return 0;
273 #endif
274 }
275
hal_sys_timer_get_max(void)276 uint32_t hal_sys_timer_get_max(void)
277 {
278 return 0xFFFFFFFF;
279 }
280
hal_sys_timer_delay(uint32_t ticks)281 void BOOT_TEXT_SRAM_LOC hal_sys_timer_delay(uint32_t ticks)
282 {
283 uint32_t start = hal_sys_timer_get();
284
285 while (hal_sys_timer_get() - start < ticks);
286 }
287
288 #ifdef CLOCK_SYNC_WORKAROUND
hal_sys_timer_delay_in_sleep(uint32_t ticks)289 void SRAM_TEXT_LOC hal_sys_timer_delay_in_sleep(uint32_t ticks)
290 {
291 uint32_t start = hal_sys_timer_get_in_sleep();
292
293 while (hal_sys_timer_get_in_sleep() - start < ticks);
294 }
295 #else
296 void hal_sys_timer_delay_in_sleep(uint32_t ticks) __attribute__((alias("hal_sys_timer_delay")));
297 #endif
298
flash_hal_sys_timer_delay(uint32_t ticks)299 void BOOT_TEXT_FLASH_LOC flash_hal_sys_timer_delay(uint32_t ticks)
300 {
301 uint32_t start = flash_hal_sys_timer_get();
302
303 while (flash_hal_sys_timer_get() - start < ticks);
304 }
305
hal_sys_timer_delay_us(uint32_t us)306 void BOOT_TEXT_SRAM_LOC hal_sys_timer_delay_us(uint32_t us)
307 {
308 #if defined(TIMER1_BASE) && !defined(FAST_TIMER_WORKAROUND)
309 uint32_t start = hal_fast_sys_timer_get();
310 uint32_t ticks = US_TO_FAST_TICKS(us);
311
312 while (hal_fast_sys_timer_get() - start < ticks);
313 #else
314 enum HAL_CMU_FREQ_T freq = hal_cmu_sys_get_freq();
315 uint32_t loop;
316 uint32_t i;
317
318 // Assuming:
319 // 1) system clock uses audio PLL
320 // 2) audio PLL is configured as 48K series, 196.608M
321 // 3) crystal is 26M
322
323 if (freq == HAL_CMU_FREQ_208M) {
324 loop = 197;
325 } else if (freq == HAL_CMU_FREQ_104M) {
326 loop = 197 / 2;
327 } else if (freq == HAL_CMU_FREQ_78M) {
328 loop = 197 / 3;
329 } else if (freq == HAL_CMU_FREQ_52M) {
330 loop = 52;
331 } else {
332 loop = 26;
333 }
334
335 loop = loop * us / 5;
336 for (i = 0; i < loop; i++) {
337 asm volatile("nop");
338 }
339 #endif
340 }
341
hal_sys_timer_delay_ns(uint32_t ns)342 void SRAM_TEXT_LOC hal_sys_timer_delay_ns(uint32_t ns)
343 {
344 #if defined(TIMER1_BASE) && !defined(FAST_TIMER_WORKAROUND)
345 uint32_t start = hal_fast_sys_timer_get();
346 uint32_t ticks = NS_TO_FAST_TICKS(ns);
347
348 while (hal_fast_sys_timer_get() - start < ticks);
349 #else
350 enum HAL_CMU_FREQ_T freq = hal_cmu_sys_get_freq();
351 uint32_t loop;
352 uint32_t i;
353
354 // Assuming:
355 // 1) system clock uses audio PLL
356 // 2) audio PLL is configured as 48K series, 196.608M
357 // 3) crystal is 26M
358
359 if (freq == HAL_CMU_FREQ_208M) {
360 loop = 197;
361 } else if (freq == HAL_CMU_FREQ_104M) {
362 loop = 197 / 2;
363 } else if (freq == HAL_CMU_FREQ_78M) {
364 loop = 197 / 3;
365 } else if (freq == HAL_CMU_FREQ_52M) {
366 loop = 52;
367 } else {
368 loop = 26;
369 }
370
371 loop = loop * ns / 5000;
372 for (i = 0; i < loop; i++) {
373 asm volatile("nop");
374 }
375 #endif
376 }
377
SRAM_TEXT_DEF(measure_cpu_freq_interval)378 static uint32_t NOINLINE SRAM_TEXT_DEF(measure_cpu_freq_interval)(uint32_t cnt)
379 {
380 uint32_t start;
381 struct DUAL_TIMER_T *t;
382 uint32_t delta;
383
384 #ifdef TIMER1_BASE
385 t = dual_timer[1];
386 delta = FAST_TIMER_VAL_DELTA;
387 #ifdef FAST_TIMER_WORKAROUND
388 if (hal_cmu_fast_timer_offline()) {
389 t = dual_timer[0];
390 delta = SLOW_TIMER_VAL_DELTA;
391 }
392 #endif // FAST_TIMER_WORKAROUND
393 #else
394 t = dual_timer[0];
395 delta = SLOW_TIMER_VAL_DELTA;
396 #endif
397
398 start = get_timer_value(&t->timer[0], delta);
399
400 asm volatile(
401 "_loop:;"
402 #ifdef __ARM_ARCH_ISA_ARM
403 "nop;"
404 "nop;"
405 #endif
406 "subs %0, #1;"
407 "cmp %0, #0;"
408 "bne _loop;"
409 : : "r"(cnt));
410
411 return start - get_timer_value(&t->timer[0], delta);
412 }
413
hal_sys_timer_calc_cpu_freq(uint32_t interval_ms,int high_res)414 uint32_t hal_sys_timer_calc_cpu_freq(uint32_t interval_ms, int high_res)
415 {
416 uint32_t ref_freq;
417 uint32_t cnt;
418 uint32_t one_sec;
419 uint32_t lock;
420 uint32_t run_interval;
421 uint32_t base_interval;
422 uint32_t freq;
423
424 // Default measurement interval
425 if (interval_ms == 0) {
426 #ifdef TIMER1_BASE
427 interval_ms = 10;
428 #else
429 interval_ms = 100;
430 #endif
431 }
432
433 ref_freq = hal_cmu_get_crystal_freq();
434 // CPU loop cycle count
435 cnt = ref_freq / 4 * interval_ms / 1000;
436
437 // Timer ticks per second
438 #ifdef TIMER1_BASE
439 one_sec = CONFIG_FAST_SYSTICK_HZ;
440 #ifdef FAST_TIMER_WORKAROUND
441 if (hal_cmu_fast_timer_offline()) {
442 one_sec = CONFIG_SYSTICK_HZ;
443 }
444 #endif // FAST_TIMER_WORKAROUND
445 #else
446 if (high_res) {
447 one_sec = CONFIG_FAST_SYSTICK_HZ;
448 } else {
449 one_sec = CONFIG_SYSTICK_HZ;
450 }
451 #endif
452 // Timer ticks per measurement interval
453 base_interval = one_sec * interval_ms / 1000;
454
455 lock = int_lock();
456
457 #ifndef TIMER1_BASE
458 if (high_res) {
459 hal_cmu_timer0_select_fast();
460 }
461 #endif
462
463 run_interval = measure_cpu_freq_interval(cnt);
464
465 #ifndef TIMER1_BASE
466 if (high_res) {
467 hal_cmu_timer0_select_slow();
468 }
469 #endif
470
471 int_unlock(lock);
472
473 #ifdef TIMER_USE_FPU
474 freq = (uint32_t)((float)ref_freq / run_interval * base_interval);
475 #else
476 freq = (uint32_t)((uint64_t)ref_freq * base_interval / run_interval);
477 #endif
478
479 if (high_res == 0) {
480 freq = (freq + 500000) / 1000000 * 1000000;
481 }
482
483 return freq;
484 }
485
486 #ifdef CALIB_SLOW_TIMER
hal_sys_timer_calib_start(void)487 void BOOT_TEXT_SRAM_LOC hal_sys_timer_calib_start(void)
488 {
489 uint32_t lock;
490 uint32_t slow;
491 uint32_t fast;
492
493 lock = int_lock();
494 #ifdef FAST_TIMER_WORKAROUND
495 ASSERT(!hal_cmu_fast_timer_offline(), "%s: Cannot calib timer while fast timer offline", __func__);
496 #endif
497 slow = hal_sys_timer_get();
498 while (hal_sys_timer_get() == slow);
499 __ISB();
500 fast = _real_fast_sys_timer_get();
501 int_unlock(lock);
502
503 slow_val = slow + 1;
504 fast_val = fast;
505 }
506
hal_sys_timer_calib_end(void)507 int BOOT_TEXT_SRAM_LOC hal_sys_timer_calib_end(void)
508 {
509 uint32_t lock;
510 uint32_t slow;
511 uint32_t fast;
512 uint32_t slow_diff;
513
514 lock = int_lock();
515 #ifdef FAST_TIMER_WORKAROUND
516 ASSERT(!hal_cmu_fast_timer_offline(), "%s: Cannot calib timer while fast timer offline", __func__);
517 #endif
518 slow = hal_sys_timer_get();
519 while (hal_sys_timer_get() == slow);
520 __ISB();
521 fast = _real_fast_sys_timer_get();
522 int_unlock(lock);
523
524 slow += 1;
525 slow_diff = slow - slow_val;
526
527 // Avoid computation error
528 if (slow_diff < MIN_CALIB_TICKS) {
529 return 1;
530 }
531 // Avoid fast tick overflow
532 if (slow_diff > MAX_CALIB_TICKS) {
533 return 2;
534 }
535
536 #ifdef TIMER_USE_FPU
537 sys_tick_hz = (float)CONFIG_FAST_SYSTICK_HZ / (fast - fast_val) * slow_diff;
538 #ifdef FAST_TIMER_COMPENSATE
539 uint32_t i;
540 for (i = FAST_TICK_RATIO_NUM-1; i >= 1; --i)
541 fast_tick_ratio[i] = fast_tick_ratio[i-1];
542 fast_tick_ratio[0] = (float)(fast - fast_val) / (float)slow_diff;
543 fast_tick_ratio_avg = 0;
544 for (i = 0; i < FAST_TICK_RATIO_NUM; ++i) {
545 if (fast_tick_ratio[i] < 100.0)
546 break;
547 fast_tick_ratio_avg += fast_tick_ratio[i];
548 }
549 fast_tick_ratio_avg = fast_tick_ratio_avg / i;
550 #endif /*FAST_TIMER_COMPENSATE*/
551 #else
552 uint64_t mul;
553 uint32_t fast_diff;
554
555 fast_diff = fast - fast_val;
556 mul = (uint64_t)CONFIG_FAST_SYSTICK_HZ * slow_diff + fast_diff / 2;
557 if ((mul >> 32) == 0) {
558 sys_tick_hz = (uint32_t)mul / fast_diff;
559 } else {
560 sys_tick_hz = mul / fast_diff;
561 }
562 #endif
563
564 if (sys_tick_hz > MAX_CALIB_SYSTICK_HZ) {
565 sys_tick_hz = MAX_CALIB_SYSTICK_HZ;
566 }
567
568 return 0;
569 }
570
hal_sys_timer_calib(void)571 void BOOT_TEXT_SRAM_LOC hal_sys_timer_calib(void)
572 {
573 hal_sys_timer_calib_start();
574 hal_sys_timer_delay(MIN_CALIB_TICKS);
575 hal_sys_timer_calib_end();
576 }
577
hal_sys_timer_systick_hz(void)578 uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_systick_hz(void)
579 {
580 #ifdef TIMER_USE_FPU
581 return (uint32_t)(sys_tick_hz + 0.5);
582 #else
583 return sys_tick_hz;
584 #endif
585 }
586
hal_sys_timer_systick_hz_float(void)587 float BOOT_TEXT_SRAM_LOC hal_sys_timer_systick_hz_float(void)
588 {
589 return sys_tick_hz;
590 }
591
hal_sys_timer_ms_to_ticks(uint32_t ms)592 uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_ms_to_ticks(uint32_t ms)
593 {
594 #ifdef TIMER_USE_FPU
595 return (uint32_t)((float)ms / 1000 * sys_tick_hz + 0.99);
596 #else
597 if (ms <= (~0UL / MAX_CALIB_SYSTICK_HZ)) {
598 return ((ms * sys_tick_hz + 1000 - 1) / 1000);
599 } else {
600 return (((uint64_t)ms * sys_tick_hz + 1000 - 1) / 1000);
601 }
602 #endif
603 }
604
hal_sys_timer_us_to_ticks(uint32_t us)605 uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_us_to_ticks(uint32_t us)
606 {
607 uint32_t ticks;
608
609 #ifdef TIMER_USE_FPU
610 ticks = (uint32_t)((float)us / (1000 * 1000) * sys_tick_hz + 0.99);
611 #else
612 if (us <= (~0UL / MAX_CALIB_SYSTICK_HZ)) {
613 ticks = ((us * sys_tick_hz / 1000 + 1000 - 1) / 1000);
614 } else {
615 ticks = (((uint64_t)us * sys_tick_hz / 1000 + 1000 - 1) / 1000);
616 }
617 #endif
618
619 if (ticks <= 1) {
620 ticks += 1;
621 }
622 return ticks;
623 }
624
hal_sys_timer_ticks_to_ms(uint32_t tick)625 uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_ticks_to_ms(uint32_t tick)
626 {
627 #ifdef TIMER_USE_FPU
628 return (uint32_t)((float)tick / sys_tick_hz * 1000 + 0.5);
629 #else
630 uint32_t hz = sys_tick_hz;
631 if (tick <= (~0UL / 1000)) {
632 return (tick * 1000 + hz / 2) / hz;
633 } else {
634 return ((uint64_t)tick * 1000 + hz / 2) / hz;
635 }
636 #endif
637 }
638
hal_sys_timer_ticks_to_us(uint32_t tick)639 uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_ticks_to_us(uint32_t tick)
640 {
641 #ifdef TIMER_USE_FPU
642 return (uint32_t)((float)tick / sys_tick_hz * (1000 * 1000) + 0.5);
643 #else
644 uint32_t hz = sys_tick_hz;
645 if (tick <= (~0UL / (1000 * 1000))) {
646 return (tick * (1000 * 1000) + hz / 2) / hz;
647 } else {
648 return ((uint64_t)tick * (1000 * 1000) + hz / 2) / hz;
649 }
650 #endif
651 }
652 #endif
653
654 #ifdef FAST_TIMER_COMPENSATE
655 static uint32_t BOOT_BSS_LOC slow_timer_begin = 0;
656 static uint32_t BOOT_BSS_LOC fast_timer_begin = 0;
657
hal_fast_timer_sleep()658 void BOOT_TEXT_SRAM_LOC hal_fast_timer_sleep()
659 {
660 uint32_t slow, fast;
661 uint32_t lock;
662
663 lock = int_lock();
664 slow = hal_sys_timer_get();
665 while (hal_sys_timer_get() == slow);
666 __ISB();
667 fast = -_real_fast_sys_timer_get();
668 fast_timer_begin = fast;
669 slow_timer_begin = slow + 1;
670 int_unlock(lock);
671 }
672
hal_fast_timer_wakeup()673 void BOOT_TEXT_SRAM_LOC hal_fast_timer_wakeup()
674 {
675 uint32_t slow, fast;
676 uint32_t load;
677 uint32_t lock;
678 float sleep_tick;
679
680 lock = int_lock();
681 slow = hal_sys_timer_get();
682 while (hal_sys_timer_get() == slow);
683 __ISB();
684 fast = _real_fast_sys_timer_get();
685 __ISB();
686 sleep_tick = fast_tick_ratio_avg * (float)(slow + 1 - slow_timer_begin) + 0.9;
687 load = fast_timer_begin - (uint32_t)sleep_tick;
688 __ISB();
689 load -= _real_fast_sys_timer_get() - fast;//float compute time
690 set_timer_load(&dual_timer[1]->timer[0], load, FAST_TIMER_VAL_DELTA);
691 int_unlock(lock);
692 }
693 #endif
694
695 #ifndef RTOS
osDelay(uint32_t ms)696 int osDelay(uint32_t ms)
697 {
698 hal_sys_timer_delay(MS_TO_TICKS(ms));
699 return 0;
700 }
701 #endif
702
703 //==========================================================
704 // Timer IRQ APIs
705 //==========================================================
706
timer_is_slow(uint32_t id)707 __STATIC_FORCEINLINE int timer_is_slow(uint32_t id)
708 {
709 return (id == 0);
710 }
711
hal_timer_common_irq_handler(uint32_t id,uint32_t sub_id)712 static void hal_timer_common_irq_handler(uint32_t id, uint32_t sub_id)
713 {
714 uint32_t elapsed;
715
716 clear_timer_irq(&dual_timer[id]->timer[sub_id]);
717 if (irq_handler[id][sub_id]) {
718 elapsed = hal_timer_common_get_elapsed_time(id, sub_id);
719 irq_handler[id][sub_id](elapsed);
720 } else {
721 dual_timer[id]->timer[sub_id].Control &= ~TIMER_CTRL_INTEN;
722 }
723 }
724
hal_timer_slow_irq_handler(void)725 static void hal_timer_slow_irq_handler(void)
726 {
727 hal_timer_common_irq_handler(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
728 }
729
730 #ifdef TIMER1_BASE
hal_timer11_irq_handler(void)731 static void hal_timer11_irq_handler(void)
732 {
733 hal_timer_common_irq_handler(1, 1);
734 }
735 #endif
736
737 #ifdef TIMER2_BASE
hal_timer2x_irq_handler(void)738 static void hal_timer2x_irq_handler(void)
739 {
740 uint32_t sub_id;
741
742 // NOTE: Some chips might combine time20 and time21 IRQ into one interrupt line
743 for (sub_id = 0; sub_id < 2; sub_id++) {
744 if (hal_timer_common_irq_pending(2, sub_id)) {
745 hal_timer_common_irq_handler(2, sub_id);
746 }
747 }
748 }
749 #endif
750
751 static const uint32_t irq_entry[ARRAY_SIZE(dual_timer)][2] = {
752 { (uint32_t)hal_timer_slow_irq_handler, (uint32_t)hal_timer_slow_irq_handler, },
753 #ifdef TIMER1_BASE
754 { 0, (uint32_t)hal_timer11_irq_handler, },
755 #endif
756 #ifdef TIMER2_BASE
757 { (uint32_t)hal_timer2x_irq_handler, (uint32_t)hal_timer2x_irq_handler, },
758 #endif
759 };
760
hal_timer_common_setup(uint32_t id,uint32_t sub_id,enum HAL_TIMER_TYPE_T type,HAL_TIMER_IRQ_HANDLER_T handler)761 static void hal_timer_common_setup(uint32_t id, uint32_t sub_id, enum HAL_TIMER_TYPE_T type, HAL_TIMER_IRQ_HANDLER_T handler)
762 {
763 uint32_t mode;
764 uint32_t irq_en;
765
766 if (type == HAL_TIMER_TYPE_ONESHOT) {
767 mode = TIMER_CTRL_ONESHOT;
768 } else if (type == HAL_TIMER_TYPE_PERIODIC) {
769 mode = TIMER_CTRL_MODE_PERIODIC;
770 } else {
771 mode = 0;
772 }
773
774 irq_handler[id][sub_id] = handler;
775
776 clear_timer_irq(&dual_timer[id]->timer[sub_id]);
777
778 irq_en = (handler && irq_entry[id][sub_id]);
779
780 if (irq_en) {
781 NVIC_SetVector(irq_num[id][sub_id], irq_entry[id][sub_id]);
782 NVIC_SetPriority(irq_num[id][sub_id], IRQ_PRIORITY_NORMAL);
783 NVIC_ClearPendingIRQ(irq_num[id][sub_id]);
784 NVIC_EnableIRQ(irq_num[id][sub_id]);
785 }
786
787 dual_timer[id]->timer[sub_id].Control = mode |
788 (irq_en ? TIMER_CTRL_INTEN : 0) |
789 TIMER_CTRL_PRESCALE_DIV_1 |
790 TIMER_CTRL_SIZE_32_BIT;
791 }
792
hal_timer_common_reload(uint32_t id,uint32_t sub_id,uint32_t load)793 static void hal_timer_common_reload(uint32_t id, uint32_t sub_id, uint32_t load)
794 {
795 uint32_t delta;
796
797 delta = timer_is_slow(id) ? SLOW_TIMER_VAL_DELTA : FAST_TIMER_VAL_DELTA;
798 if (load > HAL_TIMER_LOAD_DELTA) {
799 load -= HAL_TIMER_LOAD_DELTA;
800 } else {
801 load = HAL_TIMER_LOAD_DELTA;
802 }
803 set_timer_load(&dual_timer[id]->timer[sub_id], load, delta);
804 }
805
hal_timer_common_get_load(uint32_t id,uint32_t sub_id)806 POSSIBLY_UNUSED static uint32_t hal_timer_common_get_load(uint32_t id, uint32_t sub_id)
807 {
808 return dual_timer[id]->timer[sub_id].Load + HAL_TIMER_LOAD_DELTA;
809 }
810
hal_timer_common_bgload(uint32_t id,uint32_t sub_id,uint32_t load)811 POSSIBLY_UNUSED static void hal_timer_common_bgload(uint32_t id, uint32_t sub_id, uint32_t load)
812 {
813 if (load > HAL_TIMER_LOAD_DELTA) {
814 load -= HAL_TIMER_LOAD_DELTA;
815 } else {
816 load = HAL_TIMER_LOAD_DELTA;
817 }
818 dual_timer[id]->timer[sub_id].BGLoad = load;
819 }
820
hal_timer_common_pause(uint32_t id,uint32_t sub_id)821 POSSIBLY_UNUSED static void hal_timer_common_pause(uint32_t id, uint32_t sub_id)
822 {
823 dual_timer[id]->timer[sub_id].Control &= ~TIMER_CTRL_EN;
824 }
825
hal_timer_common_continue(uint32_t id,uint32_t sub_id)826 static void hal_timer_common_continue(uint32_t id, uint32_t sub_id)
827 {
828 dual_timer[id]->timer[sub_id].Control |= TIMER_CTRL_EN;
829 }
830
hal_timer_common_start(uint32_t id,uint32_t sub_id,uint32_t load)831 static void hal_timer_common_start(uint32_t id, uint32_t sub_id, uint32_t load)
832 {
833 start_time[id][sub_id] = timer_is_slow(id) ? hal_sys_timer_get() : hal_fast_sys_timer_get();
834 hal_timer_common_reload(id, sub_id, load);
835 hal_timer_common_continue(id, sub_id);
836 }
837
hal_timer_common_stop(uint32_t id,uint32_t sub_id)838 static void hal_timer_common_stop(uint32_t id, uint32_t sub_id)
839 {
840 dual_timer[id]->timer[sub_id].Control &= ~TIMER_CTRL_EN;
841 clear_timer_irq(&dual_timer[id]->timer[sub_id]);
842 NVIC_ClearPendingIRQ(irq_num[id][sub_id]);
843 }
844
hal_timer_common_is_enabled(uint32_t id,uint32_t sub_id)845 static int hal_timer_common_is_enabled(uint32_t id, uint32_t sub_id)
846 {
847 return !!(dual_timer[id]->timer[sub_id].Control & TIMER_CTRL_EN);
848 }
849
hal_timer_common_get_raw_value(uint32_t id,uint32_t sub_id)850 static uint32_t hal_timer_common_get_raw_value(uint32_t id, uint32_t sub_id)
851 {
852 uint32_t delta;
853
854 delta = timer_is_slow(id) ? SLOW_TIMER_VAL_DELTA : FAST_TIMER_VAL_DELTA;
855 return get_timer_value(&dual_timer[id]->timer[sub_id], delta);
856 }
857
hal_timer_common_irq_active(uint32_t id,uint32_t sub_id)858 static int hal_timer_common_irq_active(uint32_t id, uint32_t sub_id)
859 {
860 return NVIC_GetActive(irq_num[id][sub_id]);
861 }
862
hal_timer_common_irq_pending(uint32_t id,uint32_t sub_id)863 static int hal_timer_common_irq_pending(uint32_t id, uint32_t sub_id)
864 {
865 return (dual_timer[id]->timer[sub_id].MIS & TIMER_MIS_MIS);
866 }
867
hal_timer_common_get_elapsed_time(uint32_t id,uint32_t sub_id)868 static uint32_t hal_timer_common_get_elapsed_time(uint32_t id, uint32_t sub_id)
869 {
870 uint32_t time;
871
872 time = timer_is_slow(id) ? hal_sys_timer_get() : hal_fast_sys_timer_get();
873 return time - start_time[id][sub_id];
874 }
875
876 //----------------------------------------------------------
877 // Slow timer IRQ API
878 //----------------------------------------------------------
879
hal_timer_setup(enum HAL_TIMER_TYPE_T type,HAL_TIMER_IRQ_HANDLER_T handler)880 void hal_timer_setup(enum HAL_TIMER_TYPE_T type, HAL_TIMER_IRQ_HANDLER_T handler)
881 {
882 hal_timer_common_setup(0, SLOW_TIMER_SUB_ID_WITH_IRQ, type, handler);
883 }
884
hal_timer_start(uint32_t load)885 void hal_timer_start(uint32_t load)
886 {
887 hal_timer_common_start(0, SLOW_TIMER_SUB_ID_WITH_IRQ, load);
888 }
889
hal_timer_stop(void)890 void hal_timer_stop(void)
891 {
892 hal_timer_common_stop(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
893 }
894
hal_timer_continue(void)895 void hal_timer_continue(void)
896 {
897 hal_timer_common_continue(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
898 }
899
hal_timer_is_enabled(void)900 int hal_timer_is_enabled(void)
901 {
902 return hal_timer_common_is_enabled(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
903 }
904
hal_timer_reload(uint32_t load)905 void hal_timer_reload(uint32_t load)
906 {
907 hal_timer_common_reload(0, SLOW_TIMER_SUB_ID_WITH_IRQ, load);
908 }
909
hal_timer_get_raw_value(void)910 uint32_t hal_timer_get_raw_value(void)
911 {
912 return hal_timer_common_get_raw_value(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
913 }
914
hal_timer_irq_active(void)915 int hal_timer_irq_active(void)
916 {
917 return hal_timer_common_irq_active(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
918 }
919
hal_timer_irq_pending(void)920 int hal_timer_irq_pending(void)
921 {
922 return hal_timer_common_irq_pending(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
923 }
924
hal_timer_get_elapsed_time(void)925 uint32_t hal_timer_get_elapsed_time(void)
926 {
927 return hal_timer_common_get_elapsed_time(0, SLOW_TIMER_SUB_ID_WITH_IRQ);
928 }
929
930 //----------------------------------------------------------
931 // Fast timer IRQ API
932 //----------------------------------------------------------
933
934 #ifdef TIMER1_BASE
hal_fast_timer_setup(enum HAL_TIMER_TYPE_T type,HAL_TIMER_IRQ_HANDLER_T handler)935 void hal_fast_timer_setup(enum HAL_TIMER_TYPE_T type, HAL_TIMER_IRQ_HANDLER_T handler)
936 {
937 hal_timer_common_setup(1, 1, type, handler);
938 }
939
hal_fast_timer_start(uint32_t load)940 void hal_fast_timer_start(uint32_t load)
941 {
942 hal_timer_common_start(1, 1, load);
943 }
944
hal_fast_timer_stop(void)945 void hal_fast_timer_stop(void)
946 {
947 hal_timer_common_stop(1, 1);
948 }
949
hal_fast_timer_pause(void)950 void hal_fast_timer_pause(void)
951 {
952 hal_timer_common_pause(1, 1);
953 }
954
hal_fast_timer_continue(void)955 void hal_fast_timer_continue(void)
956 {
957 hal_timer_common_continue(1, 1);
958 }
959
hal_fast_timer_is_enabled(void)960 int hal_fast_timer_is_enabled(void)
961 {
962 return hal_timer_common_is_enabled(1, 1);
963 }
964
hal_fast_timer_reload(uint32_t load)965 void hal_fast_timer_reload(uint32_t load)
966 {
967 hal_timer_common_reload(1, 1, load);
968 }
969
hal_fast_timer_bgload(uint32_t load)970 void hal_fast_timer_bgload(uint32_t load)
971 {
972 hal_timer_common_bgload(1, 1, load);
973 }
974
hal_fast_timer_get_raw_value(void)975 uint32_t hal_fast_timer_get_raw_value(void)
976 {
977 return hal_timer_common_get_raw_value(1, 1);
978 }
979
hal_fast_timer_irq_active(void)980 int hal_fast_timer_irq_active(void)
981 {
982 return hal_timer_common_irq_active(1, 1);
983 }
984
hal_fast_timer_irq_pending(void)985 int hal_fast_timer_irq_pending(void)
986 {
987 return hal_timer_common_irq_pending(1, 1);
988 }
989
hal_fast_timer_get_elapsed_time(void)990 uint32_t hal_fast_timer_get_elapsed_time(void)
991 {
992 return hal_timer_common_get_elapsed_time(1, 1);
993 }
994
hal_fast_timer_get_load(void)995 uint32_t hal_fast_timer_get_load(void)
996 {
997 return hal_timer_common_get_load(1, 1);
998 }
999
hal_fast_timer_get_count(void)1000 uint32_t hal_fast_timer_get_count(void)
1001 {
1002 return dual_timer[1]->timer[1].Load - get_timer_value(&dual_timer[1]->timer[1], FAST_TIMER_VAL_DELTA);
1003 }
1004
1005 #endif
1006
1007 //----------------------------------------------------------
1008 // User timer IRQ API
1009 //----------------------------------------------------------
1010
1011 #ifdef TIMER2_BASE
hal_user_timer_clock_enable()1012 static void hal_user_timer_clock_enable()
1013 {
1014 if (hal_cmu_clock_get_status(HAL_CMU_MOD_O_TIMER2) == HAL_CMU_CLK_DISABLED) {
1015 hal_cmu_clock_enable(HAL_CMU_MOD_O_TIMER2);
1016 hal_cmu_clock_enable(HAL_CMU_MOD_P_TIMER2);
1017 hal_cmu_reset_clear(HAL_CMU_MOD_O_TIMER2);
1018 hal_cmu_reset_clear(HAL_CMU_MOD_P_TIMER2);
1019 }
1020 }
1021
hal_user_timer0_setup(enum HAL_TIMER_TYPE_T type,HAL_TIMER_IRQ_HANDLER_T handler)1022 void hal_user_timer0_setup(enum HAL_TIMER_TYPE_T type, HAL_TIMER_IRQ_HANDLER_T handler)
1023 {
1024 hal_user_timer_clock_enable();
1025 hal_timer_common_setup(2, 0, type, handler);
1026 }
1027
hal_user_timer0_start(uint32_t load)1028 void hal_user_timer0_start(uint32_t load)
1029 {
1030 hal_timer_common_start(2, 0, load);
1031 }
1032
hal_user_timer0_stop(void)1033 void hal_user_timer0_stop(void)
1034 {
1035 hal_timer_common_stop(2, 0);
1036 }
1037
hal_user_timer0_continue(void)1038 void hal_user_timer0_continue(void)
1039 {
1040 hal_timer_common_continue(2, 0);
1041 }
1042
hal_user_timer0_is_enabled(void)1043 int hal_user_timer0_is_enabled(void)
1044 {
1045 return hal_timer_common_is_enabled(2, 0);
1046 }
1047
hal_user_timer0_reload(uint32_t load)1048 void hal_user_timer0_reload(uint32_t load)
1049 {
1050 hal_timer_common_reload(2, 0, load);
1051 }
1052
hal_user_timer0_get_raw_value(void)1053 uint32_t hal_user_timer0_get_raw_value(void)
1054 {
1055 return hal_timer_common_get_raw_value(2, 0);
1056 }
1057
hal_user_timer0_irq_active(void)1058 int hal_user_timer0_irq_active(void)
1059 {
1060 return hal_timer_common_irq_active(2, 0);
1061 }
1062
hal_user_timer0_irq_pending(void)1063 int hal_user_timer0_irq_pending(void)
1064 {
1065 return hal_timer_common_irq_pending(2, 0);
1066 }
1067
hal_user_timer0_get_elapsed_time(void)1068 uint32_t hal_user_timer0_get_elapsed_time(void)
1069 {
1070 return hal_timer_common_get_elapsed_time(2, 0);
1071 }
1072
hal_user_timer1_setup(enum HAL_TIMER_TYPE_T type,HAL_TIMER_IRQ_HANDLER_T handler)1073 void hal_user_timer1_setup(enum HAL_TIMER_TYPE_T type, HAL_TIMER_IRQ_HANDLER_T handler)
1074 {
1075 hal_user_timer_clock_enable();
1076 hal_timer_common_setup(2, 1, type, handler);
1077 }
1078
hal_user_timer1_start(uint32_t load)1079 void hal_user_timer1_start(uint32_t load)
1080 {
1081 hal_timer_common_start(2, 1, load);
1082 }
1083
hal_user_timer1_stop(void)1084 void hal_user_timer1_stop(void)
1085 {
1086 hal_timer_common_stop(2, 1);
1087 }
1088
hal_user_timer1_continue(void)1089 void hal_user_timer1_continue(void)
1090 {
1091 hal_timer_common_continue(2, 1);
1092 }
1093
hal_user_timer1_is_enabled(void)1094 int hal_user_timer1_is_enabled(void)
1095 {
1096 return hal_timer_common_is_enabled(2, 1);
1097 }
1098
hal_user_timer1_reload(uint32_t load)1099 void hal_user_timer1_reload(uint32_t load)
1100 {
1101 hal_timer_common_reload(2, 1, load);
1102 }
1103
hal_user_timer1_get_raw_value(void)1104 uint32_t hal_user_timer1_get_raw_value(void)
1105 {
1106 return hal_timer_common_get_raw_value(2, 1);
1107 }
1108
hal_user_timer1_irq_active(void)1109 int hal_user_timer1_irq_active(void)
1110 {
1111 return hal_timer_common_irq_active(2, 1);
1112 }
1113
hal_user_timer1_irq_pending(void)1114 int hal_user_timer1_irq_pending(void)
1115 {
1116 return hal_timer_common_irq_pending(2, 1);
1117 }
1118
hal_user_timer1_get_elapsed_time(void)1119 uint32_t hal_user_timer1_get_elapsed_time(void)
1120 {
1121 return hal_timer_common_get_elapsed_time(2, 1);
1122 }
1123
1124 #endif
1125