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