summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-07-05 11:26:48 +0700
committerhathach <[email protected]>2025-07-05 11:26:48 +0700
commit6e88895dbc2b09e60b971f1587d19d3a2487c2f8 (patch)
tree6e5eeec457d04df6c711428bb88b1a16a2129baa /src
parent1b5f97ff23776279a011e2ab14a85f29e1aa6c10 (diff)
always define CFG_TUH_WCH_USBIP_USBFS=1 for ch32v20x since only port1 support host mode
reformat hcd usbfs add uart rx for ch32v20x bsp
Diffstat (limited to 'src')
-rw-r--r--src/common/tusb_mcu.h8
-rw-r--r--src/portable/wch/dcd_ch32_usbhs.c2
-rw-r--r--src/portable/wch/hcd_ch32_usbfs.c909
3 files changed, 412 insertions, 507 deletions
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index 2ee2132bf..a08ed79c8 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -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
diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c
index f8bf3c889..4a208b9df 100644
--- a/src/portable/wch/dcd_ch32_usbhs.c
+++ b/src/portable/wch/dcd_ch32_usbhs.c
@@ -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"
diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c
index 800390989..d176f40c5 100644
--- a/src/portable/wch/hcd_ch32_usbfs.c
+++ b/src/portable/wch/hcd_ch32_usbfs.c
@@ -37,20 +37,20 @@
#include "ch32v20x.h"
#include "ch32v20x_usb.h"
-void osal_task_delay(uint32_t msec) {
- uint32_t start = board_millis();
- while (board_millis() - start < msec) {}
-}
-
#define USBFS_RX_BUF_LEN 64
#define USBFS_TX_BUF_LEN 64
-__attribute__((aligned(4))) static uint8_t USBFS_RX_Buf[USBFS_RX_BUF_LEN];
-__attribute__((aligned(4))) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN];
+TU_ATTR_ALIGNED(4) static uint8_t USBFS_RX_Buf[USBFS_RX_BUF_LEN];
+TU_ATTR_ALIGNED(4) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN];
#define USB_XFER_TIMEOUT_MILLIS 100
// #define USB_INTERRUPT_XFER_TIMEOUT_MILLIS 1
-#define PANIC(...) do { printf("%s() L%d: ", __func__, __LINE__); printf("\r\n[PANIC] " __VA_ARGS__); while (true) { } } while (false)
+#define PANIC(...) \
+ do { \
+ printf("%s() L%d: ", __func__, __LINE__); \
+ printf("\r\n[PANIC] " __VA_ARGS__); \
+ while (true) {} \
+ } while (false)
#define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__)
@@ -70,106 +70,87 @@ __attribute__((aligned(4))) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN];
// Endpoint status
-typedef struct usb_edpt
-{
- // Is this a valid struct
- bool configured;
+typedef struct usb_edpt {
+ // Is this a valid struct
+ bool configured;
- uint8_t dev_addr;
- uint8_t ep_addr;
- uint8_t max_packet_size;
+ uint8_t dev_addr;
+ uint8_t ep_addr;
+ uint8_t max_packet_size;
- uint8_t xfer_type;
+ uint8_t xfer_type;
- // Data toggle (0 or not 0) for DATA0/1
- uint8_t data_toggle;
+ // Data toggle (0 or not 0) for DATA0/1
+ uint8_t data_toggle;
} usb_edpt_t;
-
static usb_edpt_t usb_edpt_list[CFG_TUH_DEVICE_MAX * 6] = {};
-
typedef struct usb_current_xfer_st {
- bool is_busy;
- uint8_t dev_addr;
- uint8_t ep_addr;
- // Xfer started time in millis for timeout
- uint32_t start_ms;
- uint8_t* buffer;
- uint16_t bufferlen;
- uint16_t xferred_len;
+ bool is_busy;
+ uint8_t dev_addr;
+ uint8_t ep_addr;
+ // Xfer started time in millis for timeout
+ uint32_t start_ms;
+ uint8_t *buffer;
+ uint16_t bufferlen;
+ uint16_t xferred_len;
} usb_current_xfer_t;
static volatile usb_current_xfer_t usb_current_xfer_info = {};
-
-static usb_edpt_t* get_edpt_record(uint8_t dev_addr, uint8_t ep_addr)
-{
- for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++)
- {
- usb_edpt_t* cur = &usb_edpt_list[i];
- if (cur->configured && cur->dev_addr == dev_addr && cur->ep_addr == ep_addr)
- {
- return cur;
- }
+static usb_edpt_t *get_edpt_record(uint8_t dev_addr, uint8_t ep_addr) {
+ for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) {
+ usb_edpt_t *cur = &usb_edpt_list[i];
+ if (cur->configured && cur->dev_addr == dev_addr && cur->ep_addr == ep_addr) {
+ return cur;
}
- return NULL;
+ }
+ return NULL;
}
-static usb_edpt_t* get_empty_record_slot(void)
-{
- for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++)
- {
- if (!usb_edpt_list[i].configured)
- {
- return &usb_edpt_list[i];
- }
+static usb_edpt_t *get_empty_record_slot(void) {
+ for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) {
+ if (!usb_edpt_list[i].configured) {
+ return &usb_edpt_list[i];
}
- return NULL;
+ }
+ return NULL;
}
-static usb_edpt_t* add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type)
-{
- usb_edpt_t* slot = get_empty_record_slot();
- if (slot == NULL) {
- PANIC("add_edpt_record(0x%02x, 0x%02x, ...) no slot for new record\r\n", dev_addr, ep_addr);
- }
- TU_ASSERT(slot != NULL, NULL);
+static usb_edpt_t *add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) {
+ usb_edpt_t *slot = get_empty_record_slot();
+ if (slot == NULL) {
+ PANIC("add_edpt_record(0x%02x, 0x%02x, ...) no slot for new record\r\n", dev_addr, ep_addr);
+ }
+ TU_ASSERT(slot != NULL, NULL);
- slot->dev_addr = dev_addr;
- slot->ep_addr = ep_addr;
- slot->max_packet_size = max_packet_size;
- slot->xfer_type = xfer_type;
- slot->data_toggle = 0;
+ slot->dev_addr = dev_addr;
+ slot->ep_addr = ep_addr;
+ slot->max_packet_size = max_packet_size;
+ slot->xfer_type = xfer_type;
+ slot->data_toggle = 0;
- slot->configured = true;
+ slot->configured = true;
- return slot;
+ return slot;
}
-static usb_edpt_t* get_or_add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type)
-{
- usb_edpt_t* ret = get_edpt_record(dev_addr, ep_addr);
- if (ret != NULL)
- {
- return ret;
- }
- else
- {
- return add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type);
- }
+static usb_edpt_t *get_or_add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) {
+ usb_edpt_t *ret = get_edpt_record(dev_addr, ep_addr);
+ if (ret != NULL) {
+ return ret;
+ } else {
+ return add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type);
+ }
}
-
-static void remove_edpt_record_for_device(uint8_t dev_addr)
-{
- for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++)
- {
- if (usb_edpt_list[i].configured && usb_edpt_list[i].dev_addr == dev_addr)
- {
- usb_edpt_list[i].configured = false;
- }
+static void remove_edpt_record_for_device(uint8_t dev_addr) {
+ for (size_t i = 0; i < TU_ARRAY_SIZE(usb_edpt_list); i++) {
+ if (usb_edpt_list[i].configured && usb_edpt_list[i].dev_addr == dev_addr) {
+ usb_edpt_list[i].configured = false;
}
+ }
}
// static void dump_edpt_record_list() {
@@ -183,544 +164,462 @@ static void remove_edpt_record_for_device(uint8_t dev_addr)
// }
// }
-
static bool interrupt_enabled = false;
/** Enable or disable USBFS Host function */
-static void hardware_init_host(bool enabled)
-{
- // Reset USBOTG module
- USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
+static void hardware_init_host(bool enabled) {
+ // Reset USBOTG module
+ USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
- osal_task_delay(1);
- USBOTG_H_FS->BASE_CTRL = 0;
+ tusb_time_delay_ms_api(1);
+ USBOTG_H_FS->BASE_CTRL = 0;
- if (!enabled)
- {
- // Disable all feature
- USBOTG_H_FS->BASE_CTRL = 0;
- }
- else
- {
- // Enable USB Host features
- // NVIC_DisableIRQ(USBFS_IRQn);
- hcd_int_disable(0);
- USBOTG_H_FS->BASE_CTRL = USBFS_UC_HOST_MODE | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN;
- USBOTG_H_FS->HOST_EP_MOD = USBFS_UH_EP_TX_EN | USBFS_UH_EP_RX_EN;
- USBOTG_H_FS->HOST_RX_DMA = (uint32_t)USBFS_RX_Buf;
- USBOTG_H_FS->HOST_TX_DMA = (uint32_t)USBFS_TX_Buf;
- // USBOTG_H_FS->INT_EN = USBFS_UIE_TRANSFER | USBFS_UIE_DETECT;
- USBOTG_H_FS->INT_EN = USBFS_UIE_DETECT;
- }
+ if (!enabled) {
+ // Disable all feature
+ USBOTG_H_FS->BASE_CTRL = 0;
+ } else {
+ // Enable USB Host features
+ // NVIC_DisableIRQ(USBFS_IRQn);
+ hcd_int_disable(0);
+ USBOTG_H_FS->BASE_CTRL = USBFS_UC_HOST_MODE | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN;
+ USBOTG_H_FS->HOST_EP_MOD = USBFS_UH_EP_TX_EN | USBFS_UH_EP_RX_EN;
+ USBOTG_H_FS->HOST_RX_DMA = (uint32_t) USBFS_RX_Buf;
+ USBOTG_H_FS->HOST_TX_DMA = (uint32_t) USBFS_TX_Buf;
+ // USBOTG_H_FS->INT_EN = USBFS_UIE_TRANSFER | USBFS_UIE_DETECT;
+ USBOTG_H_FS->INT_EN = USBFS_UIE_DETECT;
+ }
}
-static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggle)
-{
- LOG_CH32_USBFSH("hardware_start_xfer(pid=%s(0x%02x), ep_addr=0x%02x, toggle=%d)\r\n",
- pid == USB_PID_IN ? "IN" : pid == USB_PID_OUT ? "OUT" : pid == USB_PID_SETUP ? "SETUP" : "(other)",
- pid, ep_addr, data_toggle);
+static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggle) {
+ LOG_CH32_USBFSH("hardware_start_xfer(pid=%s(0x%02x), ep_addr=0x%02x, toggle=%d)\r\n",
+ pid == USB_PID_IN ? "IN" : pid == USB_PID_OUT ? "OUT"
+ : pid == USB_PID_SETUP ? "SETUP"
+ : "(other)",
+ pid, ep_addr, data_toggle);
- // if (pid == USB_PID_IN)
- // { // FIXME: long delay needed (at release build) about 30msec
- // loopdelay(SystemCoreClock / 1000 * 30);
- // }
+ // if (pid == USB_PID_IN)
+ // { // FIXME: long delay needed (at release build) about 30msec
+ // loopdelay(SystemCoreClock / 1000 * 30);
+ // }
- uint8_t pid_edpt = (pid << 4) | (tu_edpt_number(ep_addr) & 0x0f);
- USBOTG_H_FS->HOST_TX_CTRL = (data_toggle != 0) ? USBFS_UH_T_TOG : 0;
- USBOTG_H_FS->HOST_RX_CTRL = (data_toggle != 0) ? USBFS_UH_R_TOG : 0;
- USBOTG_H_FS->HOST_EP_PID = pid_edpt;
- USBOTG_H_FS->INT_EN |= USBFS_UIE_TRANSFER;
- USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER;
- return true;
+ uint8_t pid_edpt = (pid << 4) | (tu_edpt_number(ep_addr) & 0x0f);
+ USBOTG_H_FS->HOST_TX_CTRL = (data_toggle != 0) ? USBFS_UH_T_TOG : 0;
+ USBOTG_H_FS->HOST_RX_CTRL = (data_toggle != 0) ? USBFS_UH_R_TOG : 0;
+ USBOTG_H_FS->HOST_EP_PID = pid_edpt;
+ USBOTG_H_FS->INT_EN |= USBFS_UIE_TRANSFER;
+ USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER;
+ return true;
}
/** Set device address to communicate */
-static void hardware_update_device_address(uint8_t dev_addr)
-{
- // Keep the bit of GP_BIT. Other 7bits are actual device address.
- USBOTG_H_FS->DEV_ADDR = (USBOTG_H_FS->DEV_ADDR & USBFS_UDA_GP_BIT) | (dev_addr & USBFS_USB_ADDR_MASK);
+static void hardware_update_device_address(uint8_t dev_addr) {
+ // Keep the bit of GP_BIT. Other 7bits are actual device address.
+ USBOTG_H_FS->DEV_ADDR = (USBOTG_H_FS->DEV_ADDR & USBFS_UDA_GP_BIT) | (dev_addr & USBFS_USB_ADDR_MASK);
}
/** Set port speed */
-static void hardware_update_port_speed(tusb_speed_t speed)
-{
- LOG_CH32_USBFSH("hardware_update_port_speed(%s)\r\n", speed == TUSB_SPEED_FULL ? "Full" : speed == TUSB_SPEED_LOW ? "Low" : "(invalid)");
- switch (speed) {
+static void hardware_update_port_speed(tusb_speed_t speed) {
+ LOG_CH32_USBFSH("hardware_update_port_speed(%s)\r\n", speed == TUSB_SPEED_FULL ? "Full" : speed == TUSB_SPEED_LOW ? "Low"
+ : "(invalid)");
+ switch (speed) {
case TUSB_SPEED_LOW:
- USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED;
- USBOTG_H_FS->HOST_CTRL |= USBFS_UH_LOW_SPEED;
- USBOTG_H_FS->HOST_SETUP |= USBFS_UH_PRE_PID_EN;
- return;
+ USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED;
+ USBOTG_H_FS->HOST_CTRL |= USBFS_UH_LOW_SPEED;
+ USBOTG_H_FS->HOST_SETUP |= USBFS_UH_PRE_PID_EN;
+ return;
case TUSB_SPEED_FULL:
- USBOTG_H_FS->BASE_CTRL &= ~USBFS_UC_LOW_SPEED;
- USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_LOW_SPEED;
- USBOTG_H_FS->HOST_SETUP &= ~USBFS_UH_PRE_PID_EN;
- return;
+ USBOTG_H_FS->BASE_CTRL &= ~USBFS_UC_LOW_SPEED;
+ USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_LOW_SPEED;
+ USBOTG_H_FS->HOST_SETUP &= ~USBFS_UH_PRE_PID_EN;
+ return;
default:
- PANIC("hardware_update_port_speed(%d)\r\n", speed);
- }
+ PANIC("hardware_update_port_speed(%d)\r\n", speed);
+ }
}
-
static void hardware_set_port_address_speed(uint8_t dev_addr) {
- hardware_update_device_address(dev_addr);
- tusb_speed_t rhport_speed = hcd_port_speed_get(0);
- tusb_speed_t dev_speed = tuh_speed_get(dev_addr);
- hardware_update_port_speed(dev_speed);
- if (rhport_speed == TUSB_SPEED_FULL && dev_speed == TUSB_SPEED_LOW) {
- USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_LOW_SPEED;
- }
+ hardware_update_device_address(dev_addr);
+ tusb_speed_t rhport_speed = hcd_port_speed_get(0);
+ tusb_speed_t dev_speed = tuh_speed_get(dev_addr);
+ hardware_update_port_speed(dev_speed);
+ if (rhport_speed == TUSB_SPEED_FULL && dev_speed == TUSB_SPEED_LOW) {
+ USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_LOW_SPEED;
+ }
}
-
-static bool hardware_device_attached(void)
-{
- return USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH;
+static bool hardware_device_attached(void) {
+ return USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH;
}
-
//--------------------------------------------------------------------+
// HCD API
//--------------------------------------------------------------------+
-bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init)
-{
- (void)rhport;
- (void)rh_init;
- hardware_init_host(true);
+bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
+ (void) rhport;
+ (void) rh_init;
+ hardware_init_host(true);
- return true;
+ return true;
}
-bool hcd_deinit(uint8_t rhport)
-{
- (void)rhport;
- hardware_init_host(false);
+bool hcd_deinit(uint8_t rhport) {
+ (void) rhport;
+ hardware_init_host(false);
- return true;
+ return true;
}
-
static bool int_state_for_portreset = false;
-void hcd_port_reset(uint8_t rhport)
-{
- (void)rhport;
- LOG_CH32_USBFSH("hcd_port_reset()\r\n");
- int_state_for_portreset = interrupt_enabled;
- // NVIC_DisableIRQ(USBFS_IRQn);
- hcd_int_disable(rhport);
- hardware_update_device_address(0x00);
+void hcd_port_reset(uint8_t rhport) {
+ (void) rhport;
+ LOG_CH32_USBFSH("hcd_port_reset()\r\n");
+ int_state_for_portreset = interrupt_enabled;
+ // NVIC_DisableIRQ(USBFS_IRQn);
+ hcd_int_disable(rhport);
+ hardware_update_device_address(0x00);
- // USBOTG_H_FS->HOST_SETUP = 0x00;
+ // USBOTG_H_FS->HOST_SETUP = 0x00;
- USBOTG_H_FS->HOST_CTRL |= USBFS_UH_BUS_RESET;
+ USBOTG_H_FS->HOST_CTRL |= USBFS_UH_BUS_RESET;
- return;
+ return;
}
-void hcd_port_reset_end(uint8_t rhport)
-{
- (void)rhport;
- LOG_CH32_USBFSH("hcd_port_reset_end()\r\n");
+void hcd_port_reset_end(uint8_t rhport) {
+ (void) rhport;
+ LOG_CH32_USBFSH("hcd_port_reset_end()\r\n");
- USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_BUS_RESET;
- osal_task_delay(2);
+ USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_BUS_RESET;
+ tusb_time_delay_ms_api(2);
- if ((USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN) == 0)
- {
- if (hcd_port_speed_get(0) == TUSB_SPEED_LOW)
- {
- hardware_update_port_speed(TUSB_SPEED_LOW);
- }
+ if ((USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN) == 0) {
+ if (hcd_port_speed_get(0) == TUSB_SPEED_LOW) {
+ hardware_update_port_speed(TUSB_SPEED_LOW);
}
+ }
- USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
- USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
+ USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
+ USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
- // Suppress the attached event
- USBOTG_H_FS->INT_FG |= USBFS_UIF_DETECT;
+ // Suppress the attached event
+ USBOTG_H_FS->INT_FG |= USBFS_UIF_DETECT;
- if (int_state_for_portreset) {
- hcd_int_enable(rhport);
- }
-
- return;
+ if (int_state_for_portreset) {
+ hcd_int_enable(rhport);
+ }
}
-bool hcd_port_connect_status(uint8_t rhport)
-{
- (void)rhport;
+bool hcd_port_connect_status(uint8_t rhport) {
+ (void) rhport;
- return hardware_device_attached();
+ return hardware_device_attached();
}
-tusb_speed_t hcd_port_speed_get(uint8_t rhport)
-{
- (void)rhport;
- if (USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL)
- {
- return TUSB_SPEED_LOW;
- }
- else
- {
- return TUSB_SPEED_FULL;
- }
+tusb_speed_t hcd_port_speed_get(uint8_t rhport) {
+ (void) rhport;
+ if (USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL) {
+ return TUSB_SPEED_LOW;
+ } else {
+ return TUSB_SPEED_FULL;
+ }
}
// Close all opened endpoint belong to this device
-void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
-{
- (void)rhport;
- LOG_CH32_USBFSH("hcd_device_close(%d, 0x%02x)\r\n", rhport, dev_addr);
- remove_edpt_record_for_device(dev_addr);
-
- return;
+void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
+ (void) rhport;
+ LOG_CH32_USBFSH("hcd_device_close(%d, 0x%02x)\r\n", rhport, dev_addr);
+ remove_edpt_record_for_device(dev_addr);
}
-uint32_t hcd_frame_number(uint8_t rhport)
-{
- (void)rhport;
+uint32_t hcd_frame_number(uint8_t rhport) {
+ (void) rhport;
- return board_millis();
+ return board_millis();
}
-void hcd_int_enable(uint8_t rhport)
-{
- (void)rhport;
- NVIC_EnableIRQ(USBFS_IRQn);
- interrupt_enabled = true;
-
- return;
+void hcd_int_enable(uint8_t rhport) {
+ (void) rhport;
+ NVIC_EnableIRQ(USBFS_IRQn);
+ interrupt_enabled = true;
}
-void hcd_int_disable(uint8_t rhport)
-{
- (void)rhport;
- NVIC_DisableIRQ(USBFS_IRQn);
- interrupt_enabled = false;
-
- return;
+void hcd_int_disable(uint8_t rhport) {
+ (void) rhport;
+ NVIC_DisableIRQ(USBFS_IRQn);
+ interrupt_enabled = false;
}
-void hcd_int_handler(uint8_t rhport, bool in_isr)
-{
- (void)rhport;
- (void)in_isr;
+void hcd_int_handler(uint8_t rhport, bool in_isr) {
+ (void) rhport;
+ (void) in_isr;
- if (USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT)
- {
- // Clear the flag
- USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT;
- // Read the detection state
- bool attached = hardware_device_attached();
- LOG_CH32_USBFSH("hcd_int_handler() attached = %d\r\n", attached ? 1 : 0);
- if (attached)
- {
- hcd_event_device_attach(rhport, true);
- }
- else
- {
- hcd_event_device_remove(rhport, true);
- }
- return;
+ if (USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT) {
+ // Clear the flag
+ USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT;
+ // Read the detection state
+ bool attached = hardware_device_attached();
+ LOG_CH32_USBFSH("hcd_int_handler() attached = %d\r\n", attached ? 1 : 0);
+ if (attached) {
+ hcd_event_device_attach(rhport, true);
+ } else {
+ hcd_event_device_remove(rhport, true);
}
+ return;
+ }
- if (USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER)
- {
- // Disable transfer interrupt
- USBOTG_H_FS->INT_EN &= ~USBFS_UIE_TRANSFER;
- // Clear the flag
- // USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER;
- // Copy PID and Endpoint
- uint8_t pid_edpt = USBOTG_H_FS->HOST_EP_PID;
- uint8_t status = USBOTG_H_FS->INT_ST;
- uint8_t dev_addr = USBOTG_H_FS->DEV_ADDR & USBFS_USB_ADDR_MASK;
- // Clear register to stop transfer
- // USBOTG_H_FS->HOST_EP_PID = 0x00;
+ if (USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER) {
+ // Disable transfer interrupt
+ USBOTG_H_FS->INT_EN &= ~USBFS_UIE_TRANSFER;
+ // Clear the flag
+ // USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER;
+ // Copy PID and Endpoint
+ uint8_t pid_edpt = USBOTG_H_FS->HOST_EP_PID;
+ uint8_t status = USBOTG_H_FS->INT_ST;
+ uint8_t dev_addr = USBOTG_H_FS->DEV_ADDR & USBFS_USB_ADDR_MASK;
+ // Clear register to stop transfer
+ // USBOTG_H_FS->HOST_EP_PID = 0x00;
- LOG_CH32_USBFSH("hcd_int_handler() pid_edpt=0x%02x\r\n", pid_edpt);
+ LOG_CH32_USBFSH("hcd_int_handler() pid_edpt=0x%02x\r\n", pid_edpt);
- uint8_t request_pid = pid_edpt >> 4;
- uint8_t response_pid = status & USBFS_UIS_H_RES_MASK;
- uint8_t ep_addr = pid_edpt & 0x0f;
- if (request_pid == USB_PID_IN)
- {
- ep_addr |= 0x80;
- }
+ uint8_t request_pid = pid_edpt >> 4;
+ uint8_t response_pid = status & USBFS_UIS_H_RES_MASK;
+ uint8_t ep_addr = pid_edpt & 0x0f;
+ if (request_pid == USB_PID_IN) {
+ ep_addr |= 0x80;
+ }
- usb_edpt_t* edpt_info = get_edpt_record(dev_addr, ep_addr);
- if (edpt_info == NULL)
- {
- PANIC("\r\nget_edpt_record(0x%02x, 0x%02x) returned NULL in USBHD_IRQHandler\r\n", dev_addr, ep_addr);
- }
+ usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr);
+ if (edpt_info == NULL) {
+ PANIC("\r\nget_edpt_record(0x%02x, 0x%02x) returned NULL in USBHD_IRQHandler\r\n", dev_addr, ep_addr);
+ }
- if (status & USBFS_UIS_TOG_OK)
- {
- edpt_info->data_toggle ^= 0x01;
+ if (status & USBFS_UIS_TOG_OK) {
+ edpt_info->data_toggle ^= 0x01;
- switch (request_pid)
- {
- case USB_PID_SETUP:
- case USB_PID_OUT:
- {
- uint16_t tx_len = USBOTG_H_FS->HOST_TX_LEN;
- usb_current_xfer_info.bufferlen -= tx_len;
- usb_current_xfer_info.xferred_len += tx_len;
- if (usb_current_xfer_info.bufferlen == 0)
- {
- LOG_CH32_USBFSH("USB_PID_%s completed %d bytes\r\n", request_pid == USB_PID_OUT ? "OUT" : "SETUP", usb_current_xfer_info.xferred_len);
- usb_current_xfer_info.is_busy = false;
- hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, true);
- return;
- }
- else
- {
- LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n");
- usb_current_xfer_info.buffer += tx_len;
- uint16_t copylen = USBFS_TX_BUF_LEN;
- if (copylen > usb_current_xfer_info.bufferlen)
- {
- copylen = usb_current_xfer_info.bufferlen;
- }
- memcpy(USBFS_TX_Buf, usb_current_xfer_info.buffer, copylen);
- hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle);
- return;
- }
- }
- case USB_PID_IN:
- {
- uint16_t received_len = USBOTG_H_FS->RX_LEN;
- usb_current_xfer_info.xferred_len += received_len;
- uint16_t xferred_len = usb_current_xfer_info.xferred_len;
- LOG_CH32_USBFSH("Read %d bytes\r\n", received_len);
- // if (received_len > 0 && (usb_current_xfer_info.buffer == NULL || usb_current_xfer_info.bufferlen == 0)) {
- // PANIC("Data received but buffer not set\r\n");
- // }
- memcpy(usb_current_xfer_info.buffer, USBFS_RX_Buf, received_len);
- usb_current_xfer_info.buffer += received_len;
- if ((received_len < edpt_info->max_packet_size) || (xferred_len == usb_current_xfer_info.bufferlen))
- {
- // USB device sent all data.
- LOG_CH32_USBFSH("USB_PID_IN completed\r\n");
- usb_current_xfer_info.is_busy = false;
- hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, true);
- return;
- }
- else
- {
- // USB device may send more data.
- LOG_CH32_USBFSH("Read more data\r\n");
- hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
- return;
- }
- }
- default:
- {
- PANIC("Unknown PID: 0x%02x\n", request_pid);
- }
+ switch (request_pid) {
+ case USB_PID_SETUP:
+ case USB_PID_OUT: {
+ uint16_t tx_len = USBOTG_H_FS->HOST_TX_LEN;
+ usb_current_xfer_info.bufferlen -= tx_len;
+ usb_current_xfer_info.xferred_len += tx_len;
+ if (usb_current_xfer_info.bufferlen == 0) {
+ LOG_CH32_USBFSH("USB_PID_%s completed %d bytes\r\n", request_pid == USB_PID_OUT ? "OUT" : "SETUP", usb_current_xfer_info.xferred_len);
+ usb_current_xfer_info.is_busy = false;
+ hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, true);
+ return;
+ } else {
+ LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n");
+ usb_current_xfer_info.buffer += tx_len;
+ uint16_t copylen = USBFS_TX_BUF_LEN;
+ if (copylen > usb_current_xfer_info.bufferlen) {
+ copylen = usb_current_xfer_info.bufferlen;
}
+ memcpy(USBFS_TX_Buf, usb_current_xfer_info.buffer, copylen);
+ hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle);
+ return;
+ }
}
- else
- {
- if (response_pid == USB_PID_STALL)
- {
- LOG_CH32_USBFSH("STALL response\r\n");
- hcd_edpt_clear_stall(0, dev_addr, ep_addr);
- edpt_info->data_toggle = 0;
- hardware_start_xfer(request_pid, ep_addr, 0);
- return;
- }
- else if (response_pid == USB_PID_NAK)
- {
- LOG_CH32_USBFSH("NAK reposense\r\n");
- uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms;
- if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT)
- {
- usb_current_xfer_info.is_busy = false;
- hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true);
- }
- else if (elapsed_time > USB_XFER_TIMEOUT_MILLIS)
- {
- usb_current_xfer_info.is_busy = false;
- hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
- }
- else
- {
- hardware_start_xfer(request_pid, ep_addr, edpt_info->data_toggle);
- }
- return;
- }
- else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1)
- {
- LOG_CH32_USBFSH("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n", USBOTG_H_FS->RX_LEN);
- usb_current_xfer_info.is_busy = false;
- hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
- return;
- }
- else
- {
- LOG_CH32_USBFSH("In USBHD_IRQHandler, unexpected response PID: 0x%02x\r\n", response_pid);
- usb_current_xfer_info.is_busy = false;
- hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
- return;
- }
+ case USB_PID_IN: {
+ uint16_t received_len = USBOTG_H_FS->RX_LEN;
+ usb_current_xfer_info.xferred_len += received_len;
+ uint16_t xferred_len = usb_current_xfer_info.xferred_len;
+ LOG_CH32_USBFSH("Read %d bytes\r\n", received_len);
+ // if (received_len > 0 && (usb_current_xfer_info.buffer == NULL || usb_current_xfer_info.bufferlen == 0)) {
+ // PANIC("Data received but buffer not set\r\n");
+ // }
+ memcpy(usb_current_xfer_info.buffer, USBFS_RX_Buf, received_len);
+ usb_current_xfer_info.buffer += received_len;
+ if ((received_len < edpt_info->max_packet_size) || (xferred_len == usb_current_xfer_info.bufferlen)) {
+ // USB device sent all data.
+ LOG_CH32_USBFSH("USB_PID_IN completed\r\n");
+ usb_current_xfer_info.is_busy = false;
+ hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, true);
+ return;
+ } else {
+ // USB device may send more data.
+ LOG_CH32_USBFSH("Read more data\r\n");
+ hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
+ return;
+ }
+ }
+ default: {
+ PANIC("Unknown PID: 0x%02x\n", request_pid);
+ }
+ }
+ } else {
+ if (response_pid == USB_PID_STALL) {
+ LOG_CH32_USBFSH("STALL response\r\n");
+ hcd_edpt_clear_stall(0, dev_addr, ep_addr);
+ edpt_info->data_toggle = 0;
+ hardware_start_xfer(request_pid, ep_addr, 0);
+ return;
+ } else if (response_pid == USB_PID_NAK) {
+ LOG_CH32_USBFSH("NAK reposense\r\n");
+ uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms;
+ if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT) {
+ usb_current_xfer_info.is_busy = false;
+ hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true);
+ } else if (elapsed_time > USB_XFER_TIMEOUT_MILLIS) {
+ usb_current_xfer_info.is_busy = false;
+ hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
+ } else {
+ hardware_start_xfer(request_pid, ep_addr, edpt_info->data_toggle);
}
+ return;
+ } else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1) {
+ LOG_CH32_USBFSH("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n", USBOTG_H_FS->RX_LEN);
+ usb_current_xfer_info.is_busy = false;
+ hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
+ return;
+ } else {
+ LOG_CH32_USBFSH("In USBHD_IRQHandler, unexpected response PID: 0x%02x\r\n", response_pid);
+ usb_current_xfer_info.is_busy = false;
+ hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true);
+ return;
+ }
}
+ }
}
//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+
-bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
-{
- (void)rhport;
- uint8_t ep_addr = ep_desc->bEndpointAddress;
- uint8_t ep_num = tu_edpt_number(ep_addr);
- uint16_t max_packet_size = ep_desc->wMaxPacketSize;
- uint8_t xfer_type = ep_desc->bmAttributes.xfer;
- LOG_CH32_USBFSH("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n", rhport, dev_addr, ep_desc, ep_addr, max_packet_size, xfer_type);
-
- if (ep_num == 0x00)
- {
- TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x00, max_packet_size, xfer_type) != NULL, false);
- TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x80, max_packet_size, xfer_type) != NULL, false);
- }
- else
- {
- TU_ASSERT(get_or_add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type) != NULL, false);
- }
+bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) {
+ (void) rhport;
+ uint8_t ep_addr = ep_desc->bEndpointAddress;
+ uint8_t ep_num = tu_edpt_number(ep_addr);
+ uint16_t max_packet_size = ep_desc->wMaxPacketSize;
+ uint8_t xfer_type = ep_desc->bmAttributes.xfer;
+ LOG_CH32_USBFSH("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n", rhport, dev_addr, ep_desc, ep_addr, max_packet_size, xfer_type);
+ if (ep_num == 0x00) {
+ TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x00, max_packet_size, xfer_type) != NULL, false);
+ TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x80, max_packet_size, xfer_type) != NULL, false);
+ } else {
+ TU_ASSERT(get_or_add_edpt_record(dev_addr, ep_addr, max_packet_size, xfer_type) != NULL, false);
+ }
- USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
- USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
+ USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
+ USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
- hardware_set_port_address_speed(dev_addr);
+ hardware_set_port_address_speed(dev_addr);
- return true;
+ return true;
}
-bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen)
-{
- (void)rhport;
+bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) {
+ (void) rhport;
- LOG_CH32_USBFSH("hcd_edpt_xfer(%d, 0x%02x, 0x%02x, ...)\r\n", rhport, dev_addr, ep_addr);
+ LOG_CH32_USBFSH("hcd_edpt_xfer(%d, 0x%02x, 0x%02x, ...)\r\n", rhport, dev_addr, ep_addr);
- while (usb_current_xfer_info.is_busy) { }
+ while (usb_current_xfer_info.is_busy) {}
+ usb_current_xfer_info.is_busy = true;
- usb_current_xfer_info.is_busy = true;
+ usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr);
+ if (edpt_info == NULL) {
+ PANIC("get_edpt_record() returned NULL in hcd_edpt_xfer()\r\n");
+ }
- usb_edpt_t* edpt_info = get_edpt_record(dev_addr, ep_addr);
- if (edpt_info == NULL)
- {
- PANIC("get_edpt_record() returned NULL in hcd_edpt_xfer()\r\n");
- }
-
- hardware_set_port_address_speed(dev_addr);
+ hardware_set_port_address_speed(dev_addr);
- usb_current_xfer_info.dev_addr = dev_addr;
- usb_current_xfer_info.ep_addr = ep_addr;
- usb_current_xfer_info.buffer = buffer;
- usb_current_xfer_info.bufferlen = buflen;
- usb_current_xfer_info.start_ms = board_millis();
- usb_current_xfer_info.xferred_len = 0;
+ usb_current_xfer_info.dev_addr = dev_addr;
+ usb_current_xfer_info.ep_addr = ep_addr;
+ usb_current_xfer_info.buffer = buffer;
+ usb_current_xfer_info.bufferlen = buflen;
+ usb_current_xfer_info.start_ms = board_millis();
+ usb_current_xfer_info.xferred_len = 0;
- if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN)
- {
- LOG_CH32_USBFSH("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
- return hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
- }
- else
- {
- LOG_CH32_USBFSH("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
- uint16_t copylen = USBFS_TX_BUF_LEN;
- if (copylen > buflen)
- {
- copylen = buflen;
- }
- USBOTG_H_FS->HOST_TX_LEN = copylen;
- memcpy(USBFS_TX_Buf, buffer, copylen);
- return hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle);
+ if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
+ LOG_CH32_USBFSH("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
+ return hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle);
+ } else {
+ LOG_CH32_USBFSH("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen);
+ uint16_t copylen = USBFS_TX_BUF_LEN;
+ if (copylen > buflen) {
+ copylen = buflen;
}
+ USBOTG_H_FS->HOST_TX_LEN = copylen;
+ memcpy(USBFS_TX_Buf, buffer, copylen);
+ return hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle);
+ }
}
-bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
-{
- (void) rhport;
- (void) dev_addr;
- (void) ep_addr;
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
- return false;
+ return false;
}
-bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
-{
- (void)rhport;
-
- while (usb_current_xfer_info.is_busy) { }
+bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) {
+ (void) rhport;
+
+ while (usb_current_xfer_info.is_busy) {}
- usb_current_xfer_info.is_busy = true;
+ usb_current_xfer_info.is_busy = true;
- LOG_CH32_USBFSH("hcd_setup_send(rhport=%d, dev_addr=0x%02x, %p)\r\n", rhport, dev_addr, setup_packet);
+ LOG_CH32_USBFSH("hcd_setup_send(rhport=%d, dev_addr=0x%02x, %p)\r\n", rhport, dev_addr, setup_packet);
- hardware_set_port_address_speed(dev_addr);
+ hardware_set_port_address_speed(dev_addr);
- usb_edpt_t* edpt_info_tx = get_edpt_record(dev_addr, 0x00);
- usb_edpt_t* edpt_info_rx = get_edpt_record(dev_addr, 0x80);
- TU_ASSERT(edpt_info_tx != NULL, false);
- TU_ASSERT(edpt_info_rx != NULL, false);
+ usb_edpt_t *edpt_info_tx = get_edpt_record(dev_addr, 0x00);
+ usb_edpt_t *edpt_info_rx = get_edpt_record(dev_addr, 0x80);
+ TU_ASSERT(edpt_info_tx != NULL, false);
+ TU_ASSERT(edpt_info_rx != NULL, false);
- // Initialize data toggle (SETUP always starts with DATA0)
- // Data toggle for OUT is toggled in hcd_int_handler()
- edpt_info_tx->data_toggle = 0;
- // Data toggle for IN must be set 0x01 manually.
- edpt_info_rx->data_toggle = 0x01;
- const uint16_t setup_packet_datalen = 8;
- memcpy(USBFS_TX_Buf, setup_packet, setup_packet_datalen);
- USBOTG_H_FS->HOST_TX_LEN = setup_packet_datalen;
- uint8_t ep_addr = (setup_packet[0] & 0x80) ? 0x80 : 0x00;
- usb_current_xfer_info.dev_addr = dev_addr;
- usb_current_xfer_info.ep_addr = ep_addr;
- usb_current_xfer_info.start_ms = board_millis();
- usb_current_xfer_info.buffer = USBFS_TX_Buf;
- usb_current_xfer_info.bufferlen = setup_packet_datalen;
- usb_current_xfer_info.xferred_len = 0;
+ // Initialize data toggle (SETUP always starts with DATA0)
+ // Data toggle for OUT is toggled in hcd_int_handler()
+ edpt_info_tx->data_toggle = 0;
+ // Data toggle for IN must be set 0x01 manually.
+ edpt_info_rx->data_toggle = 0x01;
+ const uint16_t setup_packet_datalen = 8;
+ memcpy(USBFS_TX_Buf, setup_packet, setup_packet_datalen);
+ USBOTG_H_FS->HOST_TX_LEN = setup_packet_datalen;
+ uint8_t ep_addr = (setup_packet[0] & 0x80) ? 0x80 : 0x00;
+ usb_current_xfer_info.dev_addr = dev_addr;
+ usb_current_xfer_info.ep_addr = ep_addr;
+ usb_current_xfer_info.start_ms = board_millis();
+ usb_current_xfer_info.buffer = USBFS_TX_Buf;
+ usb_current_xfer_info.bufferlen = setup_packet_datalen;
+ usb_current_xfer_info.xferred_len = 0;
- hardware_start_xfer(USB_PID_SETUP, 0, 0);
+ hardware_start_xfer(USB_PID_SETUP, 0, 0);
- return true;
+ return true;
}
-bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
-{
- (void) rhport;
- (void) dev_addr;
- LOG_CH32_USBFSH("hcd_edpt_clear_stall(rhport=%d, dev_addr=0x%02x, ep_addr=0x%02x)\r\n", rhport, dev_addr, ep_addr);
- // PANIC("\r\install\r\n");
- uint8_t edpt_num = tu_edpt_number(ep_addr);
- uint8_t setup_request_clear_stall[8] = {
- 0x02, 0x01, 0x00, 0x00, edpt_num, 0x00, 0x00, 0x00
- };
- memcpy(USBFS_TX_Buf, setup_request_clear_stall, 8);
- USBOTG_H_FS->HOST_TX_LEN = 8;
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ LOG_CH32_USBFSH("hcd_edpt_clear_stall(rhport=%d, dev_addr=0x%02x, ep_addr=0x%02x)\r\n", rhport, dev_addr, ep_addr);
+ // PANIC("\r\install\r\n");
+ uint8_t edpt_num = tu_edpt_number(ep_addr);
+ uint8_t setup_request_clear_stall[8] = {
+ 0x02, 0x01, 0x00, 0x00, edpt_num, 0x00, 0x00, 0x00
+ };
+ memcpy(USBFS_TX_Buf, setup_request_clear_stall, 8);
+ USBOTG_H_FS->HOST_TX_LEN = 8;
- bool prev_int_state = interrupt_enabled;
- hcd_int_disable(0);
+ bool prev_int_state = interrupt_enabled;
+ hcd_int_disable(0);
- USBOTG_H_FS->HOST_EP_PID = (USB_PID_SETUP << 4) | 0x00;
- USBOTG_H_FS->INT_FG |= USBFS_UIF_TRANSFER;
- while ((USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER) == 0) { }
- USBOTG_H_FS->HOST_EP_PID = 0;
- uint8_t response_pid = USBOTG_H_FS->INT_ST & USBFS_UIS_H_RES_MASK;
- (void)response_pid;
- LOG_CH32_USBFSH("hcd_edpt_clear_stall() response pid=0x%02x\r\n", response_pid);
+ USBOTG_H_FS->HOST_EP_PID = (USB_PID_SETUP << 4) | 0x00;
+ USBOTG_H_FS->INT_FG |= USBFS_UIF_TRANSFER;
+ while ((USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER) == 0) {}
+ USBOTG_H_FS->HOST_EP_PID = 0;
+ uint8_t response_pid = USBOTG_H_FS->INT_ST & USBFS_UIS_H_RES_MASK;
+ (void) response_pid;
+ LOG_CH32_USBFSH("hcd_edpt_clear_stall() response pid=0x%02x\r\n", response_pid);
- if (prev_int_state) {
+ if (prev_int_state) {
hcd_int_enable(0);
- }
+ }
- return true;
+ return true;
}
#endif