1 /*
2  * Copyright (c) 2024 Michael Hope
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT wch_systick
8 
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/timer/system_timer.h>
11 #include <zephyr/irq.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/sys/util.h>
14 
15 #include <ch32fun.h>
16 
17 #define STK_SWIE  BIT(31)
18 #define STK_STRE  BIT(3)
19 #define STK_STCLK BIT(2)
20 #define STK_STIE  BIT(1)
21 #define STK_STE   BIT(0)
22 
23 #define STK_CNTIF BIT(0)
24 
25 #define CYCLES_PER_SEC  sys_clock_hw_cycles_per_sec()
26 #define CYCLES_PER_TICK (CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
27 
28 #define SYSTICK ((SysTick_Type *)(DT_INST_REG_ADDR(0)))
29 
30 static volatile uint32_t ch32v00x_systick_count;
31 
ch32v00x_systick_irq(const void * unused)32 static void ch32v00x_systick_irq(const void *unused)
33 {
34 	ARG_UNUSED(unused);
35 
36 	SYSTICK->SR = 0;
37 	ch32v00x_systick_count += CYCLES_PER_TICK; /* Track cycles. */
38 	sys_clock_announce(1);                     /* Poke the scheduler. */
39 }
40 
sys_clock_cycle_get_32(void)41 uint32_t sys_clock_cycle_get_32(void)
42 {
43 	return ch32v00x_systick_count + SYSTICK->CNT;
44 }
45 
sys_clock_elapsed(void)46 uint32_t sys_clock_elapsed(void)
47 {
48 	return 0;
49 }
50 
ch32v00x_systick_init(void)51 static int ch32v00x_systick_init(void)
52 {
53 	IRQ_CONNECT(DT_INST_IRQN(0), 0, ch32v00x_systick_irq, NULL, 0);
54 
55 	SYSTICK->SR = 0;
56 	SYSTICK->CMP = CYCLES_PER_TICK;
57 	SYSTICK->CNT = 0;
58 	SYSTICK->CTLR = STK_STRE | STK_STCLK | STK_STIE | STK_STE;
59 
60 	irq_enable(DT_INST_IRQN(0));
61 
62 	return 0;
63 }
64 
65 SYS_INIT(ch32v00x_systick_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
66