Ver código fonte

fomu: first fully-working release

This is able to transfer lots of data back and forth across MSC.

Signed-off-by: Sean Cross <sean@xobs.io>
Sean Cross 6 anos atrás
pai
commit
22fd7bf85e
1 arquivos alterados com 7 adições e 8 exclusões
  1. 7 8
      src/portable/foosn/fomu/dcd_fomu.c

+ 7 - 8
src/portable/foosn/fomu/dcd_fomu.c

@@ -63,6 +63,7 @@ static void finish_tx(void) {
       return;
   }
 
+  // If the system isn't idle, then something is very wrong.
   uint8_t in_status = usb_in_status_read();
   if (!(in_status & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET)))
     fomu_error(__LINE__);
@@ -92,8 +93,6 @@ static void process_rx(bool in_isr) {
       return;
 
     uint8_t rx_ep = (out_status >> CSR_USB_OUT_STATUS_EPNO_OFFSET) & 0xf;
-    if ((rx_ep != 0) && (rx_ep != 2) && (rx_ep != 3))
-      fomu_error(__LINE__);
 
     // If the destination buffer doesn't exist, don't drain the hardware
     // fifo.  Note that this can cause deadlocks if the host is waiting
@@ -117,9 +116,6 @@ static void process_rx(bool in_isr) {
     if (rx_buffer_offset[rx_ep] > rx_buffer_max[rx_ep])
       rx_buffer_offset[rx_ep] = rx_buffer_max[rx_ep];
 
-    if ((rx_ep == 3) && (rx_buffer[rx_ep][0] == 0x80) && (rx_buffer[rx_ep][1] == 0x25))
-      fomu_error(__LINE__);
-
     if (rx_buffer_max[rx_ep] == rx_buffer_offset[rx_ep]) {
       rx_buffer[rx_ep] = NULL;
       uint16_t len = rx_buffer_offset[rx_ep];
@@ -273,6 +269,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t
   (void)rhport;
   uint8_t ep_num = tu_edpt_number(ep_addr);
   uint8_t ep_dir = tu_edpt_dir(ep_addr);
+  TU_ASSERT(tx_ep < 16);
 
   // These sorts of transfers are handled in hardware automatically, so simply inform
   // the core that the transfer was processed.
@@ -296,7 +293,9 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t
 
     // Wait for the tx pipe to free up
     uint8_t previous_reset_count = reset_count;
-    while ((tx_buffer != NULL) || !(usb_in_status_read() & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET)))
+    while (!((tx_buffer == NULL)
+          && (usb_in_status_read() & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET))
+          && !(usb_in_status_read() & (1 << CSR_USB_IN_STATUS_HAVE_OFFSET))))
       ;
     // If a reset happens while we're waiting, abort the transfer
     if (previous_reset_count != reset_count)
@@ -315,7 +314,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t
   }
   else if (ep_dir == TUSB_DIR_OUT) {
     TU_ASSERT(rx_buffer[ep_num] == NULL);
-    TU_ASSERT((ep_num == 0) || (ep_num == 2) || (ep_num == 3));
 
     rx_buffer_offset[ep_num] = 0;
     rx_buffer_max[ep_num] = total_bytes;
@@ -324,7 +322,8 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t
     // If there's data in the buffer already, we'll try draining it
     // into the current fifo immediately.
     usb_out_ev_enable_write(0);
-    process_rx(false);
+    if (usb_out_status_read() & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET))
+      process_rx(false);
     usb_out_ev_enable_write(1);
   }
   return true;