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
+ uint32_t ticks = 0 ;
38
+ uint64_t cnt = SYSTICK -> CNT ;
39
+
34
40
ARG_UNUSED (unused );
35
41
42
+ if (cnt < last_cycles_announced ) {
43
+ uint64_t elapsed_cycles = (UINT64_MAX - last_cycles_announced ) + cnt ;
44
+ ticks = elapsed_cycles / CYCLES_PER_TICK ;
45
+
46
+ /* If we're too close to the next tick, announce that tick early now rather than
47
+ * miss it
48
+ */
49
+ if (cycles_close_to_next_cmp (elapsed_cycles % CYCLES_PER_TICK )) {
50
+ ticks ++ ;
51
+ last_cycles_announced = (cnt % CYCLES_PER_TICK ) + CYCLES_PER_TICK ;
52
+ } else {
53
+ last_cycles_announced = cnt % CYCLES_PER_TICK ;
54
+ }
55
+ } else {
56
+ ticks = (cnt - last_cycles_announced ) / CYCLES_PER_TICK ;
57
+
58
+ /* If we're too close to the next tick, announce that tick early now rather than
59
+ * miss it
60
+ */
61
+ if (cycles_close_to_next_cmp (cnt - last_cycles_announced )) {
62
+ ticks ++ ;
63
+ }
64
+
65
+ last_cycles_announced += ticks * CYCLES_PER_TICK ;
66
+ }
67
+
68
+
69
+ /* Ensure we trigger when CNT resets to zero */
70
+ if (UINT64_MAX - SYSTICK -> CMP < CYCLES_PER_TICK ) {
71
+ SYSTICK -> CMP = SYSTICK -> CMP % CYCLES_PER_TICK ;
72
+ } else {
73
+ SYSTICK -> CMP = (last_cycles_announced + CYCLES_PER_TICK );
74
+ }
75
+
36
76
SYSTICK -> SR = 0 ;
37
- ch32v00x_systick_count += CYCLES_PER_TICK ; /* Track cycles. */
38
- sys_clock_announce (1 ); /* Poke the scheduler. */
77
+
78
+ sys_clock_announce (ticks );
39
79
}
40
80
41
81
uint32_t sys_clock_cycle_get_32 (void )
42
82
{
43
- return ch32v00x_systick_count + SYSTICK -> CNT ;
83
+ return (uint32_t )SYSTICK -> CNT ;
84
+ }
85
+
86
+ uint64_t sys_clock_cycle_get_64 (void )
87
+ {
88
+ return SYSTICK -> CNT ;
44
89
}
45
90
46
91
uint32_t sys_clock_elapsed (void )
@@ -55,10 +100,11 @@ static int ch32v00x_systick_init(void)
55
100
SYSTICK -> SR = 0 ;
56
101
SYSTICK -> CMP = CYCLES_PER_TICK ;
57
102
SYSTICK -> CNT = 0 ;
58
- SYSTICK -> CTLR = STK_STRE | STK_STCLK | STK_STIE | STK_STE ;
59
103
60
104
irq_enable (DT_INST_IRQN (0 ));
61
105
106
+ SYSTICK -> CTLR = STK_STE | STK_STCLK | STK_STIE ;
107
+
62
108
return 0 ;
63
109
}
64
110
0 commit comments