summaryrefslogtreecommitdiff
path: root/src/portable
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2021-04-16 01:59:47 +0700
committerGitHub <[email protected]>2021-04-16 01:59:47 +0700
commitc611199632b9288eff76c1c4bfdce5d8cc024748 (patch)
tree8ccd5c0b34b4f1eb89276fce866ee34a9ff608e1 /src/portable
parent93dffba0ac905d8525c3092a52888e1a5db96390 (diff)
parentc7e4a8616640165b48cfb0ba4f9346982faa4344 (diff)
Merge pull request #593 from hathach/edpt_ISO_xfer
Edpt iso xfer
Diffstat (limited to 'src/portable')
-rw-r--r--src/portable/espressif/esp32s2/dcd_esp32s2.c172
-rw-r--r--src/portable/microchip/samg/dcd_samg.c35
-rw-r--r--src/portable/nuvoton/nuc120/dcd_nuc120.c60
-rw-r--r--src/portable/nuvoton/nuc121/dcd_nuc121.c59
-rw-r--r--src/portable/nuvoton/nuc505/dcd_nuc505.c82
-rw-r--r--src/portable/raspberrypi/rp2040/dcd_rp2040.c3
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c160
-rw-r--r--src/portable/st/synopsys/dcd_synopsys.c73
-rw-r--r--src/portable/template/dcd_template.c11
-rw-r--r--src/portable/ti/msp430x5xx/dcd_msp430x5xx.c81
10 files changed, 635 insertions, 101 deletions
diff --git a/src/portable/espressif/esp32s2/dcd_esp32s2.c b/src/portable/espressif/esp32s2/dcd_esp32s2.c
index 703841759..edbc872fe 100644
--- a/src/portable/espressif/esp32s2/dcd_esp32s2.c
+++ b/src/portable/espressif/esp32s2/dcd_esp32s2.c
@@ -27,6 +27,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 && TUSB_OPT_DEVICE_ENABLED
@@ -59,6 +60,7 @@
typedef struct {
uint8_t *buffer;
+ // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API
uint16_t total_len;
uint16_t queued_len;
uint16_t max_size;
@@ -319,6 +321,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
xfer->buffer = buffer;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->total_len = total_bytes;
xfer->queued_len = 0;
xfer->short_packet = false;
@@ -354,6 +357,56 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void)rhport;
+
+ // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
+ TU_ASSERT(ff->item_size == 1);
+
+ 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;
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
+ xfer->queued_len = 0;
+ xfer->short_packet = false;
+
+ uint16_t num_packets = (total_bytes / xfer->max_size);
+ uint8_t short_packet_size = total_bytes % xfer->max_size;
+
+ // Zero-size packet is special case.
+ if (short_packet_size > 0 || (total_bytes == 0)) {
+ num_packets++;
+ }
+
+ ESP_LOGV(TAG, "Transfer <-> EP%i, %s, pkgs: %i, bytes: %i",
+ epnum, ((dir == TUSB_DIR_IN) ? "USB0.HOST (in)" : "HOST->DEV (out)"),
+ num_packets, total_bytes);
+
+ // IN and OUT endpoint xfers are interrupt-driven, we just schedule them
+ // here.
+ if (dir == TUSB_DIR_IN) {
+ // A full IN transfer (multiple packets, possibly) triggers XFRC.
+ USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) | total_bytes;
+ USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M; // Enable | CNAK
+
+ // Enable fifo empty interrupt only if there are something to put in the fifo.
+ if(total_bytes != 0) {
+ USB0.dtknqr4_fifoemptymsk |= (1 << epnum);
+ }
+ } else {
+ // Each complete packet for OUT xfers triggers XFRC.
+ USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S);
+ USB0.out_ep_reg[epnum].doepctl |= USB_EPENA0_M | USB_CNAK0_M;
+ }
+ return true;
+}
+#endif
+
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
(void)rhport;
@@ -462,35 +515,46 @@ static void receive_packet(xfer_ctl_t *xfer, /* usb_out_endpoint_t * out_ep, */
to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size;
}
- uint8_t to_recv_rem = to_recv_size % 4;
- uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem;
+ // Common buffer read
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ // Ring buffer
+ tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) rx_fifo, to_recv_size);
+ }
+ else
+#endif
+ {
+ uint8_t to_recv_rem = to_recv_size % 4;
+ uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem;
- // Do not assume xfer buffer is aligned.
- uint8_t *base = (xfer->buffer + xfer->queued_len);
+ // Do not assume xfer buffer is aligned.
+ uint8_t *base = (xfer->buffer + xfer->queued_len);
- // This for loop always runs at least once- skip if less than 4 bytes
- // to collect.
- if (to_recv_size >= 4) {
- for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) {
- uint32_t tmp = (*rx_fifo);
- base[i] = tmp & 0x000000FF;
- base[i + 1] = (tmp & 0x0000FF00) >> 8;
- base[i + 2] = (tmp & 0x00FF0000) >> 16;
- base[i + 3] = (tmp & 0xFF000000) >> 24;
+ // This for loop always runs at least once- skip if less than 4 bytes
+ // to collect.
+ if (to_recv_size >= 4) {
+ for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) {
+ uint32_t tmp = (*rx_fifo);
+ base[i] = tmp & 0x000000FF;
+ base[i + 1] = (tmp & 0x0000FF00) >> 8;
+ base[i + 2] = (tmp & 0x00FF0000) >> 16;
+ base[i + 3] = (tmp & 0xFF000000) >> 24;
+ }
}
- }
- // Do not read invalid bytes from RX FIFO.
- if (to_recv_rem != 0) {
- uint32_t tmp = (*rx_fifo);
- uint8_t *last_32b_bound = base + to_recv_size_aligned;
+ // Do not read invalid bytes from RX FIFO.
+ if (to_recv_rem != 0) {
+ uint32_t tmp = (*rx_fifo);
+ uint8_t *last_32b_bound = base + to_recv_size_aligned;
- last_32b_bound[0] = tmp & 0x000000FF;
- if (to_recv_rem > 1) {
- last_32b_bound[1] = (tmp & 0x0000FF00) >> 8;
- }
- if (to_recv_rem > 2) {
- last_32b_bound[2] = (tmp & 0x00FF0000) >> 16;
+ last_32b_bound[0] = tmp & 0x000000FF;
+ if (to_recv_rem > 1) {
+ last_32b_bound[1] = (tmp & 0x0000FF00) >> 8;
+ }
+ if (to_recv_rem > 2) {
+ last_32b_bound[2] = (tmp & 0x00FF0000) >> 16;
+ }
}
}
@@ -510,37 +574,47 @@ static void transmit_packet(xfer_ctl_t *xfer, volatile usb_in_endpoint_t *in_ep,
xfer->queued_len = xfer->total_len - remaining;
uint16_t to_xfer_size = (remaining > xfer->max_size) ? xfer->max_size : remaining;
- uint8_t to_xfer_rem = to_xfer_size % 4;
- uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem;
- // Buffer might not be aligned to 32b, so we need to force alignment
- // by copying to a temp var.
- uint8_t *base = (xfer->buffer + xfer->queued_len);
-
- // This for loop always runs at least once- skip if less than 4 bytes
- // to send off.
- if (to_xfer_size >= 4) {
- for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) {
- uint32_t tmp = base[i] | (base[i + 1] << 8) |
- (base[i + 2] << 16) | (base[i + 3] << 24);
- (*tx_fifo) = tmp;
- }
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) tx_fifo, to_xfer_size);
}
+ else
+#endif
+ {
+ uint8_t to_xfer_rem = to_xfer_size % 4;
+ uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem;
- // Do not read beyond end of buffer if not divisible by 4.
- if (to_xfer_rem != 0) {
- uint32_t tmp = 0;
- uint8_t *last_32b_bound = base + to_xfer_size_aligned;
+ // Buffer might not be aligned to 32b, so we need to force alignment
+ // by copying to a temp var.
+ uint8_t *base = (xfer->buffer + xfer->queued_len);
- tmp |= last_32b_bound[0];
- if (to_xfer_rem > 1) {
- tmp |= (last_32b_bound[1] << 8);
- }
- if (to_xfer_rem > 2) {
- tmp |= (last_32b_bound[2] << 16);
+ // This for loop always runs at least once- skip if less than 4 bytes
+ // to send off.
+ if (to_xfer_size >= 4) {
+ for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) {
+ uint32_t tmp = base[i] | (base[i + 1] << 8) |
+ (base[i + 2] << 16) | (base[i + 3] << 24);
+ (*tx_fifo) = tmp;
+ }
}
- (*tx_fifo) = tmp;
+ // Do not read beyond end of buffer if not divisible by 4.
+ if (to_xfer_rem != 0) {
+ uint32_t tmp = 0;
+ uint8_t *last_32b_bound = base + to_xfer_size_aligned;
+
+ tmp |= last_32b_bound[0];
+ if (to_xfer_rem > 1) {
+ tmp |= (last_32b_bound[1] << 8);
+ }
+ if (to_xfer_rem > 2) {
+ tmp |= (last_32b_bound[2] << 16);
+ }
+
+ (*tx_fifo) = tmp;
+ }
}
}
diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c
index 2f9f1097f..62fab8d17 100644
--- a/src/portable/microchip/samg/dcd_samg.c
+++ b/src/portable/microchip/samg/dcd_samg.c
@@ -25,6 +25,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if CFG_TUSB_MCU == OPT_MCU_SAMG
@@ -43,6 +44,7 @@
typedef struct
{
uint8_t* buffer;
+ // tu_fifo_t* ff; // TODO support dcd_edpt_xfer_fifo API
uint16_t total_len;
volatile uint16_t actual_len;
uint16_t epsize;
@@ -59,6 +61,7 @@ void xfer_epsize_set(xfer_desc_t* xfer, uint16_t epsize)
void xfer_begin(xfer_desc_t* xfer, uint8_t * buffer, uint16_t total_bytes)
{
xfer->buffer = buffer;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->total_len = total_bytes;
xfer->actual_len = 0;
}
@@ -66,6 +69,7 @@ void xfer_begin(xfer_desc_t* xfer, uint8_t * buffer, uint16_t total_bytes)
void xfer_end(xfer_desc_t* xfer)
{
xfer->buffer = NULL;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->total_len = 0;
xfer->actual_len = 0;
}
@@ -293,6 +297,14 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+ return true;
+}
+#endif
+
// Stall endpoint
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
{
@@ -402,7 +414,16 @@ void dcd_int_handler(uint8_t rhport)
if (xact_len)
{
// write to EP fifo
- xact_ep_write(epnum, xfer->buffer, xact_len);
+#if 0 // TODO support dcd_edpt_xfer_fifo
+ if (xfer->ff)
+ {
+ tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) &UDP->UDP_FDR[epnum], xact_len);
+ }
+ else
+#endif
+ {
+ xact_ep_write(epnum, xfer->buffer, xact_len);
+ }
// TX ready for transfer
csr_set(epnum, UDP_CSR_TXPKTRDY_Msk);
@@ -428,7 +449,17 @@ void dcd_int_handler(uint8_t rhport)
uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos);
// Read from EP fifo
- xact_ep_read(epnum, xfer->buffer, xact_len);
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) &UDP->UDP_FDR[epnum], xact_len);
+ }
+ else
+#endif
+ {
+ xact_ep_read(epnum, xfer->buffer, xact_len);
+ }
+
xfer_packet_done(xfer);
if ( 0 == xfer_packet_len(xfer) )
diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c
index dc48e54cc..5dc3bca21 100644
--- a/src/portable/nuvoton/nuc120/dcd_nuc120.c
+++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c
@@ -34,6 +34,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC120)
@@ -76,6 +77,7 @@ static bool active_ep0_xfer;
static struct xfer_ctl_t
{
uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */
+ // tu_fifo_t * ff; /* pointer to FIFO required for dcd_edpt_xfer_fifo() */ // TODO support dcd_edpt_xfer_fifo API
union {
uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */
uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */
@@ -142,7 +144,17 @@ static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep)
{
uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size);
- memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now);
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_read_n(xfer->ff, (void *) (USBD_BUF_BASE + ep->BUFSEG), bytes_now);
+ }
+ else
+#endif
+ {
+ memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now);
+ }
+
ep->MXPLD = bytes_now;
}
@@ -267,6 +279,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
/* store away the information we'll needing now and later */
xfer->data_ptr = buffer;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->in_remaining_bytes = total_bytes;
xfer->total_bytes = total_bytes;
@@ -286,6 +299,36 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+
+ /* mine the data for the information we need */
+ tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ USBD_EP_T *ep = ep_entry(ep_addr, false);
+ struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP];
+
+ /* store away the information we'll needing now and later */
+ xfer->data_ptr = NULL; // Indicates a FIFO shall be used
+ xfer->ff = ff;
+ xfer->in_remaining_bytes = total_bytes;
+ xfer->total_bytes = total_bytes;
+
+ if (TUSB_DIR_IN == dir)
+ {
+ dcd_in_xfer(xfer, ep);
+ }
+ else
+ {
+ xfer->out_bytes_so_far = 0;
+ ep->MXPLD = xfer->max_packet_size;
+ }
+
+ return true;
+}
+#endif
+
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
@@ -389,9 +432,19 @@ void dcd_int_handler(uint8_t rhport)
if (out_ep)
{
/* copy the data from the PC to the previously provided buffer */
- memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes);
+#if 0 // // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_write_n(xfer->ff, (const void *) (USBD_BUF_BASE + ep->BUFSEG), available_bytes);
+ }
+ else
+#endif
+ {
+ memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes);
+ xfer->data_ptr += available_bytes;
+ }
+
xfer->out_bytes_so_far += available_bytes;
- xfer->data_ptr += available_bytes;
/* when the transfer is finished, alert TinyUSB; otherwise, accept more data */
if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) )
@@ -403,6 +456,7 @@ void dcd_int_handler(uint8_t rhport)
{
/* update the bookkeeping to reflect the data that has now been sent to the PC */
xfer->in_remaining_bytes -= available_bytes;
+
xfer->data_ptr += available_bytes;
/* if more data to send, send it; otherwise, alert TinyUSB that we've finished */
diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c
index c9ead6de0..d50e82846 100644
--- a/src/portable/nuvoton/nuc121/dcd_nuc121.c
+++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c
@@ -34,6 +34,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if TUSB_OPT_DEVICE_ENABLED && ( (CFG_TUSB_MCU == OPT_MCU_NUC121) || (CFG_TUSB_MCU == OPT_MCU_NUC126) )
@@ -78,6 +79,7 @@ static bool active_ep0_xfer;
static struct xfer_ctl_t
{
uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */
+ // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API
union {
uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */
uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */
@@ -144,7 +146,17 @@ static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep)
{
uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size);
- memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now);
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_read_n(xfer->ff, (void *) (USBD_BUF_BASE + ep->BUFSEG), bytes_now);
+ }
+ else
+#endif
+ {
+ memcpy((uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), xfer->data_ptr, bytes_now);
+ }
+
ep->MXPLD = bytes_now;
}
@@ -273,6 +285,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
/* store away the information we'll needing now and later */
xfer->data_ptr = buffer;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->in_remaining_bytes = total_bytes;
xfer->total_bytes = total_bytes;
@@ -292,6 +305,36 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+
+ /* mine the data for the information we need */
+ tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ USBD_EP_T *ep = ep_entry(ep_addr, false);
+ struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP];
+
+ /* store away the information we'll needing now and later */
+ xfer->data_ptr = NULL; // Indicates a FIFO shall be used
+ xfer->ff = ff;
+ xfer->in_remaining_bytes = total_bytes;
+ xfer->total_bytes = total_bytes;
+
+ if (TUSB_DIR_IN == dir)
+ {
+ dcd_in_xfer(xfer, ep);
+ }
+ else
+ {
+ xfer->out_bytes_so_far = 0;
+ ep->MXPLD = xfer->max_packet_size;
+ }
+
+ return true;
+}
+#endif
+
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
@@ -400,9 +443,19 @@ void dcd_int_handler(uint8_t rhport)
if (out_ep)
{
/* copy the data from the PC to the previously provided buffer */
- memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes);
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_write_n(xfer->ff, (const void *) (USBD_BUF_BASE + ep->BUFSEG), available_bytes);
+ }
+ else
+#endif
+ {
+ memcpy(xfer->data_ptr, (uint8_t *)(USBD_BUF_BASE + ep->BUFSEG), available_bytes);
+ xfer->data_ptr += available_bytes;
+ }
+
xfer->out_bytes_so_far += available_bytes;
- xfer->data_ptr += available_bytes;
/* when the transfer is finished, alert TinyUSB; otherwise, accept more data */
if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) )
diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c
index a7961a687..b7bbb020b 100644
--- a/src/portable/nuvoton/nuc505/dcd_nuc505.c
+++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c
@@ -34,6 +34,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC505)
@@ -94,6 +95,7 @@ static uint32_t bufseg_addr;
static struct xfer_ctl_t
{
uint8_t *data_ptr; /* data_ptr tracks where to next copy data to (for OUT) or from (for IN) */
+ // tu_fifo_t* ff; // TODO support dcd_edpt_xfer_fifo API
union {
uint16_t in_remaining_bytes; /* for IN endpoints, we track how many bytes are left to transfer */
uint16_t out_bytes_so_far; /* but for OUT endpoints, we track how many bytes we've transferred so far */
@@ -163,8 +165,7 @@ static USBD_EP_T *ep_entry(uint8_t ep_addr, bool add)
/* perform a non-control IN endpoint transfer; this is called by the ISR */
static void dcd_userEP_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep)
{
- uint16_t bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size);
- uint16_t countdown = bytes_now;
+ uint16_t const bytes_now = tu_min16(xfer->in_remaining_bytes, xfer->max_packet_size);
/* precompute what amount of data will be left */
xfer->in_remaining_bytes -= bytes_now;
@@ -180,20 +181,29 @@ static void dcd_userEP_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep)
}
/* provided buffers are thankfully 32-bit aligned, allowing most data to be transfered as 32-bit */
- while (countdown > 3)
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
{
- uint32_t u32;
- memcpy(&u32, xfer->data_ptr, 4);
+ tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) (&ep->EPDAT_BYTE), bytes_now);
+ }
+ else
+#endif
+ {
+ uint16_t countdown = bytes_now;
+ while (countdown > 3)
+ {
+ uint32_t u32;
+ memcpy(&u32, xfer->data_ptr, 4);
+
+ ep->EPDAT = u32;
+ xfer->data_ptr += 4; countdown -= 4;
+ }
- ep->EPDAT = u32;
- xfer->data_ptr += 4; countdown -= 4;
+ while (countdown--) ep->EPDAT_BYTE = *xfer->data_ptr++;
}
- while (countdown--)
- ep->EPDAT_BYTE = *xfer->data_ptr++;
/* for short packets, we must nudge the peripheral to say 'that's all folks' */
- if (bytes_now != xfer->max_packet_size)
- ep->EPRSPCTL = USBD_EPRSPCTL_SHORTTXEN_Msk;
+ if (bytes_now != xfer->max_packet_size) ep->EPRSPCTL = USBD_EPRSPCTL_SHORTTXEN_Msk;
}
/* called by dcd_init() as well as by the ISR during a USB bus reset */
@@ -385,6 +395,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
/* store away the information we'll needing now and later */
xfer->data_ptr = buffer;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->in_remaining_bytes = total_bytes;
xfer->total_bytes = total_bytes;
@@ -402,6 +413,38 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+
+ TU_ASSERT(0x80 != ep_addr && 0x00 != ep_addr); // Must not be used for control stuff
+
+ /* mine the data for the information we need */
+ tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ USBD_EP_T *ep = ep_entry(ep_addr, false);
+ struct xfer_ctl_t *xfer = &xfer_table[ep - USBD->EP];
+
+ /* store away the information we'll needing now and later */
+ xfer->data_ptr = NULL; // Indicates a FIFO shall be used
+ xfer->ff = ff;
+ xfer->in_remaining_bytes = total_bytes;
+ xfer->total_bytes = total_bytes;
+
+ if (TUSB_DIR_IN == dir)
+ {
+ ep->EPINTEN = USBD_EPINTEN_BUFEMPTYIEN_Msk;
+ }
+ else
+ {
+ xfer->out_bytes_so_far = 0;
+ ep->EPINTEN = USBD_EPINTEN_RXPKIEN_Msk;
+ }
+
+ return true;
+}
+#endif
+
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
@@ -615,12 +658,25 @@ void dcd_int_handler(uint8_t rhport)
#else
uint16_t const available_bytes = ep->EPDATCNT & USBD_EPDATCNT_DATCNT_Msk;
/* copy the data from the PC to the previously provided buffer */
- for (int count = 0; (count < available_bytes) && (xfer->out_bytes_so_far < xfer->total_bytes); count++, xfer->out_bytes_so_far++)
- *xfer->data_ptr++ = ep->EPDAT_BYTE;
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) &ep->EPDAT_BYTE, tu_min16(available_bytes, xfer->total_bytes - xfer->out_bytes_so_far));
+ }
+ else
+#endif
+ {
+ for (int count = 0; (count < available_bytes) && (xfer->out_bytes_so_far < xfer->total_bytes); count++, xfer->out_bytes_so_far++)
+ {
+ *xfer->data_ptr++ = ep->EPDAT_BYTE;
+ }
+ }
/* when the transfer is finished, alert TinyUSB; otherwise, continue accepting more data */
if ( (xfer->total_bytes == xfer->out_bytes_so_far) || (available_bytes < xfer->max_packet_size) )
+ {
dcd_event_xfer_complete(0, ep_addr, xfer->out_bytes_so_far, XFER_RESULT_SUCCESS, true);
+ }
#endif
}
diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
index f844a0c65..7731078b5 100644
--- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
@@ -35,7 +35,8 @@
#include "pico/fix/rp2040_usb_device_enumeration.h"
#endif
-
+#include "osal/osal.h"
+#include "common/tusb_fifo.h"
#include "device/dcd.h"
/*------------------------------------------------------------------*/
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index 18f0bc8e1..b8b0fc104 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -102,6 +102,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if defined(STM32F102x6) || defined(STM32F102xB) || \
defined(STM32F103x6) || defined(STM32F103xB) || \
@@ -165,6 +166,7 @@ TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligne
typedef struct
{
uint8_t * buffer;
+ // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API
uint16_t total_len;
uint16_t queued_len;
uint16_t pma_ptr;
@@ -197,6 +199,9 @@ static void dcd_pma_free(uint8_t ep_addr);
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes);
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes);
+//static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes);
+//static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes);
+
// Using a function due to better type checks
// This seems better than having to do type casts everywhere else
static inline void reg16_clear_bits(__IO uint16_t *reg, uint16_t mask) {
@@ -476,8 +481,17 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
if (count != 0U)
{
- dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]),
- *pcd_ep_rx_address_ptr(USB,EPindex), count);
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ dcd_read_packet_memory_ff(xfer->ff, *pcd_ep_rx_address_ptr(USB,EPindex), count);
+ }
+ else
+#endif
+ {
+ dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), *pcd_ep_rx_address_ptr(USB,EPindex), count);
+ }
+
xfer->queued_len = (uint16_t)(xfer->queued_len + count);
}
@@ -804,7 +818,17 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix)
len = xfer->max_packet_size;
}
uint16_t oldAddr = *pcd_ep_tx_address_ptr(USB,ep_ix);
- dcd_write_packet_memory(oldAddr, &(xfer->buffer[xfer->queued_len]), len);
+
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ dcd_write_packet_memory_ff(xfer->ff, oldAddr, len);
+ }
+ else
+#endif
+ {
+ dcd_write_packet_memory(oldAddr, &(xfer->buffer[xfer->queued_len]), len);
+ }
xfer->queued_len = (uint16_t)(xfer->queued_len + len);
pcd_set_ep_tx_cnt(USB,ep_ix,len);
@@ -821,6 +845,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir);
xfer->buffer = buffer;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->total_len = total_bytes;
xfer->queued_len = 0;
@@ -847,6 +872,39 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir);
+
+ xfer->buffer = NULL;
+ // xfer->ff = ff; // TODO support dcd_edpt_xfer_fifo API
+ xfer->total_len = total_bytes;
+ xfer->queued_len = 0;
+
+ if ( dir == TUSB_DIR_OUT )
+ {
+ if(total_bytes > xfer->max_packet_size)
+ {
+ pcd_set_ep_rx_cnt(USB,epnum,xfer->max_packet_size);
+ } else {
+ pcd_set_ep_rx_cnt(USB,epnum,total_bytes);
+ }
+ pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID);
+ }
+ else // IN
+ {
+ dcd_transmit_packet(xfer,epnum);
+ }
+ return true;
+}
+#endif
+
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
{
(void)rhport;
@@ -920,8 +978,55 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, si
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
/**
- * @brief Copy a buffer from user memory area to packet memory area (PMA).
+ * @brief Copy from FIFO to packet memory area (PMA).
+ * Uses byte-access of system memory and 16-bit access of packet memory
+ * @param wNBytes no. of bytes to be copied.
+ * @retval None
+ */
+
+// THIS FUNCTION IS UNTESTED
+
+static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes)
+{
+ // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
+ // Check for first linear part
+ void * src;
+ uint16_t len = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes); // We want to read from the FIFO
+ TU_VERIFY(len && dcd_write_packet_memory(dst, src, len)); // and write it into the PMA
+ tu_fifo_advance_read_pointer(ff, len);
+
+ // Check for wrapped part
+ if (len < wNBytes)
+ {
+ // Get remaining wrapped length
+ uint16_t len2 = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes - len);
+ TU_VERIFY(len2);
+
+ // Update destination pointer
+ dst += len;
+
+ // Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split
+ if (len % 2) // If len is uneven there is a byte left to copy
+ {
+ // Since PMA can accessed only 16 bit-wise we copy the last byte again
+ tu_fifo_backward_read_pointer(ff, 1); // Move one byte back and copy two bytes for the PMA
+ tu_fifo_read_n(ff, (void *) &pma[PMA_STRIDE*(dst>>1)], 2); // Since EP FIFOs must be of item size 1 this is safe to do
+ dst++;
+ len2--;
+ }
+
+ TU_VERIFY(dcd_write_packet_memory(dst, src, len2));
+ tu_fifo_advance_write_pointer(ff, len2);
+ }
+
+ return true;
+}
+#endif
+
+/**
+ * @brief Copy a buffer from packet memory area (PMA) to user memory area.
* Uses byte-access of system memory and 16-bit access of packet memory
* @param wNBytes no. of bytes to be copied.
* @retval None
@@ -955,5 +1060,52 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+/**
+ * @brief Copy a buffer from user packet memory area (PMA) to FIFO.
+ * Uses byte-access of system memory and 16-bit access of packet memory
+ * @param wNBytes no. of bytes to be copied.
+ * @retval None
+ */
+
+// THIS FUNCTION IS UNTESTED
+
+static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes)
+{
+ // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
+ // Check for first linear part
+ void * dst;
+ uint16_t len = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes);
+ TU_VERIFY(len && dcd_read_packet_memory(dst, src, len));
+ tu_fifo_advance_write_pointer(ff, len);
+
+ // Check for wrapped part
+ if (len < wNBytes)
+ {
+ // Get remaining wrapped length
+ uint16_t len2 = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes - len);
+ TU_VERIFY(len2);
+
+ // Update source pointer
+ src += len;
+
+ // Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split
+ if (len % 2) // If len is uneven there is a byte left to copy
+ {
+ uint32_t temp = pma[PMA_STRIDE*(src>>1)];
+ *((uint8_t *)dst++) = ((temp >> 8) & 0xFF);
+ src++;
+ len2--;
+ }
+
+ TU_VERIFY(dcd_read_packet_memory(dst, src, len2));
+ tu_fifo_advance_write_pointer(ff, len2);
+ }
+
+ return true;
+}
+
+#endif
+
#endif
diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c
index 548438b68..0fe7c2a3c 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 "common/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
@@ -135,6 +136,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;
@@ -644,6 +646,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
xfer->buffer = buffer;
+ xfer->ff = NULL;
xfer->total_len = total_bytes;
// EP0 can only handle one packet
@@ -668,6 +671,35 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return true;
}
+// The number of bytes has to be given explicitly to allow more flexible control of how many
+// bytes should be written and second to keep the return value free to give back a boolean
+// success message. If total_bytes is too big, the FIFO will copy only what is available
+// into the USB buffer!
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
+ TU_ASSERT(ff->item_size == 1);
+
+ 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;
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
+
+ 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;
@@ -867,10 +899,19 @@ static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
// Read packet off RxFIFO
- read_fifo_packet(rhport, xfer->buffer, bcnt);
+ if (xfer->ff)
+ {
+ // Ring buffer
+ tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) rx_fifo, bcnt);
+ }
+ else
+ {
+ // Linear buffer
+ read_fifo_packet(rhport, xfer->buffer, bcnt);
- // Increment pointer to xfer data
- xfer->buffer += bcnt;
+ // Increment pointer to xfer data
+ xfer->buffer += bcnt;
+ }
// Truncate transfer length in case of short packet
if(bcnt < xfer->max_size) {
@@ -966,22 +1007,30 @@ static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OT
uint16_t remaining_packets = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_PKTCNT_Msk) >> USB_OTG_DIEPTSIZ_PKTCNT_Pos;
// Process every single packet (only whole packets can be written to fifo)
- for(uint16_t i = 0; i < remaining_packets; i++){
- uint16_t remaining_bytes = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos;
+ for(uint16_t i = 0; i < remaining_packets; i++)
+ {
+ uint16_t const remaining_bytes = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos;
+
// Packet can not be larger than ep max size
- uint16_t packet_size = tu_min16(remaining_bytes, xfer->max_size);
+ uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size);
// It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current
// EP has to be checked if the buffer can take another WHOLE packet
- if(packet_size > ((in_ep[n].DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV_Msk) << 2)){
- break;
- }
+ if(packet_size > ((in_ep[n].DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV_Msk) << 2)) break;
// Push packet to Tx-FIFO
- write_fifo_packet(rhport, n, xfer->buffer, packet_size);
+ if (xfer->ff)
+ {
+ usb_fifo_t tx_fifo = FIFO_BASE(rhport, n);
+ tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) tx_fifo, packet_size);
+ }
+ else
+ {
+ write_fifo_packet(rhport, n, xfer->buffer, packet_size);
- // Increment pointer to xfer data
- xfer->buffer += packet_size;
+ // Increment pointer to xfer data
+ xfer->buffer += packet_size;
+ }
}
// Turn off TXFE if all bytes are written.
diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c
index 618812416..d8c8753d3 100644
--- a/src/portable/template/dcd_template.c
+++ b/src/portable/template/dcd_template.c
@@ -25,6 +25,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if CFG_TUSB_MCU == OPT_MCU_NONE
@@ -104,6 +105,16 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return false;
}
+// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+ (void) ep_addr;
+ (void) ff;
+ (void) total_bytes;
+ return false;
+}
+
// Stall endpoint
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
{
diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c
index e08c3536a..48e9dd592 100644
--- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c
+++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c
@@ -26,6 +26,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MSP430x5xx )
@@ -48,6 +49,7 @@ uint8_t _setup_packet[8];
typedef struct
{
uint8_t * buffer;
+ // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API
uint16_t total_len;
uint16_t queued_len;
uint16_t max_size;
@@ -306,6 +308,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
xfer->buffer = buffer;
+ // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
xfer->total_len = total_bytes;
xfer->queued_len = 0;
xfer->short_packet = false;
@@ -344,6 +347,36 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return true;
}
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+
+ 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;
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
+ xfer->queued_len = 0;
+ xfer->short_packet = false;
+
+ ep_regs_t ep_regs = EP_REGS(epnum, dir);
+
+ if(dir == TUSB_DIR_OUT)
+ {
+ ep_regs[BCTX] &= ~NAK;
+ }
+ else
+ {
+ USBIEPIFG |= (1 << epnum);
+ }
+
+ return true;
+}
+#endif
+
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
@@ -443,22 +476,32 @@ static void receive_packet(uint8_t ep_num)
to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size;
}
- uint8_t * base = (xfer->buffer + xfer->queued_len);
-
- if(ep_num == 0)
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
{
- volatile uint8_t * ep0out_buf = &USBOEP0BUF;
- for(uint16_t i = 0; i < to_recv_size; i++)
- {
- base[i] = ep0out_buf[i];
- }
+ volatile uint8_t * ep_buf = (ep_num == 0) ? &USBOEP0BUF : (&USBSTABUFF + (ep_regs[BBAX] << 3));
+ tu_fifo_write_n(xfer->ff, (const void *) ep_buf, to_recv_size);
}
else
+#endif
{
- volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3);
- for(uint16_t i = 0; i < to_recv_size ; i++)
+ uint8_t * base = (xfer->buffer + xfer->queued_len);
+
+ if(ep_num == 0)
+ {
+ volatile uint8_t * ep0out_buf = &USBOEP0BUF;
+ for(uint16_t i = 0; i < to_recv_size; i++)
+ {
+ base[i] = ep0out_buf[i];
+ }
+ }
+ else
{
- base[i] = ep_buf[i];
+ volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3);
+ for(uint16_t i = 0; i < to_recv_size ; i++)
+ {
+ base[i] = ep_buf[i];
+ }
}
}
@@ -499,7 +542,6 @@ static void transmit_packet(uint8_t ep_num)
}
// Then actually commit to transmit a packet.
- uint8_t * base = (xfer->buffer + xfer->queued_len);
uint16_t remaining = xfer->total_len - xfer->queued_len;
uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining;
@@ -513,6 +555,7 @@ static void transmit_packet(uint8_t ep_num)
if(ep_num == 0)
{
volatile uint8_t * ep0in_buf = &USBIEP0BUF;
+ uint8_t * base = (xfer->buffer + xfer->queued_len);
for(uint16_t i = 0; i < xfer_size; i++)
{
ep0in_buf[i] = base[i];
@@ -526,9 +569,19 @@ static void transmit_packet(uint8_t ep_num)
ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_IN);
volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3);
- for(int i = 0; i < xfer_size; i++)
+#if 0 // TODO support dcd_edpt_xfer_fifo API
+ if (xfer->ff)
+ {
+ tu_fifo_read_n(xfer->ff, (void *) ep_buf, xfer_size);
+ }
+ else
+#endif
{
- ep_buf[i] = base[i];
+ uint8_t * base = (xfer->buffer + xfer->queued_len);
+ for(int i = 0; i < xfer_size; i++)
+ {
+ ep_buf[i] = base[i];
+ }
}
ep_regs[BCTX] = (ep_regs[BCTX] & 0x80) + (xfer_size & 0x7F);