summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkkitayam <[email protected]>2021-11-04 22:36:36 +0900
committerkkitayam <[email protected]>2021-11-06 00:06:27 +0900
commit0b3c8c4a59e993f7f51452b2bd3d0decdc56d6c9 (patch)
tree1c8da3f674aab65c9a689c6674b2db401fbc0aa9
parent50ca0dda2ca4fe32f681f2955c9ec39355e3082e (diff)
Implement dcd_edpt_xfer_fifo for dcd_musb
-rw-r--r--src/class/audio/audio_device.c3
-rw-r--r--src/portable/mentor/musb/dcd_musb.c66
2 files changed, 55 insertions, 14 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index 28b1c1a7c..38bfc023b 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -102,7 +102,8 @@
CFG_TUSB_MCU == OPT_MCU_GD32VF103 || \
CFG_TUSB_MCU == OPT_MCU_LPC18XX || \
CFG_TUSB_MCU == OPT_MCU_LPC43XX || \
- CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
+ CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \
+ CFG_TUSB_MCU == OPT_MCU_MSP432E4xx
#if TUD_AUDIO_PREFER_RING_BUFFER
#define USE_LINEAR_BUFFER 0
#else
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index f073cd93f..5a5aa51bc 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -77,7 +77,8 @@ typedef struct
uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */
int8_t status_out;
pipe_state_t pipe0;
- pipe_state_t pipe[2][7];
+ pipe_state_t pipe[2][7]; /* pipe[direction][endpoint number - 1] */
+ uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */
} dcd_data_t;
/*------------------------------------------------------------------
@@ -244,6 +245,30 @@ static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len)
}
}
+static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir)
+{
+ static const struct {
+ void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
+ void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n);
+ void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len);
+ } ops[] = {
+ /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet},
+ /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet},
+ };
+ tu_fifo_buffer_info_t info;
+ ops[dir].tu_fifo_get_info(f, &info);
+ unsigned total_len = len;
+ len = TU_MIN(total_len, info.len_lin);
+ ops[dir].pipe_read_write(info.ptr_lin, fifo, len);
+ unsigned rem = total_len - len;
+ if (rem) {
+ len = TU_MIN(rem, info.len_wrap);
+ ops[dir].pipe_read_write(info.ptr_wrap, fifo, len);
+ rem -= len;
+ }
+ ops[dir].tu_fifo_advance(f, total_len - rem);
+}
+
static void process_setup_packet(uint8_t rhport)
{
uint32_t *p = (void*)&_dcd.setup_packet;
@@ -279,8 +304,12 @@ static bool handle_xfer_in(uint_fast8_t ep_addr)
void *buf = pipe->buf;
// TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem);
if (len) {
- pipe_write_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len);
- pipe->buf = buf + len;
+ if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) {
+ pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_IN);
+ } else {
+ pipe_write_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len);
+ pipe->buf = buf + len;
+ }
pipe->remaining = rem - len;
}
regs->TXCSRL = USB_TXCSRL1_TXRDY;
@@ -303,8 +332,12 @@ static bool handle_xfer_out(uint_fast8_t ep_addr)
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
void *buf = pipe->buf;
if (len) {
- pipe_read_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len);
- pipe->buf = buf + len;
+ if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) {
+ pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_OUT);
+ } else {
+ pipe_read_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len);
+ pipe->buf = buf + len;
+ }
pipe->remaining = rem - len;
}
if ((len < mps) || (rem == len)) {
@@ -725,12 +758,13 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
(void)rhport;
bool ret;
// TU_LOG1("X %x %d\n", ep_addr, total_bytes);
-
+ unsigned const epnum = tu_edpt_number(ep_addr);
unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn);
NVIC_DisableIRQ(USB0_IRQn);
- if (tu_edpt_number(ep_addr))
+ if (epnum) {
+ _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1);
ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes);
- else
+ } else
ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes);
if (ie) NVIC_EnableIRQ(USB0_IRQn);
return ret;
@@ -739,11 +773,17 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
// 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;
+ (void)rhport;
+ bool ret;
+ // TU_LOG1("X %x %d\n", ep_addr, total_bytes);
+ unsigned const epnum = tu_edpt_number(ep_addr);
+ TU_ASSERT(epnum);
+ unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn);
+ NVIC_DisableIRQ(USB0_IRQn);
+ _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1);
+ ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes);
+ if (ie) NVIC_EnableIRQ(USB0_IRQn);
+ return ret;
}
// Stall endpoint