Implement dcd_edpt_iso_xfer() for dcd_esp32s2.c
This commit is contained in:
@@ -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;
|
||||
uint16_t total_len;
|
||||
uint16_t queued_len;
|
||||
uint16_t max_size;
|
||||
@@ -354,6 +356,64 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcd_edpt_iso_xfer (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++;
|
||||
}
|
||||
|
||||
// Set copy mode to constant address - required since data copied to or from the hardware USB FIFO needs to be written at a constant address
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
{
|
||||
(void)rhport;
|
||||
@@ -462,6 +522,9 @@ 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;
|
||||
}
|
||||
|
||||
// Common buffer read
|
||||
if (xfer->buffer)
|
||||
{
|
||||
uint8_t to_recv_rem = to_recv_size % 4;
|
||||
uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem;
|
||||
|
||||
@@ -494,6 +557,13 @@ static void receive_packet(xfer_ctl_t *xfer, /* usb_out_endpoint_t * out_ep, */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ring buffer
|
||||
tu_fifo_write_n(xfer->ff, (const void *) rx_fifo, to_recv_size);
|
||||
}
|
||||
|
||||
xfer->queued_len += xfer_size;
|
||||
|
||||
// Per USB spec, a short OUT packet (including length 0) is always
|
||||
@@ -510,6 +580,9 @@ 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;
|
||||
|
||||
if (xfer->buffer)
|
||||
{
|
||||
uint8_t to_xfer_rem = to_xfer_size % 4;
|
||||
uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem;
|
||||
|
||||
@@ -543,6 +616,11 @@ static void transmit_packet(xfer_ctl_t *xfer, volatile usb_in_endpoint_t *in_ep,
|
||||
(*tx_fifo) = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tu_fifo_read_n(xfer->ff, (void *) tx_fifo, to_xfer_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_rx_fifo(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user