summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReinhard Panhuber <[email protected]>2021-02-23 19:41:21 +0100
committerReinhard Panhuber <[email protected]>2021-02-23 19:41:21 +0100
commit313dd1439db037e676429d11646008f143e6bdb9 (patch)
tree459afde3a995fb04ae32a2871c87e972c7ce3bce /src
parentfff6283bf751ecf8e2ef33745e03d45eb13b354e (diff)
Implement dcd_edpt_iso_xfer() for dcd_da146xx.c BUT WITHOUT DMA SUPPORT
Diffstat (limited to 'src')
-rw-r--r--src/class/audio/audio_device.c1
-rw-r--r--src/portable/dialog/da146xx/dcd_da146xx.c102
-rw-r--r--src/portable/st/synopsys/dcd_synopsys.c2
3 files changed, 94 insertions, 11 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index c71ad6b8e..ef533e540 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -135,7 +135,6 @@ typedef struct
CFG_TUSB_MCU == OPT_MCU_RP2040 || /* Don't want to change driver */ \
CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI || /* Intermediate software buffer required */ \
CFG_TUSB_MCU == OPT_MCU_CXD56 || /* No clue how driver works */ \
- CFG_TUSB_MCU == OPT_MCU_DA1469X || /* Uses DMA - Ok for FIFO, had no time for implementation */ \
CFG_TUSB_MCU == OPT_MCU_NRF5X || /* Uses DMA - Ok for FIFO, had no time for implementation */ \
CFG_TUSB_MCU == OPT_MCU_LPC11UXX || /* Uses DMA - Ok for FIFO, had no time for implementation */ \
CFG_TUSB_MCU == OPT_MCU_LPC13XX || \
diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c
index 59f728d08..8e1a5ddfd 100644
--- a/src/portable/dialog/da146xx/dcd_da146xx.c
+++ b/src/portable/dialog/da146xx/dcd_da146xx.c
@@ -25,6 +25,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_DA1469X
@@ -196,6 +197,7 @@ typedef struct
typedef struct {
EPx_REGS * regs;
uint8_t * buffer;
+ tu_fifo_t * ff;
// Total length of current transfer
uint16_t total_len;
// Bytes transferred so far
@@ -292,7 +294,6 @@ static void fill_tx_fifo(xfer_ctl_t * xfer)
EPx_REGS *regs = xfer->regs;
uint8_t const epnum = tu_edpt_number(xfer->ep_addr);
- src = &xfer->buffer[xfer->transferred];
left_to_send = xfer->total_len - xfer->transferred;
if (left_to_send > xfer->max_packet_size - xfer->last_packet_size)
{
@@ -301,12 +302,51 @@ static void fill_tx_fifo(xfer_ctl_t * xfer)
// Loop checks TCOUNT all the time since this value is saturated to 31
// and can't be read just once before.
- while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && left_to_send > 0)
+
+ if (xfer->ff)
{
- regs->txd = *src++;
- xfer->last_packet_size++;
- left_to_send--;
+ // Since TCOUNT is to be considered, we handle the FIFO reading manually here
+ // As we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
+ // Check for first linear part
+ uint8_t * src;
+ uint16_t len = tu_fifo_get_linear_read_info(xfer->ff, 0, &src, left_to_send); // We want to read from the FIFO
+ uint16_t len1 = len;
+ while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && len1 > 0)
+ {
+ regs->txd = *src++;
+ xfer->last_packet_size++;
+ len1--;
+ }
+
+ tu_fifo_advance_read_pointer(ff, len-len1);
+ left_to_send -= (len-len1);
+
+ // Check for wrapped part
+ if ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) && left_to_send > 0)
+ {
+ len = tu_fifo_get_linear_read_info(xfer->ff, 0, &src, left_to_send); // We want to read from the FIFO
+ len1 = len;
+ while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && len1 > 0)
+ {
+ regs->txd = *src++;
+ xfer->last_packet_size++;
+ len1--;
+ }
+ tu_fifo_advance_read_pointer(ff, len-len1);
+ left_to_send -= (len-len1);
+ }
}
+ else
+ {
+ src = &xfer->buffer[xfer->transferred];
+ while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && left_to_send > 0)
+ {
+ regs->txd = *src++;
+ xfer->last_packet_size++;
+ left_to_send--;
+ }
+ }
+
if (epnum != 0)
{
if (left_to_send > 0)
@@ -363,13 +403,14 @@ static void start_rx_packet(xfer_ctl_t *xfer)
xfer->last_packet_size = 0;
if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE)
{
- if (try_allocate_dma(epnum, TUSB_DIR_OUT))
+ if (try_allocate_dma(epnum, TUSB_DIR_OUT) && !xfer->ff)
{
start_rx_dma(&xfer->regs->rxd, xfer->buffer + xfer->transferred, size);
}
else
{
// Other endpoint is using DMA in that direction, fall back to interrupts.
+ // Or if an ISO EP transfer was scheduled, currently not handled by DMA!
// For endpoint size greater then FIFO size enable FIFO level warning interrupt
// when FIFO has less then 17 bytes free.
xfer->regs->rxc |= USB_USB_RXC1_REG_USB_RFWL_Msk;
@@ -409,7 +450,7 @@ static void start_tx_packet(xfer_ctl_t *xfer)
regs->txc = USB_USB_TXC1_REG_USB_IGN_ISOMSK_Msk;
if (xfer->data1) xfer->regs->txc |= USB_USB_TXC1_REG_USB_TOGGLE_TX_Msk;
- if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE && try_allocate_dma(epnum, TUSB_DIR_IN))
+ if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE && try_allocate_dma(epnum, TUSB_DIR_IN) && !xfer->ff)
{
// Whole packet will be put in FIFO by DMA. Set LAST bit before start.
start_tx_dma(xfer->buffer + xfer->transferred, &regs->txd, size);
@@ -430,9 +471,16 @@ static void read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo)
if (remaining < bytes_in_fifo) receive_this_time = remaining;
- uint8_t *buf = xfer->buffer + xfer->transferred + xfer->last_packet_size;
+ if (xfer->ff)
+ {
+ tu_fifo_write_n(xfer->ff, (const void *) &regs->rxd, receive_this_time);
+ }
+ else
+ {
+ uint8_t *buf = xfer->buffer + xfer->transferred + xfer->last_packet_size;
- for (int i = 0; i < receive_this_time; ++i) buf[i] = regs->rxd;
+ for (int i = 0; i < receive_this_time; ++i) buf[i] = regs->rxd;
+ }
xfer->last_packet_size += receive_this_time;
}
@@ -918,6 +966,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
(void)rhport;
xfer->buffer = buffer;
+ xfer->ff = NULL;
xfer->total_len = total_bytes;
xfer->last_packet_size = 0;
xfer->transferred = 0;
@@ -934,6 +983,41 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t 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);
+
+ (void)rhport;
+
+ xfer->buffer = NULL;
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
+ xfer->last_packet_size = 0;
+ xfer->transferred = 0;
+
+ if (dir == TUSB_DIR_IN)
+ {
+ tu_fifo_set_copy_mode_write(ff, TU_FIFO_COPY_CST);
+ }
+ else
+ {
+ tu_fifo_set_copy_mode_read(ff, TU_FIFO_COPY_CST);
+ }
+
+ if (dir == TUSB_DIR_OUT)
+ {
+ start_rx_packet(xfer);
+ }
+ else // IN
+ {
+ start_tx_packet(xfer);
+ }
+
+ return true;
+}
+
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
uint8_t const epnum = tu_edpt_number(ep_addr);
diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c
index 5f8c44638..1d0bb5107 100644
--- a/src/portable/st/synopsys/dcd_synopsys.c
+++ b/src/portable/st/synopsys/dcd_synopsys.c
@@ -684,7 +684,7 @@ bool dcd_edpt_iso_xfer (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
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->buffer = NULL;
xfer->ff = ff;
xfer->total_len = total_bytes;