summaryrefslogtreecommitdiff
path: root/bsp/bouffalo_lab/libraries/bl_mcu_sdk/drivers/lhal/src/bflb_mtimer.c
blob: 27b09d5b71f955b0738e9e2050a84dbf2b931828 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "bflb_mtimer.h"
#include "bflb_core.h"
#if defined(BL602) || defined(BL702) || defined(BL702L)
#include <risc-v/e24/clic.h>
#else
#include <csi_core.h>
#endif

static void (*systick_callback)(void);
static uint64_t current_set_ticks = 0;

static void systick_isr(int irq, void *arg)
{
#if defined(BL702) || defined(BL602) || defined(BL702L)
    *(volatile uint64_t *)(CLIC_CTRL_BASE + CLIC_MTIMECMP_OFFSET) += current_set_ticks;
#else
    csi_coret_config(current_set_ticks, 7);
#endif
    systick_callback();
}

void bflb_mtimer_config(uint64_t ticks, void (*interruptfun)(void))
{
    bflb_irq_disable(7);

    current_set_ticks = ticks;
    systick_callback = interruptfun;
#if defined(BL702) || defined(BL602) || defined(BL702L)
    *(volatile uint64_t *)(CLIC_CTRL_BASE + CLIC_MTIMECMP_OFFSET) = (*(volatile uint64_t *)(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET)) + ticks;
#else
    csi_coret_config_use(ticks, 7);
#endif

    bflb_irq_attach(7, systick_isr, NULL);
    bflb_irq_enable(7);
}

__WEAK uint32_t ATTR_TCM_SECTION bflb_mtimer_get_freq(void)
{
    return 1 * 1000 * 1000;
}

uint64_t ATTR_TCM_SECTION bflb_mtimer_get_time_us()
{
    volatile uint64_t tmp_low, tmp_high, tmp_low1, tmp_high1;

    do {
#if defined(BL702) || defined(BL602) || defined(BL702L)
        tmp_high = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET + 4);
        tmp_low = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET);
        tmp_low1 = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET);
        tmp_high1 = getreg32(CLIC_CTRL_BASE + CLIC_MTIME_OFFSET + 4);
#else
        tmp_high = (uint64_t)csi_coret_get_valueh();
        tmp_low = (uint64_t)csi_coret_get_value();
        tmp_low1 = (uint64_t)csi_coret_get_value();
        tmp_high1 = (uint64_t)csi_coret_get_valueh();
#endif
    } while (tmp_low > tmp_low1 || tmp_high != tmp_high1);
#ifdef CONFIG_MTIMER_CUSTOM_FREQUENCE
    return ((uint64_t)(((tmp_high1 << 32) + tmp_low1)) * ((uint64_t)(1 * 1000 * 1000)) / bflb_mtimer_get_freq());
#else
    return (uint64_t)(((tmp_high1 << 32) + tmp_low1));
#endif
}

uint32_t ATTR_TCM_SECTION __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
{
    uint64_t rem = *n;
    uint64_t b = base;
    uint64_t res, d = 1;
    uint32_t high = rem >> 32;

    res = 0;
    if (high >= base) {
        high /= base;
        res = (uint64_t) high << 32;
        rem -= (uint64_t) (high*base) << 32;
    }
    while ((int64_t)b > 0 && b < rem) {
        b = b+b;
        d = d+d;
    }

    do {
        if (rem >= b) {
            rem -= b;
            res += d;
        }
        b >>= 1;
        d >>= 1;
    } while (d);

    *n = res;
    return rem;
}

uint64_t ATTR_TCM_SECTION bflb_mtimer_get_time_ms()
{
#ifdef BFLB_BOOT2
    uint64_t ret = bflb_mtimer_get_time_us();
    __div64_32(&ret, 1000);
    return ret;
#else
    return bflb_mtimer_get_time_us() / 1000;
#endif
}

void ATTR_TCM_SECTION bflb_mtimer_delay_us(uint32_t time)
{
    uint64_t start_time = bflb_mtimer_get_time_us();

    while (bflb_mtimer_get_time_us() - start_time < time) {
    }
}

void ATTR_TCM_SECTION bflb_mtimer_delay_ms(uint32_t time)
{
    uint64_t start_time = bflb_mtimer_get_time_ms();

    while (bflb_mtimer_get_time_ms() - start_time < time) {
    }
}