From 6178f8de2f0a0a766d7e4ff202c2528c1ecce7c6 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 1 Jul 2020 13:38:59 +0300 Subject: [PATCH 1/2] ESP32-S2: Handle the fact that available EP IN FIFOs are less than the number of available EP INs ESP32-S2 has only 5 available endpoint-in FIFOs (including EP0) but 7 available EP IN numbers. This change decouples the fifo number from the endpoint number, providing FIFO numbers until they reach the limit, at which point it will return false and assert an error that too many endpoints were allocated. --- src/portable/espressif/esp32s2/dcd_esp32s2.c | 31 +++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/portable/espressif/esp32s2/dcd_esp32s2.c b/src/portable/espressif/esp32s2/dcd_esp32s2.c index d49b69a10..21bad327a 100644 --- a/src/portable/espressif/esp32s2/dcd_esp32s2.c +++ b/src/portable/espressif/esp32s2/dcd_esp32s2.c @@ -71,6 +71,20 @@ static uint32_t _setup_packet[2]; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] static xfer_ctl_t xfer_status[EP_MAX][2]; +// Max number of IN EP FIFOs +#define USB_FIFO_NUM 5 + +// Keep count of how many FIFOs are in use +static uint8_t dcd_allocated_fifos = 1; //FIFO0 is always in use + +// Will either return an unused FIFO number, or 0 if all are used. +static uint8_t dcd_get_free_fifo(){ + if (dcd_allocated_fifos < USB_FIFO_NUM) { + return dcd_allocated_fifos++; + } + return 0; +} + // Setup the control endpoint 0. static void bus_reset(void) { @@ -271,8 +285,12 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) // - Offset: GRXFSIZ + 16 + Size*(epnum-1) // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + uint8_t fifo_num = dcd_get_free_fifo(); + TU_ASSERT(fifo_num != 0); + + in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M); in_ep[epnum].diepctl |= USB_D_USBACTEP1_M | - epnum << USB_D_TXFNUM1_S | + fifo_num << USB_D_TXFNUM1_S | desc_edpt->bmAttributes.xfer << USB_D_EPTYPE1_S | (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? (1 << USB_DI_SETD0PID1_S) : 0) | desc_edpt->wMaxPacketSize.size << 0; @@ -282,8 +300,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) // Both TXFD and TXSA are in unit of 32-bit words. // IN FIFO 0 was configured during enumeration, hence the "+ 16". uint16_t const allocated_size = (USB0.grxfsiz & 0x0000ffff) + 16; - uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_MAX-1); - uint32_t const fifo_offset = allocated_size + fifo_size*(epnum-1); + uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (USB_FIFO_NUM-1); + uint32_t const fifo_offset = allocated_size + fifo_size*(fifo_num-1); // DIEPTXF starts at FIFO #1. USB0.dieptxf[epnum - 1] = (fifo_size << USB_NPTXFDEP_S) | fifo_offset; @@ -361,7 +379,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) } // Flush the FIFO, and wait until we have confirmed it cleared. - USB0.grstctl |= ((epnum - 1) << USB_TXFNUM_S); + uint8_t const fifo_num = ((in_ep[epnum].diepctl >> USB_D_TXFNUM1_S) & USB_D_TXFNUM1_V); + USB0.grstctl |= (fifo_num << USB_TXFNUM_S); USB0.grstctl |= USB_TXFFLSH_M; while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ; } else { @@ -653,6 +672,8 @@ static void _dcd_int_handler(void* arg) // start of reset ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset"); USB0.gintsts = USB_USBRST_M; + // FIFOs will be reassigned when the endpoints are reopen + dcd_allocated_fifos = 1; bus_reset(); } @@ -681,6 +702,8 @@ static void _dcd_int_handler(void* arg) if (otg_int & USB_SESENDDET_M) { dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); + // FIFOs will be reassigned when the endpoints are reopen + dcd_allocated_fifos = 1; } USB0.gotgint = otg_int; From a1a390a7883b35bbc00a85e52d1e2f76a18ebcbd Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 28 Jul 2020 10:54:23 +0300 Subject: [PATCH 2/2] Update dcd_esp32s2.c --- src/portable/espressif/esp32s2/dcd_esp32s2.c | 22 ++++++++------------ 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/portable/espressif/esp32s2/dcd_esp32s2.c b/src/portable/espressif/esp32s2/dcd_esp32s2.c index 21bad327a..5be1c82e5 100644 --- a/src/portable/espressif/esp32s2/dcd_esp32s2.c +++ b/src/portable/espressif/esp32s2/dcd_esp32s2.c @@ -54,6 +54,9 @@ // FIFO size in bytes #define EP_FIFO_SIZE 1024 +// Max number of IN EP FIFOs +#define EP_FIFO_NUM 5 + typedef struct { uint8_t *buffer; uint16_t total_len; @@ -71,17 +74,12 @@ static uint32_t _setup_packet[2]; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] static xfer_ctl_t xfer_status[EP_MAX][2]; -// Max number of IN EP FIFOs -#define USB_FIFO_NUM 5 - // Keep count of how many FIFOs are in use -static uint8_t dcd_allocated_fifos = 1; //FIFO0 is always in use +static uint8_t _allocated_fifos = 1; //FIFO0 is always in use // Will either return an unused FIFO number, or 0 if all are used. -static uint8_t dcd_get_free_fifo(){ - if (dcd_allocated_fifos < USB_FIFO_NUM) { - return dcd_allocated_fifos++; - } +static uint8_t get_free_fifo(){ + if (_allocated_fifos < EP_FIFO_NUM) return _allocated_fifos++; return 0; } @@ -285,7 +283,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) // - Offset: GRXFSIZ + 16 + Size*(epnum-1) // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". - uint8_t fifo_num = dcd_get_free_fifo(); + uint8_t fifo_num = get_free_fifo(); TU_ASSERT(fifo_num != 0); in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M); @@ -300,7 +298,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) // Both TXFD and TXSA are in unit of 32-bit words. // IN FIFO 0 was configured during enumeration, hence the "+ 16". uint16_t const allocated_size = (USB0.grxfsiz & 0x0000ffff) + 16; - uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (USB_FIFO_NUM-1); + uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_FIFO_NUM-1); uint32_t const fifo_offset = allocated_size + fifo_size*(fifo_num-1); // DIEPTXF starts at FIFO #1. @@ -673,7 +671,7 @@ static void _dcd_int_handler(void* arg) ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset"); USB0.gintsts = USB_USBRST_M; // FIFOs will be reassigned when the endpoints are reopen - dcd_allocated_fifos = 1; + _allocated_fifos = 1; bus_reset(); } @@ -702,8 +700,6 @@ static void _dcd_int_handler(void* arg) if (otg_int & USB_SESENDDET_M) { dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); - // FIFOs will be reassigned when the endpoints are reopen - dcd_allocated_fifos = 1; } USB0.gotgint = otg_int;