Compare commits
12 commits
9740ee6282
...
f30b21aa21
Author | SHA1 | Date | |
---|---|---|---|
f30b21aa21 | |||
9ba0ccf52d | |||
81080a1ce1 | |||
2ab7d4317a | |||
bb64ab5f90 | |||
f8bc6df2be | |||
f52a0135d8 | |||
2af384ddfb | |||
5f14e9385d | |||
5c3c784846 | |||
233f93aa24 | |||
|
155bcc0385 |
80 changed files with 2086 additions and 0 deletions
|
@ -4871,6 +4871,14 @@ West:
|
|||
labels:
|
||||
- "platform: TI"
|
||||
|
||||
"West project: hal_wch":
|
||||
status: maintained
|
||||
maintainers:
|
||||
- nzmichaelh
|
||||
- kholia
|
||||
files:
|
||||
- modules/hal_wch/
|
||||
|
||||
"West project: hal_wurthelektronik":
|
||||
status: maintained
|
||||
maintainers:
|
||||
|
|
5
boards/common/minichlink.board.cmake
Normal file
5
boards/common/minichlink.board.cmake
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) 2024 Dhiru Kholia
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board_set_flasher_ifnset(minichlink)
|
||||
board_finalize_runner_args(minichlink)
|
5
boards/wch/ch32v003evt/Kconfig.ch32v003evt
Normal file
5
boards/wch/ch32v003evt/Kconfig.ch32v003evt
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_CH32V003EVT
|
||||
select SOC_CH32V003
|
8
boards/wch/ch32v003evt/board.cmake
Normal file
8
boards/wch/ch32v003evt/board.cmake
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board_runner_args(openocd "--use-elf" "--cmd-reset-halt" "halt")
|
||||
include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake)
|
||||
|
||||
board_runner_args(minichlink)
|
||||
include(${ZEPHYR_BASE}/boards/common/minichlink.board.cmake)
|
6
boards/wch/ch32v003evt/board.yml
Normal file
6
boards/wch/ch32v003evt/board.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
board:
|
||||
name: ch32v003evt
|
||||
full_name: WCH CH32V003EVT
|
||||
vendor: wch
|
||||
socs:
|
||||
- name: ch32v003
|
21
boards/wch/ch32v003evt/ch32v003evt-pinctrl.dtsi
Normal file
21
boards/wch/ch32v003evt/ch32v003evt-pinctrl.dtsi
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope <michaelh@juju.nz>
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h>
|
||||
|
||||
&pinctrl {
|
||||
usart1_default: usart1_default {
|
||||
group1 {
|
||||
pinmux = <USART1_TX_PD5_0>;
|
||||
output-high;
|
||||
drive-push-pull;
|
||||
slew-rate = "max-speed-10mhz";
|
||||
};
|
||||
group2 {
|
||||
pinmux = <USART1_RX_PD6_0>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
58
boards/wch/ch32v003evt/ch32v003evt.dts
Normal file
58
boards/wch/ch32v003evt/ch32v003evt.dts
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope <michaelh@juju.nz>
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <wch/ch32v00x.dtsi>
|
||||
#include "ch32v003evt-pinctrl.dtsi"
|
||||
|
||||
/ {
|
||||
model = "ch32v003evt";
|
||||
compatible = "wch,ch32v003";
|
||||
|
||||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &usart1;
|
||||
zephyr,shell-uart = &usart1;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
red_led: led0 {
|
||||
gpios = <&gpiod 4 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
led0 = &red_led;
|
||||
};
|
||||
};
|
||||
|
||||
&clk_hse {
|
||||
clock-frequency = <DT_FREQ_M(24)>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pll {
|
||||
clocks = <&clk_hse>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&rcc {
|
||||
clocks = <&pll>;
|
||||
};
|
||||
|
||||
&gpiod {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usart1 {
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
pinctrl-0 = <&usart1_default>;
|
||||
pinctrl-names = "default";
|
||||
};
|
11
boards/wch/ch32v003evt/ch32v003evt.yaml
Normal file
11
boards/wch/ch32v003evt/ch32v003evt.yaml
Normal file
|
@ -0,0 +1,11 @@
|
|||
identifier: ch32v003evt
|
||||
name: WCH CH32V003 Evaluation Board
|
||||
type: mcu
|
||||
arch: riscv
|
||||
toolchain:
|
||||
- cross-compile
|
||||
- zephyr
|
||||
ram: 2
|
||||
flash: 16
|
||||
supported:
|
||||
- gpio
|
8
boards/wch/ch32v003evt/ch32v003evt_defconfig
Normal file
8
boards/wch/ch32v003evt/ch32v003evt_defconfig
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_MAIN_STACK_SIZE=512
|
||||
|
||||
CONFIG_IDLE_STACK_SIZE=256
|
||||
|
||||
CONFIG_ISR_STACK_SIZE=256
|
BIN
boards/wch/ch32v003evt/doc/img/ch32v003evt.webp
Normal file
BIN
boards/wch/ch32v003evt/doc/img/ch32v003evt.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
107
boards/wch/ch32v003evt/doc/index.rst
Normal file
107
boards/wch/ch32v003evt/doc/index.rst
Normal file
|
@ -0,0 +1,107 @@
|
|||
.. zephyr:board:: ch32v003evt
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
The `WCH`_ CH32V003EVT hardware provides support for QingKe 32-bit RISC-V2A
|
||||
processor and the following devices:
|
||||
|
||||
* CLOCK
|
||||
* :abbr:`GPIO (General Purpose Input Output)`
|
||||
* :abbr:`NVIC (Nested Vectored Interrupt Controller)`
|
||||
|
||||
The board is equipped with two LEDs. The `WCH webpage on CH32V003`_ contains
|
||||
the processor's information and the datasheet.
|
||||
|
||||
Hardware
|
||||
********
|
||||
|
||||
The QingKe 32-bit RISC-V2A processor of the WCH CH32V003EVT is clocked by an
|
||||
external crystal and runs at 48 MHz.
|
||||
|
||||
Supported Features
|
||||
==================
|
||||
|
||||
The ``ch32v003evt`` board target supports the following hardware features:
|
||||
|
||||
+-----------+------------+----------------------+
|
||||
| Interface | Controller | Driver/Component |
|
||||
+===========+============+======================+
|
||||
| CLOCK | on-chip | clock_control |
|
||||
+-----------+------------+----------------------+
|
||||
| GPIO | on-chip | gpio |
|
||||
+-----------+------------+----------------------+
|
||||
| PWM | on-chip | pwm |
|
||||
+-----------+------------+----------------------+
|
||||
| PINCTRL | on-chip | pinctrl |
|
||||
+-----------+------------+----------------------+
|
||||
| TIMER | on-chip | timer |
|
||||
+-----------+------------+----------------------+
|
||||
| UART | on-chip | uart |
|
||||
+-----------+------------+----------------------+
|
||||
|
||||
Other hardware features have not been enabled yet for this board.
|
||||
|
||||
Connections and IOs
|
||||
===================
|
||||
|
||||
LED
|
||||
---
|
||||
|
||||
* LED1 = Unconnected. Connect to an I/O pin (PD4).
|
||||
|
||||
Programming and Debugging
|
||||
*************************
|
||||
|
||||
Applications for the ``ch32v003evt`` board target can be built and flashed
|
||||
in the usual way (see :ref:`build_an_application` and :ref:`application_run`
|
||||
for more details); however, an external programmer is required since the board
|
||||
does not have any built-in debug support.
|
||||
|
||||
The following pins of the external programmer must be connected to the
|
||||
following pins on the PCB (see image):
|
||||
|
||||
* VCC = VCC (do not power the board from the USB port at the same time)
|
||||
* GND = GND
|
||||
* SWIO = PD1
|
||||
|
||||
Flashing
|
||||
========
|
||||
|
||||
You can use ``minichlink`` to flash the board. Once ``minichlink`` has been set
|
||||
up, build and flash applications as usual (see :ref:`build_an_application` and
|
||||
:ref:`application_run` for more details).
|
||||
|
||||
Here is an example for the :zephyr:code-sample:`blinky` application.
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/basic/blinky
|
||||
:board: ch32v003evt
|
||||
:goals: build flash
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
This board can be debugged via OpenOCD or ``minichlink``.
|
||||
|
||||
Testing the LED on the WCH CH32V003EVT
|
||||
**************************************
|
||||
|
||||
There is 1 sample program that allow you to test that the LED on the board is
|
||||
working properly with Zephyr:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
samples/basic/blinky
|
||||
|
||||
You can build and flash the examples to make sure Zephyr is running
|
||||
correctly on your board. The button and LED definitions can be found
|
||||
in :zephyr_file:`boards/wch/ch32v003evt/ch32v003evt.dts`.
|
||||
|
||||
References
|
||||
**********
|
||||
|
||||
.. target-notes::
|
||||
|
||||
.. _WCH: http://www.wch-ic.com
|
||||
.. _WCH webpage on CH32V003: https://www.wch-ic.com/products/CH32V003.html
|
15
boards/wch/ch32v003evt/support/openocd.cfg
Normal file
15
boards/wch/ch32v003evt/support/openocd.cfg
Normal file
|
@ -0,0 +1,15 @@
|
|||
#interface wlink
|
||||
adapter driver wlink
|
||||
wlink_set
|
||||
set _CHIPNAME riscv
|
||||
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
|
||||
target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME
|
||||
$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
|
||||
set _FLASHNAME $_CHIPNAME.flash
|
||||
|
||||
flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0
|
||||
|
||||
echo "Ready for Remote Connections"
|
10
boards/wch/index.rst
Normal file
10
boards/wch/index.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
.. _boards-wch:
|
||||
|
||||
WCH - Nanjing Qinheng Microelectronics Co.
|
||||
##########################################
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
**/*
|
|
@ -98,3 +98,4 @@ endif()
|
|||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AST10X0 clock_control_ast10x0.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MAX32 clock_control_max32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_AUXPLL clock_control_nrf_auxpll.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_WCH_RCC clock_control_wch_rcc.c)
|
||||
|
|
|
@ -100,4 +100,6 @@ source "drivers/clock_control/Kconfig.arm_scmi"
|
|||
|
||||
source "drivers/clock_control/Kconfig.silabs"
|
||||
|
||||
source "drivers/clock_control/Kconfig.wch_rcc"
|
||||
|
||||
endif # CLOCK_CONTROL
|
||||
|
|
7
drivers/clock_control/Kconfig.wch_rcc
Normal file
7
drivers/clock_control/Kconfig.wch_rcc
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config CLOCK_CONTROL_WCH_RCC
|
||||
bool "WCH CH32V00x Reset and Clock Control (RCC) driver"
|
||||
default y
|
||||
depends on DT_HAS_WCH_RCC_ENABLED
|
154
drivers/clock_control/clock_control_wch_rcc.c
Normal file
154
drivers/clock_control/clock_control_wch_rcc.c
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT wch_rcc
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
||||
#include <ch32_rcc.h>
|
||||
|
||||
#define WCH_RCC_CLOCK_ID_OFFSET(id) (((id) >> 5) & 0xFF)
|
||||
#define WCH_RCC_CLOCK_ID_BIT(id) ((id) & 0x1F)
|
||||
|
||||
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll)) && DT_NODE_HAS_PROP(DT_NODELABEL(pll), clocks)
|
||||
#define DT_PLL_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(pll))
|
||||
#if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(clk_hsi))
|
||||
#define WCH_RCC_PLL_SRC_IS_HSI 1
|
||||
#endif
|
||||
#if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(clk_hse))
|
||||
#define WCH_RCC_PLL_SRC_IS_HSE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DT_RCC_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(rcc))
|
||||
#if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(pll))
|
||||
#define WCH_RCC_SRC_IS_PLL 1
|
||||
#endif
|
||||
#if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_hsi))
|
||||
#define WCH_RCC_SRC_IS_HSI 1
|
||||
#endif
|
||||
#if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_hse))
|
||||
#define WCH_RCC_SRC_IS_HSE 1
|
||||
#endif
|
||||
|
||||
struct clock_control_wch_rcc_config {
|
||||
RCC_TypeDef *regs;
|
||||
};
|
||||
|
||||
static int clock_control_wch_rcc_on(const struct device *dev, clock_control_subsys_t sys)
|
||||
{
|
||||
const struct clock_control_wch_rcc_config *config = dev->config;
|
||||
RCC_TypeDef *regs = config->regs;
|
||||
uint8_t id = (uintptr_t)sys;
|
||||
uint32_t reg = (uint32_t)(®s->AHBPCENR + WCH_RCC_CLOCK_ID_OFFSET(id));
|
||||
uint32_t val = sys_read32(reg);
|
||||
|
||||
reg |= BIT(WCH_RCC_CLOCK_ID_BIT(id));
|
||||
sys_write32(val, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clock_control_wch_rcc_get_rate(const struct device *dev, clock_control_subsys_t sys,
|
||||
uint32_t *rate)
|
||||
{
|
||||
const struct clock_control_wch_rcc_config *config = dev->config;
|
||||
RCC_TypeDef *regs = config->regs;
|
||||
uint32_t cfgr0 = regs->CFGR0;
|
||||
uint32_t sysclk = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
|
||||
uint32_t ahbclk = sysclk;
|
||||
|
||||
if ((cfgr0 & RCC_HPRE_3) != 0) {
|
||||
/* The range 0b1000 divides by a power of 2, where 0b1000 is /2, 0b1001 is /4, etc.
|
||||
*/
|
||||
ahbclk /= 2 << ((cfgr0 >> 4) & 0x07);
|
||||
} else {
|
||||
/* The range 0b0nnn divides by n + 1, where 0b0000 is /1, 0b001 is /2, etc. */
|
||||
ahbclk /= ((cfgr0 >> 4) & 0x07) + 1;
|
||||
}
|
||||
|
||||
/* The datasheet says that AHB == APB1 == APB2, but the registers imply that APB1 and APB2
|
||||
* can be divided from the AHB clock. Assume that the clock tree diagram is correct and
|
||||
* always return AHB.
|
||||
*/
|
||||
*rate = ahbclk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_control_driver_api clock_control_wch_rcc_api = {
|
||||
.on = clock_control_wch_rcc_on,
|
||||
.get_rate = clock_control_wch_rcc_get_rate,
|
||||
};
|
||||
|
||||
static int clock_control_wch_rcc_init(const struct device *dev)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_DT_HAS_WCH_CH32V00X_PLL_CLOCK_ENABLED)) {
|
||||
/* Disable the PLL before potentially changing the input clocks. */
|
||||
RCC->CTLR &= ~RCC_PLLON;
|
||||
}
|
||||
|
||||
/* Always enable the LSI. */
|
||||
RCC->RSTSCKR |= RCC_LSION;
|
||||
while ((RCC->RSTSCKR & RCC_LSIRDY) == 0) {
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DT_HAS_WCH_CH32V00X_HSI_CLOCK_ENABLED)) {
|
||||
RCC->CTLR |= RCC_HSION;
|
||||
while ((RCC->CTLR & RCC_HSIRDY) == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DT_HAS_WCH_CH32V00X_HSE_CLOCK_ENABLED)) {
|
||||
RCC->CTLR |= RCC_HSEON;
|
||||
while ((RCC->CTLR & RCC_HSERDY) == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DT_HAS_WCH_CH32V00X_PLL_CLOCK_ENABLED)) {
|
||||
if (IS_ENABLED(WCH_RCC_PLL_SRC_IS_HSE)) {
|
||||
RCC->CFGR0 |= RCC_PLLSRC;
|
||||
} else if (IS_ENABLED(WCH_RCC_PLL_SRC_IS_HSI)) {
|
||||
RCC->CFGR0 &= ~RCC_PLLSRC;
|
||||
}
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
while ((RCC->CTLR & RCC_PLLRDY) == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(WCH_RCC_SRC_IS_HSI)) {
|
||||
RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_HSI;
|
||||
} else if (IS_ENABLED(WCH_RCC_SRC_IS_HSE)) {
|
||||
RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_HSE;
|
||||
} else if (IS_ENABLED(WCH_RCC_SRC_IS_PLL)) {
|
||||
RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_PLL;
|
||||
}
|
||||
RCC->CTLR |= RCC_CSSON;
|
||||
|
||||
/* Clear the interrupt flags. */
|
||||
RCC->INTR = RCC_CSSC | RCC_PLLRDYC | RCC_HSERDYC | RCC_LSIRDYC;
|
||||
/* HCLK = SYSCLK = APB1 */
|
||||
RCC->CFGR0 = (RCC->CFGR0 & ~RCC_HPRE) | RCC_HPRE_DIV1;
|
||||
/* Set the Flash to 0 wait state */
|
||||
FLASH->ACTLR = (FLASH->ACTLR & ~FLASH_ACTLR_LATENCY) | FLASH_ACTLR_LATENCY_1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CLOCK_CONTROL_WCH_RCC_INIT(idx) \
|
||||
static const struct clock_control_wch_rcc_config clock_control_wch_rcc_##idx##_config = { \
|
||||
.regs = (RCC_TypeDef *)DT_INST_REG_ADDR(idx), \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(idx, clock_control_wch_rcc_init, NULL, NULL, \
|
||||
&clock_control_wch_rcc_##idx##_config, PRE_KERNEL_1, \
|
||||
CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &clock_control_wch_rcc_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(CLOCK_CONTROL_WCH_RCC_INIT)
|
|
@ -94,6 +94,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_TCA6424A gpio_tca6424a.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_GPIO_TELINK_B91 gpio_b91.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_TEST gpio_test.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_TLE9104 gpio_tle9104.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_WCH_GPIO wch_gpio_ch32v00x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_XEC gpio_mchp_xec.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_XEC_V2 gpio_mchp_xec_v2.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_XLNX_AXI gpio_xlnx_axi.c)
|
||||
|
|
|
@ -178,6 +178,7 @@ source "drivers/gpio/Kconfig.sx1509b"
|
|||
source "drivers/gpio/Kconfig.tca6424a"
|
||||
source "drivers/gpio/Kconfig.test"
|
||||
source "drivers/gpio/Kconfig.tle9104"
|
||||
source "drivers/gpio/Kconfig.wch_ch32v00x"
|
||||
source "drivers/gpio/Kconfig.xec"
|
||||
source "drivers/gpio/Kconfig.xlnx"
|
||||
source "drivers/gpio/Kconfig.xlnx_ps"
|
||||
|
|
7
drivers/gpio/Kconfig.wch_ch32v00x
Normal file
7
drivers/gpio/Kconfig.wch_ch32v00x
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config GPIO_WCH_GPIO
|
||||
bool "WCH CH32V00x GPIO driver"
|
||||
depends on DT_HAS_WCH_GPIO_ENABLED
|
||||
default y
|
144
drivers/gpio/wch_gpio_ch32v00x.c
Normal file
144
drivers/gpio/wch_gpio_ch32v00x.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/gpio/gpio_utils.h>
|
||||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||
#include <zephyr/irq.h>
|
||||
|
||||
#include <ch32_gpio.h>
|
||||
|
||||
#define DT_DRV_COMPAT wch_gpio
|
||||
|
||||
struct gpio_ch32v00x_config {
|
||||
struct gpio_driver_config common;
|
||||
GPIO_TypeDef *regs;
|
||||
const struct device *clock_dev;
|
||||
uint8_t clock_id;
|
||||
};
|
||||
|
||||
struct gpio_ch32v00x_data {
|
||||
struct gpio_driver_data common;
|
||||
};
|
||||
|
||||
static int gpio_ch32v00x_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
|
||||
{
|
||||
const struct gpio_ch32v00x_config *config = dev->config;
|
||||
GPIO_TypeDef *regs = config->regs;
|
||||
uint32_t cnf_mode;
|
||||
uint32_t bshr = 0;
|
||||
|
||||
if ((flags & GPIO_OUTPUT) != 0) {
|
||||
cnf_mode = 0x01;
|
||||
if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
|
||||
bshr = 1 << pin;
|
||||
} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
|
||||
bshr = 1 << (16 + pin);
|
||||
}
|
||||
} else if ((flags & GPIO_INPUT) != 0) {
|
||||
if ((flags & GPIO_PULL_UP) != 0) {
|
||||
cnf_mode = 0x08;
|
||||
bshr = 1 << pin;
|
||||
} else if ((flags & GPIO_PULL_DOWN) != 0) {
|
||||
cnf_mode = 0x08;
|
||||
bshr = 1 << (16 + pin);
|
||||
} else {
|
||||
cnf_mode = 0x04;
|
||||
}
|
||||
} else {
|
||||
cnf_mode = 0x00;
|
||||
}
|
||||
|
||||
regs->CFGLR = (regs->CFGLR & ~(0x0F << (4 * pin))) | (cnf_mode << (4 * pin));
|
||||
regs->BSHR = bshr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_ch32v00x_port_get_raw(const struct device *dev, uint32_t *value)
|
||||
{
|
||||
const struct gpio_ch32v00x_config *config = dev->config;
|
||||
|
||||
*value = config->regs->INDR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_ch32v00x_port_set_masked_raw(const struct device *dev, uint32_t mask,
|
||||
uint32_t value)
|
||||
{
|
||||
const struct gpio_ch32v00x_config *config = dev->config;
|
||||
|
||||
config->regs->BSHR = ((~value & mask) << 16) | (value & mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_ch32v00x_port_set_bits_raw(const struct device *dev, uint32_t pins)
|
||||
{
|
||||
const struct gpio_ch32v00x_config *config = dev->config;
|
||||
|
||||
config->regs->BSHR = pins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_ch32v00x_port_clear_bits_raw(const struct device *dev, uint32_t pins)
|
||||
{
|
||||
const struct gpio_ch32v00x_config *config = dev->config;
|
||||
|
||||
config->regs->BCR = pins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_ch32v00x_port_toggle_bits(const struct device *dev, uint32_t pins)
|
||||
{
|
||||
const struct gpio_ch32v00x_config *config = dev->config;
|
||||
uint32_t changed = (config->regs->OUTDR ^ pins) & pins;
|
||||
|
||||
config->regs->BSHR = (changed & pins) | (~changed & pins) << 16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct gpio_driver_api gpio_ch32v00x_driver_api = {
|
||||
.pin_configure = gpio_ch32v00x_configure,
|
||||
.port_get_raw = gpio_ch32v00x_port_get_raw,
|
||||
.port_set_masked_raw = gpio_ch32v00x_port_set_masked_raw,
|
||||
.port_set_bits_raw = gpio_ch32v00x_port_set_bits_raw,
|
||||
.port_clear_bits_raw = gpio_ch32v00x_port_clear_bits_raw,
|
||||
.port_toggle_bits = gpio_ch32v00x_port_toggle_bits,
|
||||
};
|
||||
|
||||
static int gpio_ch32v00x_init(const struct device *dev)
|
||||
{
|
||||
const struct gpio_ch32v00x_config *config = dev->config;
|
||||
|
||||
clock_control_on(config->clock_dev, (clock_control_subsys_t *)(uintptr_t)config->clock_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GPIO_CH32V00X_INIT(idx) \
|
||||
static const struct gpio_ch32v00x_config gpio_ch32v00x_##idx##_config = { \
|
||||
.common = \
|
||||
{ \
|
||||
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(idx), \
|
||||
}, \
|
||||
.regs = (GPIO_TypeDef *)DT_INST_REG_ADDR(idx), \
|
||||
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \
|
||||
.clock_id = DT_INST_CLOCKS_CELL(idx, id), \
|
||||
}; \
|
||||
\
|
||||
static struct gpio_ch32v00x_data gpio_ch32v00x_##idx##_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(idx, gpio_ch32v00x_init, NULL, &gpio_ch32v00x_##idx##_data, \
|
||||
&gpio_ch32v00x_##idx##_config, PRE_KERNEL_1, \
|
||||
CONFIG_GPIO_INIT_PRIORITY, &gpio_ch32v00x_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(GPIO_CH32V00X_INIT)
|
|
@ -43,6 +43,7 @@ zephyr_library_sources_ifdef(CONFIG_NXP_PINT intc_nxp_pint.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_ICU intc_renesas_ra_icu.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NXP_IRQSTEER intc_nxp_irqsteer.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_INTC_MTK_ADSP intc_mtk_adsp.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_WCH_PFIC intc_wch_pfic.c)
|
||||
|
||||
if(CONFIG_INTEL_VTD_ICTL)
|
||||
zephyr_library_include_directories(${ZEPHYR_BASE}/arch/x86/include)
|
||||
|
|
|
@ -108,4 +108,6 @@ source "drivers/interrupt_controller/Kconfig.nxp_irqsteer"
|
|||
|
||||
source "drivers/interrupt_controller/Kconfig.mtk_adsp"
|
||||
|
||||
source "drivers/interrupt_controller/Kconfig.wch_pfic"
|
||||
|
||||
endmenu
|
||||
|
|
9
drivers/interrupt_controller/Kconfig.wch_pfic
Normal file
9
drivers/interrupt_controller/Kconfig.wch_pfic
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config WCH_PFIC
|
||||
bool "WCH Programmable Fast Interrupt Controller (PFIC)"
|
||||
default y
|
||||
depends on DT_HAS_WCH_PFIC_ENABLED
|
||||
help
|
||||
Interrupt controller for WCH PFIC.
|
43
drivers/interrupt_controller/intc_wch_pfic.c
Normal file
43
drivers/interrupt_controller/intc_wch_pfic.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT wch_pfic
|
||||
|
||||
#include <ch32_pfic.h>
|
||||
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/irq.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#define SEVONPEND (1 << 4)
|
||||
#define WFITOWFE (1 << 3)
|
||||
|
||||
void arch_irq_enable(unsigned int irq)
|
||||
{
|
||||
PFIC->IENR[irq / 32] = 1 << (irq % 32);
|
||||
}
|
||||
|
||||
void arch_irq_disable(unsigned int irq)
|
||||
{
|
||||
PFIC->IRER[irq / 32] |= 1 << (irq % 32);
|
||||
}
|
||||
|
||||
int arch_irq_is_enabled(unsigned int irq)
|
||||
{
|
||||
return ((PFIC->ISR[irq >> 5] & (1 << (irq & 0x1F))) != 0);
|
||||
}
|
||||
|
||||
static int pfic_init(void)
|
||||
{
|
||||
/* `wfi` is called with interrupts disabled. Configure the PFIC to wake up on any event,
|
||||
* including any interrupt.
|
||||
*/
|
||||
PFIC->SCTLR = SEVONPEND | WFITOWFE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(pfic_init, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY);
|
|
@ -40,5 +40,6 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_MAX32 pinctrl_max32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCMI pinctrl_imx_scmi.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_MEC5 pinctrl_mchp_mec5.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_AFIO pinctrl_wch_afio.c)
|
||||
|
||||
add_subdirectory(renesas)
|
||||
|
|
|
@ -67,6 +67,7 @@ source "drivers/pinctrl/Kconfig.ene"
|
|||
source "drivers/pinctrl/Kconfig.zynqmp"
|
||||
source "drivers/pinctrl/Kconfig.max32"
|
||||
source "drivers/pinctrl/Kconfig.mec5"
|
||||
source "drivers/pinctrl/Kconfig.wch_afio"
|
||||
|
||||
rsource "renesas/Kconfig"
|
||||
|
||||
|
|
9
drivers/pinctrl/Kconfig.wch_afio
Normal file
9
drivers/pinctrl/Kconfig.wch_afio
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config PINCTRL_WCH_AFIO
|
||||
bool "WCH AFIO pin controller driver"
|
||||
default y
|
||||
depends on DT_HAS_WCH_AFIO_ENABLED
|
||||
help
|
||||
WCH AFIO pin controller driver.
|
75
drivers/pinctrl/pinctrl_wch_afio.c
Normal file
75
drivers/pinctrl/pinctrl_wch_afio.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h>
|
||||
|
||||
#include <ch32_pinctrl.h>
|
||||
|
||||
static GPIO_TypeDef *const wch_afio_pinctrl_regs[] = {
|
||||
GPIOA,
|
||||
GPIOC,
|
||||
GPIOD,
|
||||
};
|
||||
|
||||
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pin_cnt; i++, pins++) {
|
||||
uint8_t port = (pins->config >> CH32V003_PINCTRL_PORT_SHIFT) & 0x03;
|
||||
uint8_t pin = (pins->config >> CH32V003_PINCTRL_PIN_SHIFT) & 0x0F;
|
||||
uint8_t bit0 = (pins->config >> CH32V003_PINCTRL_RM_BASE_SHIFT) & 0x1F;
|
||||
uint8_t remap = (pins->config >> CH32V003_PINCTRL_RM_SHIFT) & 0x3;
|
||||
GPIO_TypeDef *regs = wch_afio_pinctrl_regs[port];
|
||||
uint32_t pcfr1 = AFIO->PCFR1;
|
||||
uint8_t cfg = 0;
|
||||
|
||||
if (pins->output_high || pins->output_low) {
|
||||
cfg |= (pins->slew_rate + 1);
|
||||
if (pins->drive_open_drain) {
|
||||
cfg |= BIT(2);
|
||||
}
|
||||
/* Select the alternate function */
|
||||
cfg |= BIT(3);
|
||||
} else {
|
||||
if (pins->bias_pull_up || pins->bias_pull_down) {
|
||||
cfg |= BIT(3);
|
||||
}
|
||||
}
|
||||
regs->CFGLR = (regs->CFGLR & ~(0x0F << (pin * 4))) | (cfg << (pin * 4));
|
||||
|
||||
if (pins->output_high) {
|
||||
regs->OUTDR |= BIT(pin);
|
||||
regs->BSHR |= BIT(pin);
|
||||
} else if (pins->output_low) {
|
||||
regs->OUTDR |= BIT(pin);
|
||||
/* Reset the pin. */
|
||||
regs->BSHR |= BIT(pin + 16);
|
||||
} else {
|
||||
regs->OUTDR &= ~(1 << pin);
|
||||
if (pins->bias_pull_up) {
|
||||
regs->BSHR = BIT(pin);
|
||||
}
|
||||
if (pins->bias_pull_down) {
|
||||
regs->BCR = BIT(pin);
|
||||
}
|
||||
}
|
||||
|
||||
if (bit0 == CH32V003_PINMUX_I2C1_RM) {
|
||||
pcfr1 |= ((remap & 1) << CH32V003_PINMUX_I2C1_RM) |
|
||||
(((remap >> 1) & 1) << CH32V003_PINMUX_I2C1_RM1);
|
||||
} else if (bit0 == CH32V003_PINMUX_USART1_RM) {
|
||||
pcfr1 |= ((remap & 1) << CH32V003_PINMUX_USART1_RM) |
|
||||
(((remap >> 1) & 1) << CH32V003_PINMUX_USART1_RM1);
|
||||
} else {
|
||||
pcfr1 |= remap << bit0;
|
||||
}
|
||||
AFIO->PCFR1 = pcfr1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -46,6 +46,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_NXP_S32_EMIOS pwm_nxp_s32_emios.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_PWM_ENE_KB1200 pwm_ene_kb1200.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RA8 pwm_renesas_ra8.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PWM_INFINEON_CAT1 pwm_ifx_cat1.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PWM_WCH_GPTM pwm_wch_gptm.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_USERSPACE pwm_handlers.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_PWM_CAPTURE pwm_capture.c)
|
||||
|
|
|
@ -112,4 +112,6 @@ source "drivers/pwm/Kconfig.renesas_ra8"
|
|||
|
||||
source "drivers/pwm/Kconfig.ifx_cat1"
|
||||
|
||||
source "drivers/pwm/Kconfig.ch32v00x"
|
||||
|
||||
endif # PWM
|
||||
|
|
10
drivers/pwm/Kconfig.ch32v00x
Normal file
10
drivers/pwm/Kconfig.ch32v00x
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2024 Google LLC.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config PWM_WCH_GPTM
|
||||
bool "WCH General-purpose Timer (GPTM)"
|
||||
default y
|
||||
depends on DT_HAS_WCH_GPTM_ENABLED
|
||||
select PINCTRL
|
||||
help
|
||||
PWM driver WCH CH32V00x GPTM such as TIM2 on the CH32V003
|
131
drivers/pwm/pwm_wch_gptm.c
Normal file
131
drivers/pwm/pwm_wch_gptm.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Google LLC.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT wch_gptm
|
||||
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/drivers/pwm.h>
|
||||
#include <zephyr/dt-bindings/pwm/pwm.h>
|
||||
|
||||
#include <ch32_gptm.h>
|
||||
|
||||
struct pwm_wch_gptm_config {
|
||||
TIM_TypeDef *regs;
|
||||
const struct device *clock_dev;
|
||||
uint8_t clock_id;
|
||||
uint16_t prescaler;
|
||||
const struct pinctrl_dev_config *pin_cfg;
|
||||
};
|
||||
|
||||
static int pwm_wch_gptm_set_cycles(const struct device *dev, uint32_t channel,
|
||||
uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags)
|
||||
{
|
||||
const struct pwm_wch_gptm_config *config = dev->config;
|
||||
TIM_TypeDef *regs = config->regs;
|
||||
uint16_t ocxm;
|
||||
|
||||
if (period_cycles > UINT16_MAX) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (period_cycles == 0) {
|
||||
/* Force the output to 'invalid' */
|
||||
ocxm = 0x04;
|
||||
} else {
|
||||
/* PWM mode 1 */
|
||||
ocxm = 0x06;
|
||||
}
|
||||
|
||||
switch (channel) {
|
||||
case 1:
|
||||
regs->CH1CVR = pulse_cycles;
|
||||
regs->CHCTLR1 = (regs->CHCTLR1 & ~TIM_OC1M) | (ocxm * TIM_OC1M_0);
|
||||
break;
|
||||
case 2:
|
||||
regs->CH2CVR = pulse_cycles;
|
||||
regs->CHCTLR1 = (regs->CHCTLR1 & ~TIM_OC2M) | (ocxm * TIM_OC2M_0);
|
||||
break;
|
||||
case 3:
|
||||
regs->CH3CVR = pulse_cycles;
|
||||
regs->CHCTLR2 = (regs->CHCTLR2 & ~TIM_OC3M) | (ocxm * TIM_OC3M_0);
|
||||
break;
|
||||
case 4:
|
||||
regs->CH4CVR = pulse_cycles;
|
||||
regs->CHCTLR2 = (regs->CHCTLR2 & ~TIM_OC4M) | (ocxm * TIM_OC4M_0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regs->ATRLR = period_cycles;
|
||||
// regs->CCER = TIM_CC4E;
|
||||
// return 0;
|
||||
|
||||
/* Set the polarity and enable */
|
||||
uint16_t shift = 4 * (channel - 1);
|
||||
if ((flags & PWM_POLARITY_INVERTED) != 0U) {
|
||||
regs->CCER = TIM_CC1E << shift;
|
||||
// regs->CCER = (regs->CCER & ~(0x0F << shift) | (TIM_CC1E << shift);
|
||||
} else {
|
||||
regs->CCER = (TIM_CC1P | TIM_CC1E) << shift;
|
||||
// regs->CCER = regs->CCER | (TIM_CC1P << shift) | (TIM_CC1E << shift);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pwm_wch_gptm_get_cycles_per_sec(const struct device *dev, uint32_t channel,
|
||||
uint64_t *cycles)
|
||||
{
|
||||
const struct pwm_wch_gptm_config *config = dev->config;
|
||||
|
||||
/* APB1 is connected to SYSCLK */
|
||||
*cycles = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / (config->prescaler + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_driver_api pwm_wch_gptm_driver_api = {
|
||||
.set_cycles = pwm_wch_gptm_set_cycles,
|
||||
.get_cycles_per_sec = pwm_wch_gptm_get_cycles_per_sec,
|
||||
};
|
||||
|
||||
static int pwm_wch_gptm_init(const struct device *dev)
|
||||
{
|
||||
const struct pwm_wch_gptm_config *config = dev->config;
|
||||
TIM_TypeDef *regs = config->regs;
|
||||
int err;
|
||||
|
||||
clock_control_on(config->clock_dev, (clock_control_subsys_t *)(uintptr_t)config->clock_id);
|
||||
|
||||
err = pinctrl_apply_state(config->pin_cfg, PINCTRL_STATE_DEFAULT);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Disable and configure the counter */
|
||||
regs->CTLR1 = TIM_ARPE & ~TIM_CEN;
|
||||
regs->PSC = config->prescaler;
|
||||
|
||||
regs->CTLR1 |= TIM_CEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PWM_WCH_GPTM_INIT(idx) \
|
||||
PINCTRL_DT_INST_DEFINE(idx); \
|
||||
static const struct pwm_wch_gptm_config pwm_wch_gptm_##idx##_config = { \
|
||||
.regs = (TIM_TypeDef *)DT_INST_REG_ADDR(idx), \
|
||||
.prescaler = DT_INST_PROP(idx, prescaler) - 1, \
|
||||
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \
|
||||
.clock_id = DT_INST_CLOCKS_CELL(idx, id), \
|
||||
.pin_cfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(idx, &pwm_wch_gptm_init, NULL, NULL, &pwm_wch_gptm_##idx##_config, \
|
||||
POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, &pwm_wch_gptm_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(PWM_WCH_GPTM_INIT)
|
|
@ -73,6 +73,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_STELLARIS uart_stellaris.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_UART_STM32 uart_stm32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UART_SY1XX uart_sy1xx.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UART_TELINK_B91 uart_b91.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UART_WCH_USART uart_wch_usart.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UART_XEC uart_mchp_xec.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UART_XEN_HVC uart_hvc_xen.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UART_XEN_HVC_CONSOLEIO uart_hvc_xen_consoleio.c)
|
||||
|
|
|
@ -221,4 +221,6 @@ rsource "Kconfig.xmc4xxx"
|
|||
|
||||
source "drivers/serial/Kconfig.si32"
|
||||
|
||||
source "drivers/serial/Kconfig.wch_usart"
|
||||
|
||||
endif # SERIAL
|
||||
|
|
11
drivers/serial/Kconfig.wch_usart
Normal file
11
drivers/serial/Kconfig.wch_usart
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Copyright (c) 2024 Google LLC.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config UART_WCH_USART
|
||||
bool "CH32V00x USART driver"
|
||||
default y
|
||||
depends on DT_HAS_WCH_USART_ENABLED
|
||||
select SERIAL_HAS_DRIVER
|
||||
select PINCTRL
|
||||
help
|
||||
This option enables the USART driver for CH32V00x SoC family.
|
140
drivers/serial/uart_wch_usart.c
Normal file
140
drivers/serial/uart_wch_usart.c
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Google LLC.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT wch_usart
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
|
||||
#include <ch32_uart.h>
|
||||
|
||||
struct usart_wch_config {
|
||||
USART_TypeDef *regs;
|
||||
const struct device *clock_dev;
|
||||
uint32_t current_speed;
|
||||
uint8_t parity;
|
||||
uint8_t clock_id;
|
||||
const struct pinctrl_dev_config *pin_cfg;
|
||||
};
|
||||
|
||||
struct usart_wch_data {
|
||||
};
|
||||
|
||||
static int usart_wch_init(const struct device *dev)
|
||||
{
|
||||
const struct usart_wch_config *config = dev->config;
|
||||
USART_TypeDef *regs = config->regs;
|
||||
uint32_t ctlr1 = USART_CTLR1_TE | USART_CTLR1_RE | USART_CTLR1_UE;
|
||||
uint32_t clock_rate;
|
||||
clock_control_subsys_t clock_sys = (clock_control_subsys_t *)(uintptr_t)config->clock_id;
|
||||
uint32_t divn;
|
||||
int err;
|
||||
|
||||
clock_control_on(config->clock_dev, clock_sys);
|
||||
|
||||
err = clock_control_get_rate(config->clock_dev, clock_sys, &clock_rate);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
divn = (clock_rate + config->current_speed / 2) / config->current_speed;
|
||||
|
||||
switch (config->parity) {
|
||||
case UART_CFG_PARITY_NONE:
|
||||
break;
|
||||
case UART_CFG_PARITY_ODD:
|
||||
ctlr1 |= USART_CTLR1_PCE | USART_CTLR1_PS;
|
||||
break;
|
||||
case UART_CFG_PARITY_EVEN:
|
||||
ctlr1 |= USART_CTLR1_PCE;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regs->BRR = divn;
|
||||
regs->CTLR1 = ctlr1;
|
||||
regs->CTLR2 = 0;
|
||||
regs->CTLR3 = 0;
|
||||
|
||||
err = pinctrl_apply_state(config->pin_cfg, PINCTRL_STATE_DEFAULT);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usart_wch_poll_in(const struct device *dev, unsigned char *ch)
|
||||
{
|
||||
const struct usart_wch_config *config = dev->config;
|
||||
USART_TypeDef *regs = config->regs;
|
||||
|
||||
if ((regs->STATR & USART_STATR_RXNE) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ch = regs->DATAR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usart_wch_poll_out(const struct device *dev, unsigned char ch)
|
||||
{
|
||||
const struct usart_wch_config *config = dev->config;
|
||||
USART_TypeDef *regs = config->regs;
|
||||
|
||||
while ((regs->STATR & USART_STATR_TXE) == 0) {
|
||||
}
|
||||
|
||||
regs->DATAR = ch;
|
||||
}
|
||||
|
||||
static int usart_wch_err_check(const struct device *dev)
|
||||
{
|
||||
const struct usart_wch_config *config = dev->config;
|
||||
USART_TypeDef *regs = config->regs;
|
||||
uint32_t statr = regs->STATR;
|
||||
enum uart_rx_stop_reason errors = 0;
|
||||
|
||||
if ((statr & USART_STATR_PE) != 0) {
|
||||
errors |= UART_ERROR_PARITY;
|
||||
}
|
||||
if ((statr & USART_STATR_FE) != 0) {
|
||||
errors |= UART_ERROR_FRAMING;
|
||||
}
|
||||
if ((statr & USART_STATR_NE) != 0) {
|
||||
errors |= UART_ERROR_NOISE;
|
||||
}
|
||||
if ((statr & USART_STATR_ORE) != 0) {
|
||||
errors |= UART_ERROR_OVERRUN;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
static const struct uart_driver_api usart_wch_driver_api = {
|
||||
.poll_in = usart_wch_poll_in,
|
||||
.poll_out = usart_wch_poll_out,
|
||||
.err_check = usart_wch_err_check,
|
||||
};
|
||||
|
||||
#define USART_WCH_INIT(idx) \
|
||||
PINCTRL_DT_INST_DEFINE(idx); \
|
||||
static struct usart_wch_data usart_wch_##idx##_data; \
|
||||
static const struct usart_wch_config usart_wch_##idx##_config = { \
|
||||
.regs = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \
|
||||
.current_speed = DT_INST_PROP(idx, current_speed), \
|
||||
.parity = DT_INST_ENUM_IDX_OR(idx, parity, UART_CFG_PARITY_NONE), \
|
||||
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \
|
||||
.clock_id = DT_INST_CLOCKS_CELL(idx, id), \
|
||||
.pin_cfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(idx, &usart_wch_init, NULL, &usart_wch_##idx##_data, \
|
||||
&usart_wch_##idx##_config, PRE_KERNEL_1, \
|
||||
CONFIG_SERIAL_INIT_PRIORITY, &usart_wch_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(USART_WCH_INIT)
|
|
@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_ARCV2_TIMER arcv2_timer0.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_ARM_ARCH_TIMER arm_arch_timer.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_TIMER intel_adsp_timer.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CC13XX_CC26XX_RTC_TIMER cc13xx_cc26xx_rtc_timer.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CH32V00X_SYSTICK wch_systick_ch32v00x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CORTEX_M_SYSTICK cortex_m_systick.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ESP32_SYS_TIMER esp32_sys_timer.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GECKO_BURTC_TIMER gecko_burtc_timer.c)
|
||||
|
|
|
@ -70,6 +70,7 @@ source "drivers/timer/Kconfig.arcv2"
|
|||
source "drivers/timer/Kconfig.arm_arch"
|
||||
source "drivers/timer/Kconfig.cavs"
|
||||
source "drivers/timer/Kconfig.cc13xx_cc26xx_rtc"
|
||||
source "drivers/timer/Kconfig.wch_ch32v00x"
|
||||
source "drivers/timer/Kconfig.cortex_m_systick"
|
||||
source "drivers/timer/Kconfig.esp32"
|
||||
source "drivers/timer/Kconfig.gecko"
|
||||
|
|
8
drivers/timer/Kconfig.wch_ch32v00x
Normal file
8
drivers/timer/Kconfig.wch_ch32v00x
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config CH32V00X_SYSTICK
|
||||
bool "CH32V00X systick timer"
|
||||
depends on SOC_CH32V003
|
||||
default y
|
||||
depends on DT_HAS_WCH_SYSTICK_ENABLED
|
69
drivers/timer/wch_systick_ch32v00x.c
Normal file
69
drivers/timer/wch_systick_ch32v00x.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT wch_systick
|
||||
|
||||
#include <soc.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/timer/system_timer.h>
|
||||
#include <zephyr/irq.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
#include <ch32_systick.h>
|
||||
|
||||
#define STK_SWIE BIT(31)
|
||||
#define STK_STRE BIT(3)
|
||||
#define STK_STCLK BIT(2)
|
||||
#define STK_STIE BIT(1)
|
||||
#define STK_STE BIT(0)
|
||||
|
||||
#define STK_CNTIF BIT(0)
|
||||
|
||||
#define CYCLES_PER_SEC sys_clock_hw_cycles_per_sec()
|
||||
#define CYCLES_PER_TICK (CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
|
||||
|
||||
#define SYSTICK ((SysTick_Type *)(DT_INST_REG_ADDR(0)))
|
||||
|
||||
struct ch32v00x_systick_device {
|
||||
};
|
||||
|
||||
static volatile uint32_t ch32v00x_systick_count;
|
||||
|
||||
static void ch32v00x_systick_irq(const struct ch32v00x_systick_device *unused)
|
||||
{
|
||||
ARG_UNUSED(unused);
|
||||
|
||||
SYSTICK->SR = 0;
|
||||
ch32v00x_systick_count += CYCLES_PER_TICK; /* Track cycles. */
|
||||
sys_clock_announce(1); /* Poke the scheduler. */
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
return ch32v00x_systick_count + SYSTICK->CNT;
|
||||
}
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ch32v00x_systick_init(void)
|
||||
{
|
||||
IRQ_CONNECT(DT_INST_IRQN(0), 0, ch32v00x_systick_irq, NULL, 0);
|
||||
|
||||
SYSTICK->SR = 0;
|
||||
SYSTICK->CMP = CYCLES_PER_TICK;
|
||||
SYSTICK->CNT = 0;
|
||||
SYSTICK->CTLR = STK_STRE | STK_STCLK | STK_STIE | STK_STE;
|
||||
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(ch32v00x_systick_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
8
dts/bindings/clock/wch,ch32v00x-hse-clock.yaml
Normal file
8
dts/bindings/clock/wch,ch32v00x-hse-clock.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2024 Google LLC.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x HSE Clock
|
||||
|
||||
compatible: "wch,ch32v00x-hse-clock"
|
||||
|
||||
include: [fixed-clock.yaml]
|
8
dts/bindings/clock/wch,ch32v00x-hsi-clock.yaml
Normal file
8
dts/bindings/clock/wch,ch32v00x-hsi-clock.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2024 Google LLC.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x HSI Clock
|
||||
|
||||
compatible: "wch,ch32v00x-hsi-clock"
|
||||
|
||||
include: [fixed-clock.yaml]
|
16
dts/bindings/clock/wch,ch32v00x-pll-clock.yaml
Normal file
16
dts/bindings/clock/wch,ch32v00x-pll-clock.yaml
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Copyright (c) 2024 Google LLC.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x PLL
|
||||
|
||||
compatible: "wch,ch32v00x-pll-clock"
|
||||
|
||||
include: [clock-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
type: phandle-array
|
||||
required: true
|
15
dts/bindings/clock/wch,rcc.yaml
Normal file
15
dts/bindings/clock/wch,rcc.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x Reset and Clock Control (RCC)
|
||||
|
||||
compatible: "wch,rcc"
|
||||
|
||||
include: [clock-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
clock-cells:
|
||||
- id
|
19
dts/bindings/gpio/wch,gpio.yaml
Normal file
19
dts/bindings/gpio/wch,gpio.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x General-Purpose Input/Output (GPIO)
|
||||
|
||||
compatible: "wch,gpio"
|
||||
|
||||
include: [gpio-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
gpio-cells:
|
||||
- pin
|
||||
- flags
|
18
dts/bindings/interrupt-controller/wch,pfic.yaml
Normal file
18
dts/bindings/interrupt-controller/wch,pfic.yaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x Programmable Fast Interrupt Controller (PFIC)
|
||||
|
||||
compatible: "wch,pfic"
|
||||
|
||||
include: [interrupt-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
interrupt-cells:
|
||||
- irq
|
52
dts/bindings/pinctrl/wch,afio.yaml
Normal file
52
dts/bindings/pinctrl/wch,afio.yaml
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x AFIO
|
||||
|
||||
compatible: "wch,afio"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
"#address-cells":
|
||||
required: true
|
||||
const: 1
|
||||
"#size-cells":
|
||||
required: true
|
||||
const: 1
|
||||
|
||||
child-binding:
|
||||
description: |
|
||||
Each child node defines the configuration for a particular state.
|
||||
child-binding:
|
||||
description: |
|
||||
The grandchild nodes group pins that share the same pin configuration.
|
||||
|
||||
include:
|
||||
- name: pincfg-node.yaml
|
||||
property-allowlist:
|
||||
- bias-high-impedance
|
||||
- bias-pull-up
|
||||
- bias-pull-down
|
||||
- drive-open-drain
|
||||
- drive-push-pull
|
||||
- output-high
|
||||
- output-low
|
||||
|
||||
properties:
|
||||
slew-rate:
|
||||
type: string
|
||||
default: "max-speed-2mhz"
|
||||
enum:
|
||||
- "max-speed-10mhz"
|
||||
- "max-speed-2mhz"
|
||||
- "max-speed-30mhz"
|
||||
|
||||
pinmux:
|
||||
required: true
|
||||
type: array
|
||||
description: |
|
||||
An array of pins sharing the same group properties. The pins should
|
||||
be defined using pre-defined macros.
|
22
dts/bindings/pwm/wch,gptm.yaml
Normal file
22
dts/bindings/pwm/wch,gptm.yaml
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) 2024 Google LLC.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH General-purpose Timer (GPTM)
|
||||
|
||||
compatible: "wch,gptm"
|
||||
|
||||
include: [base.yaml, pwm-controller.yaml, pinctrl-device.yaml]
|
||||
|
||||
properties:
|
||||
prescaler:
|
||||
type: int
|
||||
default: 1
|
||||
description: Counter prescaler (1 to 65536)
|
||||
|
||||
"#pwm-cells":
|
||||
const: 3
|
||||
|
||||
pwm-cells:
|
||||
- channel
|
||||
- period
|
||||
- flags
|
9
dts/bindings/serial/wch,usart.yaml
Normal file
9
dts/bindings/serial/wch,usart.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
description: WCH CH32V00x UART
|
||||
|
||||
compatible: "wch,usart"
|
||||
|
||||
include: [uart-controller.yaml, pinctrl-device.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
15
dts/bindings/timer/wch,systick.yaml
Normal file
15
dts/bindings/timer/wch,systick.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: WCH CH32V00x Systick
|
||||
|
||||
compatible: "wch,systick"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
interrupts:
|
||||
required: true
|
|
@ -722,6 +722,7 @@ vot Vision Optical Technology Co., Ltd.
|
|||
vxt VXT Ltd
|
||||
wand Wandbord (Technexion)
|
||||
waveshare Waveshare Electronics
|
||||
wch WinChipHead
|
||||
wd Western Digital Corp.
|
||||
we Würth Elektronik GmbH.
|
||||
weact WeAct Studio
|
||||
|
|
161
dts/riscv/wch/ch32v00x.dtsi
Normal file
161
dts/riscv/wch/ch32v00x.dtsi
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <freq.h>
|
||||
#include <mem.h>
|
||||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||
#include <zephyr/dt-bindings/i2c/i2c.h>
|
||||
#include <zephyr/dt-bindings/clock/ch32v00x-clocks.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "wch,qingke-v2";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
clk_hse: clk-hse {
|
||||
#clock-cells = <0>;
|
||||
compatible = "wch,ch32v00x-hse-clock";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
clk_hsi: clk-hsi {
|
||||
#clock-cells = <0>;
|
||||
compatible = "wch,ch32v00x-hsi-clock";
|
||||
clock-frequency = <DT_FREQ_M(24)>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
clk_lsi: clk-lsi {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <DT_FREQ_K(128)>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pll: pll {
|
||||
#clock-cells = <0>;
|
||||
compatible = "wch,ch32v00x-pll-clock";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
sram0: memory@20000000 {
|
||||
compatible = "mmio-sram";
|
||||
reg = <0x20000000 0x800>;
|
||||
};
|
||||
|
||||
flash: flash-controller@40022000 {
|
||||
compatible = "wch,ch32v00x-flash-controller";
|
||||
reg = <0x40022000 0x400>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
flash0: flash@0 {
|
||||
compatible = "soc-nv-flash";
|
||||
reg = <0 0x4000>;
|
||||
};
|
||||
};
|
||||
|
||||
pfic: interrupt-controller@e000e000 {
|
||||
compatible = "wch,pfic";
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
reg = <0xe000e000 16>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
systick: systimer@e000f000 {
|
||||
compatible = "wch,systick";
|
||||
reg = <0xe000f000 16>;
|
||||
status = "okay";
|
||||
interrupt-parent = <&pfic>;
|
||||
interrupts = <12>;
|
||||
};
|
||||
|
||||
tim2: counter@40000000 {
|
||||
compatible = "wch,gptm";
|
||||
reg = <0x40000000 16>;
|
||||
pwm-controller;
|
||||
#pwm-cells = <3>;
|
||||
prescaler = <1>;
|
||||
clocks = <&rcc CH32V00X_CLOCK_TIM2>;
|
||||
};
|
||||
|
||||
pwr: pwr@40007000 {
|
||||
compatible = "wch,pwr";
|
||||
reg = <0x40007000 16>;
|
||||
};
|
||||
|
||||
pinctrl: pin-controller@40010000 {
|
||||
compatible = "wch,afio";
|
||||
reg = <0x40010000 16>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
status = "okay";
|
||||
|
||||
gpioa: gpio@40010800 {
|
||||
compatible = "wch,gpio";
|
||||
reg = <0x40010800 32>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <8>;
|
||||
clocks = <&rcc CH32V00X_CLOCK_IOPA>;
|
||||
};
|
||||
|
||||
gpioc: gpio@40011000 {
|
||||
compatible = "wch,gpio";
|
||||
reg = <0x40011000 32>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <8>;
|
||||
clocks = <&rcc CH32V00X_CLOCK_IOPC>;
|
||||
};
|
||||
|
||||
gpiod: gpio@40011400 {
|
||||
compatible = "wch,gpio";
|
||||
reg = <0x40011400 32>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <8>;
|
||||
clocks = <&rcc CH32V00X_CLOCK_IOPD>;
|
||||
};
|
||||
};
|
||||
|
||||
usart1: uart@40013800 {
|
||||
compatible = "wch,usart";
|
||||
reg = <0x40013800 16>;
|
||||
clocks = <&rcc CH32V00X_CLOCK_USART1>;
|
||||
interrupt-parent = <&pfic>;
|
||||
interrupts = <32>;
|
||||
};
|
||||
|
||||
rcc: rcc@40021000 {
|
||||
compatible = "wch,rcc";
|
||||
reg = <0x40021000 16>;
|
||||
#clock-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
42
include/zephyr/dt-bindings/clock/ch32v00x-clocks.h
Normal file
42
include/zephyr/dt-bindings/clock/ch32v00x-clocks.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __CH32V00X_CLOCKS_H__
|
||||
#define __CH32V00X_CLOCKS_H__
|
||||
|
||||
#define CH32V00X_AHB_PCENR_OFFSET 0
|
||||
#define CH32V00X_APB2_PCENR_OFFSET 1
|
||||
#define CH32V00X_APB1_PCENR_OFFSET 2
|
||||
|
||||
#define CH32V00X_CLOCK_CONFIG(bus, bit) (((CH32V00X_##bus##_PCENR_OFFSET) << 5) | (bit))
|
||||
|
||||
#define CH32V00X_CLOCK_DMA1 CH32V00X_CLOCK_CONFIG(AHB, 0)
|
||||
#define CH32V00X_CLOCK_SRAM CH32V00X_CLOCK_CONFIG(AHB, 2)
|
||||
#define CH32V00X_CLOCK_FLITF CH32V00X_CLOCK_CONFIG(AHB, 4)
|
||||
#define CH32V00X_CLOCK_CRC CH32V00X_CLOCK_CONFIG(AHB, 6)
|
||||
#define CH32V00X_CLOCK_USB CH32V00X_CLOCK_CONFIG(AHB, 12)
|
||||
|
||||
#define CH32V00X_CLOCK_AFIO CH32V00X_CLOCK_CONFIG(APB2, 0)
|
||||
#define CH32V00X_CLOCK_IOPA CH32V00X_CLOCK_CONFIG(APB2, 2)
|
||||
#define CH32V00X_CLOCK_IOPB CH32V00X_CLOCK_CONFIG(APB2, 3)
|
||||
#define CH32V00X_CLOCK_IOPC CH32V00X_CLOCK_CONFIG(APB2, 4)
|
||||
#define CH32V00X_CLOCK_IOPD CH32V00X_CLOCK_CONFIG(APB2, 5)
|
||||
#define CH32V00X_CLOCK_ADC1 CH32V00X_CLOCK_CONFIG(APB2, 9)
|
||||
#define CH32V00X_CLOCK_ADC2 CH32V00X_CLOCK_CONFIG(APB2, 10)
|
||||
#define CH32V00X_CLOCK_TIM1 CH32V00X_CLOCK_CONFIG(APB2, 11)
|
||||
#define CH32V00X_CLOCK_SPI1 CH32V00X_CLOCK_CONFIG(APB2, 12)
|
||||
#define CH32V00X_CLOCK_USART1 CH32V00X_CLOCK_CONFIG(APB2, 14)
|
||||
|
||||
#define CH32V00X_CLOCK_TIM2 CH32V00X_CLOCK_CONFIG(APB1, 0)
|
||||
#define CH32V00X_CLOCK_TIM3 CH32V00X_CLOCK_CONFIG(APB1, 1)
|
||||
#define CH32V00X_CLOCK_WWDG CH32V00X_CLOCK_CONFIG(APB1, 11)
|
||||
#define CH32V00X_CLOCK_USART2 CH32V00X_CLOCK_CONFIG(APB1, 17)
|
||||
#define CH32V00X_CLOCK_I2C1 CH32V00X_CLOCK_CONFIG(APB1, 21)
|
||||
#define CH32V00X_CLOCK_BKP CH32V00X_CLOCK_CONFIG(APB1, 27)
|
||||
#define CH32V00X_CLOCK_PWR CH32V00X_CLOCK_CONFIG(APB1, 28)
|
||||
#define CH32V00X_CLOCK_USB CH32V00X_CLOCK_CONFIG(APB1, 23)
|
||||
|
||||
#endif
|
136
include/zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h
Normal file
136
include/zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __CH32V003_PINCTRL_H__
|
||||
#define __CH32V003_PINCTRL_H__
|
||||
|
||||
#define CH32V003_PINMUX_PORT_PA 0
|
||||
#define CH32V003_PINMUX_PORT_PC 1
|
||||
#define CH32V003_PINMUX_PORT_PD 2
|
||||
|
||||
/*
|
||||
* Defines the starting bit for the remap field. Note that the I2C1 and USART1 fields are not
|
||||
* contigious.
|
||||
*/
|
||||
#define CH32V003_PINMUX_SPI1_RM 0
|
||||
#define CH32V003_PINMUX_I2C1_RM 1
|
||||
#define CH32V003_PINMUX_I2C1_RM1 23
|
||||
#define CH32V003_PINMUX_USART1_RM 2
|
||||
#define CH32V003_PINMUX_USART1_RM1 21
|
||||
#define CH32V003_PINMUX_TIM1_RM 6
|
||||
#define CH32V003_PINMUX_TIM2_RM 8
|
||||
|
||||
/* Port number with 0-2 */
|
||||
#define CH32V003_PINCTRL_PORT_SHIFT 0
|
||||
/* Pin number 0-15 */
|
||||
#define CH32V003_PINCTRL_PIN_SHIFT 2
|
||||
/* Base remap bit 0-31 */
|
||||
#define CH32V003_PINCTRL_RM_BASE_SHIFT 6
|
||||
/* Function remapping ID 0-3 */
|
||||
#define CH32V003_PINCTRL_RM_SHIFT 11
|
||||
|
||||
#define CH32V003_PINMUX_DEFINE(port, pin, rm, remapping) \
|
||||
((CH32V003_PINMUX_PORT_##port << CH32V003_PINCTRL_PORT_SHIFT) | \
|
||||
(pin << CH32V003_PINCTRL_PIN_SHIFT) | \
|
||||
(CH32V003_PINMUX_##rm##_RM << CH32V003_PINCTRL_RM_BASE_SHIFT) | \
|
||||
(remapping << CH32V003_PINCTRL_RM_SHIFT))
|
||||
|
||||
#define TIM1_ETR_PC5_0 CH32V003_PINMUX_DEFINE(PC, 5, TIM1, 0)
|
||||
#define TIM1_ETR_PC5_1 CH32V003_PINMUX_DEFINE(PC, 5, TIM1, 1)
|
||||
#define TIM1_ETR_PD4_2 CH32V003_PINMUX_DEFINE(PD, 4, TIM1, 2)
|
||||
#define TIM1_ETR_PC2_3 CH32V003_PINMUX_DEFINE(PC, 2, TIM1, 3)
|
||||
#define TIM1_CH1_PD2_0 CH32V003_PINMUX_DEFINE(PD, 2, TIM1, 0)
|
||||
#define TIM1_CH1_PC6_1 CH32V003_PINMUX_DEFINE(PC, 6, TIM1, 1)
|
||||
#define TIM1_CH1_PD2_2 CH32V003_PINMUX_DEFINE(PD, 2, TIM1, 2)
|
||||
#define TIM1_CH1_PC4_3 CH32V003_PINMUX_DEFINE(PC, 4, TIM1, 3)
|
||||
#define TIM1_CH2_PA1_0 CH32V003_PINMUX_DEFINE(PA, 1, TIM1, 0)
|
||||
#define TIM1_CH2_PC7_1 CH32V003_PINMUX_DEFINE(PC, 7, TIM1, 1)
|
||||
#define TIM1_CH2_PA1_2 CH32V003_PINMUX_DEFINE(PA, 1, TIM1, 2)
|
||||
#define TIM1_CH2_PC7_3 CH32V003_PINMUX_DEFINE(PC, 7, TIM1, 3)
|
||||
#define TIM1_CH3_PC3_0 CH32V003_PINMUX_DEFINE(PC, 3, TIM1, 0)
|
||||
#define TIM1_CH3_PC0_1 CH32V003_PINMUX_DEFINE(PC, 0, TIM1, 1)
|
||||
#define TIM1_CH3_PC3_2 CH32V003_PINMUX_DEFINE(PC, 3, TIM1, 2)
|
||||
#define TIM1_CH3_PC5_3 CH32V003_PINMUX_DEFINE(PC, 5, TIM1, 3)
|
||||
#define TIM1_CH4_PC4_0 CH32V003_PINMUX_DEFINE(PC, 4, TIM1, 0)
|
||||
#define TIM1_CH4_PD3_1 CH32V003_PINMUX_DEFINE(PD, 3, TIM1, 1)
|
||||
#define TIM1_CH4_PC4_2 CH32V003_PINMUX_DEFINE(PC, 4, TIM1, 2)
|
||||
#define TIM1_CH4_PD4_3 CH32V003_PINMUX_DEFINE(PD, 4, TIM1, 3)
|
||||
#define TIM1_BKIN_PC2_0 CH32V003_PINMUX_DEFINE(PC, 2, TIM1, 0)
|
||||
#define TIM1_BKIN_PC1_1 CH32V003_PINMUX_DEFINE(PC, 1, TIM1, 1)
|
||||
#define TIM1_BKIN_PC2_2 CH32V003_PINMUX_DEFINE(PC, 2, TIM1, 2)
|
||||
#define TIM1_BKIN_PC1_3 CH32V003_PINMUX_DEFINE(PC, 1, TIM1, 3)
|
||||
#define TIM1_CH1N_PD0_0 CH32V003_PINMUX_DEFINE(PD, 0, TIM1, 0)
|
||||
#define TIM1_CH1N_PC3_1 CH32V003_PINMUX_DEFINE(PC, 3, TIM1, 1)
|
||||
#define TIM1_CH1N_PD0_2 CH32V003_PINMUX_DEFINE(PD, 0, TIM1, 2)
|
||||
#define TIM1_CH1N_PC3_3 CH32V003_PINMUX_DEFINE(PC, 3, TIM1, 3)
|
||||
#define TIM1_CH2N_PA2_0 CH32V003_PINMUX_DEFINE(PA, 2, TIM1, 0)
|
||||
#define TIM1_CH2N_PC4_1 CH32V003_PINMUX_DEFINE(PC, 4, TIM1, 1)
|
||||
#define TIM1_CH2N_PA2_2 CH32V003_PINMUX_DEFINE(PA, 2, TIM1, 2)
|
||||
#define TIM1_CH2N_PD2_3 CH32V003_PINMUX_DEFINE(PD, 2, TIM1, 3)
|
||||
#define TIM1_CH3N_PD1_0 CH32V003_PINMUX_DEFINE(PD, 1, TIM1, 0)
|
||||
#define TIM1_CH3N_PD1_1 CH32V003_PINMUX_DEFINE(PD, 1, TIM1, 1)
|
||||
#define TIM1_CH3N_PD1_2 CH32V003_PINMUX_DEFINE(PD, 1, TIM1, 2)
|
||||
#define TIM1_CH3N_PC6_3 CH32V003_PINMUX_DEFINE(PC, 6, TIM1, 3)
|
||||
|
||||
#define TIM2_ETR_PD4_0 CH32V003_PINMUX_DEFINE(PD, 4, TIM2, 0)
|
||||
#define TIM2_ETR_PC5_1 CH32V003_PINMUX_DEFINE(PC, 5, TIM2, 1)
|
||||
#define TIM2_ETR_PC1_2 CH32V003_PINMUX_DEFINE(PC, 1, TIM2, 2)
|
||||
#define TIM2_ETR_PC1_3 CH32V003_PINMUX_DEFINE(PC, 1, TIM2, 3)
|
||||
#define TIM2_CH1_PD4_0 CH32V003_PINMUX_DEFINE(PD, 4, TIM2, 0)
|
||||
#define TIM2_CH1_PC5_1 CH32V003_PINMUX_DEFINE(PC, 5, TIM2, 1)
|
||||
#define TIM2_CH1_PC1_2 CH32V003_PINMUX_DEFINE(PC, 1, TIM2, 2)
|
||||
#define TIM2_CH1_PC1_3 CH32V003_PINMUX_DEFINE(PC, 1, TIM2, 3)
|
||||
#define TIM2_CH2_PD3_0 CH32V003_PINMUX_DEFINE(PD, 3, TIM2, 0)
|
||||
#define TIM2_CH2_PC2_1 CH32V003_PINMUX_DEFINE(PC, 2, TIM2, 1)
|
||||
#define TIM2_CH2_PD3_2 CH32V003_PINMUX_DEFINE(PD, 3, TIM2, 2)
|
||||
#define TIM2_CH2_PC7_3 CH32V003_PINMUX_DEFINE(PC, 7, TIM2, 3)
|
||||
#define TIM2_CH3_PC0_0 CH32V003_PINMUX_DEFINE(PC, 0, TIM2, 0)
|
||||
#define TIM2_CH3_PD2_1 CH32V003_PINMUX_DEFINE(PD, 2, TIM2, 1)
|
||||
#define TIM2_CH3_PC0_2 CH32V003_PINMUX_DEFINE(PC, 0, TIM2, 2)
|
||||
#define TIM2_CH3_PD6_3 CH32V003_PINMUX_DEFINE(PD, 6, TIM2, 3)
|
||||
#define TIM2_CH4_PD7_0 CH32V003_PINMUX_DEFINE(PD, 7, TIM2, 0)
|
||||
#define TIM2_CH4_PC1_1 CH32V003_PINMUX_DEFINE(PC, 1, TIM2, 1)
|
||||
#define TIM2_CH4_PD7_2 CH32V003_PINMUX_DEFINE(PD, 7, TIM2, 2)
|
||||
#define TIM2_CH4_PD5_3 CH32V003_PINMUX_DEFINE(PD, 5, TIM2, 3)
|
||||
|
||||
#define USART1_CK_PD4_0 CH32V003_PINMUX_DEFINE(PD, 4, USART1, 0)
|
||||
#define USART1_CK_PD7_1 CH32V003_PINMUX_DEFINE(PD, 7, USART1, 1)
|
||||
#define USART1_CK_PD7_2 CH32V003_PINMUX_DEFINE(PD, 7, USART1, 2)
|
||||
#define USART1_CK_PC5_3 CH32V003_PINMUX_DEFINE(PC, 5, USART1, 3)
|
||||
#define USART1_TX_PD5_0 CH32V003_PINMUX_DEFINE(PD, 5, USART1, 0)
|
||||
#define USART1_TX_PD0_1 CH32V003_PINMUX_DEFINE(PD, 0, USART1, 1)
|
||||
#define USART1_TX_PD6_2 CH32V003_PINMUX_DEFINE(PD, 6, USART1, 2)
|
||||
#define USART1_TX_PC0_3 CH32V003_PINMUX_DEFINE(PC, 0, USART1, 3)
|
||||
#define USART1_RX_PD6_0 CH32V003_PINMUX_DEFINE(PD, 6, USART1, 0)
|
||||
#define USART1_RX_PD1_1 CH32V003_PINMUX_DEFINE(PD, 1, USART1, 1)
|
||||
#define USART1_RX_PD5_2 CH32V003_PINMUX_DEFINE(PD, 5, USART1, 2)
|
||||
#define USART1_RX_PC1_3 CH32V003_PINMUX_DEFINE(PC, 1, USART1, 3)
|
||||
#define USART1_CTS_PD3_0 CH32V003_PINMUX_DEFINE(PD, 3, USART1, 0)
|
||||
#define USART1_CTS_PC3_1 CH32V003_PINMUX_DEFINE(PC, 3, USART1, 1)
|
||||
#define USART1_CTS_PC6_2 CH32V003_PINMUX_DEFINE(PC, 6, USART1, 2)
|
||||
#define USART1_CTS_PC6_3 CH32V003_PINMUX_DEFINE(PC, 6, USART1, 3)
|
||||
#define USART1_RTS_PC2_0 CH32V003_PINMUX_DEFINE(PC, 2, USART1, 0)
|
||||
#define USART1_RTS_PC2_1 CH32V003_PINMUX_DEFINE(PC, 2, USART1, 1)
|
||||
#define USART1_RTS_PC7_2 CH32V003_PINMUX_DEFINE(PC, 7, USART1, 2)
|
||||
#define USART1_RTS_PC7_3 CH32V003_PINMUX_DEFINE(PC, 7, USART1, 3)
|
||||
|
||||
#define SPI1_NSS_PC1_0 CH32V003_PINMUX_DEFINE(PC, 1, SPI1, 0)
|
||||
#define SPI1_NSS_PC0_1 CH32V003_PINMUX_DEFINE(PC, 0, SPI1, 1)
|
||||
#define SPI1_SCK_PC5_0 CH32V003_PINMUX_DEFINE(PC, 5, SPI1, 0)
|
||||
#define SPI1_SCK_PC5_1 CH32V003_PINMUX_DEFINE(PC, 5, SPI1, 1)
|
||||
#define SPI1_MISO_PC7_0 CH32V003_PINMUX_DEFINE(PC, 7, SPI1, 0)
|
||||
#define SPI1_MISO_PC7_1 CH32V003_PINMUX_DEFINE(PC, 7, SPI1, 1)
|
||||
#define SPI1_MOSI_PC6_0 CH32V003_PINMUX_DEFINE(PC, 6, SPI1, 0)
|
||||
#define SPI1_MOSI_PC6_1 CH32V003_PINMUX_DEFINE(PC, 6, SPI1, 1)
|
||||
|
||||
#define I2C1_SCL_PC2_0 CH32V003_PINMUX_DEFINE(PC, 2, I2C1, 0)
|
||||
#define I2C1_SCL_PD1_1 CH32V003_PINMUX_DEFINE(PD, 1, I2C1, 1)
|
||||
#define I2C1_SCL_PC5_2 CH32V003_PINMUX_DEFINE(PC, 5, I2C1, 2)
|
||||
#define I2C1_SDA_PC1_0 CH32V003_PINMUX_DEFINE(PC, 1, I2C1, 0)
|
||||
#define I2C1_SDA_PD0_1 CH32V003_PINMUX_DEFINE(PD, 0, I2C1, 1)
|
||||
#define I2C1_SDA_PC6_2 CH32V003_PINMUX_DEFINE(PC, 6, I2C1, 2)
|
||||
|
||||
#endif /* __CH32V003_PINCTRL_H__ */
|
3
modules/hal_wch/CMakeLists.txt
Normal file
3
modules/hal_wch/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
if(CONFIG_SOC_SERIES_CH32V00X)
|
||||
zephyr_include_directories(${ZEPHYR_HAL_WCH_MODULE_DIR}/ch32v003fun .)
|
||||
endif()
|
7
modules/hal_wch/Kconfig
Normal file
7
modules/hal_wch/Kconfig
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Copyright (c) 2024 Dhiru Kholia
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# file is empty and kept as a place holder if/when Kconfig is needed
|
16
modules/hal_wch/ch32_gpio.h
Normal file
16
modules/hal_wch/ch32_gpio.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_GPIO_H
|
||||
#define _CH32_GPIO_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
16
modules/hal_wch/ch32_gptm.h
Normal file
16
modules/hal_wch/ch32_gptm.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Google LLC.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_GPTM_H
|
||||
#define _CH32_GPTM_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
16
modules/hal_wch/ch32_pfic.h
Normal file
16
modules/hal_wch/ch32_pfic.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_PFIC_H
|
||||
#define _CH32_PFIC_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
16
modules/hal_wch/ch32_pinctrl.h
Normal file
16
modules/hal_wch/ch32_pinctrl.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_PINCTRL_H
|
||||
#define _CH32_PINCTRL_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
16
modules/hal_wch/ch32_rcc.h
Normal file
16
modules/hal_wch/ch32_rcc.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_RCC_H
|
||||
#define _CH32_RCC_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
16
modules/hal_wch/ch32_soc.h
Normal file
16
modules/hal_wch/ch32_soc.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_SOC_H
|
||||
#define _CH32_SOC_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
16
modules/hal_wch/ch32_systick.h
Normal file
16
modules/hal_wch/ch32_systick.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_SYSTICK_H
|
||||
#define _CH32_SYSTICK_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
16
modules/hal_wch/ch32_uart.h
Normal file
16
modules/hal_wch/ch32_uart.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _CH32_UART_H
|
||||
#define _CH32_UART_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#include <ch32v003fun.h>
|
||||
#else
|
||||
#error "SoC not supported!"
|
||||
#endif
|
||||
|
||||
#endif
|
14
modules/hal_wch/funconfig.h
Normal file
14
modules/hal_wch/funconfig.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Dhiru Kholia
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _FUNCONFIG_H
|
||||
#define _FUNCONFIG_H
|
||||
|
||||
#ifdef CONFIG_SOC_CH32V003
|
||||
#define CH32V003 1
|
||||
#endif
|
||||
|
||||
#endif
|
45
samples/basic/blinky_pwm/boards/ch32v003evt.overlay
Normal file
45
samples/basic/blinky_pwm/boards/ch32v003evt.overlay
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2021 Andrei-Edward Popa
|
||||
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <zephyr/dt-bindings/pwm/pwm.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/ch32v003-pinctrl.h>
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
pwm-0 = &tim2;
|
||||
pwm-led0 = &pwm_red_led;
|
||||
};
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
/* Remap 0 on PD4 */
|
||||
pwm_red_led: pwm_red_led_2 {
|
||||
pwms = <&tim2 0 1000 PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
tim2_default: tim2_default {
|
||||
group1 {
|
||||
pinmux = <TIM2_CH1_PD4_0>;
|
||||
//output-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&tim2 {
|
||||
pinctrl-0 = <&tim2_default>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
channel0@0 {
|
||||
reg = <0x0>;
|
||||
timer = <0>;
|
||||
};
|
||||
};
|
|
@ -40,6 +40,7 @@ _names = [
|
|||
'jlink',
|
||||
'linkserver',
|
||||
'mdb',
|
||||
'minichlink',
|
||||
'misc',
|
||||
'native',
|
||||
'nios2',
|
||||
|
|
95
scripts/west_commands/runners/minichlink.py
Normal file
95
scripts/west_commands/runners/minichlink.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
# Copyright (c) 2024 Google LLC.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
"""WCH CH32V00x specific runner."""
|
||||
|
||||
import argparse
|
||||
|
||||
from runners.core import ZephyrBinaryRunner, RunnerCaps, RunnerConfig
|
||||
|
||||
|
||||
class MiniChLinkBinaryRunner(ZephyrBinaryRunner):
|
||||
"""Runner for CH32V00x based devices using minichlink."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
cfg: RunnerConfig,
|
||||
minichlink: str,
|
||||
erase: bool,
|
||||
reset: bool,
|
||||
dt_flash: bool,
|
||||
terminal: bool,
|
||||
):
|
||||
super().__init__(cfg)
|
||||
|
||||
self.minichlink = minichlink
|
||||
self.erase = erase
|
||||
self.reset = reset
|
||||
self.dt_flash = dt_flash
|
||||
self.terminal = terminal
|
||||
|
||||
@classmethod
|
||||
def name(cls):
|
||||
return "minichlink"
|
||||
|
||||
@classmethod
|
||||
def capabilities(cls) -> RunnerCaps:
|
||||
return RunnerCaps(commands={"flash"}, flash_addr=True, erase=True, reset=True)
|
||||
|
||||
@classmethod
|
||||
def do_add_parser(cls, parser: argparse.ArgumentParser):
|
||||
parser.add_argument(
|
||||
"--minichlink", default="minichlink", help="path to the minichlink binary"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--terminal",
|
||||
default=False,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="open the terminal after flashing. Implies --reset.",
|
||||
)
|
||||
parser.set_defaults(reset=True)
|
||||
|
||||
@classmethod
|
||||
def do_create(cls, cfg: RunnerConfig, args: argparse.Namespace):
|
||||
return MiniChLinkBinaryRunner(
|
||||
cfg,
|
||||
minichlink=args.minichlink,
|
||||
erase=args.erase,
|
||||
reset=args.reset,
|
||||
dt_flash=(args.dt_flash == "y"),
|
||||
terminal=args.terminal,
|
||||
)
|
||||
|
||||
def do_run(self, command: str, **kwargs):
|
||||
self.require(self.minichlink)
|
||||
|
||||
if command == "flash":
|
||||
self.flash()
|
||||
else:
|
||||
raise ValueError("BUG: unhandled command f{command}")
|
||||
|
||||
def flash(self):
|
||||
self.ensure_output("bin")
|
||||
|
||||
cmd = [self.minichlink, "-a"]
|
||||
|
||||
if self.erase:
|
||||
cmd.append("-E")
|
||||
|
||||
flash_addr = 0
|
||||
if self.dt_flash:
|
||||
flash_addr = self.flash_address_from_build_conf(self.build_conf)
|
||||
|
||||
cmd.extend(["-w", self.cfg.bin_file or "", f"0x{flash_addr:x}"])
|
||||
|
||||
if self.reset or self.terminal:
|
||||
cmd.append("-b")
|
||||
|
||||
if self.terminal:
|
||||
cmd.append("-T")
|
||||
|
||||
if self.terminal:
|
||||
self.check_call(cmd)
|
||||
else:
|
||||
self.check_output(cmd)
|
|
@ -31,6 +31,7 @@ def test_runner_imports():
|
|||
'linkserver',
|
||||
'mdb-hw',
|
||||
'mdb-nsim',
|
||||
'minichlink',
|
||||
'misc-flasher',
|
||||
'native',
|
||||
'nios2',
|
||||
|
|
9
soc/wch/ch32v00x/CMakeLists.txt
Normal file
9
soc/wch/ch32v00x/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_sources(
|
||||
soc_irq.S
|
||||
vector.S
|
||||
)
|
||||
|
||||
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "")
|
13
soc/wch/ch32v00x/Kconfig
Normal file
13
soc/wch/ch32v00x/Kconfig
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SOC_CH32V003
|
||||
select RISCV
|
||||
select BUILD_OUTPUT_HEX
|
||||
select RISCV_ISA_RV32E
|
||||
select RISCV_ISA_EXT_ZICSR
|
||||
select RISCV_ISA_EXT_ZIFENCEI
|
||||
select RISCV_ISA_EXT_C
|
||||
select CH32V00X_SYSTICK
|
||||
select ATOMIC_OPERATIONS_C
|
||||
imply XIP
|
24
soc/wch/ch32v00x/Kconfig.defconfig
Normal file
24
soc/wch/ch32v00x/Kconfig.defconfig
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if SOC_CH32V003
|
||||
|
||||
config NUM_IRQS
|
||||
default 48
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default 48000000
|
||||
|
||||
config MAIN_STACK_SIZE
|
||||
default 512
|
||||
|
||||
config IDLE_STACK_SIZE
|
||||
default 256
|
||||
|
||||
config ISR_STACK_SIZE
|
||||
default 256
|
||||
|
||||
config CLOCK_CONTROL
|
||||
default y
|
||||
|
||||
endif # SOC_CH32V003
|
15
soc/wch/ch32v00x/Kconfig.soc
Normal file
15
soc/wch/ch32v00x/Kconfig.soc
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SOC_SERIES_CH32V00X
|
||||
bool
|
||||
|
||||
config SOC_CH32V003
|
||||
bool
|
||||
select SOC_SERIES_CH32V00X
|
||||
|
||||
config SOC_SERIES
|
||||
default "ch32v00x" if SOC_SERIES_CH32V00X
|
||||
|
||||
config SOC
|
||||
default "ch32v003" if SOC_CH32V003
|
42
soc/wch/ch32v00x/pinctrl_soc.h
Normal file
42
soc/wch/ch32v00x/pinctrl_soc.h
Normal file
|
@ -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 ch32v003_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 ch32v003_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
|
14
soc/wch/ch32v00x/soc.h
Normal file
14
soc/wch/ch32v00x/soc.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __SOC_H__
|
||||
#define __SOC_H__
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <zephyr/types.h>
|
||||
#endif /* !_ASMLANGUAGE */
|
||||
|
||||
#endif /* __SOC_H__ */
|
7
soc/wch/ch32v00x/soc.yml
Normal file
7
soc/wch/ch32v00x/soc.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright (c) 2024 Michael Hope
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
series:
|
||||
- name: ch32v00x
|
||||
socs:
|
||||
- name: ch32v003
|
19
soc/wch/ch32v00x/soc_irq.S
Normal file
19
soc/wch/ch32v00x/soc_irq.S
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <offsets.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
|
||||
/* 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
|
25
soc/wch/ch32v00x/vector.S
Normal file
25
soc/wch/ch32v00x/vector.S
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Michael Hope
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/toolchain.h>
|
||||
|
||||
/* Exports */
|
||||
GTEXT(__start)
|
||||
|
||||
/* Imports */
|
||||
GTEXT(__initialize)
|
||||
|
||||
SECTION_FUNC(vectors, ivt)
|
||||
.option norvc
|
||||
j __start
|
||||
.rept 38
|
||||
.word _isr_wrapper
|
||||
.endr
|
||||
|
||||
SECTION_FUNC(vectors, __start)
|
||||
li a0, 3
|
||||
csrw mtvec, a0
|
||||
j __initialize
|
5
west.yml
5
west.yml
|
@ -247,6 +247,11 @@ manifest:
|
|||
path: modules/hal/ti
|
||||
groups:
|
||||
- hal
|
||||
- name: hal_wch
|
||||
revision: 1de9d3e406726702ce7cfc504509a02ecc463554
|
||||
path: modules/hal/wch
|
||||
groups:
|
||||
- hal
|
||||
- name: hal_wurthelektronik
|
||||
revision: e3e2797b224fc48fdef1bc3e5a12a7c73108bba2
|
||||
path: modules/hal/wurthelektronik
|
||||
|
|
Loading…
Reference in a new issue