From 6f868034224b770816e6ff146ef04ea8ab290a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thi=C3=A9baud=20Fuchs?= Date: Wed, 17 Apr 2024 17:50:28 +0200 Subject: [PATCH] Fix bus reset, try to prevent ep0 overwrite --- src/wch-ch56x-lib/USBDevice/usb20.c | 10 ++++++---- src/wch-ch56x-lib/USBDevice/usb_device.c | 7 +++++-- src/wch-ch56x-lib/USBDevice/usb_endpoints.h | 4 +++- tests/test_firmware_usb_loopback/User/main.c | 4 ++-- .../User/main.c | 4 ++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/wch-ch56x-lib/USBDevice/usb20.c b/src/wch-ch56x-lib/USBDevice/usb20.c index 9cb20ac..e34c4ab 100644 --- a/src/wch-ch56x-lib/USBDevice/usb20.c +++ b/src/wch-ch56x-lib/USBDevice/usb20.c @@ -740,10 +740,13 @@ __attribute__((interrupt("WCH-Interrupt-fast"))) void USBHS_IRQHandler(void) if (ep0_passthrough_enabled) { - usb2_backend_current_device->endpoints.endp0_passthrough_setup_callback( + volatile USB_ENDPOINT* endp0 = &usb2_backend_current_device->endpoints.rx[0]; + + endp0->state = usb2_backend_current_device->endpoints.endp0_passthrough_setup_callback( usb2_backend_current_device->endpoints.rx[0].buffer, sizeof(USB_SETUP)); + *usb2_get_rx_endpoint_addr_reg(0) = (uint32_t)endp0->buffer; R8_UEP0_TX_CTRL = UEP_T_RES_NAK | RB_UEP_T_TOG_1; - R8_UEP0_RX_CTRL = UEP_R_RES_ACK | RB_UEP_T_TOG_1; + R8_UEP0_RX_CTRL = endp0->state | RB_UEP_T_TOG_1; } else { @@ -815,11 +818,10 @@ __attribute__((interrupt("WCH-Interrupt-fast"))) void USBHS_IRQHandler(void) } else if (R8_USB_INT_FG & RB_USB_IF_BUSRST) { - // usb2_user_handled.usb2_device_handle_bus_reset(); + usb2_user_handled.usb2_device_handle_bus_reset(); usb2_set_device_address(0); usb2_backend_current_device->addr = 0; usb2_setup_endpoints(); - // usb2_backend_current_device->speed = SPEED_NONE; usb2_backend_current_device->state = DEFAULT; R8_USB_INT_FG = RB_USB_IF_BUSRST; } diff --git a/src/wch-ch56x-lib/USBDevice/usb_device.c b/src/wch-ch56x-lib/USBDevice/usb_device.c index 9677645..8b6bf26 100644 --- a/src/wch-ch56x-lib/USBDevice/usb_device.c +++ b/src/wch-ch56x-lib/USBDevice/usb_device.c @@ -24,8 +24,11 @@ uint16_t _default_endp0_user_handled_control_request(USB_SETUP* request, { return 0xffff; } -void _default_endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size); -void _default_endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size) {} +uint8_t _default_endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size); +uint8_t _default_endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size) +{ + return ENDP_STATE_ACK; +} void _default_endp_tx_complete(TRANSACTION_STATUS status); void _default_endp_tx_complete(TRANSACTION_STATUS status) {} uint8_t _default_endp_rx_callback(uint8_t* const ptr, uint16_t size); diff --git a/src/wch-ch56x-lib/USBDevice/usb_endpoints.h b/src/wch-ch56x-lib/USBDevice/usb_endpoints.h index f15d935..b3abd56 100644 --- a/src/wch-ch56x-lib/USBDevice/usb_endpoints.h +++ b/src/wch-ch56x-lib/USBDevice/usb_endpoints.h @@ -53,8 +53,10 @@ typedef struct usb_endpoints_t /** * @brief Called by the USB2 backend in passthrough mode after receiving a * SETUP request. + * @return new state of endpoint response (ACK 0x00, NAK 0X02, STALL 0X03). + * This will set the response for the next transfer (not this one). */ - void (*endp0_passthrough_setup_callback)(uint8_t* ptr, uint16_t size); + uint8_t (*endp0_passthrough_setup_callback)(uint8_t* ptr, uint16_t size); /** * @brief Called by the backend when it has confirmed data has been sent diff --git a/tests/test_firmware_usb_loopback/User/main.c b/tests/test_firmware_usb_loopback/User/main.c index 4a69bf8..19d8670 100644 --- a/tests/test_firmware_usb_loopback/User/main.c +++ b/tests/test_firmware_usb_loopback/User/main.c @@ -132,8 +132,8 @@ uint16_t endp0_user_handled_control_request(USB_SETUP* request, return 0xffff; } -void endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size); -void endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size) {} +uint8_t endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size); +uint8_t endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size) { return ENDP_STATE_ACK; } void usb2_device_handle_bus_reset(void); void usb2_device_handle_bus_reset(void) diff --git a/tests/test_firmware_usb_loopback_separate_usb_stacks/User/main.c b/tests/test_firmware_usb_loopback_separate_usb_stacks/User/main.c index 06166b8..90f7a78 100644 --- a/tests/test_firmware_usb_loopback_separate_usb_stacks/User/main.c +++ b/tests/test_firmware_usb_loopback_separate_usb_stacks/User/main.c @@ -57,8 +57,8 @@ uint16_t endp0_user_handled_control_request(USB_SETUP* request, return 0xffff; } -void endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size); -void endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size) {} +uint8_t endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size); +uint8_t endp0_passthrough_setup_callback(uint8_t* ptr, uint16_t size) { return ENDP_STATE_ACK; } void usb2_device_handle_bus_reset(void); void usb2_device_handle_bus_reset(void)