From dd46b8ce39e11180fcefb803336791502c19d4a0 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Wed, 22 Oct 2025 20:34:22 +0800 Subject: [PATCH] feat: support custom ep0 mps Signed-off-by: sakumisu <1203593632@qq.com> --- core/usbd_core.c | 12 +++++- port/chipidea/usb_dc_chipidea.c | 2 +- port/dwc2/usb_dc_dwc2.c | 67 ++++++++++++++++++++++++++------- port/hpmicro/usb_dc_hpm.c | 2 +- 4 files changed, 66 insertions(+), 17 deletions(-) diff --git a/core/usbd_core.c b/core/usbd_core.c index 66ec4dc6..efe3c222 100644 --- a/core/usbd_core.c +++ b/core/usbd_core.c @@ -1145,18 +1145,26 @@ void usbd_event_suspend_handler(uint8_t busid) void usbd_event_reset_handler(uint8_t busid) { + struct usb_endpoint_descriptor ep0; + usbd_set_address(busid, 0); g_usbd_core[busid].device_address = 0; g_usbd_core[busid].configuration = 0; g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP; #ifdef CONFIG_USBDEV_ADVANCE_DESC g_usbd_core[busid].speed = USB_SPEED_UNKNOWN; + + USB_ASSERT_MSG(g_usbd_core[busid].descriptors->device_descriptor_callback != NULL, + "device_descriptor_callback is NULL\r\n"); + + struct usb_device_descriptor *device_desc = g_usbd_core[busid].descriptors->device_descriptor_callback(g_usbd_core[busid].speed); + ep0.wMaxPacketSize = device_desc->bMaxPacketSize0; +#else + ep0.wMaxPacketSize = USB_CTRL_EP_MPS; #endif - struct usb_endpoint_descriptor ep0; ep0.bLength = 7; ep0.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT; - ep0.wMaxPacketSize = USB_CTRL_EP_MPS; ep0.bmAttributes = USB_ENDPOINT_TYPE_CONTROL; ep0.bEndpointAddress = USB_CONTROL_IN_EP0; ep0.bInterval = 0; diff --git a/port/chipidea/usb_dc_chipidea.c b/port/chipidea/usb_dc_chipidea.c index 106f8af5..76760357 100644 --- a/port/chipidea/usb_dc_chipidea.c +++ b/port/chipidea/usb_dc_chipidea.c @@ -649,7 +649,7 @@ void USBD_IRQHandler(uint8_t busid) memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM); memset(g_chipidea_udc[busid].out_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM); usbd_event_reset_handler(busid); - chipidea_bus_reset(busid, 64); + chipidea_bus_reset(busid, g_chipidea_udc[busid].in_ep[0].ep_mps); } if (int_status & intr_suspend) { diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c index a5de3f29..88dd5fcc 100644 --- a/port/dwc2/usb_dc_dwc2.c +++ b/port/dwc2/usb_dc_dwc2.c @@ -675,6 +675,7 @@ uint8_t usbd_get_port_speed(uint8_t busid) int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) { uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress); + uint16_t ep_mps; USB_ASSERT_MSG(ep_idx < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1), "Ep addr %02x overflow", ep->bEndpointAddress); @@ -682,14 +683,34 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); g_dwc2_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); + ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + if (ep_idx == 0) { + switch (ep_mps) { + case 64: + ep_mps = EP_MPS_64; + break; + case 32: + ep_mps = EP_MPS_32; + break; + case 16: + ep_mps = EP_MPS_16; + break; + case 8: + ep_mps = EP_MPS_8; + break; + + default: + ep_mps = EP_MPS_64; + break; + } + } + USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx)); - if ((USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_USBAEP) == 0) { - USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & USB_OTG_DOEPCTL_MPSIZ) | - ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | - USB_OTG_DIEPCTL_SD0PID_SEVNFRM | - USB_OTG_DOEPCTL_USBAEP; - } + USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (ep_mps & USB_OTG_DOEPCTL_MPSIZ) | + ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DOEPCTL_USBAEP; } else { uint16_t fifo_size; if (ep_idx == 0) { @@ -703,14 +724,34 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) g_dwc2_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); g_dwc2_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); + ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + if (ep_idx == 0) { + switch (ep_mps) { + case 64: + ep_mps = EP_MPS_64; + break; + case 32: + ep_mps = EP_MPS_32; + break; + case 16: + ep_mps = EP_MPS_16; + break; + case 8: + ep_mps = EP_MPS_8; + break; + + default: + ep_mps = EP_MPS_64; + break; + } + } + USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx); - if ((USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0) { - USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & USB_OTG_DIEPCTL_MPSIZ) | - ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | (ep_idx << 22) | - USB_OTG_DIEPCTL_SD0PID_SEVNFRM | - USB_OTG_DIEPCTL_USBAEP; - } + USB_OTG_INEP(ep_idx)->DIEPCTL |= (ep_mps & USB_OTG_DIEPCTL_MPSIZ) | + ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) | (ep_idx << 22) | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DIEPCTL_USBAEP; dwc2_flush_txfifo(busid, ep_idx); } return 0; @@ -1046,7 +1087,7 @@ void USBD_IRQHandler(uint8_t busid) usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len); } } - // clang-format off + // clang-format off process_setup: // clang-format on if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) { diff --git a/port/hpmicro/usb_dc_hpm.c b/port/hpmicro/usb_dc_hpm.c index beb84826..d4c73d4a 100644 --- a/port/hpmicro/usb_dc_hpm.c +++ b/port/hpmicro/usb_dc_hpm.c @@ -307,7 +307,7 @@ void USBD_IRQHandler(uint8_t busid) memset(g_hpm_udc[busid].in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); memset(g_hpm_udc[busid].out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); usbd_event_reset_handler(busid); - usb_device_bus_reset(handle, 64); + usb_device_bus_reset(handle, g_hpm_udc[busid].in_ep[0].ep_mps); } if (int_status & intr_suspend) {