diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c index c1c3ca8c..8825ab19 100644 --- a/port/dwc2/usb_hc_dwc2.c +++ b/port/dwc2/usb_hc_dwc2.c @@ -339,22 +339,6 @@ static inline void dwc2_chan_enable_csplit(struct usbh_bus *bus, uint8_t ch_num, } } -static inline void dwc2_chan_reenable(struct usbh_bus *bus, uint8_t ch_num) -{ - __IO uint32_t tmpreg; - uint8_t is_oddframe; - - is_oddframe = (((uint32_t)USB_OTG_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U; - USB_OTG_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM; - USB_OTG_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29; - - /* Set host channel enable */ - tmpreg = USB_OTG_HC(ch_num)->HCCHAR; - tmpreg &= ~USB_OTG_HCCHAR_CHDIS; - tmpreg |= USB_OTG_HCCHAR_CHENA; - USB_OTG_HC(ch_num)->HCCHAR = tmpreg; -} - static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num) { volatile uint32_t ChannelEna = (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31; @@ -1215,12 +1199,15 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) /* restart ssplit transfer */ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { case USB_ENDPOINT_TYPE_CONTROL: + chan->do_csplit = 0; + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; case USB_ENDPOINT_TYPE_BULK: chan->do_csplit = 0; - dwc2_chan_enable_csplit(bus, ch_num, false); - dwc2_chan_reenable(bus, ch_num); + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); break; case USB_ENDPOINT_TYPE_INTERRUPT: + chan->do_csplit = 0; dwc2_chan_enable_csplit(bus, ch_num, false); urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb); @@ -1235,17 +1222,39 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) } } else if (chan_intstatus & USB_OTG_HCINT_ACK) { if (chan->do_ssplit) { - /* start ssplit transfer */ + /* start csplit transfer */ chan->do_csplit = 1; chan->ssplit_frame = dwc2_get_full_frame_num(bus); - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } } else if (chan_intstatus & USB_OTG_HCINT_NYET) { if (chan->do_ssplit) { /* restart csplit transfer */ - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + chan->do_csplit = 1; + chan->ssplit_frame = dwc2_get_full_frame_num(bus); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } else { urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb); @@ -1352,12 +1361,15 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) /* restart ssplit transfer */ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { case USB_ENDPOINT_TYPE_CONTROL: + chan->do_csplit = 0; + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; case USB_ENDPOINT_TYPE_BULK: chan->do_csplit = 0; - dwc2_chan_enable_csplit(bus, ch_num, false); - dwc2_chan_reenable(bus, ch_num); + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); break; case USB_ENDPOINT_TYPE_INTERRUPT: + chan->do_csplit = 0; dwc2_chan_enable_csplit(bus, ch_num, false); urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb); @@ -1372,17 +1384,39 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) } } else if (chan_intstatus & USB_OTG_HCINT_ACK) { if (chan->do_ssplit) { - /* start ssplit transfer */ + /* start csplit transfer */ chan->do_csplit = 1; chan->ssplit_frame = dwc2_get_full_frame_num(bus); - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } } else if (chan_intstatus & USB_OTG_HCINT_NYET) { if (chan->do_ssplit) { /* restart csplit transfer */ - dwc2_chan_enable_csplit(bus, ch_num, true); - dwc2_chan_reenable(bus, ch_num); + chan->do_csplit = 1; + chan->ssplit_frame = dwc2_get_full_frame_num(bus); + switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) { + case USB_ENDPOINT_TYPE_CONTROL: + dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer + urb->actual_length - 8, urb->transfer_buffer_length); + break; + case USB_ENDPOINT_TYPE_BULK: + case USB_ENDPOINT_TYPE_INTERRUPT: + dwc2_bulk_intr_urb_init(bus, ch_num, urb, urb->transfer_buffer + urb->actual_length, urb->transfer_buffer_length); + break; + + default: + break; + } } else { urb->errorcode = -USB_ERR_NAK; dwc2_urb_waitup(urb);