Jelajahi Sumber

able to response to scsi inquiry, but failed to response to test unit ready

hathach 6 tahun lalu
induk
melakukan
050fa2fd39
5 mengubah file dengan 125 tambahan dan 55 penghapusan
  1. 9 0
      src/class/msc/msc_device.c
  2. 1 1
      src/common/tusb_common.h
  3. 3 2
      src/device/usbd.c
  4. 107 51
      src/portable/microchip/samg/dcd_samg.c
  5. 5 1
      src/tusb.c

+ 9 - 0
src/class/msc/msc_device.c

@@ -378,6 +378,9 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
       TU_ASSERT( event == XFER_RESULT_SUCCESS &&
       TU_ASSERT( event == XFER_RESULT_SUCCESS &&
                  xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE );
                  xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE );
 
 
+      TU_LOG2("  Command Block Wrapper\n");
+      TU_LOG2_MEM(p_cbw, xferred_bytes, 2);
+
       p_csw->signature    = MSC_CSW_SIGNATURE;
       p_csw->signature    = MSC_CSW_SIGNATURE;
       p_csw->tag          = p_cbw->tag;
       p_csw->tag          = p_cbw->tag;
       p_csw->data_residue = 0;
       p_csw->data_residue = 0;
@@ -448,6 +451,9 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
     break;
     break;
 
 
     case MSC_STAGE_DATA:
     case MSC_STAGE_DATA:
+      //TU_LOG2("  SCSI Data\n");
+      //TU_LOG2_MEM(_mscd_buf, xferred_bytes, 2);
+
       // OUT transfer, invoke callback if needed
       // OUT transfer, invoke callback if needed
       if ( !tu_bit_test(p_cbw->dir, 7) )
       if ( !tu_bit_test(p_cbw->dir, 7) )
       {
       {
@@ -538,6 +544,9 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
       // Wait for the command status wrapper complete event
       // Wait for the command status wrapper complete event
       if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) )
       if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) )
       {
       {
+        TU_LOG2("  Command Status Wrapper\n");
+        TU_LOG2_MEM(p_csw, xferred_bytes, 2);
+
         // Move to default CMD stage
         // Move to default CMD stage
         p_msc->stage = MSC_STAGE_CMD;
         p_msc->stage = MSC_STAGE_CMD;
 
 

+ 1 - 1
src/common/tusb_common.h

@@ -213,7 +213,7 @@ static inline bool     tu_bit_test (uint32_t value, uint8_t pos) { return (value
 // 2 : print out log
 // 2 : print out log
 #if CFG_TUSB_DEBUG
 #if CFG_TUSB_DEBUG
 
 
-void tu_print_mem(void const *buf, uint8_t size, uint16_t count);
+void tu_print_mem(void const *buf, uint16_t count, uint8_t indent);
 
 
 #ifndef tu_printf
 #ifndef tu_printf
   #define tu_printf         printf
   #define tu_printf         printf

+ 3 - 2
src/device/usbd.c

@@ -376,8 +376,7 @@ void tud_task (void)
       break;
       break;
 
 
       case DCD_EVENT_SETUP_RECEIVED:
       case DCD_EVENT_SETUP_RECEIVED:
-        TU_LOG2("  ");
-        TU_LOG2_MEM(&event.setup_received, 1, 8);
+        TU_LOG2_MEM(&event.setup_received, 8, 2);
 
 
         // Mark as connected after receiving 1st setup packet.
         // Mark as connected after receiving 1st setup packet.
         // But it is easier to set it every time instead of wasting time to check then set
         // But it is easier to set it every time instead of wasting time to check then set
@@ -949,6 +948,8 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
   TU_VERIFY( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) );
   TU_VERIFY( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) );
   _usbd_dev.ep_status[epnum][dir].busy = true;
   _usbd_dev.ep_status[epnum][dir].busy = true;
 
 
+  TU_LOG2("  XFER Endpoint: 0x%02X, Bytes: %d\r\n", ep_addr, total_bytes);
+
   return true;
   return true;
 }
 }
 
 

+ 107 - 51
src/portable/microchip/samg/dcd_samg.c

@@ -51,6 +51,11 @@ typedef struct
 // Endpoint 0-5, each can only be either OUT or In
 // Endpoint 0-5, each can only be either OUT or In
 xfer_desc_t _dcd_xfer[EP_COUNT];
 xfer_desc_t _dcd_xfer[EP_COUNT];
 
 
+void xfer_epsize_set(xfer_desc_t* xfer, uint16_t epsize)
+{
+  xfer->epsize = epsize;
+}
+
 void xfer_begin(xfer_desc_t* xfer, uint8_t * buffer, uint16_t total_bytes)
 void xfer_begin(xfer_desc_t* xfer, uint8_t * buffer, uint16_t total_bytes)
 {
 {
   xfer->buffer     = buffer;
   xfer->buffer     = buffer;
@@ -73,14 +78,23 @@ void xfer_packet_done(xfer_desc_t* xfer)
 }
 }
 
 
 //------------- Transaction helpers -------------//
 //------------- Transaction helpers -------------//
-static uint16_t xact_in(uint8_t epnum, xfer_desc_t* xfer)
-{
-  uint16_t const xact_len = xfer_packet_len(xfer);
 
 
-  // Write data to fifo
-  for(uint16_t i=0; i<xact_len; i++) UDP->UDP_FDR[epnum] = (uint32_t) xfer->buffer[i];
+// Write data to EP FIFO, return number of written bytes
+static void xact_ep_write(uint8_t epnum, uint8_t* buffer, uint16_t xact_len)
+{
+  for(uint16_t i=0; i<xact_len; i++)
+  {
+    UDP->UDP_FDR[epnum] = (uint32_t) buffer[i];
+  }
+}
 
 
-  return xact_len;
+// Read data from EP FIFO
+static void xact_ep_read(uint8_t epnum, uint8_t* buffer, uint16_t xact_len)
+{
+  for(uint16_t i=0; i<xact_len; i++)
+  {
+    buffer[i] = (uint8_t) UDP->UDP_FDR[epnum];
+  }
 }
 }
 
 
 /*------------------------------------------------------------------*/
 /*------------------------------------------------------------------*/
@@ -92,7 +106,7 @@ static void bus_reset(void)
 {
 {
   tu_memclr(_dcd_xfer, sizeof(_dcd_xfer));
   tu_memclr(_dcd_xfer, sizeof(_dcd_xfer));
 
 
-  _dcd_xfer[0].epsize = CFG_TUD_ENDPOINT0_SIZE;
+  xfer_epsize_set(&_dcd_xfer[0], CFG_TUD_ENDPOINT0_SIZE);
 
 
   // Enable EP0 control
   // Enable EP0 control
   UDP->UDP_CSR[0] = UDP_CSR_EPEDS_Msk;
   UDP->UDP_CSR[0] = UDP_CSR_EPEDS_Msk;
@@ -205,11 +219,13 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
   // Must not already enabled
   // Must not already enabled
   TU_ASSERT((UDP->UDP_CSR[epnum] & UDP_CSR_EPEDS_Msk) == 0);
   TU_ASSERT((UDP->UDP_CSR[epnum] & UDP_CSR_EPEDS_Msk) == 0);
 
 
+  xfer_epsize_set(&_dcd_xfer[epnum], ep_desc->wMaxPacketSize.size);
+
   // Configure type and eanble EP
   // Configure type and eanble EP
   UDP->UDP_CSR[epnum] = UDP_CSR_EPEDS_Msk | UDP_CSR_EPTYPE(ep_desc->bmAttributes.xfer + 4*dir);
   UDP->UDP_CSR[epnum] = UDP_CSR_EPEDS_Msk | UDP_CSR_EPTYPE(ep_desc->bmAttributes.xfer + 4*dir);
 
 
-  // Enable EP Interrupt
-  UDP->UDP_IER |= (1 << epnum);
+  // Enable EP Interrupt for IN
+  if (dir == TUSB_DIR_IN) UDP->UDP_IER |= (1 << epnum);
 
 
   return true;
   return true;
 }
 }
@@ -225,27 +241,47 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
   xfer_desc_t* xfer = &_dcd_xfer[epnum];
   xfer_desc_t* xfer = &_dcd_xfer[epnum];
   xfer_begin(xfer, buffer, total_bytes);
   xfer_begin(xfer, buffer, total_bytes);
 
 
-  // Configure DIR bit for control endpoint
-  if ( epnum == 0 )
-  {
-    if (dir == TUSB_DIR_OUT)
-    {
-      // Clear DIR bit
-      UDP->UDP_CSR[0] &= ~UDP_CSR_DIR_Msk;
-    }else
-    {
-      // Set DIR bit
-      UDP->UDP_CSR[0] |= UDP_CSR_DIR_Msk;
-    }
-  }
-
   if (dir == TUSB_DIR_IN)
   if (dir == TUSB_DIR_IN)
   {
   {
-    xact_in(epnum, xfer);
+    // Set DIR bit for EP0
+    if ( epnum == 0 ) UDP->UDP_CSR[epnum] |= UDP_CSR_DIR_Msk;
+
+    xact_ep_write(epnum, xfer->buffer, xfer_packet_len(xfer));
 
 
     // TX ready for transfer
     // TX ready for transfer
     UDP->UDP_CSR[epnum] |= UDP_CSR_TXPKTRDY_Msk;
     UDP->UDP_CSR[epnum] |= UDP_CSR_TXPKTRDY_Msk;
   }
   }
+  else
+  {
+    // Clear DIR bit for EP0
+    if ( epnum == 0 ) UDP->UDP_CSR[epnum] &= ~UDP_CSR_DIR_Msk;
+
+    // OUT Data may already received and acked by hardware
+    // Read it as 1st packet then continue with transfer if needed
+//    uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos);
+//
+//    if ( xact_len )
+//    {
+//      // Read from EP fifo
+//      xact_ep_read(epnum, xfer->buffer, xact_len);
+//      xfer_packet_done(xfer);
+//
+//      // Clear DATA Bank0 bit
+//      UDP->UDP_CSR[epnum] &= ~UDP_CSR_RX_DATA_BK0_Msk;
+//
+//      if ( 0 == xfer_packet_len(xfer) )
+//      {
+//        // Disable OUT EP interrupt when transfer is complete
+//        UDP->UDP_IER &= ~(1 << epnum);
+//
+//        dcd_event_xfer_complete(rhport, epnum, xact_len, XFER_RESULT_SUCCESS, false);
+//        return true; // complete
+//      }
+//    }
+
+    // Enable interrupt when starting OUT transfer
+    UDP->UDP_IER |= (1 << epnum);
+  }
 
 
   return true;
   return true;
 }
 }
@@ -325,47 +361,67 @@ void dcd_isr(uint8_t rhport)
 
 
       // Clear Setup bit
       // Clear Setup bit
       UDP->UDP_CSR[0] &= ~UDP_CSR_RXSETUP_Msk;
       UDP->UDP_CSR[0] &= ~UDP_CSR_RXSETUP_Msk;
+
+      return;
     }
     }
   }
   }
 
 
   for(uint8_t epnum = 0; epnum < EP_COUNT; epnum++)
   for(uint8_t epnum = 0; epnum < EP_COUNT; epnum++)
   {
   {
-    xfer_desc_t* xfer = &_dcd_xfer[epnum];
-
-    // Endpoint IN
-    if (UDP->UDP_CSR[epnum] & UDP_CSR_TXCOMP_Msk)
+    if ( intr_status & TU_BIT(epnum) )
     {
     {
-      xfer_packet_done(xfer);
+      xfer_desc_t* xfer = &_dcd_xfer[epnum];
 
 
-      if ( xact_in(epnum, xfer) )
+      // Endpoint IN
+      if (UDP->UDP_CSR[epnum] & UDP_CSR_TXCOMP_Msk)
       {
       {
-        // TX ready for transfer
-        UDP->UDP_CSR[epnum] |= UDP_CSR_TXPKTRDY_Msk;
-      }else
-      {
-        // xfer is complete
-        dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true);
+        xfer_packet_done(xfer);
+
+        uint16_t const xact_len = xfer_packet_len(xfer);
+
+        if (xact_len)
+        {
+          // write to EP fifo
+          xact_ep_write(epnum, xfer->buffer, xact_len);
+
+          // TX ready for transfer
+          UDP->UDP_CSR[epnum] |= UDP_CSR_TXPKTRDY_Msk;
+        }else
+        {
+          // xfer is complete
+          dcd_event_xfer_complete(rhport, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true);
+        }
+
+        // Clear TX Complete bit
+        UDP->UDP_CSR[epnum] &= ~UDP_CSR_TXCOMP_Msk;
       }
       }
 
 
-      // Clear TX Complete bit
-      UDP->UDP_CSR[epnum] &= ~UDP_CSR_TXCOMP_Msk;
-    }
+      // Endpoint OUT
+      if (UDP->UDP_CSR[epnum] & UDP_CSR_RX_DATA_BK0_Msk)
+      {
+        uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos);
 
 
-    // Endpoint OUT
-    if (UDP->UDP_CSR[epnum] & UDP_CSR_RX_DATA_BK0_Msk)
-    {
-      uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos);
+        // Read from EP fifo
+        xact_ep_read(epnum, xfer->buffer, xact_len);
+        xfer_packet_done(xfer);
 
 
-      dcd_event_xfer_complete(rhport, epnum, xact_len, XFER_RESULT_SUCCESS, true);
+        if ( 0 == xfer_packet_len(xfer) )
+        {
+          // Disable OUT EP interrupt when transfer is complete
+          UDP->UDP_IER &= ~(1 << epnum);
 
 
-      // Clear DATA Bank0 bit
-      UDP->UDP_CSR[epnum] &= ~UDP_CSR_RX_DATA_BK0_Msk;
-    }
+          dcd_event_xfer_complete(rhport, epnum, xact_len, XFER_RESULT_SUCCESS, true);
+        }
 
 
-    // Stall sent to host
-    if (UDP->UDP_CSR[epnum] & UDP_CSR_STALLSENT_Msk)
-    {
-      UDP->UDP_CSR[epnum] &= ~UDP_CSR_STALLSENT_Msk;
+        // Clear DATA Bank0 bit
+        UDP->UDP_CSR[epnum] &= ~UDP_CSR_RX_DATA_BK0_Msk;
+      }
+
+      // Stall sent to host
+      if (UDP->UDP_CSR[epnum] & UDP_CSR_STALLSENT_Msk)
+      {
+        UDP->UDP_CSR[epnum] &= ~UDP_CSR_STALLSENT_Msk;
+      }
     }
     }
   }
   }
 }
 }

+ 5 - 1
src/tusb.c

@@ -81,8 +81,10 @@ static void dump_str_line(uint8_t const* buf, uint16_t count)
 // size  : item size in bytes
 // size  : item size in bytes
 // count : number of item
 // count : number of item
 // print offet or not (handfy for dumping large memory)
 // print offet or not (handfy for dumping large memory)
-void tu_print_mem(void const *buf, uint8_t size, uint16_t count)
+void tu_print_mem(void const *buf, uint16_t count, uint8_t indent)
 {
 {
+  uint8_t const size = 1; // fixed 1 byte for now
+
   if ( !buf || !count )
   if ( !buf || !count )
   {
   {
     tu_printf("NULL\r\n");
     tu_printf("NULL\r\n");
@@ -110,6 +112,8 @@ void tu_print_mem(void const *buf, uint8_t size, uint16_t count)
         tu_printf("\r\n");
         tu_printf("\r\n");
       }
       }
 
 
+      for(uint8_t s=0; s < indent; s++) tu_printf(" ");
+
       // print offset or absolute address
       // print offset or absolute address
       tu_printf("%03lX: ", 16*i/item_per_line);
       tu_printf("%03lX: ", 16*i/item_per_line);
     }
     }