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; |       return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // If the system isn't idle, then something is very wrong. | ||||||
|   uint8_t in_status = usb_in_status_read(); |   uint8_t in_status = usb_in_status_read(); | ||||||
|   if (!(in_status & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET))) |   if (!(in_status & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET))) | ||||||
|     fomu_error(__LINE__); |     fomu_error(__LINE__); | ||||||
| @@ -92,8 +93,6 @@ static void process_rx(bool in_isr) { | |||||||
|       return; |       return; | ||||||
|  |  | ||||||
|     uint8_t rx_ep = (out_status >> CSR_USB_OUT_STATUS_EPNO_OFFSET) & 0xf; |     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 |     // If the destination buffer doesn't exist, don't drain the hardware | ||||||
|     // fifo.  Note that this can cause deadlocks if the host is waiting |     // 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]) |     if (rx_buffer_offset[rx_ep] > rx_buffer_max[rx_ep]) | ||||||
|       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]) { |     if (rx_buffer_max[rx_ep] == rx_buffer_offset[rx_ep]) { | ||||||
|       rx_buffer[rx_ep] = NULL; |       rx_buffer[rx_ep] = NULL; | ||||||
|       uint16_t len = rx_buffer_offset[rx_ep]; |       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; |   (void)rhport; | ||||||
|   uint8_t ep_num = tu_edpt_number(ep_addr); |   uint8_t ep_num = tu_edpt_number(ep_addr); | ||||||
|   uint8_t ep_dir = tu_edpt_dir(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 |   // These sorts of transfers are handled in hardware automatically, so simply inform | ||||||
|   // the core that the transfer was processed. |   // 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 |     // Wait for the tx pipe to free up | ||||||
|     uint8_t previous_reset_count = reset_count; |     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 a reset happens while we're waiting, abort the transfer | ||||||
|     if (previous_reset_count != reset_count) |     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) { |   else if (ep_dir == TUSB_DIR_OUT) { | ||||||
|     TU_ASSERT(rx_buffer[ep_num] == NULL); |     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_offset[ep_num] = 0; | ||||||
|     rx_buffer_max[ep_num] = total_bytes; |     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 |     // If there's data in the buffer already, we'll try draining it | ||||||
|     // into the current fifo immediately. |     // into the current fifo immediately. | ||||||
|     usb_out_ev_enable_write(0); |     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); |     usb_out_ev_enable_write(1); | ||||||
|   } |   } | ||||||
|   return true; |   return true; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Sean Cross
					Sean Cross