summaryrefslogtreecommitdiff
path: root/hw/bsp/ch583
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2026-06-22 21:30:58 +0200
committerHiFiPhile <[email protected]>2026-06-22 21:30:58 +0200
commit693cdce08e14833f26f4e8a1f26e4fd546be4c35 (patch)
tree7667d2223dc32d9f21b5b60ab200e64ed46e3e20 /hw/bsp/ch583
parent41e9eaa65a935136085d78ec4b99c81ff991b560 (diff)
parentcd3561bf158afd5a5718904b8139a338d1e3b67c (diff)
Merge remote-tracking branch 'tinyusb/master' into pr-osal-spin-deinit
Signed-off-by: HiFiPhile <[email protected]>
Diffstat (limited to 'hw/bsp/ch583')
-rw-r--r--hw/bsp/ch583/boards/ch582m_evt/board.cmake5
-rw-r--r--hw/bsp/ch583/boards/ch582m_evt/board.h61
-rw-r--r--hw/bsp/ch583/boards/ch582m_evt/board.mk3
-rw-r--r--hw/bsp/ch583/boards/yd-ch582m/board.cmake5
-rw-r--r--hw/bsp/ch583/boards/yd-ch582m/board.h61
-rw-r--r--hw/bsp/ch583/boards/yd-ch582m/board.mk3
-rw-r--r--hw/bsp/ch583/ch583_it.c37
-rw-r--r--hw/bsp/ch583/ch583_it.h46
-rw-r--r--hw/bsp/ch583/debug_uart.c86
-rw-r--r--hw/bsp/ch583/debug_uart.h44
-rw-r--r--hw/bsp/ch583/family.c194
-rw-r--r--hw/bsp/ch583/family.cmake108
-rw-r--r--hw/bsp/ch583/family.mk59
-rw-r--r--hw/bsp/ch583/linker/ch582.ld167
-rw-r--r--hw/bsp/ch583/system_ch583.c39
-rw-r--r--hw/bsp/ch583/system_ch583.h43
-rw-r--r--hw/bsp/ch583/wch-riscv.cfg17
17 files changed, 978 insertions, 0 deletions
diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.cmake b/hw/bsp/ch583/boards/ch582m_evt/board.cmake
new file mode 100644
index 000000000..4129c4550
--- /dev/null
+++ b/hw/bsp/ch583/boards/ch582m_evt/board.cmake
@@ -0,0 +1,5 @@
+set(LD_FLASH_SIZE 448K)
+set(LD_RAM_SIZE 32K)
+
+function(update_board TARGET)
+endfunction()
diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.h b/hw/bsp/ch583/boards/ch582m_evt/board.h
new file mode 100644
index 000000000..c3483bf17
--- /dev/null
+++ b/hw/bsp/ch583/boards/ch582m_evt/board.h
@@ -0,0 +1,61 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* metadata:
+ name: CH582M-EVT evaluation board
+ url: https://www.wch-ic.com/products/CH582.html
+*/
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// LED: PB4 on CH582M-EVT
+#define LED_PIN GPIO_Pin_4
+#define LED_STATE_ON 0
+
+// Directly reuse BOOT pin as user button
+#define BUTTON_PIN GPIO_Pin_22
+#define BUTTON_STATE_ACTIVE 0
+
+// UART: UART1 TX=PA9, RX=PA8
+#define CFG_BOARD_UART_BAUDRATE 115200
+
+// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd;
+// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later.
+#ifndef BOARD_TUD_RHPORT
+#define BOARD_TUD_RHPORT 0
+#endif
+// #ifndef BOARD_TUH_RHPORT
+// #define BOARD_TUH_RHPORT 1
+// #endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.mk b/hw/bsp/ch583/boards/ch582m_evt/board.mk
new file mode 100644
index 000000000..a13979799
--- /dev/null
+++ b/hw/bsp/ch583/boards/ch582m_evt/board.mk
@@ -0,0 +1,3 @@
+LDFLAGS += \
+ -Wl,--defsym=__FLASH_SIZE=448K \
+ -Wl,--defsym=__RAM_SIZE=32K \
diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.cmake b/hw/bsp/ch583/boards/yd-ch582m/board.cmake
new file mode 100644
index 000000000..4129c4550
--- /dev/null
+++ b/hw/bsp/ch583/boards/yd-ch582m/board.cmake
@@ -0,0 +1,5 @@
+set(LD_FLASH_SIZE 448K)
+set(LD_RAM_SIZE 32K)
+
+function(update_board TARGET)
+endfunction()
diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.h b/hw/bsp/ch583/boards/yd-ch582m/board.h
new file mode 100644
index 000000000..0da5747bc
--- /dev/null
+++ b/hw/bsp/ch583/boards/yd-ch582m/board.h
@@ -0,0 +1,61 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* metadata:
+ name: yd-ch582m from vcc-gnd studio
+ url: http://vcc-gnd.com/
+*/
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// LED: PB4 on yd-ch582m board
+#define LED_PIN GPIO_Pin_4
+#define LED_STATE_ON 0
+
+// Directly reuse BOOT pin as user button
+#define BUTTON_PIN GPIO_Pin_22
+#define BUTTON_STATE_ACTIVE 0
+
+// UART: UART1 TX=PA9, RX=PA8
+#define CFG_BOARD_UART_BAUDRATE 115200
+
+// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd;
+// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later.
+#ifndef BOARD_TUD_RHPORT
+#define BOARD_TUD_RHPORT 0
+#endif
+// #ifndef BOARD_TUH_RHPORT
+// #define BOARD_TUH_RHPORT 1
+// #endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.mk b/hw/bsp/ch583/boards/yd-ch582m/board.mk
new file mode 100644
index 000000000..a13979799
--- /dev/null
+++ b/hw/bsp/ch583/boards/yd-ch582m/board.mk
@@ -0,0 +1,3 @@
+LDFLAGS += \
+ -Wl,--defsym=__FLASH_SIZE=448K \
+ -Wl,--defsym=__RAM_SIZE=32K \
diff --git a/hw/bsp/ch583/ch583_it.c b/hw/bsp/ch583/ch583_it.c
new file mode 100644
index 000000000..8479c537a
--- /dev/null
+++ b/hw/bsp/ch583/ch583_it.c
@@ -0,0 +1,37 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "ch583_it.h"
+
+// NMI exception handler
+__INTERRUPT __HIGH_CODE void NMI_Handler(void) {
+ while (1) {}
+}
+
+// Hard Fault exception handler
+__INTERRUPT __HIGH_CODE void HardFault_Handler(void) {
+ while (1) {}
+}
diff --git a/hw/bsp/ch583/ch583_it.h b/hw/bsp/ch583/ch583_it.h
new file mode 100644
index 000000000..29d175403
--- /dev/null
+++ b/hw/bsp/ch583/ch583_it.h
@@ -0,0 +1,46 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef CH583_IT_H_
+#define CH583_IT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "CH58x_common.h"
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void USB_IRQHandler(void);
+// void USB2_IRQHandler(void); // host on USB2 (rhport 1) — re-add together with the host driver
+void SysTick_Handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CH583_IT_H_ */
diff --git a/hw/bsp/ch583/debug_uart.c b/hw/bsp/ch583/debug_uart.c
new file mode 100644
index 000000000..850e40718
--- /dev/null
+++ b/hw/bsp/ch583/debug_uart.c
@@ -0,0 +1,86 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "debug_uart.h"
+#include "CH58x_common.h"
+
+//--------------------------------------------------------------------+
+// Ring buffer based UART TX for non-blocking writes
+//--------------------------------------------------------------------+
+
+#define UART_RINGBUFFER_SIZE_TX 128
+#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX - 1)
+
+static char tx_buf[UART_RINGBUFFER_SIZE_TX];
+static uint32_t tx_produce;
+static volatile uint32_t tx_consume;
+
+void uart_write(char c) {
+ uint32_t tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
+
+ // If the ring buffer is full, drain it here as the FIFO frees up: nothing else advances
+ // tx_consume between uart_write() calls, so a plain spin would deadlock on a >buffer-size burst.
+ while (tx_produce_next == tx_consume) {
+ if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) {
+ R8_UART1_THR = tx_buf[tx_consume];
+ tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
+ }
+ }
+
+ // If UART TX FIFO is empty and no pending data, send directly
+ if ((tx_consume == tx_produce) && (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP)) {
+ R8_UART1_THR = c;
+ } else {
+ tx_buf[tx_produce] = c;
+ tx_produce = tx_produce_next;
+ }
+}
+
+void uart_sync(void) {
+ // Wait for ring buffer to drain
+ while (tx_consume != tx_produce) {
+ if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) {
+ R8_UART1_THR = tx_buf[tx_consume];
+ tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
+ }
+ }
+ // Wait for last byte to finish transmitting
+ while (!(R8_UART1_LSR & RB_LSR_TX_ALL_EMP)) {}
+}
+
+void usart_printf_init(uint32_t baudrate) {
+ tx_produce = 0;
+ tx_consume = 0;
+
+ // Configure UART1 pins: TX=PA9, RX=PA8
+ GPIOA_SetBits(GPIO_Pin_9);
+ GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
+ GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
+
+ // Init UART1 with specified baud rate
+ UART1_DefInit();
+ UART1_BaudRateCfg(baudrate);
+}
diff --git a/hw/bsp/ch583/debug_uart.h b/hw/bsp/ch583/debug_uart.h
new file mode 100644
index 000000000..44c3e7948
--- /dev/null
+++ b/hw/bsp/ch583/debug_uart.h
@@ -0,0 +1,44 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef DEBUG_UART_H_
+#define DEBUG_UART_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void uart_write(char c);
+void uart_sync(void);
+void usart_printf_init(uint32_t baudrate);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DEBUG_UART_H_ */
diff --git a/hw/bsp/ch583/family.c b/hw/bsp/ch583/family.c
new file mode 100644
index 000000000..716e2b76b
--- /dev/null
+++ b/hw/bsp/ch583/family.c
@@ -0,0 +1,194 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+/* metadata:
+ manufacturer: WCH
+*/
+
+// WCH SDK's DEBUG macro enables a _write() that conflicts with TinyUSB's.
+// TinyUSB uses UART1 for printf via debug_uart.c, so DEBUG is not needed.
+// If you need a different UART or want to keep SDK's DEBUG, modify
+// debug_uart.c (TinyUSB side) or CH58x_sys.c (SDK side) to remove one _write().
+// If done, remove this #error to continue.
+#ifdef DEBUG
+ #error "Remove the DEBUG macro from preprocessor defines to avoid " \
+ "duplicate _write() between WCH SDK and TinyUSB. " \
+ "TinyUSB uses UART1 by default (see debug_uart.c)."
+#endif
+
+#include "debug_uart.h"
+#include "CH58x_common.h"
+#include "ch583_it.h"
+
+#include "bsp/board_api.h"
+#include "board.h"
+
+//--------------------------------------------------------------------+
+// Forward USB interrupt events to TinyUSB IRQ Handler
+//--------------------------------------------------------------------+
+
+// Device only: the shared dcd_ch32_usbfs.c drives USB0 (rhport 0). CH58x's second controller
+// (USB2 / rhport 1) was driven by the now-removed ch58x host driver; its handler is kept
+// commented out below to ease re-adding host support.
+__INTERRUPT __HIGH_CODE void USB_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+
+// __INTERRUPT __HIGH_CODE void USB2_IRQHandler(void) {
+// tusb_int_handler(1, true);
+// }
+
+//--------------------------------------------------------------------+
+// SysTick
+//--------------------------------------------------------------------+
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+volatile uint32_t system_ticks = 0;
+
+__INTERRUPT __HIGH_CODE void SysTick_Handler(void) {
+ SysTick->SR = 0;
+ system_ticks++;
+}
+
+uint32_t tusb_time_millis_api(void) {
+ return system_ticks;
+}
+#endif
+
+//--------------------------------------------------------------------+
+// Board Init
+//--------------------------------------------------------------------+
+
+void board_init(void) {
+ // Disable interrupts during init
+ PFIC_DisableAllIRQ();
+
+ // Set system clock to PLL 60MHz (default for CH582)
+ SetSysClock(CLK_SOURCE_PLL_60MHz);
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+ SysTick_Config(GetSysClock() / 1000);
+#endif
+
+ // UART1 init for debug output
+#ifdef CFG_BOARD_UART_BAUDRATE
+ usart_printf_init(CFG_BOARD_UART_BAUDRATE);
+#endif
+
+ // LED
+#ifdef LED_PORT_IS_A
+ GPIOA_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA);
+#else
+ GPIOB_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA);
+#endif
+
+ // Button
+#ifdef BUTTON_PIN
+ #ifdef BUTTON_PORT_IS_A
+ GPIOA_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU);
+ #else
+ GPIOB_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU);
+ #endif
+#endif
+
+ // Device only on USB0 (rhport 0): enable analog function for USB1 D+/D- and assert its D+
+ // pull-up. The shared dcd_ch32_usbfs.c drives USB0; CH58x host / USB2 (rhport 1) is unsupported
+ // here — to re-add host, also OR in RB_PIN_USB2_IE below.
+ R16_PIN_ANALOG_IE |= RB_PIN_USB_IE; // | RB_PIN_USB2_IE (re-add for host on USB2)
+#if CFG_TUD_ENABLED
+ R16_PIN_ANALOG_IE |= RB_PIN_USB_DP_PU;
+#endif
+
+ // Keep USB clock active during sleep
+ R8_SLP_CLK_OFF1 &= ~RB_SLP_CLK_USB;
+
+ // Enable interrupts globally
+ PFIC_EnableAllIRQ();
+
+ board_delay(2);
+}
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+
+void board_led_write(bool state) {
+#ifdef LED_PORT_IS_A
+ if (state ^ LED_STATE_ON) {
+ GPIOA_ResetBits(LED_PIN);
+ } else {
+ GPIOA_SetBits(LED_PIN);
+ }
+#else
+ if (state ^ LED_STATE_ON) {
+ GPIOB_ResetBits(LED_PIN);
+ } else {
+ GPIOB_SetBits(LED_PIN);
+ }
+#endif
+}
+
+uint32_t board_button_read(void) {
+#ifdef BUTTON_PIN
+ #ifdef BUTTON_PORT_IS_A
+ return BUTTON_STATE_ACTIVE == (GPIOA_ReadPortPin(BUTTON_PIN) ? 1 : 0);
+ #else
+ return BUTTON_STATE_ACTIVE == (GPIOB_ReadPortPin(BUTTON_PIN) ? 1 : 0);
+ #endif
+#else
+ return 0;
+#endif
+}
+
+// CH58x has no memory-mapped unique-ID register (unlike ch32v10x/v20x at 0x1FFFF7E8), but the
+// factory programs a unique 6-byte MAC address into FlashROM (it is a BLE part). GetMACAddress()
+// reads it via the ISP ROM command FLASH_EEPROM_CMD, which is provided by libISP583.a.
+size_t board_get_unique_id(uint8_t id[], size_t max_len) {
+ // FLASH_EEPROM_CMD writes word-granular and requires a 4-byte-aligned buffer (CH58x_flash.c);
+ // size 8 matches the SDK's GET_UNIQUE_ID buffer (6 MAC bytes + 2 it pads), so the read can't
+ // run past the end whether it returns 6 or a full 8.
+ TU_ATTR_ALIGNED(4) uint8_t mac[8];
+ GetMACAddress(mac);
+ size_t len = TU_MIN(max_len, (size_t) 6); // the 6-byte MAC is the unique part
+ memcpy(id, mac, len);
+ return len;
+}
+
+int board_uart_read(uint8_t* buf, int len) {
+ (void) buf;
+ (void) len;
+ return 0;
+}
+
+int board_uart_write(void const* buf, int len) {
+ int txsize = len;
+ const char* bufc = (const char*) buf;
+ while (txsize--) {
+ uart_write(*bufc++);
+ }
+ uart_sync();
+ return len;
+}
diff --git a/hw/bsp/ch583/family.cmake b/hw/bsp/ch583/family.cmake
new file mode 100644
index 000000000..a379298e5
--- /dev/null
+++ b/hw/bsp/ch583/family.cmake
@@ -0,0 +1,108 @@
+include_guard()
+
+set(SDK_DIR ${TOP}/hw/mcu/wch/ch583)
+set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS CH583 CACHE INTERNAL "")
+set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg")
+
+#------------------------------------
+# Startup & Linker script
+#------------------------------------
+if (NOT DEFINED LD_FILE_GNU)
+ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/ch582.ld)
+endif ()
+set(LD_FILE_Clang ${LD_FILE_GNU})
+if (NOT DEFINED STARTUP_FILE_GNU)
+ set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_CH583.S)
+endif ()
+set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+
+#------------------------------------
+# Board Target
+#------------------------------------
+function(family_add_board BOARD_TARGET)
+ add_library(${BOARD_TARGET} STATIC
+ ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_gpio.c
+ ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_clk.c
+ ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_uart1.c
+ ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_sys.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch583_it.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch583.c
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${SDK_SRC_DIR}/RVMSIS
+ ${SDK_SRC_DIR}/StdPeriphDriver/inc
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ )
+ target_link_libraries(${BOARD_TARGET} PUBLIC
+ ${SDK_SRC_DIR}/StdPeriphDriver/libISP583.a
+ )
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ CFG_TUD_WCH_USBIP_USBFS=1
+ FREQ_SYS=60000000
+ DISK_LIB_ENABLE=0
+ INT_SOFT
+ )
+
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_compile_options(${BOARD_TARGET} PUBLIC
+ -flto
+ -msmall-data-limit=16
+ -mno-save-restore
+ -fmessage-length=0
+ -fsigned-char
+ -Wno-error=strict-prototypes
+ )
+ endif ()
+endfunction()
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+ family_add_tinyusb(${TARGET} OPT_MCU_CH583)
+
+ target_sources(${TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${TOP}/src/portable/wch/dcd_ch32_usbfs.c
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${TARGET} PUBLIC
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE}
+ -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE}
+ "LINKER:--script=${LD_FILE_GNU}"
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ message(FATAL_ERROR "Clang is not supported for CH58x")
+ endif ()
+
+ set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES
+ SKIP_LINTING ON
+ COMPILE_OPTIONS -w)
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_openocd_wch(${TARGET})
+endfunction()
diff --git a/hw/bsp/ch583/family.mk b/hw/bsp/ch583/family.mk
new file mode 100644
index 000000000..98d0f9337
--- /dev/null
+++ b/hw/bsp/ch583/family.mk
@@ -0,0 +1,59 @@
+# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable
+#CROSS_COMPILE ?= riscv32-unknown-elf-
+
+# Toolchain from https://nucleisys.com/download.php
+#CROSS_COMPILE ?= riscv-nuclei-elf-
+
+# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
+CROSS_COMPILE ?= riscv-none-elf-
+
+SDK_DIR = hw/mcu/wch/ch583
+SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+CPU_CORE ?= rv32imac-ilp32
+
+CFLAGS += \
+ -flto \
+ -msmall-data-limit=16 \
+ -mno-save-restore \
+ -fmessage-length=0 \
+ -fsigned-char \
+ -DCFG_TUSB_MCU=OPT_MCU_CH583 \
+ -DCFG_TUD_WCH_USBIP_USBFS=1 \
+ -DFREQ_SYS=60000000 \
+ -DDISK_LIB_ENABLE=0 \
+ -DINT_SOFT \
+ -Wno-error=strict-prototypes
+
+LDFLAGS += \
+ -nostartfiles \
+ --specs=nosys.specs --specs=nano.specs
+
+LIBS += $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/libISP583.a
+
+SRC_C += \
+ src/portable/wch/dcd_ch32_usbfs.c \
+ $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_gpio.c \
+ $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_clk.c \
+ $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_uart1.c \
+ $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_sys.c \
+ $(FAMILY_PATH)/debug_uart.c \
+ $(FAMILY_PATH)/ch583_it.c \
+ $(FAMILY_PATH)/system_ch583.c
+
+SRC_S += \
+ $(SDK_SRC_DIR)/Startup/startup_CH583.S
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/$(SDK_SRC_DIR)/RVMSIS \
+ $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/inc
+
+LD_FILE ?= $(FAMILY_PATH)/linker/ch582.ld
+
+OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
+flash: flash-openocd-wch
+
+# For freeRTOS port source
+FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V
diff --git a/hw/bsp/ch583/linker/ch582.ld b/hw/bsp/ch583/linker/ch582.ld
new file mode 100644
index 000000000..821998a49
--- /dev/null
+++ b/hw/bsp/ch583/linker/ch582.ld
@@ -0,0 +1,167 @@
+/* CH582 Linker Script for TinyUSB
+ * Based on WCH CH583 SDK Link.ld
+ * Supports parameterized flash/ram sizes via --defsym
+ */
+
+/* Default sizes if not provided via --defsym */
+__flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 448K;
+__ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 32K;
+__stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048;
+
+ENTRY( _start )
+
+PROVIDE( _stack_size = __stack_size );
+
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size
+}
+
+SECTIONS
+{
+ .init :
+ {
+ _sinit = .;
+ . = ALIGN(4);
+ KEEP(*(SORT_NONE(.init)))
+ . = ALIGN(4);
+ _einit = .;
+ } >FLASH AT>FLASH
+
+ .highcodelalign :
+ {
+ . = ALIGN(4);
+ PROVIDE(_highcode_lma = .);
+ } >FLASH AT>FLASH
+
+ .highcode :
+ {
+ . = ALIGN(4);
+ PROVIDE(_highcode_vma_start = .);
+ *(.vector);
+ KEEP(*(SORT_NONE(.vector_handler)))
+ *(.highcode);
+ *(.highcode.*);
+ . = ALIGN(4);
+ PROVIDE(_highcode_vma_end = .);
+ } >RAM AT>FLASH
+
+ .text :
+ {
+ . = ALIGN(4);
+ KEEP(*(SORT_NONE(.handle_reset)))
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata*)
+ *(.sdata2.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.gnu.linkonce.t.*)
+ . = ALIGN(4);
+ } >FLASH AT>FLASH
+
+ .fini :
+ {
+ KEEP(*(SORT_NONE(.fini)))
+ . = ALIGN(4);
+ } >FLASH AT>FLASH
+
+ PROVIDE( _etext = . );
+ PROVIDE( _eitcm = . );
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >FLASH AT>FLASH
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >FLASH AT>FLASH
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >FLASH AT>FLASH
+
+ .ctors :
+ {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } >FLASH AT>FLASH
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } >FLASH AT>FLASH
+
+ .dlalign :
+ {
+ . = ALIGN(4);
+ PROVIDE(_data_lma = .);
+ } >FLASH AT>FLASH
+
+ .data :
+ {
+ . = ALIGN(4);
+ PROVIDE(_data_vma = .);
+ *(.gnu.linkonce.r.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ . = ALIGN(4);
+ PROVIDE( _edata = .);
+ } >RAM AT>FLASH
+
+ .bss :
+ {
+ . = ALIGN(4);
+ PROVIDE( _sbss = .);
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON*)
+ . = ALIGN(4);
+ PROVIDE( _ebss = .);
+ } >RAM AT>FLASH
+
+ PROVIDE( _end = _ebss);
+ PROVIDE( end = . );
+
+ .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
+ {
+ PROVIDE( _heap_end = . );
+ . = ALIGN(4);
+ PROVIDE(_susrstack = . );
+ . = . + __stack_size;
+ PROVIDE( _eusrstack = .);
+ __freertos_irq_stack_top = .;
+ } >RAM
+}
diff --git a/hw/bsp/ch583/system_ch583.c b/hw/bsp/ch583/system_ch583.c
new file mode 100644
index 000000000..d3724f0ce
--- /dev/null
+++ b/hw/bsp/ch583/system_ch583.c
@@ -0,0 +1,39 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "CH58x_common.h"
+#include "system_ch583.h"
+
+uint32_t SystemCoreClock = FREQ_SYS;
+
+void SystemInit(void) {
+ SetSysClock(CLK_SOURCE_PLL_60MHz);
+ SystemCoreClock = GetSysClock();
+}
+
+void SystemCoreClockUpdate(void) {
+ SystemCoreClock = GetSysClock();
+}
diff --git a/hw/bsp/ch583/system_ch583.h b/hw/bsp/ch583/system_ch583.h
new file mode 100644
index 000000000..c174c9f5e
--- /dev/null
+++ b/hw/bsp/ch583/system_ch583.h
@@ -0,0 +1,43 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 TinyUSB contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef SYSTEM_CH583_H_
+#define SYSTEM_CH583_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
+
+extern void SystemInit(void);
+extern void SystemCoreClockUpdate(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SYSTEM_CH583_H_ */
diff --git a/hw/bsp/ch583/wch-riscv.cfg b/hw/bsp/ch583/wch-riscv.cfg
new file mode 100644
index 000000000..64d595d8e
--- /dev/null
+++ b/hw/bsp/ch583/wch-riscv.cfg
@@ -0,0 +1,17 @@
+adapter driver wlinke
+adapter speed 6000
+transport select sdi
+
+wlink_set_address 0x00000000
+set _CHIPNAME wch_riscv
+sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001
+
+set _TARGETNAME $_CHIPNAME.cpu
+
+target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME
+$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 0x8000 -work-area-backup 1
+set _FLASHNAME $_CHIPNAME.flash
+
+flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0
+
+echo "Ready for Remote Connections"