summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2026-06-23 10:06:50 +0200
committerHiFiPhile <[email protected]>2026-06-23 10:26:08 +0200
commit030bb962aed6efba443221660fb13f6dbd3ae710 (patch)
tree2c99a05c5768e4546bfdbb7dde000acefbcbcc14
parentcd3561bf158afd5a5718904b8139a338d1e3b67c (diff)
dcd/ch32hs: defer bus reset event for proper speed detection
Signed-off-by: HiFiPhile <[email protected]>
-rw-r--r--src/portable/wch/dcd_ch32_usbhs.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c
index ea3b052ad..4ab92817e 100644
--- a/src/portable/wch/dcd_ch32_usbhs.c
+++ b/src/portable/wch/dcd_ch32_usbhs.c
@@ -59,6 +59,7 @@ static xfer_ctl_t xfer_status[EP_MAX][2];
TU_ATTR_ALIGNED(4) static uint8_t ep0_buffer[CFG_TUD_ENDPOINT0_SIZE];
static bool ep0_tog;
static bool ep_data_tog[EP_MAX][2];
+static bool reset_evt_pending;
static void set_ep_toggle(uint8_t ep_num, tusb_dir_t ep_dir, bool data1) {
if (ep_dir == TUSB_DIR_IN) {
@@ -424,6 +425,23 @@ void dcd_int_handler(uint8_t rhport) {
}
USBHSD->INT_FG = (int_flag & USBHS_TRANSFER_FLAG); /* Clear flag */
} else if (int_flag & USBHS_SETUP_FLAG) {
+ if (reset_evt_pending) {
+ reset_evt_pending = false;
+ tusb_speed_t actual_speed;
+ switch(USBHSD->SPEED_TYPE & USBHS_SPEED_TYPE_MASK){
+ case USBHS_SPEED_TYPE_FULL:
+ actual_speed = TUSB_SPEED_FULL;
+ break;
+ case USBHS_SPEED_TYPE_LOW:
+ actual_speed = TUSB_SPEED_LOW;
+ break;
+ default:
+ actual_speed = TUSB_SPEED_HIGH;
+ break;
+ }
+ dcd_event_bus_reset(0, actual_speed, true);
+ }
+
tusb_control_request_t const* setup =
(tusb_control_request_t const*) ep0_buffer;
ep0_tog = true;
@@ -434,27 +452,9 @@ void dcd_int_handler(uint8_t rhport) {
USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */
} else if (int_flag & USBHS_BUS_RST_FLAG) {
- // TODO CH32 does not detect actual speed at this time (should be known at end of reset)
- // This interrupt probably triggered at start of bus reset
- // tusb_speed_t actual_speed;
- // switch(USBHSD->SPEED_TYPE & USBHS_SPEED_TYPE_MASK){
- // case USBHS_SPEED_TYPE_HIGH:
- // actual_speed = TUSB_SPEED_HIGH;
- // break;
- // case USBHS_SPEED_TYPE_FULL:
- // actual_speed = TUSB_SPEED_FULL;
- // break;
- // case USBHS_SPEED_TYPE_LOW:
- // actual_speed = TUSB_SPEED_LOW;
- // break;
- // default:
- // TU_ASSERT(0,);
- // break;
- // }
- // dcd_event_bus_reset(0, actual_speed, true);
-
- dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true);
-
+ // This interrupt probably triggered at start of bus reset before the speed negotiation has completed.
+ // Defer the bus reset event until the next setup packet is received in order to determine the actual speed of the bus.
+ reset_evt_pending = true;
USBHSD->DEV_AD = 0;
memset(ep_data_tog, 0, sizeof(ep_data_tog));
ep0_tog = true;