ソースを参照

add dcd_edpt_close and iso xfer.

MasterPhi 4 年 前
コミット
16b802d50c
1 ファイル変更49 行追加26 行削除
  1. 49 26
      src/portable/nxp/transdimension/dcd_transdimension.c

+ 49 - 26
src/portable/nxp/transdimension/dcd_transdimension.c

@@ -239,8 +239,9 @@ void dcd_init(uint8_t rhport)
   dcd_reg->USBMODE = USBMODE_CM_DEVICE;
   dcd_reg->USBMODE = USBMODE_CM_DEVICE;
   dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION;
   dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION;
 
 
-  // TODO Force fullspeed on non-highspeed port
-  // dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED;
+#if !TUD_OPT_HIGH_SPEED
+  dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED;
+#endif
 
 
   CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t));
   CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t));
 
 
@@ -329,22 +330,22 @@ static void qtd_init_fifo(dcd_qtd_t* p_qtd, tu_fifo_buffer_info_t *info, uint16_
   if (len_lin != 0)
   if (len_lin != 0)
   {
   {
     p_qtd->buffer[0]   = (uint32_t) info->ptr_lin;
     p_qtd->buffer[0]   = (uint32_t) info->ptr_lin;
-                
+
     len_lin -= 4096 - ((uint32_t) info->ptr_lin - tu_align4k((uint32_t) info->ptr_lin));
     len_lin -= 4096 - ((uint32_t) info->ptr_lin - tu_align4k((uint32_t) info->ptr_lin));
-    
+
     // Set linear part
     // Set linear part
     uint8_t i = 1;
     uint8_t i = 1;
     for(; i<5; i++)
     for(; i<5; i++)
     {
     {
       if (len_lin <= 0) break;
       if (len_lin <= 0) break;
       p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096;
       p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096;
-      len_lin -= 4096;  
+      len_lin -= 4096;
     }
     }
     // Set wrapped part
     // Set wrapped part
     for(uint8_t page = 0; i<5; i++, page++)
     for(uint8_t page = 0; i<5; i++, page++)
     {
     {
       p_qtd->buffer[i] |= (uint32_t) info->ptr_wrap + 4096 * page;
       p_qtd->buffer[i] |= (uint32_t) info->ptr_wrap + 4096 * page;
-    }  
+    }
   }
   }
 }
 }
 
 
@@ -373,9 +374,6 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
 
 
 bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
 bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
 {
 {
-  // TODO not support ISO yet
-  TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
-
   uint8_t const epnum  = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
   uint8_t const epnum  = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
   uint8_t const dir    = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
   uint8_t const dir    = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
   uint8_t const ep_idx = 2*epnum + dir;
   uint8_t const ep_idx = 2*epnum + dir;
@@ -387,14 +385,25 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
   dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx];
   dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx];
   tu_memclr(p_qhd, sizeof(dcd_qhd_t));
   tu_memclr(p_qhd, sizeof(dcd_qhd_t));
 
 
-  p_qhd->zero_length_termination = 1;
   p_qhd->max_package_size        = p_endpoint_desc->wMaxPacketSize.size;
   p_qhd->max_package_size        = p_endpoint_desc->wMaxPacketSize.size;
   p_qhd->qtd_overlay.next        = QTD_NEXT_INVALID;
   p_qhd->qtd_overlay.next        = QTD_NEXT_INVALID;
 
 
+  if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
+  {
+    p_qhd->iso_mult = 1;
+  } else
+  {
+    p_qhd->zero_length_termination = 1;
+  }
+
   CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t));
   CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t));
 
 
   // Enable EP Control
   // Enable EP Control
   dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
   dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
+
+  // Clear EP type
+  dcd_reg->ENDPTCTRL[epnum] &=~(0x03 << (dir ? 18 : 2));
+
   dcd_reg->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0);
   dcd_reg->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0);
 
 
   return true;
   return true;
@@ -406,6 +415,22 @@ void dcd_edpt_close_all (uint8_t rhport)
   // TODO implement dcd_edpt_close_all()
   // TODO implement dcd_edpt_close_all()
 }
 }
 
 
+void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
+{
+  uint8_t const epnum  = tu_edpt_number(ep_addr);
+  uint8_t const dir    = tu_edpt_dir(ep_addr);
+
+  dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
+
+  // Flush EP
+  uint32_t flush_mask = TU_BIT(epnum) << (dir ? 16 : 0);
+  dcd_reg->ENDPTFLUSH = flush_mask;
+  while(dcd_reg->ENDPTFLUSH & flush_mask);
+
+  // Clear EP enable
+  dcd_reg->ENDPTCTRL[epnum] &=~(ENDPTCTRL_ENABLE << (dir ? 16 : 0));
+}
+
 bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
 bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
 {
 {
   dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
   dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
@@ -442,7 +467,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
 }
 }
 
 
 // fifo has to be aligned to 4k boundary
 // fifo has to be aligned to 4k boundary
-bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) 
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
 {
 {
   dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
   dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
   uint8_t const epnum = tu_edpt_number(ep_addr);
   uint8_t const epnum = tu_edpt_number(ep_addr);
@@ -460,34 +485,33 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
   dcd_qtd_t * p_qtd      = &_dcd_data.qtd[ep_idx];
   dcd_qtd_t * p_qtd      = &_dcd_data.qtd[ep_idx];
 
 
   tu_fifo_buffer_info_t fifo_info;
   tu_fifo_buffer_info_t fifo_info;
-    
-  if(dir == TUSB_DIR_IN)
+
+  if (dir)
   {
   {
     tu_fifo_get_read_info(ff, &fifo_info);
     tu_fifo_get_read_info(ff, &fifo_info);
-  }
-  else
+  } else
   {
   {
     tu_fifo_get_write_info(ff, &fifo_info);
     tu_fifo_get_write_info(ff, &fifo_info);
   }
   }
-    
+
   if(total_bytes <= fifo_info.len_lin)
   if(total_bytes <= fifo_info.len_lin)
   {
   {
     // Limit transfer length to total_bytes
     // Limit transfer length to total_bytes
     fifo_info.len_wrap = 0;
     fifo_info.len_wrap = 0;
     fifo_info.len_lin = total_bytes;
     fifo_info.len_lin = total_bytes;
-  }
-  else
+  } else
   {
   {
-    // Class driver ensure at least total_bytes elements in fifo
+    // Class driver need to ensure at least total_bytes elements in fifo
     fifo_info.len_wrap = total_bytes - fifo_info.len_lin;
     fifo_info.len_wrap = total_bytes - fifo_info.len_lin;
   }
   }
   // Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the
   // Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the
   // address to 32-byte boundaries.
   // address to 32-byte boundaries.
   // void* cast to suppress cast-align warning, buffer must be
   // void* cast to suppress cast-align warning, buffer must be
   CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_lin, 4), fifo_info.len_lin + 31);
   CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_lin, 4), fifo_info.len_lin + 31);
-  if(fifo_info.len_wrap > 0)
+  if (fifo_info.len_wrap > 0)
+  {
      CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_wrap, 4), fifo_info.len_wrap + 31);
      CleanInvalidateDCache_by_Addr((uint32_t*) tu_align((uint32_t) fifo_info.ptr_wrap, 4), fifo_info.len_wrap + 31);
-
+  }
   //------------- Prepare qtd -------------//
   //------------- Prepare qtd -------------//
   qtd_init_fifo(p_qtd, &fifo_info, total_bytes);
   qtd_init_fifo(p_qtd, &fifo_info, total_bytes);
   p_qtd->int_on_complete = true;
   p_qtd->int_on_complete = true;
@@ -576,20 +600,19 @@ void dcd_int_handler(uint8_t rhport)
               ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS;
               ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS;
 
 
           uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 );
           uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 );
-            
+
           uint16_t xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes;
           uint16_t xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes;
 
 
           if (p_qhd->ff)
           if (p_qhd->ff)
           {
           {
-            if(tu_edpt_dir(ep_addr) == TUSB_DIR_IN)
+            if (tu_edpt_dir(ep_addr))
             {
             {
               tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes);
               tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes);
-            }
-            else
+            } else
             {
             {
               tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes);
               tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes);
             }
             }
-          }  
+          }
           dcd_event_xfer_complete(rhport, ep_addr, xferred_bytes, result, true); // only number of bytes in the IOC qtd
           dcd_event_xfer_complete(rhport, ep_addr, xferred_bytes, result, true); // only number of bytes in the IOC qtd
         }
         }
       }
       }