|
|
@@ -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,6 +74,15 @@ 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];
|
|
|
|
|
|
+// Keep count of how many FIFOs are 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 get_free_fifo(){
|
|
|
+ if (_allocated_fifos < EP_FIFO_NUM) return _allocated_fifos++;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
// Setup the control endpoint 0.
|
|
|
static void bus_reset(void)
|
|
|
{
|
|
|
@@ -271,8 +283,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 = 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 +298,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) / (EP_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 +377,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 {
|
|
|
@@ -660,6 +677,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
|
|
|
+ _allocated_fifos = 1;
|
|
|
bus_reset();
|
|
|
}
|
|
|
|