• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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