Skip to content

Add Host support for ch32v20x usbfs #2793

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/dual/host_hid_to_device_cdc/only.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
board:mimxrt1060_evk
board:mimxrt1064_evk
board:mcb1800
mcu:CH32V20X
mcu:RP2040
mcu:ra6m5
mcu:MAX3421
Expand Down
1 change: 1 addition & 0 deletions examples/dual/host_info_to_device_cdc/only.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
board:mimxrt1060_evk
board:mimxrt1064_evk
board:mcb1800
mcu:CH32V20X
mcu:RP2040
mcu:ra6m5
mcu:MAX3421
Expand Down
1 change: 1 addition & 0 deletions examples/host/bare_api/only.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
Expand Down
1 change: 1 addition & 0 deletions examples/host/cdc_msc_hid/only.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
Expand Down
1 change: 1 addition & 0 deletions examples/host/device_info/only.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:CH32V20X
mcu:ESP32S2
mcu:ESP32S3
mcu:ESP32P4
Expand Down
1 change: 1 addition & 0 deletions examples/host/hid_controller/only.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
Expand Down
1 change: 1 addition & 0 deletions examples/host/midi_rx/only.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:CH32V20X
mcu:ESP32S2
mcu:ESP32S3
mcu:ESP32P4
Expand Down
1 change: 1 addition & 0 deletions examples/host/msc_file_explorer/only.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
Expand Down
64 changes: 35 additions & 29 deletions hw/bsp/ch32v20x/family.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,56 +20,56 @@ manufacturer: WCH
#include "bsp/board_api.h"
#include "board.h"

/* CH32v203 depending on variants can support 2 USB IPs: FSDEV and USBFS.
/* CH32v203 depending on variants can support 2 USB IPs: FSDEV (port0) and USBFS (port1).
* By default, we use FSDEV, but you can explicitly select by define:
* - CFG_TUD_WCH_USBIP_FSDEV
* - CFG_TUD_WCH_USBIP_USBFS
*/

// USBFS
__attribute__((interrupt)) __attribute__((used))
void USBHD_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_USBFS
// Port0: USBD (fsdev)
__attribute__((interrupt)) __attribute__((used)) void USB_LP_CAN1_RX0_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
tud_int_handler(0);
#endif
}

__attribute__((interrupt)) __attribute__((used))
void USBHDWakeUp_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_USBFS
__attribute__((interrupt)) __attribute__((used)) void USB_HP_CAN1_TX_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
tud_int_handler(0);
#endif

}

// USBD (fsdev)
__attribute__((interrupt)) __attribute__((used))
void USB_LP_CAN1_RX0_IRQHandler(void) {
__attribute__((interrupt)) __attribute__((used)) void USBWakeUp_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
tud_int_handler(0);
#endif
}

__attribute__((interrupt)) __attribute__((used))
void USB_HP_CAN1_TX_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
tud_int_handler(0);
// Port1: USBFS
__attribute__((interrupt)) __attribute__((used)) void USBHD_IRQHandler(void) {
#if CFG_TUD_ENABLED && CFG_TUD_WCH_USBIP_USBFS
tud_int_handler(1);
#endif

#if CFG_TUH_ENABLED
tuh_int_handler(1);
#endif
}

__attribute__((interrupt)) __attribute__((used))
void USBWakeUp_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
__attribute__((interrupt)) __attribute__((used)) void USBHDWakeUp_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_USBFS
tud_int_handler(0);
#endif
}


//--------------------------------------------------------------------+
// Board API
//--------------------------------------------------------------------+
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;

__attribute__((interrupt))
void SysTick_Handler(void) {
__attribute__((interrupt)) void SysTick_Handler(void) {
SysTick->SR = 0;
system_ticks++;
}
Expand Down Expand Up @@ -108,7 +108,7 @@ void board_init(void) {
#ifdef UART_DEV
UART_CLOCK_EN();
GPIO_InitTypeDef usart_init = {
.GPIO_Pin = UART_TX_PIN,
.GPIO_Pin = UART_TX_PIN | UART_RX_PIN,
.GPIO_Speed = GPIO_Speed_50MHz,
.GPIO_Mode = GPIO_Mode_AF_PP,
};
Expand All @@ -119,7 +119,7 @@ void board_init(void) {
.USART_WordLength = USART_WordLength_8b,
.USART_StopBits = USART_StopBits_1,
.USART_Parity = USART_Parity_No,
.USART_Mode = USART_Mode_Tx,
.USART_Mode = USART_Mode_Tx | USART_Mode_Rx,
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
};
USART_Init(UART_DEV, &usart);
Expand Down Expand Up @@ -189,9 +189,19 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) {
}

int board_uart_read(uint8_t *buf, int len) {
(void) buf;
(void) len;
#ifdef UART_DEV
int count;
for (count = 0; count < len; count++) {
if (USART_GetFlagStatus(UART_DEV, USART_FLAG_RXNE) == RESET) {
break;
}
buf[count] = USART_ReceiveData(UART_DEV);
}
return count;
#else
(void) buf; (void) len;
return 0;
#endif
}

int board_uart_write(void const *buf, int len) {
Expand All @@ -207,7 +217,3 @@ int board_uart_write(void const *buf, int len) {

return len;
}

//--------------------------------------------------------------------
// Neopixel
//--------------------------------------------------------------------
28 changes: 14 additions & 14 deletions hw/bsp/ch32v20x/family.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ set(FAMILY_MCUS CH32V20X CACHE INTERNAL "")
set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg")

# Port0 use FSDev, Port1 use USBFS
if (NOT DEFINED PORT)
set(PORT 0)
endif()
if (NOT DEFINED RHPORT_DEVICE)
set(RHPORT_DEVICE 0)
endif ()

# only port1 support host mode
set(RHPORT_HOST 1)

#------------------------------------
# BOARD_TARGET
Expand Down Expand Up @@ -56,18 +59,16 @@ function(add_board_target BOARD_TARGET)
)
target_compile_definitions(${BOARD_TARGET} PUBLIC
CH32V20x_${MCU_VARIANT}
BOARD_TUD_RHPORT=${RHPORT_DEVICE}
BOARD_TUH_RHPORT=${RHPORT_HOST}
)

if (PORT EQUAL 0)
target_compile_definitions(${BOARD_TARGET} PUBLIC
CFG_TUD_WCH_USBIP_FSDEV=1
)
elseif (PORT EQUAL 1)
target_compile_definitions(${BOARD_TARGET} PUBLIC
CFG_TUD_WCH_USBIP_USBFS=1
)
if (RHPORT_DEVICE EQUAL 0)
target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUD_WCH_USBIP_FSDEV=1)
elseif (RHPORT_DEVICE EQUAL 1)
target_compile_definitions(${BOARD_TARGET} PUBLIC CFG_TUH_WCH_USBIP_USBFS=1)
else()
message(FATAL_ERROR "Invalid PORT ${PORT}")
message(FATAL_ERROR "Invalid RHPORT_DEVICE ${RHPORT_DEVICE}")
endif()

update_board(${BOARD_TARGET})
Expand Down Expand Up @@ -127,12 +128,11 @@ function(family_configure_example TARGET RTOS)

target_sources(${TARGET} PUBLIC
${TOP}/src/portable/wch/dcd_ch32_usbfs.c
${TOP}/src/portable/wch/hcd_ch32_usbfs.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
)
target_link_libraries(${TARGET} PUBLIC board_${BOARD})



# Flashing
family_add_bin_hex(${TARGET})
family_flash_openocd_wch(${TARGET})
Expand Down
3 changes: 3 additions & 0 deletions hw/bsp/ch32v20x/family.mk
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ CFLAGS += -Wno-error=strict-prototypes
ifeq ($(PORT),0)
$(info "Using FSDEV driver")
CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1
$(info "Using USBFS Host driver")
CFLAGS += -DCFG_TUH_WCH_USBIP_USBFS=1
else
$(info "Using USBFS driver")
CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1
Expand All @@ -43,6 +45,7 @@ LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld

SRC_C += \
src/portable/wch/dcd_ch32_usbfs.c \
src/portable/wch/hcd_ch32_usbfs.c \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
$(SDK_SRC_DIR)/Core/core_riscv.c \
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \
Expand Down
8 changes: 7 additions & 1 deletion src/common/tusb_mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,11 +503,17 @@
#define TUP_DCD_ENDPOINT_MAX 8

#elif TU_CHECK_MCU(OPT_MCU_CH32V20X)
// v20x support both FSDEV (USBD) and USBFS, default to FSDEV
// v20x support both port0 FSDEV (USBD) and port1 USBFS
#define TUP_USBIP_WCH_USBFS

#ifndef CFG_TUH_WCH_USBIP_USBFS
#define CFG_TUH_WCH_USBIP_USBFS 1
#endif

#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_CH32

// default to FSDEV for device
#if !defined(CFG_TUD_WCH_USBIP_USBFS)
#define CFG_TUD_WCH_USBIP_USBFS 0
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/portable/wch/dcd_ch32_usbhs.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

#include "tusb_option.h"

#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && CFG_TUD_WCH_USBIP_USBHS
#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && defined(CFG_TUD_WCH_USBIP_USBHS) && CFG_TUD_WCH_USBIP_USBHS
#include "ch32_usbhs_reg.h"

#include "device/dcd.h"
Expand Down
Loading
Loading