Skip to content
4 changes: 3 additions & 1 deletion data/schemas/keyboard.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"GD32VF103",
"WB32F3G71",
"WB32FQ95",
"CH579M",
"AT32F415",
"atmega16u2",
"atmega32u2",
Expand Down Expand Up @@ -265,7 +266,8 @@
"uf2boot",
"unknown",
"usbasploader",
"wb32-dfu"
"wb32-dfu",
"ch-isp"
]
},
"bootloader_instructions": {
Expand Down
3 changes: 2 additions & 1 deletion lib/python/qmk/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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",
Expand Down
20 changes: 20 additions & 0 deletions platforms/chibios/boards/WCH_CH579_KEY12/board/board.c
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions platforms/chibios/boards/WCH_CH579_KEY12/board/board.h
Original file line number Diff line number Diff line change
@@ -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_ */
9 changes: 9 additions & 0 deletions platforms/chibios/boards/WCH_CH579_KEY12/board/board.mk
Original file line number Diff line number Diff line change
@@ -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)
14 changes: 14 additions & 0 deletions platforms/chibios/boards/WCH_CH579_KEY12/configs/chconf.h
Original file line number Diff line number Diff line change
@@ -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 <chconf.h>
43 changes: 43 additions & 0 deletions platforms/chibios/boards/WCH_CH579_KEY12/configs/halconf.h
Original file line number Diff line number Diff line change
@@ -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 <halconf.h>
31 changes: 31 additions & 0 deletions platforms/chibios/boards/WCH_CH579_KEY12/configs/mcuconf.h
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions platforms/chibios/bootloader.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)),)
Expand Down
16 changes: 16 additions & 0 deletions platforms/chibios/bootloaders/ch_isp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2026 Ryan McLean
// SPDX-License-Identifier: GPL-2.0-or-later

#include "bootloader.h"
#include <ch.h>
#include <hal.h>

__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();
}
5 changes: 5 additions & 0 deletions platforms/chibios/chibios_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions platforms/chibios/flash.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
15 changes: 15 additions & 0 deletions platforms/chibios/mcu_selection.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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