Skip to content

Commit 4f831f5

Browse files
committed
fix(port/dwc2/usb_hc_dwc2): do not disable channel for non-split periodic channels in buffer dma
Signed-off-by: sakumisu <[email protected]>
1 parent 684041f commit 4f831f5

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

port/dwc2/usb_hc_dwc2.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct dwc2_hcd {
6666
#define DWC2_EP0_STATE_INSTATUS 3
6767
#define DWC2_EP0_STATE_OUTSTATUS 4
6868

69-
static inline int dwc2_reset(uint8_t busid)
69+
static inline int dwc2_reset(struct usbh_bus *bus)
7070
{
7171
volatile uint32_t count = 0U;
7272

@@ -81,7 +81,7 @@ static inline int dwc2_reset(uint8_t busid)
8181
count = 0U;
8282
USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
8383

84-
if (g_dwc2_udc[busid].GSNPSID < 0x4F54420AU) {
84+
if (g_dwc2_hcd[bus->hcd.hcd_id].GSNPSID < 0x4F54420AU) {
8585
do {
8686
if (++count > 200000U) {
8787
USB_LOG_ERR("DWC2 reset timeout\r\n");
@@ -326,19 +326,24 @@ static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint
326326
static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num)
327327
{
328328
volatile uint32_t ChannelEna = (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
329+
volatile uint32_t HcEpType = (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
330+
volatile uint32_t SplitEna = (USB_OTG_HC(ch_num)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
329331
volatile uint32_t count = 0U;
330-
__IO uint32_t value;
332+
volatile uint32_t value;
331333

332-
if (((USB_OTG_GLB->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) &&
333-
(ChannelEna == 0U)) {
334+
/* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
335+
At the end of the next uframe/frame (in the worst case), the core generates a channel halted
336+
and disables the channel automatically. */
337+
if ((((USB_OTG_GLB->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
338+
((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR))))) {
334339
return;
335340
}
336341

337342
USB_OTG_HC(ch_num)->HCINTMSK = 0;
338343

339344
value = USB_OTG_HC(ch_num)->HCCHAR;
340345
value |= USB_OTG_HCCHAR_CHDIS;
341-
value &= ~USB_OTG_HCCHAR_CHENA;
346+
value |= USB_OTG_HCCHAR_CHENA;
342347
value &= ~USB_OTG_HCCHAR_EPDIR;
343348
USB_OTG_HC(ch_num)->HCCHAR = value;
344349
do {
@@ -360,7 +365,7 @@ static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
360365
USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
361366

362367
USB_OTG_HPRT = (USB_OTG_HPRT_PRST | hprt0);
363-
usb_osal_msleep(100U); /* See Note #1 */
368+
usb_osal_msleep(100U);
364369
USB_OTG_HPRT = ((~USB_OTG_HPRT_PRST) & hprt0);
365370
usb_osal_msleep(10U);
366371

@@ -388,7 +393,7 @@ static inline uint16_t dwc2_get_full_frame_num(struct usbh_bus *bus)
388393
{
389394
uint16_t frame = usbh_get_frame_number(bus);
390395

391-
/* USB_OTG_HFNUM_FRNUM_Msk is 0xFFFF��but max frame num is 0x3FFF */
396+
/* USB_OTG_HFNUM_FRNUM_Msk is 0xFFFF but max frame num is 0x3FFF */
392397
return ((frame & 0x3FFF) >> 3);
393398
}
394399

0 commit comments

Comments
 (0)