stm32: Rework usbotg transmit interrupts

Use the XFRC interrupt instead of TXFE.  Don't mask/unmask the tx
interrupts during runtime.  This fixes some race conditions where a tx
notification may have previously gotten lost.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-09-07 16:07:54 -04:00
parent ccb8db5ea1
commit 4fa41d9c61
1 changed files with 10 additions and 7 deletions

View File

@ -169,11 +169,9 @@ usb_send_bulk_in(void *data, uint_fast8_t len)
if (!(ctl & USB_OTG_DIEPCTL_USBAEP)) if (!(ctl & USB_OTG_DIEPCTL_USBAEP))
// Controller not enabled - discard data // Controller not enabled - discard data
return len; return len;
if (ctl & USB_OTG_DIEPCTL_EPENA) { if (ctl & USB_OTG_DIEPCTL_EPENA)
// Wait for space to transmit // Wait for space to transmit
OTGD->DIEPEMPMSK |= (1 << USB_CDC_EP_BULK_IN);
return -1; return -1;
}
return fifo_write_packet(USB_CDC_EP_BULK_IN, data, len); return fifo_write_packet(USB_CDC_EP_BULK_IN, data, len);
} }
@ -235,7 +233,6 @@ usb_send_ep0(const void *data, uint_fast8_t len)
} }
if (EPIN(0)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { if (EPIN(0)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) {
// Wait for space to transmit // Wait for space to transmit
OTGD->DIEPEMPMSK |= (1 << 0);
OTG->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; OTG->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
return -1; return -1;
} }
@ -323,13 +320,18 @@ OTG_FS_IRQHandler(void)
if (sts & USB_OTG_GINTSTS_IEPINT) { if (sts & USB_OTG_GINTSTS_IEPINT) {
// Can transmit data - disable irq and notify endpoint // Can transmit data - disable irq and notify endpoint
uint32_t daint = OTGD->DAINT; uint32_t daint = OTGD->DAINT;
OTGD->DIEPEMPMSK &= ~daint; if (daint & (1 << 0)) {
if (daint & (1 << 0)) USB_OTG_INEndpointTypeDef *epi = EPIN(0);
epi->DIEPINT = epi->DIEPINT;
usb_notify_ep0(); usb_notify_ep0();
if (daint & (1 << USB_CDC_EP_BULK_IN)) }
if (daint & (1 << USB_CDC_EP_BULK_IN)) {
USB_OTG_INEndpointTypeDef *epi = EPIN(USB_CDC_EP_BULK_IN);
epi->DIEPINT = epi->DIEPINT;
usb_notify_bulk_in(); usb_notify_bulk_in();
} }
} }
}
DECL_CONSTANT_STR("RESERVE_PINS_USB", "PA11,PA12"); DECL_CONSTANT_STR("RESERVE_PINS_USB", "PA11,PA12");
@ -370,6 +372,7 @@ usb_init(void)
// Enable interrupts // Enable interrupts
OTGD->DAINTMSK = (1 << 0) | (1 << USB_CDC_EP_BULK_IN); OTGD->DAINTMSK = (1 << 0) | (1 << USB_CDC_EP_BULK_IN);
OTGD->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
OTG->GINTMSK = USB_OTG_GINTMSK_RXFLVLM | USB_OTG_GINTMSK_IEPINT; OTG->GINTMSK = USB_OTG_GINTMSK_RXFLVLM | USB_OTG_GINTMSK_IEPINT;
OTG->GAHBCFG = USB_OTG_GAHBCFG_GINT; OTG->GAHBCFG = USB_OTG_GAHBCFG_GINT;
armcm_enable_irq(OTG_FS_IRQHandler, OTG_FS_IRQn, 1); armcm_enable_irq(OTG_FS_IRQHandler, OTG_FS_IRQn, 1);