From db60fa1c63ae58c205e43e144253dab6815bb2d1 Mon Sep 17 00:00:00 2001 From: Matthew Tran Date: Sun, 19 Nov 2023 18:26:40 -0800 Subject: add CH32V20x USB OTG/FS driver --- src/class/video/video_device.c | 2 +- src/common/tusb_mcu.h | 4 + src/portable/wch/ch32_usbfs_reg.h | 77 ++++++++++ src/portable/wch/dcd_ch32_usbfs.c | 304 ++++++++++++++++++++++++++++++++++++++ src/tusb_option.h | 1 + 5 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 src/portable/wch/ch32_usbfs_reg.h create mode 100644 src/portable/wch/dcd_ch32_usbfs.c (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 4218835aa..974289b69 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -609,7 +609,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - uint_fast32_t interval, interval_ms; + uint_fast32_t interval, interval_ms = 0; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 3a7d6ad33..eab112015 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -410,6 +410,10 @@ #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 + +#elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + #define TUP_DCD_ENDPOINT_MAX 8 + #endif diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h new file mode 100644 index 000000000..3b8e49ae2 --- /dev/null +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -0,0 +1,77 @@ +#ifndef USB_CH32_USBFS_REG_H +#define USB_CH32_USBFS_REG_H + +#if (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#include +#endif + +// CTRL +#define USBFS_CTRL_DMA_EN (1 << 0) +#define USBFS_CTRL_CLR_ALL (1 << 1) +#define USBFS_CTRL_RESET_SIE (1 << 2) +#define USBFS_CTRL_INT_BUSY (1 << 3) +#define USBFS_CTRL_SYS_CTRL (1 << 4) +#define USBFS_CTRL_DEV_PUEN (1 << 5) +#define USBFS_CTRL_LOW_SPEED (1 << 6) +#define USBFS_CTRL_HOST_MODE (1 << 7) + +// INT_EN +#define USBFS_INT_EN_BUS_RST (1 << 0) +#define USBFS_INT_EN_DETECT (1 << 0) +#define USBFS_INT_EN_TRANSFER (1 << 1) +#define USBFS_INT_EN_SUSPEND (1 << 2) +#define USBFS_INT_EN_HST_SOF (1 << 3) +#define USBFS_INT_EN_FIFO_OV (1 << 4) +#define USBFS_INT_EN_DEV_NAK (1 << 6) +#define USBFS_INT_EN_DEV_SOF (1 << 7) + +// INT_FG +#define USBFS_INT_FG_BUS_RST (1 << 0) +#define USBFS_INT_FG_DETECT (1 << 0) +#define USBFS_INT_FG_TRANSFER (1 << 1) +#define USBFS_INT_FG_SUSPEND (1 << 2) +#define USBFS_INT_FG_HST_SOF (1 << 3) +#define USBFS_INT_FG_FIFO_OV (1 << 4) +#define USBFS_INT_FG_SIE_FREE (1 << 5) +#define USBFS_INT_FG_TOG_OK (1 << 6) +#define USBFS_INT_FG_IS_NAK (1 << 7) + +// INT_ST +#define USBFS_INT_ST_MASK_UIS_ENDP(x) (((x) >> 0) & 0x0F) +#define USBFS_INT_ST_MASK_UIS_TOKEN(x) (((x) >> 4) & 0x03) + +// UDEV_CTRL +#define USBFS_UDEV_CTRL_PORT_EN (1 << 0) +#define USBFS_UDEV_CTRL_GP_BIT (1 << 1) +#define USBFS_UDEV_CTRL_LOW_SPEED (1 << 2) +#define USBFS_UDEV_CTRL_DM_PIN (1 << 4) +#define USBFS_UDEV_CTRL_DP_PIN (1 << 5) +#define USBFS_UDEV_CTRL_PD_DIS (1 << 7) + +// TX_CTRL +#define USBFS_EP_T_RES_MASK (3 << 0) +#define USBFS_EP_T_TOG (1 << 2) +#define USBFS_EP_T_AUTO_TOG (1 << 3) + +#define USBFS_EP_T_RES_ACK (0 << 0) +#define USBFS_EP_T_RES_NYET (1 << 0) +#define USBFS_EP_T_RES_NAK (2 << 0) +#define USBFS_EP_T_RES_STALL (3 << 0) + +// RX_CTRL +#define USBFS_EP_R_RES_MASK (3 << 0) +#define USBFS_EP_R_TOG (1 << 2) +#define USBFS_EP_R_AUTO_TOG (1 << 3) + +#define USBFS_EP_R_RES_ACK (0 << 0) +#define USBFS_EP_R_RES_NYET (1 << 0) +#define USBFS_EP_R_RES_NAK (2 << 0) +#define USBFS_EP_R_RES_STALL (3 << 0) + +// token PID +#define PID_OUT 0 +#define PID_SOF 1 +#define PID_IN 2 +#define PID_SETUP 3 + +#endif // USB_CH32_USBFS_REG_H diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c new file mode 100644 index 000000000..256c46696 --- /dev/null +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -0,0 +1,304 @@ +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) + +#include +#include "device/dcd.h" +#include "ch32_usbfs_reg.h" + +/* private defines */ +#define EP_MAX (8) + +#define EP_DMA(ep) ((&USBOTG_FS->UEP0_DMA)[ep]) +#define EP_TX_LEN(ep) ((&USBOTG_FS->UEP0_TX_LEN)[2 * ep]) +#define EP_TX_CTRL(ep) ((&USBOTG_FS->UEP0_TX_CTRL)[4 * ep]) +#define EP_RX_CTRL(ep) ((&USBOTG_FS->UEP0_RX_CTRL)[4 * ep]) + +/* private data */ +struct usb_xfer { + bool valid; + uint8_t *buffer; + size_t len; + size_t processed_len; + size_t max_size; +}; + +static struct { + bool ep0_tog; + bool isochronous[EP_MAX]; + struct usb_xfer xfer[EP_MAX][2]; + TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; + TU_ATTR_ALIGNED(4) struct { + // OUT transfers >64 bytes will overwrite queued IN data! + uint8_t out[64]; + uint8_t in[1023]; + uint8_t pad; + } ep3_buffer; +} data; + +/* private helpers */ +static void update_in(uint8_t rhport, uint8_t ep, bool force) { + struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_IN]; + if (xfer->valid) { + if (force || xfer->len) { + size_t len = TU_MIN(xfer->max_size, xfer->len); + if (ep == 0) { + memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk + } else if (ep == 3) { + memcpy(data.ep3_buffer.in, xfer->buffer, len); + } else { + memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + EP_TX_LEN(ep) = len; + if (ep == 0) { + EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); + data.ep0_tog = !data.ep0_tog; + } else if (data.isochronous[ep]) { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; + } + } else { + xfer->valid = false; + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; + dcd_event_xfer_complete(rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, + XFER_RESULT_SUCCESS, true); + } + } +} + +static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { + struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; + if (xfer->valid) { + size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); + if (ep == 3) { + memcpy(xfer->buffer, data.ep3_buffer.out, len); + } else { + memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + if (xfer->len == 0 || len < xfer->max_size) { + xfer->valid = false; + dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); + } + + if (ep == 0) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } +} + +/* public functions */ +void dcd_init(uint8_t rhport) { + // init registers + USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; + USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; + USBOTG_FS->DEV_ADDR = 0x00; + + USBOTG_FS->INT_FG = 0xFF; + USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; + + // setup endpoint 0 + EP_DMA(0) = (uint32_t) &data.buffer[0][0]; + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + // enable other endpoints but NAK everything + USBOTG_FS->UEP4_1_MOD = 0xCC; + USBOTG_FS->UEP2_3_MOD = 0xCC; + USBOTG_FS->UEP5_6_MOD = 0xCC; + USBOTG_FS->UEP7_MOD = 0x0C; + + for (uint8_t ep = 1; ep < EP_MAX; ep++) { + EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + } + EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + + dcd_connect(rhport); +} + +void dcd_int_handler(uint8_t rhport) { + (void) rhport; + uint8_t status = USBOTG_FS->INT_FG; + if (status & USBFS_INT_FG_TRANSFER) { + uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); + uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); + + switch (token) { + case PID_OUT: { + uint16_t rx_len = USBOTG_FS->RX_LEN; + update_out(rhport, ep, rx_len); + break; + } + + case PID_IN: + update_in(rhport, ep, false); + break; + + case PID_SETUP: + data.ep0_tog = true; + dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); + break; + } + + USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; + } else if (status & USBFS_INT_FG_BUS_RST) { + data.ep0_tog = true; + data.xfer[0][TUSB_DIR_OUT].max_size = 64; + data.xfer[0][TUSB_DIR_IN].max_size = 64; + + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + + USBOTG_FS->DEV_ADDR = 0x00; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; + } else if (status & USBFS_INT_FG_SUSPEND) { + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; + dcd_event_handler(&event, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; + } +} + +void dcd_int_enable(uint8_t rhport) { + (void) rhport; + NVIC_EnableIRQ(USBHD_IRQn); +} + +void dcd_int_disable(uint8_t rhport) { + (void) rhport; + NVIC_DisableIRQ(USBHD_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void) dev_addr; + dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response +} + +void dcd_remote_wakeup(uint8_t rhport) { + (void) rhport; + // TODO optional +} + +void dcd_connect(uint8_t rhport) { + (void) rhport; + USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; +} + +void dcd_disconnect(uint8_t rhport) { + (void) rhport; + USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; +} + +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { + (void) rhport; + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; + } + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { + (void) rhport; + uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); + uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); + TU_ASSERT(ep < EP_MAX); + + data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; + data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); + + if (ep != 0) { + if (dir == TUSB_DIR_OUT) { + if (data.isochronous[ep]) { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; + } else { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; + } + } else { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + } + } + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) { + (void) rhport; + // TODO optional +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + (void) ep_addr; + // TODO optional +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + struct usb_xfer *xfer = &data.xfer[ep][dir]; + xfer->valid = true; + xfer->buffer = buffer; + xfer->len = total_bytes; + xfer->processed_len = 0; + + if (dir == TUSB_DIR_IN) { + update_in(rhport, ep, true); + } + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; + } else { + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; + } + } +} + +#endif // CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) diff --git a/src/tusb_option.h b/src/tusb_option.h index 058427e0e..3d04825a4 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -181,6 +181,7 @@ // WCH #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x +#define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X // NXP LPC MCX -- cgit v1.3.1 From 2a67ce773dcd68f7f8c4c07fce2e6e4f7947e03d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 May 2024 20:13:00 +0700 Subject: change default risv-gcc to riscv-none-elf- and add _zicsr extension add cmake for ch32v20x, skip freertos examples for CH32V20X, also skip net webserver due to lack of RAM update to use openocd with wlinke adapter --- .github/workflows/ci_set_matrix.py | 4 +- .idea/cmake.xml | 4 +- examples/build_system/cmake/cpu/rv32i-ilp32.cmake | 4 +- .../build_system/cmake/cpu/rv32imac-ilp32.cmake | 4 +- .../build_system/cmake/toolchain/riscv_gcc.cmake | 19 +++- examples/build_system/make/cpu/rv32i-ilp32.mk | 11 ++- examples/build_system/make/cpu/rv32imac-ilp32.mk | 10 +- .../device/audio_4_channel_mic_freertos/skip.txt | 1 + examples/device/audio_test_freertos/skip.txt | 1 + examples/device/net_lwip_webserver/skip.txt | 1 + examples/device/video_capture_2ch/skip.txt | 1 + hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 7 ++ hw/bsp/ch32v20x/family.cmake | 109 +++++++++++++++++++++ hw/bsp/ch32v20x/family.mk | 17 ++-- hw/bsp/ch32v20x/wch-riscv.cfg | 1 - hw/bsp/ch32v307/family.cmake | 1 - hw/bsp/ch32v307/family.mk | 8 +- hw/bsp/ch32v307/wch-riscv.cfg | 16 +-- hw/bsp/family_support.cmake | 1 + hw/bsp/fomu/family.mk | 6 +- hw/bsp/gd32vf103/family.mk | 7 +- src/portable/wch/dcd_ch32_usbfs.c | 8 ++ 22 files changed, 191 insertions(+), 50 deletions(-) create mode 100644 hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake create mode 100644 hw/bsp/ch32v20x/family.cmake (limited to 'src') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 62239c9ad..c6f4e8fe2 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -7,14 +7,14 @@ toolchain_list = { "arm-iar": "", "arm-gcc": "", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", - "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz", + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz" } # family: [supported toolchain] family_list = { "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], - "ch32v307 fomu gd32vf103": ["riscv-gcc"], + "ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], diff --git a/.idea/cmake.xml b/.idea/cmake.xml index bb13a0466..a34f19e1f 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -66,6 +66,7 @@ + @@ -103,6 +104,7 @@ + @@ -120,7 +122,6 @@ - @@ -130,6 +131,7 @@ + \ No newline at end of file diff --git a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake index b4889e6ff..605c40ba1 100644 --- a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake +++ b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake @@ -1,13 +1,13 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32i + -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32i + -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") diff --git a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake index dd1bc0af7..584d90519 100644 --- a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake +++ b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake @@ -1,13 +1,13 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32imac + -march=rv32imac_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32imac + -march=rv32imac_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") diff --git a/examples/build_system/cmake/toolchain/riscv_gcc.cmake b/examples/build_system/cmake/toolchain/riscv_gcc.cmake index 904b27294..d788df023 100644 --- a/examples/build_system/cmake/toolchain/riscv_gcc.cmake +++ b/examples/build_system/cmake/toolchain/riscv_gcc.cmake @@ -1,15 +1,24 @@ +# default Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +if (NOT DEFINED CROSS_COMPILE) + set(CROSS_COMPILE "riscv-none-elf-") +endif () + +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) +endif () + if (NOT DEFINED CMAKE_C_COMPILER) - set(CMAKE_C_COMPILER "riscv-none-embed-gcc") + set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) endif () if (NOT DEFINED CMAKE_CXX_COMPILER) - set(CMAKE_CXX_COMPILER "riscv-none-embed-g++") + set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++) endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) -set(CMAKE_SIZE "riscv-none-embed-size" CACHE FILEPATH "") -set(CMAKE_OBJCOPY "riscv-none-embed-objcopy" CACHE FILEPATH "") -set(CMAKE_OBJDUMP "riscv-none-embed-objdump" CACHE FILEPATH "") +set(CMAKE_SIZE ${CROSS_COMPILE}size CACHE FILEPATH "") +set(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy CACHE FILEPATH "") +set(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump CACHE FILEPATH "") include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) diff --git a/examples/build_system/make/cpu/rv32i-ilp32.mk b/examples/build_system/make/cpu/rv32i-ilp32.mk index a465baf4c..af764afc5 100644 --- a/examples/build_system/make/cpu/rv32i-ilp32.mk +++ b/examples/build_system/make/cpu/rv32i-ilp32.mk @@ -1,12 +1,15 @@ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ - -march=rv32i \ + -march=rv32i_zicsr \ -mabi=ilp32 \ -else ifeq ($(TOOLCHAIN),iar) - #CFLAGS += --cpu cortex-a53 - #ASFLAGS += --cpu cortex-a53 +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + -march=rv32i_zicsr \ + -mabi=ilp32 \ +else ifeq ($(TOOLCHAIN),iar) + $(error not support) endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/rv32imac-ilp32.mk b/examples/build_system/make/cpu/rv32imac-ilp32.mk index 2b6493e48..19c322ebc 100644 --- a/examples/build_system/make/cpu/rv32imac-ilp32.mk +++ b/examples/build_system/make/cpu/rv32imac-ilp32.mk @@ -1,11 +1,15 @@ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ - -march=rv32imac \ + -march=rv32imac_zicsr \ + -mabi=ilp32 \ + +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + -march=rv32imac_zicsr \ -mabi=ilp32 \ else ifeq ($(TOOLCHAIN),iar) - #CFLAGS += --cpu cortex-a53 - #ASFLAGS += --cpu cortex-a53 + $(error not support) endif diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 0b689192d..4769af009 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index a6f96b288..6aaa27661 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index 43cdab71a..51af58667 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:LPC11UXX mcu:LPC13XX mcu:LPC15XX diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 86697899b..1786297f9 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -2,6 +2,7 @@ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:GD32VF103 +mcu:CH32V20X mcu:CH32V307 mcu:STM32L0 family:espressif diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake new file mode 100644 index 000000000..2699f3e15 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -0,0 +1,7 @@ +set(MCU_VARIANT D6) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CH32V20x_D6 + ) +endfunction() diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake new file mode 100644 index 000000000..fb39e3630 --- /dev/null +++ b/hw/bsp/ch32v20x/family.cmake @@ -0,0 +1,109 @@ +include_guard() + +set(CH32_FAMILY ch32v20x) +set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V20X CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/Ld/Link.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Core/core_riscv.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medany + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_CH32V20X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) +endfunction() diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 2d94f19fb..7e290bb18 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -1,3 +1,9 @@ +# 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- @@ -9,23 +15,21 @@ DEPS_SUBMODULES += $(CH32V20X_SDK) CH32V20X_SDK_SRC = $(CH32V20X_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ - -march=rv32imac_zicsr \ - -mabi=ilp32 \ -mcmodel=medany \ -ffunction-sections \ -fdata-sections \ -ffat-lto-objects \ -flto \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ LDFLAGS_GCC += \ -Wl,--gc-sections \ - -specs=nosys.specs \ - -specs=nano.specs \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ LD_FILE = $(CH32V20X_SDK_SRC)/Ld/Link.ld @@ -46,5 +50,6 @@ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V # wch-link is not supported yet in official openOCD yet. We need to either use # 1. download openocd as part of mounriver studio http://www.mounriver.com/download or # 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +OPENOCD ?= $(HOME)/app/riscv-openocd-wch/src/openocd flash: $(BUILD)/$(PROJECT).elf - openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit + $(OPENOCD) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit diff --git a/hw/bsp/ch32v20x/wch-riscv.cfg b/hw/bsp/ch32v20x/wch-riscv.cfg index 56a18d77e..aa35aa9c5 100644 --- a/hw/bsp/ch32v20x/wch-riscv.cfg +++ b/hw/bsp/ch32v20x/wch-riscv.cfg @@ -1,4 +1,3 @@ -#interface wlink adapter driver wlinke adapter speed 6000 transport select sdi diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index 87a0f2eba..fb478d387 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -11,7 +11,6 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -set(OPENOCD_OPTION2 "-c wlink_reset_resume") #------------------------------------ # BOARD_TARGET diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 7232bfa08..df9ded4a0 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -1,11 +1,11 @@ # https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable #CROSS_COMPILE ?= riscv32-unknown-elf- -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE ?= riscv-none-embed- +# 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- +CROSS_COMPILE ?= riscv-none-elf- # Submodules CH32V307_SDK = hw/mcu/wch/ch32v307 @@ -16,8 +16,6 @@ CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 -# -march=rv32imac_zicsr - CFLAGS += \ -flto \ -msmall-data-limit=8 \ diff --git a/hw/bsp/ch32v307/wch-riscv.cfg b/hw/bsp/ch32v307/wch-riscv.cfg index 0d24d16ca..aa35aa9c5 100644 --- a/hw/bsp/ch32v307/wch-riscv.cfg +++ b/hw/bsp/ch32v307/wch-riscv.cfg @@ -1,13 +1,15 @@ -#interface wlink -adapter driver wlink -wlink_set -set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 +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 riscv -chain-position $_TARGETNAME -$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index df4f616ef..6eef5b88b 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -440,6 +440,7 @@ function(family_flash_openocd TARGET) endfunction() # Add flash openocd-wch target +# compiled from https://github.com/hathach/riscv-openocd-wch or https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz function(family_flash_openocd_wch TARGET) if (NOT DEFINED OPENOCD) set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd) diff --git a/hw/bsp/fomu/family.mk b/hw/bsp/fomu/family.mk index 78f20d7db..69a546964 100644 --- a/hw/bsp/fomu/family.mk +++ b/hw/bsp/fomu/family.mk @@ -1,9 +1,5 @@ -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE = riscv-none-embed- - # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -# CROSS_COMPILE = riscv-none-elf- -# -march=rv32i_zicsr +CROSS_COMPILE = riscv-none-elf- CPU_CORE ?= rv32i-ilp32 diff --git a/hw/bsp/gd32vf103/family.mk b/hw/bsp/gd32vf103/family.mk index 646564eae..48588886c 100644 --- a/hw/bsp/gd32vf103/family.mk +++ b/hw/bsp/gd32vf103/family.mk @@ -4,11 +4,8 @@ # Toolchain from https://nucleisys.com/download.php #CROSS_COMPILE ?= riscv-nuclei-elf- -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE ?= riscv-none-embed- - # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -# CROSS_COMPILE ?= riscv-none-elf- +CROSS_COMPILE ?= riscv-none-elf- # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk @@ -22,8 +19,6 @@ STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 -# -march=rv32imac_zicsr - CFLAGS += \ -mcmodel=medlow \ -mstrict-align \ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 256c46696..83f625e21 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -201,6 +201,14 @@ void dcd_disconnect(uint8_t rhport) { USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && -- cgit v1.3.1 From ab5f2768773634efe8c79add7e009e2e2ca63279 Mon Sep 17 00:00:00 2001 From: Matthew Tran Date: Fri, 17 May 2024 09:52:06 -0700 Subject: fix ep0 stall not clearing --- src/portable/wch/dcd_ch32_usbfs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 83f625e21..3af3ff6d7 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -148,6 +148,8 @@ void dcd_int_handler(uint8_t rhport) { case PID_SETUP: data.ep0_tog = true; + dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_IN)); // setup clears stall + dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_OUT)); dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); break; } @@ -261,10 +263,12 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to uint8_t dir = tu_edpt_dir(ep_addr); struct usb_xfer *xfer = &data.xfer[ep][dir]; + dcd_int_disable(rhport); xfer->valid = true; xfer->buffer = buffer; xfer->len = total_bytes; xfer->processed_len = 0; + dcd_int_enable(rhport); if (dir == TUSB_DIR_IN) { update_in(rhport, ep, true); -- cgit v1.3.1 From 5fee292606e4c5502b2172328c02d5df24eb0c7c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 17 May 2024 16:13:59 +0700 Subject: temp code --- hw/bsp/ch32v307/family.c | 25 +++++++++++++++++++++++++ hw/bsp/ch32v307/family.cmake | 23 ++++++++++++++--------- src/common/tusb_mcu.h | 4 ++-- src/portable/wch/ch32_usbfs_reg.h | 9 ++++++++- src/portable/wch/dcd_ch32_usbfs.c | 2 +- 5 files changed, 50 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 245fa5674..50e48e7df 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -46,6 +46,18 @@ __attribute__ ((used)) void USBHS_IRQHandler_impl (void) tud_int_handler(0); } + +void OTG_FS_IRQHandler (void) __attribute__((naked)); +void OTG_FS_IRQHandler (void) +{ + __asm volatile ("call OTG_FS_IRQHandler_impl; mret"); +} + +__attribute__ ((used)) void OTG_FS_IRQHandler_impl (void) +{ + tud_int_handler(0); +} + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -72,6 +84,7 @@ void board_init(void) { usart_printf_init(115200); + #if 0 RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); @@ -79,6 +92,18 @@ void board_init(void) { RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); + #else + uint8_t otg_div; + switch (SystemCoreClock) { + case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; + case 96000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div2; break; + case 144000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div3; break; + default: TU_ASSERT(0,); break; + } + RCC_OTGFSCLKConfig(otg_div); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); + #endif + GPIO_InitTypeDef GPIO_InitStructure = {0}; // LED diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index fb478d387..8a4bd7730 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -1,5 +1,6 @@ include_guard() +set(CH32_FAMILY ch32v30x) set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) # include board specific @@ -12,6 +13,8 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") +# Port0 Fullspeed, Port1 Highspeed + #------------------------------------ # BOARD_TARGET #------------------------------------ @@ -27,18 +30,18 @@ function(add_board_target BOARD_TARGET) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_ch32v30x_D8C.S) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Core/core_riscv.c - ${SDK_DIR}/Peripheral/src/ch32v30x_gpio.c - ${SDK_DIR}/Peripheral/src/ch32v30x_misc.c - ${SDK_DIR}/Peripheral/src/ch32v30x_rcc.c - ${SDK_DIR}/Peripheral/src/ch32v30x_usart.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch32v30x_it.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch32v30x.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${CH32_FAMILY}_it.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC @@ -46,7 +49,8 @@ function(add_board_target BOARD_TARGET) ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + #BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED ) update_board(${BOARD_TARGET}) @@ -100,7 +104,8 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V307 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/wch/dcd_ch32_usbhs.c + #${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index eab112015..e313fea05 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -404,8 +404,8 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 8 +// #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_DCD_ENDPOINT_MAX 16 diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 3b8e49ae2..d5341f3a8 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -1,8 +1,15 @@ #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H -#if (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) +#include +#define USBHD_IRQn OTG_FS_IRQn + +#elif (CFG_TUSB_MCU == OPT_MCU_CH32V20X) #include + +#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) +#include #endif // CTRL diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 3af3ff6d7..3e4b6cae5 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,6 +1,6 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X || CFG_TUSB_MCU == OPT_MCU_CH32V307) #include #include "device/dcd.h" -- cgit v1.3.1 From b19295c1c15de676e7cebd5bd5b6aa53887c6a56 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 17:26:04 +0700 Subject: use correct wch usbhs, usbfs for ch32v307 using CFG_TUD_MAX_SPEED --- examples/build_system/make/rules.mk | 11 ++++++ hw/bsp/ch32v20x/family.mk | 10 +---- hw/bsp/ch32v307/family.c | 77 ++++++++++++------------------------- hw/bsp/ch32v307/family.cmake | 27 +++++++------ hw/bsp/ch32v307/family.mk | 61 +++++++++++++---------------- src/common/tusb_mcu.h | 16 ++++++-- src/portable/wch/ch32_usbhs_reg.h | 4 +- src/portable/wch/dcd_ch32_usbfs.c | 3 +- src/portable/wch/dcd_ch32_usbhs.c | 6 +-- 9 files changed, 98 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/examples/build_system/make/rules.mk b/examples/build_system/make/rules.mk index 7b6b339ed..102c6db0c 100644 --- a/examples/build_system/make/rules.mk +++ b/examples/build_system/make/rules.mk @@ -134,6 +134,17 @@ OPENOCD_OPTION ?= flash-openocd: $(BUILD)/$(PROJECT).elf openocd $(OPENOCD_OPTION) -c "program $< verify reset exit" +# --------------- openocd-wch ----------------- +# wch-linke is not supported yet in official openOCD yet. We need to either use +# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or +# 2. compiled from https://github.com/hathach/riscv-openocd-wch or +# https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +# with ./configure --disable-werror --enable-wlinke --enable-ch347=no +OPENOCD_WCH ?= /home/${USER}/app/riscv-openocd-wch/src/openocd +OPENOCD_WCH_OPTION ?= +flash-openocd-wch: $(BUILD)/$(PROJECT).elf + $(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit + # --------------- dfu-util ----------------- DFU_UTIL_OPTION ?= -a 0 flash-dfu-util: $(BUILD)/$(PROJECT).bin diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 6b09fdac7..5c8b31a1c 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -16,8 +16,6 @@ CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ -mcmodel=medany \ - -ffunction-sections \ - -fdata-sections \ -ffat-lto-objects \ -flto \ -DCH32V20x_${MCU_VARIANT} \ @@ -46,9 +44,5 @@ INC += \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V -# wch-link is not supported yet in official openOCD yet. We need to either use -# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or -# 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz -OPENOCD ?= $(HOME)/app/riscv-openocd-wch/src/openocd -flash: $(BUILD)/$(PROJECT).elf - $(OPENOCD) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 50e48e7df..fe37ea8e3 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -35,41 +35,31 @@ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USBHS_IRQHandler (void) __attribute__((naked)); -void USBHS_IRQHandler (void) -{ - __asm volatile ("call USBHS_IRQHandler_impl; mret"); -} +// TODO maybe having FS as port0, HS as port1 -__attribute__ ((used)) void USBHS_IRQHandler_impl (void) -{ +__attribute__((interrupt)) void USBHS_IRQHandler(void) { + #if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED tud_int_handler(0); + #endif } - -void OTG_FS_IRQHandler (void) __attribute__((naked)); -void OTG_FS_IRQHandler (void) -{ - __asm volatile ("call OTG_FS_IRQHandler_impl; mret"); -} - -__attribute__ ((used)) void OTG_FS_IRQHandler_impl (void) -{ +__attribute__((interrupt)) void OTG_FS_IRQHandler(void) { + #if CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED tud_int_handler(0); + #endif } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -uint32_t SysTick_Config(uint32_t ticks) -{ +uint32_t SysTick_Config(uint32_t ticks) { NVIC_EnableIRQ(SysTicK_IRQn); - SysTick->CTLR=0; - SysTick->SR=0; - SysTick->CNT=0; - SysTick->CMP=ticks-1; - SysTick->CTLR=0xF; + SysTick->CTLR = 0; + SysTick->SR = 0; + SysTick->CNT = 0; + SysTick->CMP = ticks - 1; + SysTick->CTLR = 0xF; return 0; } @@ -82,17 +72,17 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #endif - usart_printf_init(115200); + usart_printf_init(115200); - #if 0 +#if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED + // Use Highspeed USB RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); - - #else +#else uint8_t otg_div; switch (SystemCoreClock) { case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; @@ -102,7 +92,7 @@ void board_init(void) { } RCC_OTGFSCLKConfig(otg_div); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); - #endif +#endif GPIO_InitTypeDef GPIO_InitStructure = {0}; @@ -127,24 +117,14 @@ void board_init(void) { } #if CFG_TUSB_OS == OPT_OS_NONE - volatile uint32_t system_ticks = 0; -/* Small workaround to support HW stack save/restore */ -void SysTick_Handler (void) __attribute__((naked)); -void SysTick_Handler (void) -{ - __asm volatile ("call SysTick_Handler_impl; mret"); -} - -__attribute__((used)) void SysTick_Handler_impl (void) -{ +__attribute__((interrupt)) void SysTick_Handler(void) { SysTick->SR = 0; system_ticks++; } -uint32_t board_millis (void) -{ +uint32_t board_millis(void) { return system_ticks; } @@ -154,36 +134,29 @@ uint32_t board_millis (void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write (bool state) -{ +void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state); } -uint32_t board_button_read (void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read (uint8_t *buf, int 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 board_uart_write(void const* buf, int len) { int txsize = len; - while ( txsize-- ) - { + while (txsize--) { uart_write(*(uint8_t const*) buf); buf++; } return len; } - - #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index 8a4bd7730..fd475c987 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -1,7 +1,8 @@ include_guard() set(CH32_FAMILY ch32v30x) -set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -13,7 +14,10 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -# Port0 Fullspeed, Port1 Highspeed +# default to highspeed +if (NOT DEFINED SPEED) + set(SPEED high) +endif() #------------------------------------ # BOARD_TARGET @@ -30,27 +34,26 @@ function(add_board_target BOARD_TARGET) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/Core/core_riscv.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${CH32_FAMILY}_it.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/Peripheral/inc + ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC - #BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED - BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + BOARD_TUD_MAX_SPEED=$,OPT_MODE_HIGH_SPEED,OPT_MODE_FULL_SPEED> ) update_board(${BOARD_TARGET}) @@ -104,7 +107,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V307 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - #${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ${TOP}/src/portable/wch/dcd_ch32_usbhs.c ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index df9ded4a0..2dbe0c46a 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -7,63 +7,54 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- -# Submodules -CH32V307_SDK = hw/mcu/wch/ch32v307 - -# WCH-SDK paths -CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC +CH32_FAMILY = ch32v30x +SDK_DIR = hw/mcu/wch/ch32v307 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# default to use high speed port, unless specified in board.mk or command line +SPEED ?= high + CFLAGS += \ -flto \ -msmall-data-limit=8 \ - -mno-save-restore -Os \ + -mno-save-restore \ -fmessage-length=0 \ -fsigned-char \ - -ffunction-sections \ - -fdata-sections \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ - -Xlinker --gc-sections \ - -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +ifeq ($(SPEED),high) + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using USBHS driver for HighSpeed mode") +else + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + $(info "Using USBFS driver for FullSpeed mode") +endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ - --specs=nosys.specs --specs=nano.specs + --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/wch/dcd_ch32_usbhs.c \ - $(CH32V307_SDK_SRC)/Core/core_riscv.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_gpio.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_misc.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_rcc.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_usart.c + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/Core/core_riscv.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c SRC_S += \ - $(CH32V307_SDK_SRC)/Startup/startup_ch32v30x_D8C.S + $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_D8C.S INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(CH32V307_SDK_SRC)/Peripheral/inc + $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V -# wch-link is not supported yet in official openOCD yet. We need to either use -# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or -# 2. compiled from modified source https://github.com/kprasadvnsi/riscv-openocd-wch -# -# Note: For Linux, somehow openocd in mounriver studio does not seem to have wch-link enable, -# therefore we need to compile it from source as follows: -# git clone https://github.com/kprasadvnsi/riscv-openocd-wch -# cd riscv-openocd-wch -# ./bootstrap -# ./configure CFLAGS="-Wno-error" --enable-wlink -# make -# openocd binaries will be generated in riscv-openocd-wch/src - -# flash target ROM bootloader -OPENOCD_WCH = /home/${USER}/app/riscv-openocd-wch/src/openocd -flash: $(BUILD)/$(PROJECT).elf - $(OPENOCD_WCH) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c wlink_reset_resume -c exit +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index e313fea05..d928e44e8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -404,14 +404,22 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) - #define TUP_DCD_ENDPOINT_MAX 8 -// #define TUP_RHPORT_HIGHSPEED 1 + // v307 support both FS and HS + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + #define TUP_USBIP_WCH_USBFS #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 9b956231f..6ae91ec71 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -2,9 +2,9 @@ #define _USB_CH32_USBHS_REG_H #if (CFG_TUSB_MCU == OPT_MCU_CH32V307) -#include + #include #elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) -#include + #include #endif /******************* GLOBAL ******************/ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 3e4b6cae5..413fe92c9 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,6 +1,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X || CFG_TUSB_MCU == OPT_MCU_CH32V307) +// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) #include #include "device/dcd.h" diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 68e2179e9..9a12fc97f 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -26,11 +26,11 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && ((CFG_TUSB_MCU == OPT_MCU_CH32V307) || (CFG_TUSB_MCU == OPT_MCU_CH32F20X)) -#include "device/dcd.h" - +// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is high speed +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) #include "ch32_usbhs_reg.h" +#include "device/dcd.h" // Max number of bi-directional endpoints including EP0 #define EP_MAX 16 -- cgit v1.3.1 From 07d879378f052386699aba1eb41f04d4d32fb865 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 17:32:40 +0700 Subject: code format add missing MIT license --- .idea/cmake.xml | 2 + src/portable/wch/ch32_usbfs_reg.h | 41 +++- src/portable/wch/ch32_usbhs_reg.h | 37 ++- src/portable/wch/dcd_ch32_usbfs.c | 482 ++++++++++++++++++++------------------ 4 files changed, 323 insertions(+), 239 deletions(-) (limited to 'src') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index a34f19e1f..d96b46853 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -132,6 +132,8 @@ + + \ No newline at end of file diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index d5341f3a8..0a50a6169 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -1,15 +1,42 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * 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 USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H -#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) -#include -#define USBHD_IRQn OTG_FS_IRQn +#if CFG_TUSB_MCU == OPT_MCU_CH32V307 + #include + #define USBHD_IRQn OTG_FS_IRQn -#elif (CFG_TUSB_MCU == OPT_MCU_CH32V20X) -#include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include -#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) -#include +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include #endif // CTRL diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 6ae91ec71..a3a41bb6a 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -1,9 +1,36 @@ -#ifndef _USB_CH32_USBHS_REG_H -#define _USB_CH32_USBHS_REG_H - -#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * 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 USB_CH32_USBHS_REG_H +#define USB_CH32_USBHS_REG_H + +#if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include -#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 413fe92c9..dafe4414e 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,9 +1,35 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * 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 "tusb_option.h" // Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed #if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) -#include #include "device/dcd.h" #include "ch32_usbfs_reg.h" @@ -17,301 +43,303 @@ /* private data */ struct usb_xfer { - bool valid; - uint8_t *buffer; - size_t len; - size_t processed_len; - size_t max_size; + bool valid; + uint8_t* buffer; + size_t len; + size_t processed_len; + size_t max_size; }; static struct { - bool ep0_tog; - bool isochronous[EP_MAX]; - struct usb_xfer xfer[EP_MAX][2]; - TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; - TU_ATTR_ALIGNED(4) struct { - // OUT transfers >64 bytes will overwrite queued IN data! - uint8_t out[64]; - uint8_t in[1023]; - uint8_t pad; - } ep3_buffer; + bool ep0_tog; + bool isochronous[EP_MAX]; + struct usb_xfer xfer[EP_MAX][2]; + TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; + TU_ATTR_ALIGNED(4) struct { + // OUT transfers >64 bytes will overwrite queued IN data! + uint8_t out[64]; + uint8_t in[1023]; + uint8_t pad; + } ep3_buffer; } data; /* private helpers */ static void update_in(uint8_t rhport, uint8_t ep, bool force) { - struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_IN]; - if (xfer->valid) { - if (force || xfer->len) { - size_t len = TU_MIN(xfer->max_size, xfer->len); - if (ep == 0) { - memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk - } else if (ep == 3) { - memcpy(data.ep3_buffer.in, xfer->buffer, len); - } else { - memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); - } - xfer->buffer += len; - xfer->len -= len; - xfer->processed_len += len; - - EP_TX_LEN(ep) = len; - if (ep == 0) { - EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); - data.ep0_tog = !data.ep0_tog; - } else if (data.isochronous[ep]) { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; - } - } else { - xfer->valid = false; - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; - dcd_event_xfer_complete(rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, - XFER_RESULT_SUCCESS, true); - } + struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_IN]; + if (xfer->valid) { + if (force || xfer->len) { + size_t len = TU_MIN(xfer->max_size, xfer->len); + if (ep == 0) { + memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk + } else if (ep == 3) { + memcpy(data.ep3_buffer.in, xfer->buffer, len); + } else { + memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + EP_TX_LEN(ep) = len; + if (ep == 0) { + EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); + data.ep0_tog = !data.ep0_tog; + } else if (data.isochronous[ep]) { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; + } + } else { + xfer->valid = false; + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; + dcd_event_xfer_complete( + rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, + XFER_RESULT_SUCCESS, true); } + } } static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { - struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; - if (xfer->valid) { - size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); - if (ep == 3) { - memcpy(xfer->buffer, data.ep3_buffer.out, len); - } else { - memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); - } - xfer->buffer += len; - xfer->len -= len; - xfer->processed_len += len; - - if (xfer->len == 0 || len < xfer->max_size) { - xfer->valid = false; - dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); - } - - if (ep == 0) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; - } + struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_OUT]; + if (xfer->valid) { + size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); + if (ep == 3) { + memcpy(xfer->buffer, data.ep3_buffer.out, len); + } else { + memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); } -} + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; -/* public functions */ -void dcd_init(uint8_t rhport) { - // init registers - USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; - USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; - USBOTG_FS->DEV_ADDR = 0x00; - - USBOTG_FS->INT_FG = 0xFF; - USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; - - // setup endpoint 0 - EP_DMA(0) = (uint32_t) &data.buffer[0][0]; - EP_TX_LEN(0) = 0; - EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + if (xfer->len == 0 || len < xfer->max_size) { + xfer->valid = false; + dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); + } - // enable other endpoints but NAK everything - USBOTG_FS->UEP4_1_MOD = 0xCC; - USBOTG_FS->UEP2_3_MOD = 0xCC; - USBOTG_FS->UEP5_6_MOD = 0xCC; - USBOTG_FS->UEP7_MOD = 0x0C; - - for (uint8_t ep = 1; ep < EP_MAX; ep++) { - EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + if (ep == 0) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } - EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + } +} - dcd_connect(rhport); +/* public functions */ +void dcd_init(uint8_t rhport) { + // init registers + USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; + USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; + USBOTG_FS->DEV_ADDR = 0x00; + + USBOTG_FS->INT_FG = 0xFF; + USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; + + // setup endpoint 0 + EP_DMA(0) = (uint32_t) &data.buffer[0][0]; + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + // enable other endpoints but NAK everything + USBOTG_FS->UEP4_1_MOD = 0xCC; + USBOTG_FS->UEP2_3_MOD = 0xCC; + USBOTG_FS->UEP5_6_MOD = 0xCC; + USBOTG_FS->UEP7_MOD = 0x0C; + + for (uint8_t ep = 1; ep < EP_MAX; ep++) { + EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + } + EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + + dcd_connect(rhport); } void dcd_int_handler(uint8_t rhport) { - (void) rhport; - uint8_t status = USBOTG_FS->INT_FG; - if (status & USBFS_INT_FG_TRANSFER) { - uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); - uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); - - switch (token) { - case PID_OUT: { - uint16_t rx_len = USBOTG_FS->RX_LEN; - update_out(rhport, ep, rx_len); - break; - } - - case PID_IN: - update_in(rhport, ep, false); - break; - - case PID_SETUP: - data.ep0_tog = true; - dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_IN)); // setup clears stall - dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_OUT)); - dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); - break; - } - - USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; - } else if (status & USBFS_INT_FG_BUS_RST) { + (void) rhport; + uint8_t status = USBOTG_FS->INT_FG; + if (status & USBFS_INT_FG_TRANSFER) { + uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); + uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); + + switch (token) { + case PID_OUT: { + uint16_t rx_len = USBOTG_FS->RX_LEN; + update_out(rhport, ep, rx_len); + break; + } + + case PID_IN: + update_in(rhport, ep, false); + break; + + case PID_SETUP: + // setup clears stall + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + data.ep0_tog = true; - data.xfer[0][TUSB_DIR_OUT].max_size = 64; - data.xfer[0][TUSB_DIR_IN].max_size = 64; + dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); + break; + } - dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; + } else if (status & USBFS_INT_FG_BUS_RST) { + data.ep0_tog = true; + data.xfer[0][TUSB_DIR_OUT].max_size = 64; + data.xfer[0][TUSB_DIR_IN].max_size = 64; - USBOTG_FS->DEV_ADDR = 0x00; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); - USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; - } else if (status & USBFS_INT_FG_SUSPEND) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; - dcd_event_handler(&event, true); - USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; - } + USBOTG_FS->DEV_ADDR = 0x00; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; + } else if (status & USBFS_INT_FG_SUSPEND) { + dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; + dcd_event_handler(&event, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; + } } void dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(USBHD_IRQn); + (void) rhport; + NVIC_EnableIRQ(USBHD_IRQn); } void dcd_int_disable(uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(USBHD_IRQn); + (void) rhport; + NVIC_DisableIRQ(USBHD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void) dev_addr; - dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response + (void) dev_addr; + dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response } void dcd_remote_wakeup(uint8_t rhport) { - (void) rhport; - // TODO optional + (void) rhport; + // TODO optional } void dcd_connect(uint8_t rhport) { - (void) rhport; - USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; + (void) rhport; + USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; } void dcd_disconnect(uint8_t rhport) { - (void) rhport; - USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; + (void) rhport; + USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { - (void) rhport; - if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS) { - USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; - } - EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { + (void) rhport; + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; + } + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { - (void) rhport; - uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); - uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); - TU_ASSERT(ep < EP_MAX); - - data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; - data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); - - if (ep != 0) { - if (dir == TUSB_DIR_OUT) { - if (data.isochronous[ep]) { - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; - } else { - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; - } - } else { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; - } +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { + (void) rhport; + uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); + uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); + TU_ASSERT(ep < EP_MAX); + + data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; + data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); + + if (ep != 0) { + if (dir == TUSB_DIR_OUT) { + if (data.isochronous[ep]) { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; + } else { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; + } + } else { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; } - return true; + } + return true; } void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - // TODO optional + (void) rhport; + // TODO optional } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - (void) ep_addr; - // TODO optional + (void) rhport; + (void) ep_addr; + // TODO optional } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - - struct usb_xfer *xfer = &data.xfer[ep][dir]; - dcd_int_disable(rhport); - xfer->valid = true; - xfer->buffer = buffer; - xfer->len = total_bytes; - xfer->processed_len = 0; - dcd_int_enable(rhport); - - if (dir == TUSB_DIR_IN) { - update_in(rhport, ep, true); - } - return true; +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + struct usb_xfer* xfer = &data.xfer[ep][dir]; + dcd_int_disable(rhport); + xfer->valid = true; + xfer->buffer = buffer; + xfer->len = total_bytes; + xfer->processed_len = 0; + dcd_int_enable(rhport); + + if (dir == TUSB_DIR_IN) { + update_in(rhport, ep, true); + } + return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - if (ep == 0) { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; - } else { - EP_TX_LEN(0) = 0; - EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; - } + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; - } + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; + } + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - if (ep == 0) { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; - } + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; - } + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; } + } } -#endif // CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#endif -- cgit v1.3.1 From 10b1e38404c044345e9ea0f3e5c678af94eb0f0a Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 18:30:38 +0700 Subject: revert unrelated changes to video_device.c --- src/class/video/video_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 974289b69..4218835aa 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -609,7 +609,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - uint_fast32_t interval, interval_ms = 0; + uint_fast32_t interval, interval_ms; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; -- cgit v1.3.1