From 8cecb81517a07bcd83d083dcafc86a21861f55aa Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Tue, 11 Oct 2022 15:50:22 +0200 Subject: [PATCH] usbdev_synopsys_dwc2: Mask RX FIFO irq with DMA When using DMA to transfer endpoint data from the RX FIFO to the endpoint memory, the RXFLVL irq is not needed as that is already handled by the DMA. Furthermore, servicing this irq anyway can cause the event handling to interpret data from the FIFO as the endpoint and status marker during the DMA transfer. This commit masks the RXFLVL irq while DMA is used for the endpoint transfers. --- .../usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c b/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c index b0bddebd73ec..114a6473013d 100644 --- a/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c +++ b/drivers/usbdev_synopsys_dwc2/usbdev_synopsys_dwc2.c @@ -85,8 +85,7 @@ USB_OTG_GINTMSK_USBRST | \ USB_OTG_GINTMSK_OTGINT | \ USB_OTG_GINTMSK_IEPINT | \ - USB_OTG_GINTMSK_OEPINT | \ - USB_OTG_GINTMSK_RXFLVLM) + USB_OTG_GINTMSK_OEPINT) #define DWC2_PKTSTS_GONAK 0x01 /**< Rx fifo global out nak */ #define DWC2_PKTSTS_DATA_UPDT 0x02 /**< Rx fifo data update */ @@ -855,9 +854,14 @@ static void _usbdev_init(usbdev_t *dev) _device_regs(conf)->DIEPMSK |= USB_OTG_DIEPMSK_XFRCM; } + uint32_t gint_mask = DWC2_FSHS_USB_GINT_MASK; + if (!_uses_dma(conf)) { + gint_mask |= USB_OTG_GINTMSK_RXFLVLM; + } + /* Clear the interrupt flags and unmask those interrupts */ - _global_regs(conf)->GINTSTS |= DWC2_FSHS_USB_GINT_MASK; - _global_regs(conf)->GINTMSK |= DWC2_FSHS_USB_GINT_MASK; + _global_regs(conf)->GINTSTS |= gint_mask; + _global_regs(conf)->GINTMSK |= gint_mask; DEBUG("usbdev: USB peripheral currently in %s mode\n", (_global_regs( @@ -1277,7 +1281,7 @@ void _isr_common(dwc2_usb_otg_fshs_t *usbdev) uint32_t status = _global_regs(conf)->GINTSTS; if (status) { - if (status & USB_OTG_GINTSTS_RXFLVL) { + if ((status & USB_OTG_GINTSTS_RXFLVL) && !_uses_dma(conf)) { unsigned epnum = _global_regs(conf)->GRXSTSR & USB_OTG_GRXSTSP_EPNUM_Msk; usbdev->usbdev.epcb(&usbdev->out[epnum].ep, USBDEV_EVENT_ESR);