Skip to content

Commit 7f6b519

Browse files
committed
soc: Add support for the WCH CH32V303
Adds support for building an image for the ch32v303. Signed-off-by: Miguel Gazquez <[email protected]>
1 parent 791e44c commit 7f6b519

16 files changed

+453
-2
lines changed

drivers/timer/Kconfig.wch_ch32v00x

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33

44
config CH32V00X_SYSTICK
55
bool "CH32V00X systick timer"
6-
depends on SOC_CH32V003 || SOC_SERIES_QINGKE_V4C
6+
depends on SOC_CH32V003 || SOC_SERIES_QINGKE_V4C || SOC_SERIES_QINGKE_V4F
77
default y
88
depends on DT_HAS_WCH_SYSTICK_ENABLED

dts/bindings/cpu/wch,qingke-v4f.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025 Bootlin
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: WCH QingKe V4F RISC-V MCU
5+
6+
compatible: "wch,qingke-v4f"
7+
8+
include: riscv,cpus.yaml

dts/riscv/wch/ch32v303/ch32v303.dtsi

+217
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
* Copyright (c) 2025 Bootlin
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <freq.h>
8+
#include <mem.h>
9+
#include <wch/qingke-v4f.dtsi>
10+
#include <zephyr/dt-bindings/gpio/gpio.h>
11+
#include <zephyr/dt-bindings/i2c/i2c.h>
12+
#include <zephyr/dt-bindings/clock/ch32v20x_30x-clocks.h>
13+
14+
/ {
15+
clocks {
16+
clk_hse: clk-hse {
17+
#clock-cells = <0>;
18+
compatible = "wch,ch32v00x-hse-clock";
19+
clock-frequency = <DT_FREQ_M(32)>;
20+
status = "disabled";
21+
};
22+
23+
clk_hsi: clk-hsi {
24+
#clock-cells = <0>;
25+
compatible = "wch,ch32v00x-hsi-clock";
26+
clock-frequency = <DT_FREQ_M(8)>;
27+
status = "disabled";
28+
};
29+
30+
clk_lsi: clk-lsi {
31+
#clock-cells = <0>;
32+
compatible = "fixed-clock";
33+
clock-frequency = <DT_FREQ_K(32)>;
34+
status = "disabled";
35+
};
36+
37+
pll: pll {
38+
#clock-cells = <0>;
39+
compatible = "wch,ch32v20x_30x-pll-clock";
40+
mul = <18>;
41+
status = "disabled";
42+
};
43+
};
44+
45+
soc {
46+
sram0: memory@20000000 {
47+
compatible = "mmio-sram";
48+
reg = <0x20000000 DT_SIZE_K(32)>;
49+
};
50+
51+
flash: flash-controller@40022000 {
52+
compatible = "wch,ch32v20x_30x-flash-controller";
53+
reg = <0x40022000 0x400>;
54+
55+
#address-cells = <1>;
56+
#size-cells = <1>;
57+
58+
flash0: flash@08000000 {
59+
compatible = "soc-nv-flash";
60+
reg = <0x08000000 DT_SIZE_K(480)>;
61+
};
62+
};
63+
64+
pwr: pwr@40007000 {
65+
compatible = "wch,pwr";
66+
reg = <0x40007000 16>;
67+
};
68+
69+
pinctrl: pin-controller@40010000 {
70+
compatible = "wch,20x_30x-afio";
71+
reg = <0x40010000 16>;
72+
#address-cells = <1>;
73+
#size-cells = <1>;
74+
status = "okay";
75+
76+
gpioa: gpio@40010800 {
77+
compatible = "wch,gpio";
78+
reg = <0x40010800 0x20>;
79+
gpio-controller;
80+
#gpio-cells = <2>;
81+
ngpios = <8>;
82+
clocks = <&rcc CH32V20X_V30X_CLOCK_IOPA>;
83+
};
84+
85+
gpiob: gpio@40010C00 {
86+
compatible = "wch,gpio";
87+
reg = <0x40010C00 0x20>;
88+
gpio-controller;
89+
#gpio-cells = <2>;
90+
ngpios = <8>;
91+
clocks = <&rcc CH32V20X_V30X_CLOCK_IOPB>;
92+
};
93+
94+
gpioc: gpio@40011000 {
95+
compatible = "wch,gpio";
96+
reg = <0x40011000 0x20>;
97+
gpio-controller;
98+
#gpio-cells = <2>;
99+
ngpios = <8>;
100+
clocks = <&rcc CH32V20X_V30X_CLOCK_IOPC>;
101+
};
102+
103+
gpiod: gpio@40011400 {
104+
compatible = "wch,gpio";
105+
reg = <0x40011400 0x20>;
106+
gpio-controller;
107+
#gpio-cells = <2>;
108+
ngpios = <8>;
109+
clocks = <&rcc CH32V20X_V30X_CLOCK_IOPD>;
110+
};
111+
};
112+
113+
usart1: uart@40013800 {
114+
compatible = "wch,usart";
115+
reg = <0x40013800 0x20>;
116+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART1>;
117+
interrupt-parent = <&pfic>;
118+
interrupts = <53>;
119+
status = "disabled";
120+
};
121+
122+
usart2: uart@40004400 {
123+
compatible = "wch,usart";
124+
reg = <0x40004400 0x20>;
125+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART2>;
126+
interrupt-parent = <&pfic>;
127+
interrupts = <54>;
128+
status = "disabled";
129+
};
130+
131+
usart3: uart@40004800 {
132+
compatible = "wch,usart";
133+
reg = <0x40004800 0x20>;
134+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART3>;
135+
interrupt-parent = <&pfic>;
136+
interrupts = <55>;
137+
status = "disabled";
138+
};
139+
140+
usart4: uart@40004c00 {
141+
compatible = "wch,usart";
142+
reg = <0x40004C00 0x20>;
143+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART4>;
144+
interrupt-parent = <&pfic>;
145+
interrupts = <68>;
146+
status = "disabled";
147+
};
148+
149+
usart5: uart@40005000 {
150+
compatible = "wch,usart";
151+
reg = <0x40005000 0x20>;
152+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART5>;
153+
interrupt-parent = <&pfic>;
154+
interrupts = <69>;
155+
status = "disabled";
156+
};
157+
158+
usart6: uart@40001800 {
159+
compatible = "wch,usart";
160+
reg = <0x40001800 0x20>;
161+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART6>;
162+
interrupt-parent = <&pfic>;
163+
interrupts = <87>;
164+
status = "disabled";
165+
};
166+
167+
usart7: uart@40001c00 {
168+
compatible = "wch,usart";
169+
reg = <0x40001c00 0x20>;
170+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART7>;
171+
interrupt-parent = <&pfic>;
172+
interrupts = <88>;
173+
status = "disabled";
174+
};
175+
176+
usart8: uart@40002000 {
177+
compatible = "wch,usart";
178+
reg = <0x40002000 0x20>;
179+
clocks = <&rcc CH32V20X_V30X_CLOCK_USART8>;
180+
interrupt-parent = <&pfic>;
181+
interrupts = <89>;
182+
status = "disabled";
183+
};
184+
185+
rcc: rcc@40021000 {
186+
compatible = "wch,rcc";
187+
reg = <0x40021000 16>;
188+
#clock-cells = <1>;
189+
status = "okay";
190+
};
191+
192+
dma1: dma@40020000 {
193+
compatible = "wch,wch-dma";
194+
reg = <0x40020000 0x90>;
195+
clocks = <&rcc CH32V20X_V30X_CLOCK_DMA1>;
196+
#dma-cells = <1>;
197+
interrupt-parent = <&pfic>;
198+
interrupts = <27>, <28>, <29>, <30>, <31>, <32>, <33>;
199+
dma-channels = <7>;
200+
};
201+
202+
dma2: dma@40020400 {
203+
compatible = "wch,wch-dma";
204+
reg = <0x40020400 0x90>;
205+
clocks = <&rcc CH32V20X_V30X_CLOCK_DMA2>;
206+
#dma-cells = <1>;
207+
interrupt-parent = <&pfic>;
208+
interrupts = <72>, <73>, <74>, <75>, <76>, <98>, <99>, <100>,
209+
<101>, <102>, <103>;
210+
dma-channels = <11>;
211+
};
212+
};
213+
};
214+
215+
&cpu0 {
216+
clock-frequency = <DT_FREQ_M(144)>;
217+
};

dts/riscv/wch/qingke-v4f.dtsi

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2025 Bootlin
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
#address-cells = <1>;
9+
#size-cells = <1>;
10+
11+
cpus {
12+
#address-cells = <1>;
13+
#size-cells = <0>;
14+
15+
cpu0: cpu@0 {
16+
device_type = "cpu";
17+
compatible = "wch,qingke-v4f";
18+
reg = <0>;
19+
riscv,isa = "rv32imacf_zicsr_zifencei";
20+
};
21+
};
22+
23+
soc {
24+
#address-cells = <1>;
25+
#size-cells = <1>;
26+
compatible = "simple-bus";
27+
ranges;
28+
29+
pfic: interrupt-controller@e000e000 {
30+
compatible = "wch,pfic";
31+
#address-cells = <0>;
32+
#interrupt-cells = <1>;
33+
interrupt-controller;
34+
reg = <0xe000e000 0x10>;
35+
status = "okay";
36+
};
37+
38+
systick: systimer@e000f000 {
39+
compatible = "wch,systick";
40+
reg = <0xe000f000 0x10>;
41+
status = "okay";
42+
interrupt-parent = <&pfic>;
43+
interrupts = <12>;
44+
};
45+
};
46+
};

modules/hal_wch/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
if(CONFIG_SOC_CH32V003 OR CONFIG_SOC_SERIES_QINGKE_V4C)
1+
if(CONFIG_SOC_FAMILY_CH32V)
22
zephyr_include_directories(${ZEPHYR_HAL_WCH_MODULE_DIR}/ch32fun .)
33
endif()

modules/hal_wch/hal_ch32fun.h

+9
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,13 @@
1717
#include <ch32fun.h>
1818
#endif
1919

20+
#if defined(CONFIG_SOC_SERIES_QINGKE_V4F)
21+
#define CH32V30x 1
22+
#if defined(CONFIG_SOC_CH32V303)
23+
#define CH32V30x_D8 1
24+
#endif
25+
26+
#include <ch32fun.h>
27+
#endif
28+
2029
#endif
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2024 Michael Hope
2+
# Copyright (c) 2024 Jianxiong Gu
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
zephyr_sources(
6+
soc_irq.S
7+
vector.S
8+
)
9+
10+
zephyr_include_directories(.)

soc/wch/ch32v/qingke_v4f/Kconfig

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2025 Bootlin
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config SOC_SERIES_QINGKE_V4F
5+
select RISCV_ISA_RV32I
6+
select RISCV_ISA_EXT_M
7+
select RISCV_ISA_EXT_A
8+
select RISCV_ISA_EXT_C
9+
select RISCV_ISA_EXT_F
10+
select RISCV_ISA_EXT_ZICSR
11+
select RISCV_ISA_EXT_ZIFENCEI
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright (c) 2025 Bootlin
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
if SOC_SERIES_QINGKE_V4F
5+
6+
config SYS_CLOCK_HW_CYCLES_PER_SEC
7+
default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency)
8+
9+
config MAIN_STACK_SIZE
10+
default 512
11+
12+
config IDLE_STACK_SIZE
13+
default 256
14+
15+
config ISR_STACK_SIZE
16+
default 256
17+
18+
config CLOCK_CONTROL
19+
default y
20+
21+
rsource "Kconfig.defconfig.*"
22+
23+
endif # SOC_SERIES_QINGKE_V4F
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 Bootlin
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
if SOC_CH32V303
5+
6+
config VECTOR_TABLE_SIZE
7+
default 103
8+
9+
config NUM_IRQS
10+
default 128
11+
12+
endif # SOC_CH32V303

soc/wch/ch32v/qingke_v4f/Kconfig.soc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2025 Bootlin
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config SOC_SERIES_QINGKE_V4F
5+
bool
6+
select SOC_FAMILY_CH32V
7+
8+
config SOC_SERIES
9+
default "qingke_v4f" if SOC_SERIES_QINGKE_V4F
10+
11+
rsource "Kconfig.soc.*"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2025 Bootlin
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config SOC_CH32V303
5+
bool
6+
select SOC_SERIES_QINGKE_V4F
7+
8+
config SOC
9+
default "ch32v303" if SOC_CH32V303

0 commit comments

Comments
 (0)