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>
This commit is contained in:
		| @@ -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,6 +322,7 @@ 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); | ||||
|     if (usb_out_status_read() & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET)) | ||||
|       process_rx(false); | ||||
|     usb_out_ev_enable_write(1); | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sean Cross
					Sean Cross