From f67b3216073901af963cc3c1a111ca0df5726cc0 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sat, 22 Feb 2025 15:41:41 +0100 Subject: [PATCH] soc: Introduce Qingke V4C-based CH32V208 SoC This introduces the only CH32 Serie Qingke V4C SoC, CH32V208 Signed-off-by: Camille BAUD --- dts/bindings/cpu/wch,qingke-v4c.yaml | 8 + dts/riscv/wch/ch32v208/ch32v208.dtsi | 157 ++++++++++++++++++ dts/riscv/wch/ch32v208/ch32v208cbu.dtsi | 15 ++ dts/riscv/wch/ch32v208/ch32v208gbu.dtsi | 23 +++ dts/riscv/wch/ch32v208/ch32v208rbt.dtsi | 11 ++ dts/riscv/wch/ch32v208/ch32v208wbu.dtsi | 11 ++ dts/riscv/wch/qingke-v4c.dtsi | 46 +++++ modules/hal_wch/CMakeLists.txt | 2 +- modules/hal_wch/ch32fun.h | 5 + soc/wch/ch32v/qingke_v4c/CMakeLists.txt | 10 ++ soc/wch/ch32v/qingke_v4c/Kconfig | 10 ++ soc/wch/ch32v/qingke_v4c/Kconfig.defconfig | 23 +++ .../qingke_v4c/Kconfig.defconfig.ch32v208 | 12 ++ soc/wch/ch32v/qingke_v4c/Kconfig.soc | 11 ++ soc/wch/ch32v/qingke_v4c/Kconfig.soc.ch32v208 | 9 + soc/wch/ch32v/qingke_v4c/pinctrl_soc.h | 42 +++++ soc/wch/ch32v/qingke_v4c/soc_irq.S | 19 +++ soc/wch/ch32v/qingke_v4c/vector.S | 29 ++++ soc/wch/ch32v/soc.yml | 3 + 19 files changed, 445 insertions(+), 1 deletion(-) create mode 100644 dts/bindings/cpu/wch,qingke-v4c.yaml create mode 100644 dts/riscv/wch/ch32v208/ch32v208.dtsi create mode 100644 dts/riscv/wch/ch32v208/ch32v208cbu.dtsi create mode 100644 dts/riscv/wch/ch32v208/ch32v208gbu.dtsi create mode 100644 dts/riscv/wch/ch32v208/ch32v208rbt.dtsi create mode 100644 dts/riscv/wch/ch32v208/ch32v208wbu.dtsi create mode 100644 dts/riscv/wch/qingke-v4c.dtsi create mode 100644 soc/wch/ch32v/qingke_v4c/CMakeLists.txt create mode 100644 soc/wch/ch32v/qingke_v4c/Kconfig create mode 100644 soc/wch/ch32v/qingke_v4c/Kconfig.defconfig create mode 100644 soc/wch/ch32v/qingke_v4c/Kconfig.defconfig.ch32v208 create mode 100644 soc/wch/ch32v/qingke_v4c/Kconfig.soc create mode 100644 soc/wch/ch32v/qingke_v4c/Kconfig.soc.ch32v208 create mode 100644 soc/wch/ch32v/qingke_v4c/pinctrl_soc.h create mode 100644 soc/wch/ch32v/qingke_v4c/soc_irq.S create mode 100644 soc/wch/ch32v/qingke_v4c/vector.S diff --git a/dts/bindings/cpu/wch,qingke-v4c.yaml b/dts/bindings/cpu/wch,qingke-v4c.yaml new file mode 100644 index 00000000000..2fd160474c2 --- /dev/null +++ b/dts/bindings/cpu/wch,qingke-v4c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: WCH QingKe V4C RISC-V MCU + +compatible: "wch,qingke-v4c" + +include: riscv,cpus.yaml diff --git a/dts/riscv/wch/ch32v208/ch32v208.dtsi b/dts/riscv/wch/ch32v208/ch32v208.dtsi new file mode 100644 index 00000000000..c92324dad64 --- /dev/null +++ b/dts/riscv/wch/ch32v208/ch32v208.dtsi @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +/ { + clocks { + clk_hse: clk-hse { + #clock-cells = <0>; + compatible = "wch,ch32v00x-hse-clock"; + clock-frequency = ; + status = "disabled"; + }; + + clk_hsi: clk-hsi { + #clock-cells = <0>; + compatible = "wch,ch32v00x-hsi-clock"; + clock-frequency = ; + status = "disabled"; + }; + + clk_lsi: clk-lsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + status = "disabled"; + }; + + pll: pll { + #clock-cells = <0>; + compatible = "wch,ch32v20x_30x-pll-clock"; + mul = <18>; + status = "disabled"; + }; + }; + + soc { + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(64)>; + }; + + flash: flash-controller@40022000 { + compatible = "wch,ch32v20x_30x-flash-controller"; + reg = <0x40022000 0x400>; + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_K(128)>; + }; + }; + + pwr: pwr@40007000 { + compatible = "wch,pwr"; + reg = <0x40007000 16>; + }; + + pinctrl: pin-controller@40010000 { + compatible = "wch,20x_30x-afio"; + reg = <0x40010000 16>; + #address-cells = <1>; + #size-cells = <1>; + + gpioa: gpio@40010800 { + compatible = "wch,gpio"; + reg = <0x40010800 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + clocks = <&rcc CH32V20X_V30X_CLOCK_IOPA>; + }; + + gpiob: gpio@40010C00 { + compatible = "wch,gpio"; + reg = <0x40010C00 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + clocks = <&rcc CH32V20X_V30X_CLOCK_IOPB>; + }; + + gpioc: gpio@40011000 { + compatible = "wch,gpio"; + reg = <0x40011000 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + clocks = <&rcc CH32V20X_V30X_CLOCK_IOPC>; + }; + + gpiod: gpio@40011400 { + compatible = "wch,gpio"; + reg = <0x40011400 0x20>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + clocks = <&rcc CH32V20X_V30X_CLOCK_IOPD>; + }; + }; + + usart1: uart@40013800 { + compatible = "wch,usart"; + reg = <0x40013800 0x20>; + clocks = <&rcc CH32V20X_V30X_CLOCK_USART1>; + interrupt-parent = <&pfic>; + interrupts = <53>; + status = "disabled"; + }; + + usart2: uart@40004400 { + compatible = "wch,usart"; + reg = <0x40004400 0x20>; + clocks = <&rcc CH32V20X_V30X_CLOCK_USART2>; + interrupt-parent = <&pfic>; + interrupts = <54>; + status = "disabled"; + }; + + usart3: uart@40004800 { + compatible = "wch,usart"; + reg = <0x40004800 0x20>; + clocks = <&rcc CH32V20X_V30X_CLOCK_USART3>; + interrupt-parent = <&pfic>; + interrupts = <55>; + status = "disabled"; + }; + + usart4: uart@40004c00 { + compatible = "wch,usart"; + reg = <0x40004C00 0x20>; + clocks = <&rcc CH32V20X_V30X_CLOCK_USART4>; + interrupt-parent = <&pfic>; + interrupts = <68>; + status = "disabled"; + }; + + rcc: rcc@40021000 { + compatible = "wch,rcc"; + reg = <0x40021000 16>; + #clock-cells = <1>; + }; + }; +}; + +&cpu0 { + clock-frequency = ; +}; diff --git a/dts/riscv/wch/ch32v208/ch32v208cbu.dtsi b/dts/riscv/wch/ch32v208/ch32v208cbu.dtsi new file mode 100644 index 00000000000..e4f958ca2c8 --- /dev/null +++ b/dts/riscv/wch/ch32v208/ch32v208cbu.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpioc { + gpio-reserved-ranges = <0 13>; +}; + +&gpiod { + gpio-reserved-ranges = <0 16>; +}; diff --git a/dts/riscv/wch/ch32v208/ch32v208gbu.dtsi b/dts/riscv/wch/ch32v208/ch32v208gbu.dtsi new file mode 100644 index 00000000000..3241b148c93 --- /dev/null +++ b/dts/riscv/wch/ch32v208/ch32v208gbu.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpioa { + gpio-reserved-ranges = <8 3>, <15 1>; +}; + +&gpiob { + gpio-reserved-ranges = <0 6>, <9 7>; +}; + +&gpioc { + gpio-reserved-ranges = <0 7>, <10 4>; +}; + +&gpiod { + gpio-reserved-ranges = <0 16>; +}; diff --git a/dts/riscv/wch/ch32v208/ch32v208rbt.dtsi b/dts/riscv/wch/ch32v208/ch32v208rbt.dtsi new file mode 100644 index 00000000000..7507be1f731 --- /dev/null +++ b/dts/riscv/wch/ch32v208/ch32v208rbt.dtsi @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpiod { + gpio-reserved-ranges = <0 2>, <3 12>; +}; diff --git a/dts/riscv/wch/ch32v208/ch32v208wbu.dtsi b/dts/riscv/wch/ch32v208/ch32v208wbu.dtsi new file mode 100644 index 00000000000..d2e72c30a8f --- /dev/null +++ b/dts/riscv/wch/ch32v208/ch32v208wbu.dtsi @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&gpiod { + gpio-reserved-ranges = <0 2>, <7 8>; +}; diff --git a/dts/riscv/wch/qingke-v4c.dtsi b/dts/riscv/wch/qingke-v4c.dtsi new file mode 100644 index 00000000000..c4b00b5fdd7 --- /dev/null +++ b/dts/riscv/wch/qingke-v4c.dtsi @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "wch,qingke-v4c"; + reg = <0>; + riscv,isa = "rv32imac_zicsr_zifencei"; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + pfic: interrupt-controller@e000e000 { + compatible = "wch,pfic"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0xe000e000 0x10>; + status = "okay"; + }; + + systick: systimer@e000f000 { + compatible = "wch,systick"; + reg = <0xe000f000 0x10>; + status = "okay"; + interrupt-parent = <&pfic>; + interrupts = <12>; + }; + }; +}; diff --git a/modules/hal_wch/CMakeLists.txt b/modules/hal_wch/CMakeLists.txt index 822f83b867b..ad16ad6c62b 100644 --- a/modules/hal_wch/CMakeLists.txt +++ b/modules/hal_wch/CMakeLists.txt @@ -1,3 +1,3 @@ -if(CONFIG_SOC_CH32V003) +if(CONFIG_SOC_CH32V003 OR CONFIG_SOC_SERIES_QINGKE_V4C) zephyr_include_directories(${ZEPHYR_HAL_WCH_MODULE_DIR}/ch32v003fun .) endif() diff --git a/modules/hal_wch/ch32fun.h b/modules/hal_wch/ch32fun.h index b239ed5f61b..555bcd3e75b 100644 --- a/modules/hal_wch/ch32fun.h +++ b/modules/hal_wch/ch32fun.h @@ -12,4 +12,9 @@ #include #endif +#if defined(CONFIG_SOC_SERIES_QINGKE_V4C) +#define CH32V20x 1 +#include +#endif + #endif diff --git a/soc/wch/ch32v/qingke_v4c/CMakeLists.txt b/soc/wch/ch32v/qingke_v4c/CMakeLists.txt new file mode 100644 index 00000000000..a7e9de643d6 --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Michael Hope +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + soc_irq.S + vector.S +) + +zephyr_include_directories(.) diff --git a/soc/wch/ch32v/qingke_v4c/Kconfig b/soc/wch/ch32v/qingke_v4c/Kconfig new file mode 100644 index 00000000000..732a7d8a9ec --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_QINGKE_V4C + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI diff --git a/soc/wch/ch32v/qingke_v4c/Kconfig.defconfig b/soc/wch/ch32v/qingke_v4c/Kconfig.defconfig new file mode 100644 index 00000000000..a782adfdfd2 --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/Kconfig.defconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_QINGKE_V4C + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +config MAIN_STACK_SIZE + default 512 + +config IDLE_STACK_SIZE + default 256 + +config ISR_STACK_SIZE + default 256 + +config CLOCK_CONTROL + default y + +rsource "Kconfig.defconfig.*" + +endif # SOC_SERIES_QINGKE_V4C diff --git a/soc/wch/ch32v/qingke_v4c/Kconfig.defconfig.ch32v208 b/soc/wch/ch32v/qingke_v4c/Kconfig.defconfig.ch32v208 new file mode 100644 index 00000000000..f7b4b3fe1ec --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/Kconfig.defconfig.ch32v208 @@ -0,0 +1,12 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +if SOC_CH32V208 + +config VECTOR_TABLE_SIZE + default 103 + +config NUM_IRQS + default 128 + +endif # SOC_CH32V208 diff --git a/soc/wch/ch32v/qingke_v4c/Kconfig.soc b/soc/wch/ch32v/qingke_v4c/Kconfig.soc new file mode 100644 index 00000000000..33ffd7e3f21 --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/Kconfig.soc @@ -0,0 +1,11 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_QINGKE_V4C + bool + select SOC_FAMILY_CH32V + +config SOC_SERIES + default "qingke_v4c" if SOC_SERIES_QINGKE_V4C + +rsource "Kconfig.soc.*" diff --git a/soc/wch/ch32v/qingke_v4c/Kconfig.soc.ch32v208 b/soc/wch/ch32v/qingke_v4c/Kconfig.soc.ch32v208 new file mode 100644 index 00000000000..8baa7d35833 --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/Kconfig.soc.ch32v208 @@ -0,0 +1,9 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config SOC_CH32V208 + bool + select SOC_SERIES_QINGKE_V4C + +config SOC + default "ch32v208" if SOC_CH32V208 diff --git a/soc/wch/ch32v/qingke_v4c/pinctrl_soc.h b/soc/wch/ch32v/qingke_v4c/pinctrl_soc.h new file mode 100644 index 00000000000..a448d447b3a --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/pinctrl_soc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __PINCTRL_SOC_H__ +#define __PINCTRL_SOC_H__ + +/** + * @brief Type to hold a pin's pinctrl configuration. + */ +struct ch32v208_pinctrl_soc_pin { + uint32_t config: 22; + bool bias_pull_up: 1; + bool bias_pull_down: 1; + bool drive_open_drain: 1; + bool drive_push_pull: 1; + bool output_high: 1; + bool output_low: 1; + uint8_t slew_rate: 2; +}; + +typedef struct ch32v208_pinctrl_soc_pin pinctrl_soc_pin_t; + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .config = DT_PROP_BY_IDX(node_id, prop, idx), \ + .bias_pull_up = DT_PROP(node_id, bias_pull_up), \ + .bias_pull_down = DT_PROP(node_id, bias_pull_down), \ + .drive_open_drain = DT_PROP(node_id, drive_open_drain), \ + .drive_push_pull = DT_PROP(node_id, drive_push_pull), \ + .output_high = DT_PROP(node_id, output_high), \ + .output_low = DT_PROP(node_id, output_low), \ + .slew_rate = DT_ENUM_IDX(node_id, slew_rate), \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +#endif diff --git a/soc/wch/ch32v/qingke_v4c/soc_irq.S b/soc/wch/ch32v/qingke_v4c/soc_irq.S new file mode 100644 index 00000000000..fcb0daea51d --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/soc_irq.S @@ -0,0 +1,19 @@ +/* Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* Exports */ +GTEXT(__soc_is_irq) +GTEXT(__soc_handle_irq) + +SECTION_FUNC(exception.other, __soc_is_irq) + csrr a0, mcause + srli a0, a0, 31 + ret + +SECTION_FUNC(exception.other, __soc_handle_irq) + ret diff --git a/soc/wch/ch32v/qingke_v4c/vector.S b/soc/wch/ch32v/qingke_v4c/vector.S new file mode 100644 index 00000000000..d078444d85e --- /dev/null +++ b/soc/wch/ch32v/qingke_v4c/vector.S @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Michael Hope + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#ifndef CONFIG_VECTOR_TABLE_SIZE +#error "VECTOR_TABLE_SIZE must be defined" +#endif + +/* Exports */ +GTEXT(__start) + +/* Imports */ +GTEXT(__initialize) + +SECTION_FUNC(vectors, ivt) + .option norvc + j __start + .rept CONFIG_VECTOR_TABLE_SIZE + .word _isr_wrapper + .endr + +SECTION_FUNC(vectors, __start) + li a0, 3 + csrw mtvec, a0 + j __initialize diff --git a/soc/wch/ch32v/soc.yml b/soc/wch/ch32v/soc.yml index c01905a7ed7..a019651b5dc 100644 --- a/soc/wch/ch32v/soc.yml +++ b/soc/wch/ch32v/soc.yml @@ -7,3 +7,6 @@ family: - name: qingke-v2 socs: - name: ch32v003 + - name: qingke-v4c + socs: + - name: ch32v208