Просмотр исходного кода

Revert dcd_alloc_mem_for_conf() but keep changes from @kasjer for ISO EP

Add tud_audio_set_itf_close_EP_cb()
Reinhard Panhuber 5 лет назад
Родитель
Сommit
032e84c9be

+ 5 - 1
src/class/audio/audio_device.c

@@ -876,6 +876,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
   {
     _audiod_itf[idxDriver].ep_in_as_intf_num = 0;
     usbd_edpt_close(rhport, _audiod_itf[idxDriver].ep_in);
+
+    // Invoke callback - can be used to stop data sampling
+    if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request));
+
     _audiod_itf[idxDriver].ep_in = 0;                           // Necessary?
   }
 #endif
@@ -928,7 +932,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
             _audiod_itf[idxDriver].ep_in = ep_addr;
             _audiod_itf[idxDriver].ep_in_as_intf_num = itf;
 
-            // Invoke callback and trigger data generation - if not already running
+            // Invoke callback - can be used to trigger data sampling if not already running
             if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
 
             // Schedule first transmit - in case no sample data is available a ZLP is loaded

+ 3 - 0
src/class/audio/audio_device.h

@@ -272,6 +272,9 @@ TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t * n_bytes_c
 // Invoked when audio set interface request received
 TU_ATTR_WEAK bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request);
 
+// Invoked when audio set interface request received which closes an EP
+TU_ATTR_WEAK bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request);
+
 // Invoked when audio class specific set request received for an EP
 TU_ATTR_WEAK bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff);
 

+ 0 - 4
src/device/dcd.h

@@ -115,10 +115,6 @@ void dcd_connect(uint8_t rhport) TU_ATTR_WEAK;
 // Disconnect by disabling internal pull-up resistor on D+/D-
 void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
 
-// Invoked when a set configuration request was received
-// Helper to allow for dynamic EP buffer allocation according to configuration descriptor
-TU_ATTR_WEAK bool dcd_alloc_mem_for_conf(uint8_t rhport, tusb_desc_configuration_t const * desc_cfg);
-
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 0 - 3
src/device/usbd.c

@@ -786,9 +786,6 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
   tusb_desc_configuration_t const * desc_cfg = (tusb_desc_configuration_t const *) tud_descriptor_configuration_cb(cfg_num-1); // index is cfg_num-1
   TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION);
 
-  // Allow for dynamic allocation of EP buffer for current configuration - only one configuration may be active according to USB specification
-  if (dcd_alloc_mem_for_conf) TU_ASSERT(dcd_alloc_mem_for_conf(rhport, desc_cfg));
-
   // Parse configuration descriptor
   _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1 : 0;
   _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED) ? 1 : 0;

+ 107 - 362
src/portable/st/synopsys/dcd_synopsys.c

@@ -47,53 +47,53 @@
 
 #if TUSB_OPT_DEVICE_ENABLED && \
     ( (CFG_TUSB_MCU == OPT_MCU_STM32F1 && defined(STM32F1_SYNOPSYS)) || \
-      CFG_TUSB_MCU == OPT_MCU_STM32F2 || \
-      CFG_TUSB_MCU == OPT_MCU_STM32F4 || \
-      CFG_TUSB_MCU == OPT_MCU_STM32F7 || \
-      CFG_TUSB_MCU == OPT_MCU_STM32H7 || \
-      (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) \
+        CFG_TUSB_MCU == OPT_MCU_STM32F2 || \
+        CFG_TUSB_MCU == OPT_MCU_STM32F4 || \
+        CFG_TUSB_MCU == OPT_MCU_STM32F7 || \
+        CFG_TUSB_MCU == OPT_MCU_STM32H7 || \
+        (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) \
     )
 
 // EP_MAX       : Max number of bi-directional endpoints including EP0
 // EP_FIFO_SIZE : Size of dedicated USB SRAM
 #if CFG_TUSB_MCU == OPT_MCU_STM32F1
-  #include "stm32f1xx.h"
-  #define EP_MAX_FS       4
-  #define EP_FIFO_SIZE_FS 1280
+#include "stm32f1xx.h"
+#define EP_MAX_FS       4
+#define EP_FIFO_SIZE_FS 1280
 
 #elif CFG_TUSB_MCU == OPT_MCU_STM32F2
-  #include "stm32f2xx.h"
-  #define EP_MAX_FS       USB_OTG_FS_MAX_IN_ENDPOINTS
-  #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
+#include "stm32f2xx.h"
+#define EP_MAX_FS       USB_OTG_FS_MAX_IN_ENDPOINTS
+#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
 
 #elif CFG_TUSB_MCU == OPT_MCU_STM32F4
-  #include "stm32f4xx.h"
-  #define EP_MAX_FS       USB_OTG_FS_MAX_IN_ENDPOINTS
-  #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
-  #define EP_MAX_HS       USB_OTG_HS_MAX_IN_ENDPOINTS
-  #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE
+#include "stm32f4xx.h"
+#define EP_MAX_FS       USB_OTG_FS_MAX_IN_ENDPOINTS
+#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
+#define EP_MAX_HS       USB_OTG_HS_MAX_IN_ENDPOINTS
+#define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE
 
 #elif CFG_TUSB_MCU == OPT_MCU_STM32H7
-  #include "stm32h7xx.h"
-  #define EP_MAX_FS       9
-  #define EP_FIFO_SIZE_FS 4096
-  #define EP_MAX_HS       9
-  #define EP_FIFO_SIZE_HS 4096
+#include "stm32h7xx.h"
+#define EP_MAX_FS       9
+#define EP_FIFO_SIZE_FS 4096
+#define EP_MAX_HS       9
+#define EP_FIFO_SIZE_HS 4096
 
 #elif CFG_TUSB_MCU == OPT_MCU_STM32F7
-  #include "stm32f7xx.h"
-  #define EP_MAX_FS       6
-  #define EP_FIFO_SIZE_FS 1280
-  #define EP_MAX_HS       9
-  #define EP_FIFO_SIZE_HS 4096
+#include "stm32f7xx.h"
+#define EP_MAX_FS       6
+#define EP_FIFO_SIZE_FS 1280
+#define EP_MAX_HS       9
+#define EP_FIFO_SIZE_HS 4096
 
 #elif CFG_TUSB_MCU == OPT_MCU_STM32L4
-  #include "stm32l4xx.h"
-  #define EP_MAX_FS       6
-  #define EP_FIFO_SIZE_FS 1280
+#include "stm32l4xx.h"
+#define EP_MAX_FS       6
+#define EP_FIFO_SIZE_FS 1280
 
 #else
-  #error "Unsupported MCUs"
+#error "Unsupported MCUs"
 
 #endif
 
@@ -105,16 +105,16 @@
 
 // On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS
 #if TUD_OPT_RHPORT == 0
-  #define EP_MAX            EP_MAX_FS
-  #define EP_FIFO_SIZE      EP_FIFO_SIZE_FS
-  #define RHPORT_REGS_BASE  USB_OTG_FS_PERIPH_BASE
-  #define RHPORT_IRQn       OTG_FS_IRQn
+#define EP_MAX            EP_MAX_FS
+#define EP_FIFO_SIZE      EP_FIFO_SIZE_FS
+#define RHPORT_REGS_BASE  USB_OTG_FS_PERIPH_BASE
+#define RHPORT_IRQn       OTG_FS_IRQn
 
 #else
-  #define EP_MAX            EP_MAX_HS
-  #define EP_FIFO_SIZE      EP_FIFO_SIZE_HS
-  #define RHPORT_REGS_BASE  USB_OTG_HS_PERIPH_BASE
-  #define RHPORT_IRQn       OTG_HS_IRQn
+#define EP_MAX            EP_MAX_HS
+#define EP_FIFO_SIZE      EP_FIFO_SIZE_HS
+#define RHPORT_REGS_BASE  USB_OTG_HS_PERIPH_BASE
+#define RHPORT_IRQn       OTG_HS_IRQn
 #endif
 
 #define GLOBAL_BASE(_port)     ((USB_OTG_GlobalTypeDef*) RHPORT_REGS_BASE)
@@ -145,7 +145,7 @@ typedef struct TU_ATTR_PACKED {
   // The codes assigned to those fields, according to the USB specification, can be neatly used as indices.
   uint16_t ep_size[EP_MAX][2];          ///< dim 1: EP number, dim 2: EP direction denoted by TUSB_DIR_OUT (= 0) and TUSB_DIR_IN (= 1)
   bool ep_transfer_type[EP_MAX][2][4];      ///< dim 1: EP number, dim 2: EP direction, dim 3: transfer type, where 0 = Control, 1 = Isochronous, 2 = Bulk, and 3 = Interrupt
-                        ///< I know very well that EP0 can only be used as control EP and we waste space here but for the sake of simplicity we accept that. It is used in a non-persistent way anyway!
+  ///< I know very well that EP0 can only be used as control EP and we waste space here but for the sake of simplicity we accept that. It is used in a non-persistent way anyway!
 } ep_sz_tt_report_t;
 
 typedef volatile uint32_t * usb_fifo_t;
@@ -167,7 +167,7 @@ static void bus_reset(uint8_t rhport)
   USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
   USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
   USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  //  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
+  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
 
   tu_memclr(xfer_status, sizeof(xfer_status));
 
@@ -217,93 +217,28 @@ static void bus_reset(uint8_t rhport)
   //   are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended.  Maybe provide a macro for application to
   //   overwrite this.
 
-  // We rework this here and initialize the FIFOs here only for the USB reset case. The rest is done once a
-  // configuration was set from the host. For this initialization phase we use 64 bytes as FIFO size.
-
-  // Found by trial: 10 + 2 + CFG_TUD_ENDPOINT0_SIZE/4 + 1 + 6 - not quite sure where 1 + 6 comes from but this works for 8/16/32/64 EP0 size
-  _allocated_fifo_words = 10 + 2 + CFG_TUD_ENDPOINT0_SIZE/4 + 1 + 6;    // 64 bytes max packet size + 2 words (for the status of the control OUT data packet) + 10 words (for setup packets)
-
-  //  _allocated_fifo_words = 47 + 2*EP_MAX;    // 64 bytes max packet size + 2 words (for the status of the control OUT data packet) + 10 words (for setup packets)
+#if TUD_OPT_HIGH_SPEED
+  _allocated_fifo_words = 271 + 2*EP_MAX;
+#else
+  _allocated_fifo_words =  47 + 2*EP_MAX;
+#endif
 
   usb_otg->GRXFSIZ = _allocated_fifo_words;
 
   // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word )
-  usb_otg->DIEPTXF0_HNPTXFSIZ = (CFG_TUD_ENDPOINT0_SIZE/4 << USB_OTG_TX0FD_Pos) | _allocated_fifo_words;
+  usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | _allocated_fifo_words;
 
-  _allocated_fifo_words += CFG_TUD_ENDPOINT0_SIZE/4;
+  _allocated_fifo_words += 16;
 
-  // Set SETUP packet count to 3
-  out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos);
-
-  usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT;
+  // TU_LOG2_INT(_allocated_fifo_words);
 
+  // Fixed control EP0 size to 64 bytes
+  in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
+  xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64;
 
-  //#if TUD_OPT_HIGH_SPEED
-  //  _allocated_fifo_words = 271 + 2*EP_MAX;
-  //#else
-  //  _allocated_fifo_words =  47 + 2*EP_MAX;
-  //#endif
-  //
-  //  usb_otg->GRXFSIZ = _allocated_fifo_words;
-  //
-  //  // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word )
-  //  usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | _allocated_fifo_words;
-  //
-  //  _allocated_fifo_words += 16;
-  //
-  //  // TU_LOG2_INT(_allocated_fifo_words);
-  //
-  //  // Fixed control EP0 size to 64 bytes
-  //  in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-  //  xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64;
-  //
-  //  // Set SETUP packet count to 3
-  //  out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos);
-  //
-  //  usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT;
-}
-
-// Required after new configuration received in case EP0 max packet size has changed
-static void set_EP0_max_pkt_size(void)
-{
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  uint32_t enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos;
-
-  // Maximum packet size for EP 0 is set for both directions by writing DIEPCTL.
-  switch (enum_spd)
-  {
-    case 0x00:  // High speed - always 64 byte
-      in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64;
-      break;
-
-    case 0x03:  // Full speed
-#if CFG_TUD_ENDPOINT0_SIZE == 64
-      in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64;
-#elif CFG_TUD_ENDPOINT0_SIZE == 32
-      in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      in_ep[0].DIEPCTL |= (0x01 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 32;
-#elif CFG_TUD_ENDPOINT0_SIZE == 16
-      in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      in_ep[0].DIEPCTL |= (0x02 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 16;
-#elif CFG_TUD_ENDPOINT0_SIZE == 8
-      in_ep[0].DIEPCTL |= (0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 8;
-#else
-# error CFG_TUD_ENDPOINT0_SIZE MUST be 8, 16, 32, or 64!
-#endif
-      break;
+  out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos);
 
-    default:    // Low speed - always 8 bytes
-      in_ep[0].DIEPCTL |= (0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-      xfer_status[0][TUSB_DIR_OUT].max_size = 8;
-      xfer_status[0][TUSB_DIR_IN].max_size = 8;
-  }
+  usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT;
 }
 
 // Set turn-around timeout according to link speed
@@ -536,8 +471,8 @@ void dcd_init (uint8_t rhport)
   if ( rhport == 0 ) usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN;
 
   usb_otg->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);
+      USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM     |
+      USB_OTG_GINTMSK_RXFLVLM  | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0);
 
   // Enable global interrupt
   usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
@@ -594,7 +529,7 @@ void dcd_disconnect(uint8_t rhport)
 
 bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
 {
-//  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
+  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
   USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
   USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
   USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
@@ -620,15 +555,13 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
   if(dir == TUSB_DIR_OUT)
   {
     out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) |
-                             (desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) |
-                             (desc_edpt->wMaxPacketSize.size << USB_OTG_DOEPCTL_MPSIZ_Pos);
+        (desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) |
+        (desc_edpt->wMaxPacketSize.size << USB_OTG_DOEPCTL_MPSIZ_Pos);
 
     dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum));
   }
   else
   {
-    // FIFO allocation done in dcd_alloc_mem_for_conf()
-
     // "USB Data FIFOs" section in reference manual
     // Peripheral FIFO architecture
     //
@@ -654,35 +587,35 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
     //    - Interrupt is EPSize
     //    - Bulk/ISO is max(EPSize, remaining-fifo / non-opened-EPIN)
 
-//    uint16_t const fifo_remaining = EP_FIFO_SIZE/4 - _allocated_fifo_words;
-//    uint16_t fifo_size = desc_edpt->wMaxPacketSize.size / 4;
-//
-//    if ( desc_edpt->bmAttributes.xfer != TUSB_XFER_INTERRUPT )
-//    {
-//      uint8_t opened = 0;
-//      for(uint8_t i = 0; i < EP_MAX; i++)
-//      {
-//        if ( (i != epnum) && (xfer_status[i][TUSB_DIR_IN].max_size > 0) ) opened++;
-//      }
-//
-//      // EP Size or equally divided of remaining whichever is larger
-//      fifo_size = tu_max16(fifo_size, fifo_remaining / (EP_MAX - opened));
-//    }
-//
-//    // FIFO overflows, we probably need a better allocating scheme
-//    TU_ASSERT(fifo_size <= fifo_remaining);
-//
-//    // DIEPTXF starts at FIFO #1.
-//    // Both TXFD and TXSA are in unit of 32-bit words.
-//    usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | _allocated_fifo_words;
-//
-//    _allocated_fifo_words += fifo_size;
+    uint16_t const fifo_remaining = EP_FIFO_SIZE/4 - _allocated_fifo_words;
+    uint16_t fifo_size = (desc_edpt->wMaxPacketSize.size + 3) / 4;  // +3 for rounding up to next full word
+
+    if ( desc_edpt->bmAttributes.xfer != TUSB_XFER_INTERRUPT )
+    {
+      uint8_t opened = 0;
+      for(uint8_t i = 0; i < EP_MAX; i++)
+      {
+        if ( (i != epnum) && (xfer_status[i][TUSB_DIR_IN].max_size > 0) ) opened++;
+      }
+
+      // EP Size or equally divided of remaining whichever is larger
+      fifo_size = tu_max16(fifo_size, fifo_remaining / (EP_MAX - opened));
+    }
+
+    // FIFO overflows, we probably need a better allocating scheme
+    TU_ASSERT(fifo_size <= fifo_remaining);
+
+    // DIEPTXF starts at FIFO #1.
+    // Both TXFD and TXSA are in unit of 32-bit words.
+    usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | _allocated_fifo_words;
+
+    _allocated_fifo_words += fifo_size;
 
     in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) |
-                            (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) |
-                            (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) |
-                            (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) |
-                            (desc_edpt->wMaxPacketSize.size << USB_OTG_DIEPCTL_MPSIZ_Pos);
+        (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) |
+        (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) |
+        (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) |
+        (desc_edpt->wMaxPacketSize.size << USB_OTG_DIEPCTL_MPSIZ_Pos);
 
     dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum));
   }
@@ -780,7 +713,20 @@ static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
  */
 void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
 {
+  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
+
+  uint8_t const epnum = tu_edpt_number(ep_addr);
+  uint8_t const dir   = tu_edpt_dir(ep_addr);
+
   dcd_edpt_disable(rhport, ep_addr, false);
+  if (dir == TUSB_DIR_IN)
+  {
+    uint16_t const fifo_size = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXFD_Msk) >> USB_OTG_DIEPTXF_INEPTXFD_Pos;
+    uint16_t const fifo_start = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXSA_Msk) >> USB_OTG_DIEPTXF_INEPTXSA_Pos;
+    // For now only endpoint that has FIFO at the end of FIFO memory can be closed without fuss.
+    TU_ASSERT(fifo_start + fifo_size == _allocated_fifo_words,);
+    _allocated_fifo_words -= fifo_size;
+  }
 }
 
 void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
@@ -892,7 +838,7 @@ static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_
 
   switch(pktsts) {
     case 0x01: // Global OUT NAK (Interrupt)
-    break;
+      break;
 
     case 0x02: // Out packet recvd
     {
@@ -920,18 +866,18 @@ static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_
 
     case 0x04: // Setup packet done (Interrupt)
       out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos);
-    break;
+      break;
 
     case 0x06: // Setup packet recvd
       // We can receive up to three setup packets in succession, but
       // only the last one is valid.
       _setup_packet[0] = (* rx_fifo);
       _setup_packet[1] = (* rx_fifo);
-    break;
+      break;
 
     default: // Invalid
       TU_BREAKPOINT();
-    break;
+      break;
   }
 }
 
@@ -1049,9 +995,6 @@ void dcd_int_handler(uint8_t rhport)
     tusb_speed_t const speed = get_speed(rhport);
 
     set_turnaround(usb_otg, speed);
-
-    set_EP0_max_pkt_size();
-
     dcd_event_bus_reset(rhport, speed, true);
   }
 
@@ -1115,209 +1058,11 @@ void dcd_int_handler(uint8_t rhport)
     handle_epin_ints(rhport, dev, in_ep);
   }
 
-  // Check for Incomplete isochronous IN transfer
-  if(int_status & USB_OTG_GINTSTS_IISOIXFR) {
-    TU_LOG2("      IISOIXFR!\r\n");
-  }
-}
-
-// Helper function which parses through the current configuration descriptors to find the biggest EPs in size.
-static bool get_ep_size_report(uint8_t rhport, tusb_desc_configuration_t const * desc_cfg, ep_sz_tt_report_t * p_report)
-{
-  (void) rhport;
-
-  //  tu_memclr(p_report, sizeof(ep_sz_tt_report_t));   // This does not initialize the first two entries ... i do not know why!
-
-  // EP0 sizes and usages are fixed
-  p_report->ep_size[0][TUSB_DIR_OUT] = p_report->ep_size[0][TUSB_DIR_IN] = CFG_TUD_ENDPOINT0_SIZE;
-  p_report->ep_transfer_type[0][TUSB_DIR_OUT][TUSB_XFER_CONTROL] = p_report->ep_transfer_type[0][TUSB_DIR_IN][TUSB_XFER_CONTROL] = true;
-
-  // Parse interface descriptor
-  uint8_t const * p_desc   = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t);
-  uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + desc_cfg->wTotalLength;
-
-  uint8_t addr;
-
-  while( p_desc < desc_end )
-  {
-    if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc))
-    {
-
-      addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
-
-      // Verify values - this checks may be omitted in case we trust the descriptors to be okay
-      TU_VERIFY(tu_edpt_number(addr) < EP_MAX);
-      TU_VERIFY(tu_edpt_dir(addr) <= TUSB_DIR_IN);
-      TU_VERIFY(((tusb_desc_endpoint_t const*) p_desc)->bmAttributes.xfer <= TUSB_XFER_INTERRUPT);
-
-      p_report->ep_size[tu_edpt_number(addr)][tu_edpt_dir(addr)] = tu_max16(p_report->ep_size[tu_edpt_number(addr)][tu_edpt_dir(addr)], ((tusb_desc_endpoint_t const*) p_desc)->wMaxPacketSize.size);
-      p_report->ep_transfer_type[tu_edpt_number(addr)][tu_edpt_dir(addr)][((tusb_desc_endpoint_t const*) p_desc)->bmAttributes.xfer] = true;
-    }
-    p_desc = tu_desc_next(p_desc); // Proceed
-  }
-  return true;
-}
-
-// Setup FIFO buffers at configuration time.
-// The idea is to use this information such that the FIFOs need to be configured only once
-// at configuration time and no more later. This makes it easy in case you want to close and open EPs for different
-// purposes at any time (without taking care of other active EPs). You also avoid the nasty need of defragmenting
-// the TX buffers, which is likely to happen.
-// Certainly, this function does not allow for the highest possible flexibility as it only works in the worst case
-// (all biggest EPs can be active at the same time). However, this should not be a problem for almost all applications.
-
-// Spare space is assigned equally divided to bulk and interrupt EPs.
-// Pure isochronous EPs do not get any spare space as it does not make any sense.
-TU_ATTR_WEAK bool dcd_alloc_mem_for_conf(uint8_t rhport, tusb_desc_configuration_t const * desc_cfg)
-{
-  (void) rhport;
-
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-
-  //  for(uint8_t n = 0; n < EP_MAX; n++) {
-  //      out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
-  //  }
-
-  out_ep[0].DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
-
-  // Deactivate Interrupts?
-  dev->DAINTMSK &= ~((1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos));
-  dev->DOEPMSK &= ~(USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM);
-  dev->DIEPMSK &= ~(USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM);
-
-  //     usb_otg->GINTMSK &= ~(USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT);
-
-  // Determine maximum required spaces for individual EPs and what kind of usage (control, bulk, etc.) they are used for
-  ep_sz_tt_report_t report = {0};               // dim 1: EP number, dim 2: EP direction, dim 3: transfer type
-  TU_VERIFY(get_ep_size_report(rhport, desc_cfg, &report));
-
-  // With that information, set the following up:
-  // The RX buffer size (as it is a shared buffer here) is set to the sum of the two biggest out EPs plus all the required extra words used for setup packets etc.
-  // This should work well for all kinds of applications
-
-  // Determine number of used out EPs of current configuration and size of two biggest out EPs
-  uint8_t nUsedOutEPs = 0, cnt_ep, cnt_tt;
-  uint16_t sz[2] = {0, 0};
-  uint16_t fifo_depth;
-
-  for (cnt_ep = 0; cnt_ep < EP_MAX; cnt_ep++)
-  {
-    for (cnt_tt = 0; cnt_tt <= TUSB_XFER_INTERRUPT; cnt_tt++)
-    {
-      if (report.ep_transfer_type[cnt_ep][TUSB_DIR_OUT][cnt_tt])
-      {
-        nUsedOutEPs++;
-        break;
-      }
-    }
-
-    fifo_depth = report.ep_size[cnt_ep][TUSB_DIR_OUT] / 4 + 1;
-    if (sz[0] < fifo_depth)
-    {
-      sz[1] = sz[0];
-      sz[0] = fifo_depth;
-    }
-    else if (sz[1] < report.ep_size[cnt_ep][TUSB_DIR_OUT])
-    {
-      sz[1] = fifo_depth;
-    }
-  }
-
-  // For configuration use the approach as explained in bus_reset()
-  _allocated_fifo_words = 13 + 1 + 1 + 2 * nUsedOutEPs + sz[0] + sz[1] + 2;   // again, i do not really know why we need + 2 but otherwise it does not work
-
-  usb_otg->GRXFSIZ = _allocated_fifo_words;
-
-  // Control IN uses FIFO 0 with report.ep_size[0][TUSB_DIR_IN] bytes ( report.ep_size[0][TUSB_DIR_IN]/4 32-bit word )
-  fifo_depth = report.ep_size[0][TUSB_DIR_IN] / 4;
-  fifo_depth = tu_max16(16, fifo_depth);
-  usb_otg->DIEPTXF0_HNPTXFSIZ = (fifo_depth << USB_OTG_TX0FD_Pos) | _allocated_fifo_words;
-
-  _allocated_fifo_words += fifo_depth;
-
-  // For configuration of remaining in EPs use the approach as explained in dcd_edpt_open() except that:
-  // - ISO EPs only get EP size as FIFO size. More makes no sense since within one frame precisely EP size bytes are transfered and not more.
-  //   Furthermore, double buffering is not possible (for this silicon) since once FIFO was written to and transmit bit was set you are
-  //   not allowed to write to the FIFO any more until transmit was done. So you can not send something and buffer the next frame in the
-  //   meantime into the buffer. TODO: check for high speed and uC types which can do this!
-  // - Interrupt EPs only get EP size as FIFO size
-  // - Bulk and control (other than EP0 - this is possible) get spare space equally divided - those profit the most from extra space
-
-  // "USB Data FIFOs" section in reference manual
-  // Peripheral FIFO architecture
-  //
-  // --------------- 320 or 1024 ( 1280 or 4096 bytes )
-  // | IN FIFO MAX |
-  // ---------------
-  // |    ...      |
-  // --------------- y + x + w + GRXFSIZ
-  // | IN FIFO 2   |
-  // --------------- x + w + GRXFSIZ
-  // | IN FIFO 1   |
-  // --------------- w + GRXFSIZ
-  // | IN FIFO 0   |
-  // --------------- GRXFSIZ
-  // | OUT FIFO    |
-  // | ( Shared )  |
-  // --------------- 0
-  //
-  // In FIFO is allocated by following rules:
-  // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n".
-  // - Offset: allocated so far
-  // - Size - as described above
-
-  // Determine required numbers
-  // Remaining space available in bytes
-  uint16_t const fifo_remaining = EP_FIFO_SIZE/4 - _allocated_fifo_words;
-
-  // Required space by EPs in words, number of bulk and control EPs
-  uint16_t ep_sz_total = 0;
-  // Number of bulk and control EPs
-  uint8_t nbc = 0;
-  // EP0 is already taken care of so exclude that here
-  for (cnt_ep = 1; cnt_ep < EP_MAX; cnt_ep++)
-  {
-    fifo_depth = (report.ep_size[cnt_ep][TUSB_DIR_IN] + 3) / 4;     // Since we need full words take care of remainders!
-    if (fifo_depth > 0 && fifo_depth < 16) fifo_depth = 16;         // Minimum FIFO depth is 16
-    ep_sz_total += fifo_depth;
-    nbc += (report.ep_transfer_type[cnt_ep][TUSB_DIR_IN][TUSB_XFER_BULK] | report.ep_transfer_type[cnt_ep][TUSB_DIR_IN][TUSB_XFER_CONTROL]);
-  }
-
-  if (ep_sz_total > fifo_remaining)
-  {
-    // Too less space available to apply this allocation scheme - return false and set a flag such that a different approach may be used TODO: introduce flag
-    return false;
-  }
-
-  uint16_t extra_space = nbc > 0 ? (fifo_remaining - ep_sz_total) / nbc : 0;        // If no bulk or control EPs are used we just leave the rest of the memory unused
-
-  // Setup FIFOs
-  for (cnt_ep = 1; cnt_ep < EP_MAX; cnt_ep++)
-  {
-    // If EP is used
-    if (report.ep_size[cnt_ep][TUSB_DIR_IN] > 0)
-    {
-      fifo_depth = (report.ep_size[cnt_ep][TUSB_DIR_IN] + 3) / 4 + ((report.ep_transfer_type[cnt_ep][TUSB_DIR_IN][TUSB_XFER_BULK] || report.ep_transfer_type[cnt_ep][TUSB_DIR_IN][TUSB_XFER_CONTROL]) ? extra_space : 0);
-      fifo_depth = tu_max16(16, fifo_depth);
-      usb_otg->DIEPTXF[cnt_ep - 1] = (fifo_depth << USB_OTG_DIEPTXF_INEPTXFD_Pos) | _allocated_fifo_words;
-      _allocated_fifo_words += fifo_depth;
-    }
-  }
-
-  //  usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT;
-
-  // Enable interrupts
-  dev->DAINTMSK |= (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos);
-  dev->DOEPMSK |= USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
-  dev->DIEPMSK |= USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM;
-
-  //     USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT;
-
-  out_ep[0].DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
-
-  return true;
+//  // Check for Incomplete isochronous IN transfer
+//  if(int_status & USB_OTG_GINTSTS_IISOIXFR) {
+//    printf("      IISOIXFR!\r\n");
+////    TU_LOG2("      IISOIXFR!\r\n");
+//  }
 }
 
 #endif