1 #include "bflb_mtimer.h"
2 #include "bflb_core.h"
3 #if defined(BL602) || defined(BL702) || defined(BL702L)
4 #include <risc-v/e24/clic.h>
5 #else
6 #include <csi_core.h>
7 #endif
8
9 static void (*systick_callback)(void);
10 static uint64_t current_set_ticks = 0;
11
systick_isr(int irq,void * arg)12 static void systick_isr(int irq, void *arg)
13 {
14 #if defined(BL702) || defined(BL602) || defined(BL702L)
15 *(volatile uint64_t *)(CLIC_CTRL_BASE + CLIC_MTIMECMP_OFFSET) += current_set_ticks;
16 #else
17 csi_coret_config(current_set_ticks, 7);
18 #endif
19 systick_callback();
20 }
21
bflb_mtimer_config(uint64_t ticks,void (* interruptfun)(void))22 void bflb_mtimer_config(uint64_t ticks, void (*interruptfun)(void))
23 {
24 bflb_irq_disable(7);
25
26 current_set_ticks = ticks;
27 systick_callback = interruptfun;
28 #if defined(BL702) || defined(BL602) || defined(BL702L)
29 *(volatile uint64_t *)(CLIC_CTRL_BASE + CLIC_MTIMECMP_OFFSET) = (*(volatile uint64_t *)(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET)) + ticks;
30 #else
31 csi_coret_config_use(ticks, 7);
32 #endif
33
34 bflb_irq_attach(7, systick_isr, NULL);
35 bflb_irq_enable(7);
36 }
37
bflb_mtimer_get_freq(void)38 __WEAK uint32_t ATTR_TCM_SECTION bflb_mtimer_get_freq(void)
39 {
40 return 1 * 1000 * 1000;
41 }
42
bflb_mtimer_get_time_us()43 uint64_t ATTR_TCM_SECTION bflb_mtimer_get_time_us()
44 {
45 volatile uint64_t tmp_low, tmp_high, tmp_low1, tmp_high1;
46
47 do {
48 #if defined(BL702) || defined(BL602) || defined(BL702L)
49 tmp_high = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET + 4);
50 tmp_low = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET);
51 tmp_low1 = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET);
52 tmp_high1 = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET + 4);
53 #else
54 tmp_high = (uint64_t)csi_coret_get_valueh();
55 tmp_low = (uint64_t)csi_coret_get_value();
56 tmp_low1 = (uint64_t)csi_coret_get_value();
57 tmp_high1 = (uint64_t)csi_coret_get_valueh();
58 #endif
59 } while (tmp_low > tmp_low1 || tmp_high != tmp_high1);
60 #ifdef CONFIG_MTIMER_CUSTOM_FREQUENCE
61 return ((uint64_t)(((tmp_high1 << 32) + tmp_low1)) * ((uint64_t)(1 * 1000 * 1000)) / bflb_mtimer_get_freq());
62 #else
63 return (uint64_t)(((tmp_high1 << 32) + tmp_low1));
64 #endif
65 }
66
__div64_32(uint64_t * n,uint32_t base)67 uint32_t ATTR_TCM_SECTION __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
68 {
69 uint64_t rem = *n;
70 uint64_t b = base;
71 uint64_t res, d = 1;
72 uint32_t high = rem >> 32;
73
74 res = 0;
75 if (high >= base) {
76 high /= base;
77 res = (uint64_t) high << 32;
78 rem -= (uint64_t) (high*base) << 32;
79 }
80 while ((int64_t)b > 0 && b < rem) {
81 b = b+b;
82 d = d+d;
83 }
84
85 do {
86 if (rem >= b) {
87 rem -= b;
88 res += d;
89 }
90 b >>= 1;
91 d >>= 1;
92 } while (d);
93
94 *n = res;
95 return rem;
96 }
97
bflb_mtimer_get_time_ms()98 uint64_t ATTR_TCM_SECTION bflb_mtimer_get_time_ms()
99 {
100 #ifdef BFLB_BOOT2
101 uint64_t ret = bflb_mtimer_get_time_us();
102 __div64_32(&ret, 1000);
103 return ret;
104 #else
105 return bflb_mtimer_get_time_us() / 1000;
106 #endif
107 }
108
bflb_mtimer_delay_us(uint32_t time)109 void ATTR_TCM_SECTION bflb_mtimer_delay_us(uint32_t time)
110 {
111 uint64_t start_time = bflb_mtimer_get_time_us();
112
113 while (bflb_mtimer_get_time_us() - start_time < time) {
114 }
115 }
116
bflb_mtimer_delay_ms(uint32_t time)117 void ATTR_TCM_SECTION bflb_mtimer_delay_ms(uint32_t time)
118 {
119 uint64_t start_time = bflb_mtimer_get_time_ms();
120
121 while (bflb_mtimer_get_time_ms() - start_time < time) {
122 }
123 }
124