diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index d3a26923b541..c2c467c40eba 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -98,6 +98,7 @@ "GD32VF103", "WB32F3G71", "WB32FQ95", + "CH579M", "AT32F415", "atmega16u2", "atmega32u2", @@ -265,7 +266,8 @@ "uf2boot", "unknown", "usbasploader", - "wb32-dfu" + "wb32-dfu", + "ch-isp" ] }, "bootloader_instructions": { diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index e3e47c2bd280..5ec9109784f9 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -22,7 +22,7 @@ MAX_KEYBOARD_SUBFOLDERS = 5 # Supported processor types -CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK64FX512', 'MK66FX1M0', 'RP2040', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G0B1', 'STM32G431', 'STM32G474', 'STM32H723', 'STM32H733', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95', 'AT32F415' +CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK64FX512', 'MK66FX1M0', 'RP2040', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G0B1', 'STM32G431', 'STM32G474', 'STM32H723', 'STM32H733', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95', 'AT32F415', 'CH579M' LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' @@ -57,6 +57,7 @@ "WB32F3G71": "wb32-dfu", "WB32FQ95": "wb32-dfu", "AT32F415": "at32-dfu", + "CH579M": "ch-isp", "atmega16u2": "atmel-dfu", "atmega32u2": "atmel-dfu", "atmega16u4": "atmel-dfu", diff --git a/platforms/chibios/boards/WCH_CH579_KEY12/board/board.c b/platforms/chibios/boards/WCH_CH579_KEY12/board/board.c new file mode 100644 index 000000000000..cb5eba749f46 --- /dev/null +++ b/platforms/chibios/boards/WCH_CH579_KEY12/board/board.c @@ -0,0 +1,20 @@ +// Copyright 2026 Ryan McLean +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "hal.h" + +void __early_init(void) { + /* Nothing needed here — usb_lld_start() handles D+ pull-up at 48 MHz. */ +} + +/** + * @brief Board-specific initialisation. + */ +void boardInit(void) {} + +/** + * @brief PAL setup. + */ +#if HAL_USE_PAL || defined(__DOXYGEN__) +const PALConfig pal_default_config = {0}; +#endif diff --git a/platforms/chibios/boards/WCH_CH579_KEY12/board/board.h b/platforms/chibios/boards/WCH_CH579_KEY12/board/board.h new file mode 100644 index 000000000000..0523a92676cb --- /dev/null +++ b/platforms/chibios/boards/WCH_CH579_KEY12/board/board.h @@ -0,0 +1,20 @@ +// Copyright 2026 Ryan McLean +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +/* + * Board identifier — WCH CH579M macropad (KEY12-V02). + */ + +#define CH579M + +#if !defined(_FROM_ASM_) +# ifdef __cplusplus +extern "C" { +# endif +void boardInit(void); +# ifdef __cplusplus +} +# endif +#endif /* _FROM_ASM_ */ diff --git a/platforms/chibios/boards/WCH_CH579_KEY12/board/board.mk b/platforms/chibios/boards/WCH_CH579_KEY12/board/board.mk new file mode 100644 index 000000000000..842e33590594 --- /dev/null +++ b/platforms/chibios/boards/WCH_CH579_KEY12/board/board.mk @@ -0,0 +1,9 @@ +# List of all the board related files. +BOARDSRC = $(BOARD_PATH)/board/board.c + +# Required include directories +BOARDINC = $(BOARD_PATH)/board + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/platforms/chibios/boards/WCH_CH579_KEY12/configs/chconf.h b/platforms/chibios/boards/WCH_CH579_KEY12/configs/chconf.h new file mode 100644 index 000000000000..f5295cbb44a6 --- /dev/null +++ b/platforms/chibios/boards/WCH_CH579_KEY12/configs/chconf.h @@ -0,0 +1,14 @@ +/* Copyright 2024 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + */ + +#pragma once + +/* CH579M uses ARM Cortex-M0 SysTick in periodic mode. */ +#define CH_CFG_ST_TIMEDELTA 0 + +#include_next diff --git a/platforms/chibios/boards/WCH_CH579_KEY12/configs/halconf.h b/platforms/chibios/boards/WCH_CH579_KEY12/configs/halconf.h new file mode 100644 index 000000000000..e76d5665d0c0 --- /dev/null +++ b/platforms/chibios/boards/WCH_CH579_KEY12/configs/halconf.h @@ -0,0 +1,43 @@ +/* Copyright 2024 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + */ + +#pragma once + +/* + * HAL driver enable switches for CH579M / KEY12-V02. + * Only PAL (GPIO), ST (SysTick tick), and USB are needed for a basic QMK HID keyboard. + */ + +#define HAL_USE_PAL TRUE +#define HAL_USE_ST TRUE +#define HAL_USE_USB TRUE + +/* Everything else off */ +#define HAL_USE_ADC FALSE +#define HAL_USE_CAN FALSE +#define HAL_USE_DAC FALSE +#define HAL_USE_EFL FALSE +#define HAL_USE_GPT FALSE +#define HAL_USE_I2C FALSE +#define HAL_USE_ICU FALSE +#define HAL_USE_MAC FALSE +#define HAL_USE_MMC_SPI FALSE +#define HAL_USE_PWM FALSE +#define HAL_USE_RTC FALSE +#define HAL_USE_SDC FALSE +#define HAL_USE_SERIAL FALSE +#define HAL_USE_SERIAL_USB FALSE +#define HAL_USE_SIO FALSE +#define HAL_USE_SPI FALSE +#define HAL_USE_TRNG FALSE +#define HAL_USE_UART FALSE +#define HAL_USE_USB TRUE +#define HAL_USE_WDG FALSE +#define HAL_USE_WSPI FALSE + +#include_next diff --git a/platforms/chibios/boards/WCH_CH579_KEY12/configs/mcuconf.h b/platforms/chibios/boards/WCH_CH579_KEY12/configs/mcuconf.h new file mode 100644 index 000000000000..2a9e62da2706 --- /dev/null +++ b/platforms/chibios/boards/WCH_CH579_KEY12/configs/mcuconf.h @@ -0,0 +1,31 @@ +/* Copyright 2024 QMK + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + */ + +#pragma once + +/* + * CH579M MCU configuration. + * Overrides defaults in the CH579 HAL driver headers. + */ + +#define CH579M_MCUCONF TRUE + +/* + * Clock — HSI 32 MHz (CK32M) direct as HCLK; PLL on for USB 48 MHz. + * hal_lld_init() powers on the PLL (USB peripheral derives Fpll/10=48 MHz + * independently) and switches HCLK to CK32M direct mode (CLK_SYS_MOD=10). + * Datasheet Fsys spec: 32 MHz direct is within the valid range. + */ +#define CH579_HSECLK 0 /* No external crystal */ +#define CH579_SYSCLK 32000000UL /* CK32M direct (32 MHz HCLK) */ + +/* + * IRQ priorities (0 = highest on CM0, 3 = lowest). + */ +#define CH579_ST_IRQ_PRIORITY 2 +#define CH579_USB_IRQ_PRIORITY 1 diff --git a/platforms/chibios/bootloader.mk b/platforms/chibios/bootloader.mk index e292e1e0b08b..de712459a679 100644 --- a/platforms/chibios/bootloader.mk +++ b/platforms/chibios/bootloader.mk @@ -128,6 +128,12 @@ ifeq ($(strip $(BOOTLOADER)), at32-dfu) DFU_ARGS ?= -d 2E3C:DF11 -a 0 -s 0x08000000:leave DFU_SUFFIX_ARGS ?= -v 2E3C -p DF11 endif +ifeq ($(strip $(BOOTLOADER)), ch-isp) + # WCH CH579M ISP bootloader (wchisp / ch579flash) + OPT_DEFS += -DBOOTLOADER_CH_ISP + BOOTLOADER_TYPE = ch_isp + FIRMWARE_FORMAT = bin +endif ifeq ($(strip $(BOOTLOADER_TYPE)),) ifneq ($(strip $(BOOTLOADER)),) diff --git a/platforms/chibios/bootloaders/ch_isp.c b/platforms/chibios/bootloaders/ch_isp.c new file mode 100644 index 000000000000..f6e98396dc34 --- /dev/null +++ b/platforms/chibios/bootloaders/ch_isp.c @@ -0,0 +1,16 @@ +// Copyright 2026 Ryan McLean +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bootloader.h" +#include +#include + +__attribute__((weak)) void bootloader_jump(void) { + /* CH579M ISP mode is usually entered by resetting with a specific pin low, + * or by executing a specific ROM function. For now, a system reset is used. */ + NVIC_SystemReset(); +} + +__attribute__((weak)) void mcu_reset(void) { + NVIC_SystemReset(); +} diff --git a/platforms/chibios/chibios_config.h b/platforms/chibios/chibios_config.h index 41546e3e507c..bef81f9acc04 100644 --- a/platforms/chibios/chibios_config.h +++ b/platforms/chibios/chibios_config.h @@ -188,6 +188,11 @@ # define PAL_OUTPUT_SPEED_HIGHEST 0 #endif +/* WCH CH579 compatibility */ +#if defined(CH579_SYSCLK) +# define CPU_CLOCK CH579_SYSCLK +#endif + #if !defined(REALTIME_COUNTER_CLOCK) # define REALTIME_COUNTER_CLOCK CPU_CLOCK #endif diff --git a/platforms/chibios/flash.mk b/platforms/chibios/flash.mk index 073475483493..ec28c1617d90 100644 --- a/platforms/chibios/flash.mk +++ b/platforms/chibios/flash.mk @@ -23,6 +23,21 @@ define EXEC_DFU_UTIL $(DFU_UTIL) $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin endef +WCHISP ?= wchisp + +define EXEC_WCHISP + if ! lsusb -d 4348:55e0 > /dev/null 2>&1; then \ + printf "$(MSG_BOOTLOADER_NOT_FOUND_QUICK_RETRY)" ;\ + printf "Reset the board into ISP mode (hold BOOT low while plugging in).\n" ;\ + while ! lsusb -d 4348:55e0 > /dev/null 2>&1; do \ + printf "." ;\ + sleep $(BOOTLOADER_RETRY_TIME) ;\ + done ;\ + printf "\n" ;\ + fi + $(WCHISP) flash $(BUILD_DIR)/$(TARGET).bin +endef + WB32_DFU_UPDATER ?= wb32-dfu-updater_cli define EXEC_WB32_DFU_UPDATER @@ -117,6 +132,8 @@ else ifeq ($(strip $(MCU_FAMILY)),AT32) $(UNSYNC_OUTPUT_CMD) && $(call EXEC_DFU_UTIL) else ifeq ($(strip $(MCU_FAMILY)),GD32V) $(UNSYNC_OUTPUT_CMD) && $(call EXEC_DFU_UTIL) +else ifeq ($(strip $(MCU_FAMILY)),WCH) + $(UNSYNC_OUTPUT_CMD) && $(call EXEC_WCHISP) else $(PRINT_OK); $(SILENT) || printf "$(MSG_FLASH_BOOTLOADER)" endif diff --git a/platforms/chibios/mcu_selection.mk b/platforms/chibios/mcu_selection.mk index 199bdb232118..cf618725d205 100644 --- a/platforms/chibios/mcu_selection.mk +++ b/platforms/chibios/mcu_selection.mk @@ -911,3 +911,18 @@ ifneq ($(findstring GD32VF103, $(MCU)),) USE_FPU ?= no endif + +ifneq ($(findstring CH579M, $(MCU)),) + MCU = cortex-m0 + ARMV = 6 + MCU_FAMILY = WCH + MCU_SERIES = CH579 + MCU_LDSCRIPT ?= CH579M + MCU_STARTUP ?= ch579m + BOARD ?= WCH_CH579_KEY12 + USE_FPU ?= no + USE_CHIBIOS_CONTRIB = yes + USE_PROCESS_STACKSIZE ?= 0x800 + USE_EXCEPTIONS_STACKSIZE ?= 0x400 + FIRMWARE_FORMAT ?= bin +endif