14
14
15
15
#include <hal_ch32fun.h>
16
16
17
- #define STK_SWIE BIT(31)
18
- #define STK_STRE BIT(3)
19
17
#define STK_STCLK BIT(2)
20
18
#define STK_STIE BIT(1)
21
19
#define STK_STE BIT(0)
27
25
28
26
#define SYSTICK ((SysTick_Type *)(DT_INST_REG_ADDR(0)))
29
27
30
- static volatile uint32_t ch32v00x_systick_count ;
28
+ static uint64_t last_cycles_announced ;
29
+
30
+ static inline bool cycles_close_to_next_cmp (uint32_t cycles )
31
+ {
32
+ return (cycles % CYCLES_PER_TICK ) > (9 * CYCLES_PER_TICK / 10 );
33
+ }
31
34
32
35
static void ch32v00x_systick_irq (const void * unused )
33
36
{
37
+ uint64_t elapsed_cycles ;
38
+ uint32_t ticks = 0 ;
39
+ uint64_t cnt = SYSTICK -> CNT ;
40
+
34
41
ARG_UNUSED (unused );
35
42
43
+ if (cnt < last_cycles_announced ) {
44
+ elapsed_cycles = (UINT64_MAX - last_cycles_announced ) + cnt ;
45
+ ticks = elapsed_cycles / CYCLES_PER_TICK ;
46
+
47
+ /* If we're too close to the next tick, announce that tick early now rather than
48
+ * miss it
49
+ */
50
+ if (cycles_close_to_next_cmp (elapsed_cycles % CYCLES_PER_TICK )) {
51
+ ticks ++ ;
52
+ last_cycles_announced = (cnt % CYCLES_PER_TICK ) + CYCLES_PER_TICK ;
53
+ } else {
54
+ last_cycles_announced = cnt % CYCLES_PER_TICK ;
55
+ }
56
+ } else {
57
+ ticks = (cnt - last_cycles_announced ) / CYCLES_PER_TICK ;
58
+
59
+ /* If we're too close to the next tick, announce that tick early now rather than
60
+ * miss it
61
+ */
62
+ if (cycles_close_to_next_cmp (cnt - last_cycles_announced )) {
63
+ ticks ++ ;
64
+ }
65
+
66
+ last_cycles_announced += ticks * CYCLES_PER_TICK ;
67
+ }
68
+
69
+
70
+ /* Ensure we trigger when CNT resets to zero */
71
+ if (UINT64_MAX - SYSTICK -> CMP < CYCLES_PER_TICK ) {
72
+ SYSTICK -> CMP = SYSTICK -> CMP % CYCLES_PER_TICK ;
73
+ } else {
74
+ SYSTICK -> CMP = (last_cycles_announced + CYCLES_PER_TICK );
75
+ }
76
+
36
77
SYSTICK -> SR = 0 ;
37
- ch32v00x_systick_count += CYCLES_PER_TICK ; /* Track cycles. */
38
- sys_clock_announce (1 ); /* Poke the scheduler. */
78
+
79
+ sys_clock_announce (ticks );
39
80
}
40
81
41
82
uint32_t sys_clock_cycle_get_32 (void )
42
83
{
43
- return ch32v00x_systick_count + SYSTICK -> CNT ;
84
+ return (uint32_t )SYSTICK -> CNT ;
85
+ }
86
+
87
+ uint64_t sys_clock_cycle_get_64 (void )
88
+ {
89
+ return SYSTICK -> CNT ;
44
90
}
45
91
46
92
uint32_t sys_clock_elapsed (void )
@@ -55,10 +101,11 @@ static int ch32v00x_systick_init(void)
55
101
SYSTICK -> SR = 0 ;
56
102
SYSTICK -> CMP = CYCLES_PER_TICK ;
57
103
SYSTICK -> CNT = 0 ;
58
- SYSTICK -> CTLR = STK_STRE | STK_STCLK | STK_STIE | STK_STE ;
59
104
60
105
irq_enable (DT_INST_IRQN (0 ));
61
106
107
+ SYSTICK -> CTLR = STK_STE | STK_STCLK | STK_STIE ;
108
+
62
109
return 0 ;
63
110
}
64
111
0 commit comments