From 6b4592c82de79ac4d0173d6eed40bc6fe2b55e8f Mon Sep 17 00:00:00 2001 From: dragonmux Date: Thu, 18 Apr 2024 17:24:53 +0100 Subject: [PATCH] usb/dwc: Corrected how interrupts are handled for the H7's DWC2 so that setup and out packets are properly acknowledged --- lib/usb/usb_dwc_common.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/usb/usb_dwc_common.c b/lib/usb/usb_dwc_common.c index ac7468d5..d0b82a13 100644 --- a/lib/usb/usb_dwc_common.c +++ b/lib/usb/usb_dwc_common.c @@ -365,34 +365,43 @@ void dwc_poll(usbd_device *usbd_dev) } /* - * There is no global interrupt flag for transmit complete. + * There is not always a global interrupt flag for transmit complete. * The XFRC bit must be checked in each OTG_DIEPINT(x). * * Iterate over the IN endpoints, triggering any post-transmit actions. */ - for (size_t i = 0; i < ENDPOINT_COUNT; i++) { - if (REBASE(OTG_DIEPINT(i)) & OTG_DIEPINTX_XFRC) { - /* Transfer complete. */ - if (usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN]) { - usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN](usbd_dev, i); - } +#if defined(STM32H7) + if (intsts & OTG_GINTSTS_IEPINT) { +#endif + for (size_t i = 0; i < ENDPOINT_COUNT; i++) { + if (REBASE(OTG_DIEPINT(i)) & OTG_DIEPINTX_XFRC) { + /* Transfer complete. */ + REBASE(OTG_DIEPINT(i)) = OTG_DIEPINTX_XFRC; - REBASE(OTG_DIEPINT(i)) = OTG_DIEPINTX_XFRC; + if (usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN]) { + usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN](usbd_dev, i); + } + } } +#if defined(STM32H7) } +#endif /* Note: RX and TX handled differently in this device. */ if (intsts & OTG_GINTSTS_RXFLVL) { /* Receive FIFO non-empty. */ - uint32_t rxstsp = REBASE(OTG_GRXSTSP); - uint32_t pktsts = rxstsp & OTG_GRXSTSP_PKTSTS_MASK; - uint8_t ep = rxstsp & OTG_GRXSTSP_EPNUM_MASK; + const uint32_t rxstsp = REBASE(OTG_GRXSTSP); + const uint32_t pktsts = rxstsp & OTG_GRXSTSP_PKTSTS_MASK; + const uint8_t ep = rxstsp & OTG_GRXSTSP_EPNUM_MASK; if (pktsts == OTG_GRXSTSP_PKTSTS_SETUP_COMP) { usbd_dev->user_callback_ctr[ep][USB_TRANSACTION_SETUP](usbd_dev, ep); } if (pktsts == OTG_GRXSTSP_PKTSTS_OUT_COMP || pktsts == OTG_GRXSTSP_PKTSTS_SETUP_COMP) { +#if defined(STM32H7) + REBASE(OTG_DOEPINT(ep)) = OTG_DOEPINTX_STUP; +#endif REBASE(OTG_DOEPTSIZ(ep)) = usbd_dev->doeptsiz[ep]; REBASE(OTG_DOEPCTL(ep)) |= OTG_DOEPCTL0_EPENA | (usbd_dev->force_nak[ep] ? OTG_DOEPCTL0_SNAK : OTG_DOEPCTL0_CNAK); @@ -416,7 +425,7 @@ void dwc_poll(usbd_device *usbd_dev) usbd_dev->rxbcnt = (rxstsp & OTG_GRXSTSP_BCNT_MASK) >> 4U; if (type == USB_TRANSACTION_SETUP) { - dwc_ep_read_packet(usbd_dev, ep, &usbd_dev->control_state.req, 8); + dwc_ep_read_packet(usbd_dev, ep, &usbd_dev->control_state.req, 8U); } else if (usbd_dev->user_callback_ctr[ep][type]) { usbd_dev->user_callback_ctr[ep][type](usbd_dev, ep); }