diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c index 36fb9cb2..e9de2602 100644 --- a/port/dwc2/usb_dc_dwc2.c +++ b/port/dwc2/usb_dc_dwc2.c @@ -877,8 +877,12 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SODDFRM; USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; } + } + + if (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS || + g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) { USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); - USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29)); + USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & ((usbd_get_ep_mult(busid, ep) + 1) << 29)); } if (g_dwc2_udc[busid].user_params.device_dma_enable) { diff --git a/port/dwc2/usb_dwc2_reg.h b/port/dwc2/usb_dwc2_reg.h index cdf4f51a..599d4ea5 100644 --- a/port/dwc2/usb_dwc2_reg.h +++ b/port/dwc2/usb_dwc2_reg.h @@ -215,9 +215,7 @@ typedef struct #define USB_OTG_HCFG_FSLSS_Pos (2U) #define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */ #define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */ -#define USB_OTG_HFIR_RELOAD_CTRL_Pos (16U) -#define USB_OTG_HFIR_RELOAD_CTRL_Msk (0x1UL << USB_OTG_HFIR_RELOAD_CTRL_Pos) -#define USB_OTG_HFIR_RELOAD_CTRL USB_OTG_HFIR_RELOAD_CTRL_Msk + /******************** Bit definition for USB_OTG_DCFG register ********************/ #define USB_OTG_DCFG_DSPD_Pos (0U) @@ -335,6 +333,9 @@ typedef struct #define USB_OTG_HFIR_FRIVL_Pos (0U) #define USB_OTG_HFIR_FRIVL_Msk (0xFFFFUL << USB_OTG_HFIR_FRIVL_Pos) /*!< 0x0000FFFF */ #define USB_OTG_HFIR_FRIVL USB_OTG_HFIR_FRIVL_Msk /*!< Frame interval */ +#define USB_OTG_HFIR_RELOAD_CTRL_Pos (16U) +#define USB_OTG_HFIR_RELOAD_CTRL_Msk (0x1UL << USB_OTG_HFIR_RELOAD_CTRL_Pos) +#define USB_OTG_HFIR_RELOAD_CTRL USB_OTG_HFIR_RELOAD_CTRL_Msk /******************** Bit definition for USB_OTG_HFNUM register ********************/ #define USB_OTG_HFNUM_FRNUM_Pos (0U) diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c index 9b7b2ab1..3ceead00 100644 --- a/port/dwc2/usb_hc_dwc2.c +++ b/port/dwc2/usb_hc_dwc2.c @@ -222,7 +222,14 @@ static inline uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t po } } -static inline void dwc2_chan_char_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed) +static inline void dwc2_chan_char_init(struct usbh_bus *bus, + uint8_t ch_num, + uint8_t dev_addr, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps, + uint8_t ep_mult, + uint8_t speed) { uint32_t regval; @@ -230,7 +237,8 @@ static inline void dwc2_chan_char_init(struct usbh_bus *bus, uint8_t ch_num, uin regval = (((uint32_t)ep_mps << USB_OTG_HCCHAR_MPSIZ_Pos) & USB_OTG_HCCHAR_MPSIZ) | ((((uint32_t)ep_addr & 0x7FU) << USB_OTG_HCCHAR_EPNUM_Pos) & USB_OTG_HCCHAR_EPNUM) | (((uint32_t)ep_type << USB_OTG_HCCHAR_EPTYP_Pos) & USB_OTG_HCCHAR_EPTYP) | - (((uint32_t)devaddr << USB_OTG_HCCHAR_DAD_Pos) & USB_OTG_HCCHAR_DAD); + (((uint32_t)ep_mult << USB_OTG_HCCHAR_MC_Pos) & USB_OTG_HCCHAR_MC) | + (((uint32_t)dev_addr << USB_OTG_HCCHAR_DAD_Pos) & USB_OTG_HCCHAR_DAD); if ((ep_addr & 0x80U) == 0x80U) { regval |= USB_OTG_HCCHAR_EPDIR; @@ -272,7 +280,14 @@ static inline void dwc2_chan_splt_init(struct usbh_bus *bus, uint8_t ch_num) } } -static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed) +static void dwc2_chan_init(struct usbh_bus *bus, + uint8_t ch_num, + uint8_t dev_addr, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps, + uint8_t ep_mult, + uint8_t speed) { /* Clear old interrupt conditions for this host channel. */ USB_OTG_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU; @@ -283,7 +298,7 @@ static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr /* Enable the top level host channel interrupt. */ USB_OTG_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU); - dwc2_chan_char_init(bus, ch_num, devaddr, ep_addr, ep_type, ep_mps, speed); + dwc2_chan_char_init(bus, ch_num, dev_addr, ep_addr, ep_type, ep_mps, ep_mult, speed); dwc2_chan_splt_init(bus, ch_num); } @@ -519,27 +534,62 @@ static void dwc2_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct us if (chan->ep0_state == DWC2_EP0_STATE_SETUP) /* fill setup */ { chan->num_packets = dwc2_calculate_packet_num(8, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen); - dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed); + dwc2_chan_init(bus, + chidx, + urb->hport->dev_addr, + 0x00, + USB_ENDPOINT_TYPE_CONTROL, + USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), + 1, + urb->hport->speed); dwc2_chan_transfer(bus, chidx, 0x00, (uint8_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP); } else if (chan->ep0_state == DWC2_EP0_STATE_INDATA) /* fill in data */ { chan->num_packets = dwc2_calculate_packet_num(datalen, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen); - dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed); + dwc2_chan_init(bus, + chidx, + urb->hport->dev_addr, + 0x80, + USB_ENDPOINT_TYPE_CONTROL, + USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), + 1, + urb->hport->speed); dwc2_chan_transfer(bus, chidx, 0x80, buffer, chan->xferlen, chan->num_packets, data_pid); } else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) /* fill out data */ { chan->num_packets = dwc2_calculate_packet_num(datalen, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen); - dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed); + dwc2_chan_init(bus, + chidx, + urb->hport->dev_addr, + 0x00, + USB_ENDPOINT_TYPE_CONTROL, + USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), + 1, + urb->hport->speed); dwc2_chan_transfer(bus, chidx, 0x00, buffer, chan->xferlen, chan->num_packets, data_pid); } else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) /* fill in status */ { chan->num_packets = dwc2_calculate_packet_num(0, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen); - dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed); + dwc2_chan_init(bus, + chidx, + urb->hport->dev_addr, + 0x80, + USB_ENDPOINT_TYPE_CONTROL, + USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), + 1, + urb->hport->speed); dwc2_chan_transfer(bus, chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1); } else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) /* fill out status */ { chan->num_packets = dwc2_calculate_packet_num(0, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen); - dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed); + dwc2_chan_init(bus, + chidx, + urb->hport->dev_addr, + 0x00, + USB_ENDPOINT_TYPE_CONTROL, + USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), + 1, + urb->hport->speed); dwc2_chan_transfer(bus, chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1); } } @@ -562,7 +612,14 @@ static void dwc2_bulk_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct } chan->num_packets = dwc2_calculate_packet_num(datalen, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen); - dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed); + dwc2_chan_init(bus, + chidx, + urb->hport->dev_addr, + urb->ep->bEndpointAddress, + USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), + USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), + USB_GET_MULT(urb->ep->wMaxPacketSize) + 1, + urb->hport->speed); dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, buffer, chan->xferlen, chan->num_packets, urb->data_toggle == 0 ? HC_PID_DATA0 : HC_PID_DATA1); }