summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/device/usbd.c29
-rw-r--r--src/device/usbd_pvt.h3
-rw-r--r--src/portable/st/synopsys/dcd_synopsys.c39
3 files changed, 71 insertions, 0 deletions
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 791d533ae..55e76bb66 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -1188,6 +1188,35 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
}
}
+bool usbd_edpt_ISO_xfer(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ TU_LOG2(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
+
+ // Attempt to transfer on a busy endpoint, sound like an race condition !
+ TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
+
+ // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return
+ // and usbd task can preempt and clear the busy
+ _usbd_dev.ep_status[epnum][dir].busy = true;
+
+ if ( dcd_edpt_ISO_xfer(rhport, ep_addr, ff, total_bytes) )
+ {
+ TU_LOG2("OK\r\n");
+ return true;
+ }else
+ {
+ // DCD error, mark endpoint as ready to allow next transfer
+ _usbd_dev.ep_status[epnum][dir].busy = false;
+ _usbd_dev.ep_status[epnum][dir].claimed = 0;
+ TU_LOG2("failed\r\n");
+ TU_BREAKPOINT();
+ return false;
+ }
+}
+
bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index 212c3a202..de2f37281 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -72,6 +72,9 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr);
// Submit a usb transfer
bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
+// Submit a usb ISO transfer by use of a FIFO (ring buffer)
+bool usbd_edpt_ISO_xfer(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes);
+
// Claim an endpoint before submitting a transfer.
// If caller does not make any transfer, it must release endpoint for others.
bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr);
diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c
index 35c814460..0aee6a919 100644
--- a/src/portable/st/synopsys/dcd_synopsys.c
+++ b/src/portable/st/synopsys/dcd_synopsys.c
@@ -28,6 +28,7 @@
*/
#include "tusb_option.h"
+#include "tusb_fifo.h"
// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval)
// We disable SOF for now until needed later on
@@ -134,6 +135,7 @@ static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2];
typedef struct {
uint8_t * buffer;
+ tu_fifo_t * ff;
uint16_t total_len;
uint16_t max_size;
uint8_t interval;
@@ -659,6 +661,38 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return true;
}
+bool dcd_edpt_ISO_xfer (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
+ xfer->buffer = NULL; // Indicates a FIFO shall be used
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
+
+ // EP0 can only handle one packet
+ if(epnum == 0) {
+ ep0_pending[dir] = total_bytes;
+ // Schedule the first transaction for EP0 transfer
+ edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]);
+ return true;
+ }
+
+ uint16_t num_packets = (total_bytes / xfer->max_size);
+ uint8_t const short_packet_size = total_bytes % xfer->max_size;
+
+ // Zero-size packet is special case.
+ if(short_packet_size > 0 || (total_bytes == 0)) {
+ num_packets++;
+ }
+
+ // Schedule packets to be sent within interrupt
+ edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes);
+
+ return true;
+}
+
static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
{
(void) rhport;
@@ -849,6 +883,9 @@ static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_
{
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
+
+ // TODO: TAKE CARE OF ISO FIFO!
+
// Read packet off RxFIFO
read_fifo_packet(rhport, xfer->buffer, bcnt);
@@ -960,6 +997,8 @@ static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OT
break;
}
+ // TODO: TAKE CARE OF ISO FIFO!
+
// Push packet to Tx-FIFO
write_fifo_packet(rhport, n, xfer->buffer, packet_size);