diff --git a/src/usbd_stm32f429_otgfs.c b/src/usbd_stm32f429_otgfs.c index a41479e..87f0971 100644 --- a/src/usbd_stm32f429_otgfs.c +++ b/src/usbd_stm32f429_otgfs.c @@ -132,13 +132,15 @@ static void enable(bool enable) { OTG->DIEPTXF0_HNPTXFSIZ = RX_FIFO_SZ | (0x10 << 16); /* unmask EP interrupts */ OTGD->DIEPMSK = USB_OTG_DIEPMSK_XFRCM; + OTGD->DOEPMSK = USB_OTG_DOEPMSK_XFRCM; /* unmask core interrupts */ OTG->GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | #if !defined(USBD_SOF_DISABLED) USB_OTG_GINTMSK_SOFM | #endif USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | - USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_RXFLVLM; + USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_RXFLVLM | + USB_OTG_GINTMSK_OEPINT; /* clear pending interrupts */ OTG->GINTSTS = 0xFFFFFFFF; /* unmask global interrupt */ @@ -424,6 +426,29 @@ static void evt_poll(usbd_device *dev, usbd_evt_callback callback) { } else if (_t & USB_OTG_GINTSTS_WKUINT) { OTG->GINTSTS = USB_OTG_GINTSTS_WKUINT; evt = usbd_evt_wkup; + } else if(_t & USB_OTG_GINTSTS_OEPINT){ + for(int cur_ep = 0; cur_ep < MAX_EP; cur_ep++){ + USB_OTG_OUTEndpointTypeDef* epo = EPOUT(cur_ep); + if (epo->DOEPINT & USB_OTG_DOEPINT_XFRC) { + epo->DOEPINT = USB_OTG_DOEPINT_XFRC; + + uint8_t ep_is_isochr = + _FLD2VAL(USB_OTG_DOEPCTL_EPTYP, epo->DOEPCTL) == USB_EPTYPE_ISOCHRONUS; + + // Since isochronous endpoints can only receive data on the + // specified odd or even frame num, after each reception we must + // configure the EONUM field + if (ep_is_isochr) { + uint8_t odd_now = _FLD2VAL(USB_OTG_DSTS_FNSOF, OTGD->DSTS) & 1u; + if (odd_now) { + epo->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + } else { + epo->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; + } + } + } + } + continue; } else { /* no more supported events */ return;