diff --git a/src/portable/espressif/esp32s2/dcd_esp32s2.c b/src/portable/espressif/esp32s2/dcd_esp32s2.c index 16c0e720..10c789da 100644 --- a/src/portable/espressif/esp32s2/dcd_esp32s2.c +++ b/src/portable/espressif/esp32s2/dcd_esp32s2.c @@ -179,7 +179,8 @@ void dcd_init(uint8_t rhport) USB0.gintmsk = 0; //mask all USB0.gotgint = ~0U; //clear OTG ints USB0.gintsts = ~0U; //clear pending ints - USB0.gintmsk = USB_MODEMISMSK_M | + USB0.gintmsk = USB_OTGINTMSK_M | + USB_MODEMISMSK_M | #if USE_SOF USB_SOFMSK_M | #endif @@ -189,7 +190,7 @@ void dcd_init(uint8_t rhport) USB_USBRSTMSK_M | USB_ENUMDONEMSK_M | USB_RESETDETMSK_M | - USB_DISCONNINTMSK_M; + USB_DISCONNINTMSK_M; // host most only } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) @@ -638,12 +639,6 @@ static void _dcd_int_handler(void* arg) const uint32_t int_status = USB0.gintsts; //const uint32_t int_msk = USB0.gintmsk; - if (int_status & USB_DISCONNINT_M) { - ESP_EARLY_LOGV(TAG, "dcd_int_handler - disconnected"); - USB0.gintsts = USB_DISCONNINT_M; - dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); - } - if (int_status & USB_USBRST_M) { // start of reset ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset"); @@ -666,6 +661,21 @@ static void _dcd_int_handler(void* arg) dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); } + if (int_status & USB_OTGINT_M) + { + // OTG INT bit is read-only + ESP_EARLY_LOGV(TAG, "dcd_int_handler - disconnected"); + + uint32_t const otg_int = USB0.gotgint; + + if (otg_int & USB_SESENDDET_M) + { + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); + } + + USB0.gotgint = otg_int; + } + #if USE_SOF if (int_status & USB_SOF_M) { USB0.gintsts = USB_SOF_M; @@ -674,26 +684,25 @@ static void _dcd_int_handler(void* arg) #endif if (int_status & USB_RXFLVI_M) { + // RXFLVL bit is read-only ESP_EARLY_LOGV(TAG, "dcd_int_handler - rx!"); - USB0.gintsts = USB_RXFLVI_M; - // disable RXFLVI interrupt until we read data from FIFO + // Mask out RXFLVL while reading data from FIFO USB0.gintmsk &= ~USB_RXFLVIMSK_M; - read_rx_fifo(); - - // re-enable RXFLVI USB0.gintmsk |= USB_RXFLVIMSK_M; } // OUT endpoint interrupt handling. if (int_status & USB_OEPINT_M) { + // OEPINT is read-only ESP_EARLY_LOGV(TAG, "dcd_int_handler - OUT endpoint!"); handle_epout_ints(); } // IN endpoint interrupt handling. if (int_status & USB_IEPINT_M) { + // IEPINT bit read-only ESP_EARLY_LOGV(TAG, "dcd_int_handler - IN endpoint!"); handle_epin_ints(); } diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 3386abda..243ddd15 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -75,6 +75,11 @@ /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#define USE_SOF 0 + #define DEVICE_BASE (USB_OTG_DeviceTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE) #define OUT_EP_BASE (USB_OTG_OUTEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_OUT_ENDPOINT_BASE) #define IN_EP_BASE (USB_OTG_INEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_IN_ENDPOINT_BASE) @@ -187,15 +192,13 @@ void dcd_init (uint8_t rhport) // TODO: PHYSEL is read-only on some cores (STM32F407). Worth gating? USB_OTG_FS->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos) | USB_OTG_GUSBCFG_PHYSEL; - // Clear all used interrupts - USB_OTG_FS->GINTSTS |= USB_OTG_GINTSTS_OTGINT | USB_OTG_GINTSTS_MMIS | \ - USB_OTG_GINTSTS_USBRST | USB_OTG_GINTSTS_ENUMDNE | \ - USB_OTG_GINTSTS_ESUSP | USB_OTG_GINTSTS_USBSUSP | USB_OTG_GINTSTS_SOF; + // Clear all interrupts + USB_OTG_FS->GINTSTS |= USB_OTG_FS->GINTSTS; - // Required as part of core initialization. Disable OTGINT as we don't use - // it right now. TODO: How should mode mismatch be handled? It will cause + // Required as part of core initialization. + // TODO: How should mode mismatch be handled? It will cause // the core to stop working/require reset. - USB_OTG_FS->GINTMSK |= /* USB_OTG_GINTMSK_OTGINT | */ USB_OTG_GINTMSK_MMISM; + USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; @@ -203,9 +206,9 @@ void dcd_init (uint8_t rhport) // (non zero-length packet), send STALL back and discard. Full speed. dev->DCFG |= USB_OTG_DCFG_NZLSOHSK | (3 << USB_OTG_DCFG_DSPD_Pos); - USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | \ - USB_OTG_GINTMSK_SOFM | USB_OTG_GINTMSK_RXFLVLM /* SB_OTG_GINTMSK_ESUSPM | \ - USB_OTG_GINTMSK_USBSUSPM */; + USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | + USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | + USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); // Enable USB transceiver. USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_PWRDWN; @@ -687,22 +690,56 @@ void dcd_int_handler(uint8_t rhport) { dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); } + if(int_status & USB_OTG_GINTSTS_USBSUSP) + { + USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_USBSUSP; + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + + if(int_status & USB_OTG_GINTSTS_WKUINT) + { + USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_WKUINT; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + + if(int_status & USB_OTG_GINTSTS_OTGINT) + { + // OTG INT bit is read-only + uint32_t const otg_int = USB_OTG_FS->GOTGINT; + + if (otg_int & USB_OTG_GOTGINT_SEDET) + { + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); + } + + USB_OTG_FS->GOTGINT = otg_int; + } + +#if USE_SOF if(int_status & USB_OTG_GINTSTS_SOF) { USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_SOF; dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } +#endif if(int_status & USB_OTG_GINTSTS_RXFLVL) { + // RXFLVL bit is read-only + + // Mask out RXFLVL while reading data from FIFO + USB_OTG_FS->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; read_rx_fifo(out_ep); + USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; } // OUT endpoint interrupt handling. if(int_status & USB_OTG_GINTSTS_OEPINT) { + // OEPINT is read-only handle_epout_ints(dev, out_ep); } // IN endpoint interrupt handling. if(int_status & USB_OTG_GINTSTS_IEPINT) { + // IEPINT bit read-only handle_epin_ints(dev, in_ep); } }