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