Skip to content

Commit ed81f7b

Browse files
committed
Update dcd_esp32s2.c
1 parent 9dc3902 commit ed81f7b

File tree

1 file changed

+127
-53
lines changed

1 file changed

+127
-53
lines changed

components/arduino_tinyusb/src/dcd_esp32s2.c

Lines changed: 127 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
*/
2828

2929
#include "tusb_option.h"
30+
#include "common/tusb_fifo.h"
3031

3132
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 && TUSB_OPT_DEVICE_ENABLED
3233

@@ -59,6 +60,7 @@
5960

6061
typedef struct {
6162
uint8_t *buffer;
63+
// tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API
6264
uint16_t total_len;
6365
uint16_t queued_len;
6466
uint16_t max_size;
@@ -371,6 +373,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
371373

372374
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
373375
xfer->buffer = buffer;
376+
// xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
374377
xfer->total_len = total_bytes;
375378
xfer->queued_len = 0;
376379
xfer->short_packet = false;
@@ -406,6 +409,56 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
406409
return true;
407410
}
408411

412+
#if 0 // TODO support dcd_edpt_xfer_fifo API
413+
bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
414+
{
415+
(void)rhport;
416+
417+
// USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
418+
TU_ASSERT(ff->item_size == 1);
419+
420+
uint8_t const epnum = tu_edpt_number(ep_addr);
421+
uint8_t const dir = tu_edpt_dir(ep_addr);
422+
423+
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
424+
xfer->buffer = NULL;
425+
xfer->ff = ff;
426+
xfer->total_len = total_bytes;
427+
xfer->queued_len = 0;
428+
xfer->short_packet = false;
429+
430+
uint16_t num_packets = (total_bytes / xfer->max_size);
431+
uint8_t short_packet_size = total_bytes % xfer->max_size;
432+
433+
// Zero-size packet is special case.
434+
if (short_packet_size > 0 || (total_bytes == 0)) {
435+
num_packets++;
436+
}
437+
438+
ESP_LOGV(TAG, "Transfer <-> EP%i, %s, pkgs: %i, bytes: %i",
439+
epnum, ((dir == TUSB_DIR_IN) ? "USB0.HOST (in)" : "HOST->DEV (out)"),
440+
num_packets, total_bytes);
441+
442+
// IN and OUT endpoint xfers are interrupt-driven, we just schedule them
443+
// here.
444+
if (dir == TUSB_DIR_IN) {
445+
// A full IN transfer (multiple packets, possibly) triggers XFRC.
446+
USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) | total_bytes;
447+
USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M; // Enable | CNAK
448+
449+
// Enable fifo empty interrupt only if there are something to put in the fifo.
450+
if(total_bytes != 0) {
451+
USB0.dtknqr4_fifoemptymsk |= (1 << epnum);
452+
}
453+
} else {
454+
// Each complete packet for OUT xfers triggers XFRC.
455+
USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S);
456+
USB0.out_ep_reg[epnum].doepctl |= USB_EPENA0_M | USB_CNAK0_M;
457+
}
458+
return true;
459+
}
460+
#endif
461+
409462
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
410463
{
411464
(void)rhport;
@@ -514,35 +567,46 @@ static void receive_packet(xfer_ctl_t *xfer, /* usb_out_endpoint_t * out_ep, */
514567
to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size;
515568
}
516569

517-
uint8_t to_recv_rem = to_recv_size % 4;
518-
uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem;
519-
520-
// Do not assume xfer buffer is aligned.
521-
uint8_t *base = (xfer->buffer + xfer->queued_len);
522-
523-
// This for loop always runs at least once- skip if less than 4 bytes
524-
// to collect.
525-
if (to_recv_size >= 4) {
526-
for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) {
527-
uint32_t tmp = (*rx_fifo);
528-
base[i] = tmp & 0x000000FF;
529-
base[i + 1] = (tmp & 0x0000FF00) >> 8;
530-
base[i + 2] = (tmp & 0x00FF0000) >> 16;
531-
base[i + 3] = (tmp & 0xFF000000) >> 24;
532-
}
570+
// Common buffer read
571+
#if 0 // TODO support dcd_edpt_xfer_fifo API
572+
if (xfer->ff)
573+
{
574+
// Ring buffer
575+
tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) rx_fifo, to_recv_size);
533576
}
577+
else
578+
#endif
579+
{
580+
uint8_t to_recv_rem = to_recv_size % 4;
581+
uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem;
582+
583+
// Do not assume xfer buffer is aligned.
584+
uint8_t *base = (xfer->buffer + xfer->queued_len);
585+
586+
// This for loop always runs at least once- skip if less than 4 bytes
587+
// to collect.
588+
if (to_recv_size >= 4) {
589+
for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) {
590+
uint32_t tmp = (*rx_fifo);
591+
base[i] = tmp & 0x000000FF;
592+
base[i + 1] = (tmp & 0x0000FF00) >> 8;
593+
base[i + 2] = (tmp & 0x00FF0000) >> 16;
594+
base[i + 3] = (tmp & 0xFF000000) >> 24;
595+
}
596+
}
534597

535-
// Do not read invalid bytes from RX FIFO.
536-
if (to_recv_rem != 0) {
537-
uint32_t tmp = (*rx_fifo);
538-
uint8_t *last_32b_bound = base + to_recv_size_aligned;
598+
// Do not read invalid bytes from RX FIFO.
599+
if (to_recv_rem != 0) {
600+
uint32_t tmp = (*rx_fifo);
601+
uint8_t *last_32b_bound = base + to_recv_size_aligned;
539602

540-
last_32b_bound[0] = tmp & 0x000000FF;
541-
if (to_recv_rem > 1) {
542-
last_32b_bound[1] = (tmp & 0x0000FF00) >> 8;
543-
}
544-
if (to_recv_rem > 2) {
545-
last_32b_bound[2] = (tmp & 0x00FF0000) >> 16;
603+
last_32b_bound[0] = tmp & 0x000000FF;
604+
if (to_recv_rem > 1) {
605+
last_32b_bound[1] = (tmp & 0x0000FF00) >> 8;
606+
}
607+
if (to_recv_rem > 2) {
608+
last_32b_bound[2] = (tmp & 0x00FF0000) >> 16;
609+
}
546610
}
547611
}
548612

@@ -562,37 +626,47 @@ static void transmit_packet(xfer_ctl_t *xfer, volatile usb_in_endpoint_t *in_ep,
562626
xfer->queued_len = xfer->total_len - remaining;
563627

564628
uint16_t to_xfer_size = (remaining > xfer->max_size) ? xfer->max_size : remaining;
565-
uint8_t to_xfer_rem = to_xfer_size % 4;
566-
uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem;
567-
568-
// Buffer might not be aligned to 32b, so we need to force alignment
569-
// by copying to a temp var.
570-
uint8_t *base = (xfer->buffer + xfer->queued_len);
571-
572-
// This for loop always runs at least once- skip if less than 4 bytes
573-
// to send off.
574-
if (to_xfer_size >= 4) {
575-
for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) {
576-
uint32_t tmp = base[i] | (base[i + 1] << 8) |
577-
(base[i + 2] << 16) | (base[i + 3] << 24);
578-
(*tx_fifo) = tmp;
579-
}
629+
630+
#if 0 // TODO support dcd_edpt_xfer_fifo API
631+
if (xfer->ff)
632+
{
633+
tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) tx_fifo, to_xfer_size);
580634
}
635+
else
636+
#endif
637+
{
638+
uint8_t to_xfer_rem = to_xfer_size % 4;
639+
uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem;
640+
641+
// Buffer might not be aligned to 32b, so we need to force alignment
642+
// by copying to a temp var.
643+
uint8_t *base = (xfer->buffer + xfer->queued_len);
644+
645+
// This for loop always runs at least once- skip if less than 4 bytes
646+
// to send off.
647+
if (to_xfer_size >= 4) {
648+
for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) {
649+
uint32_t tmp = base[i] | (base[i + 1] << 8) |
650+
(base[i + 2] << 16) | (base[i + 3] << 24);
651+
(*tx_fifo) = tmp;
652+
}
653+
}
581654

582-
// Do not read beyond end of buffer if not divisible by 4.
583-
if (to_xfer_rem != 0) {
584-
uint32_t tmp = 0;
585-
uint8_t *last_32b_bound = base + to_xfer_size_aligned;
655+
// Do not read beyond end of buffer if not divisible by 4.
656+
if (to_xfer_rem != 0) {
657+
uint32_t tmp = 0;
658+
uint8_t *last_32b_bound = base + to_xfer_size_aligned;
586659

587-
tmp |= last_32b_bound[0];
588-
if (to_xfer_rem > 1) {
589-
tmp |= (last_32b_bound[1] << 8);
590-
}
591-
if (to_xfer_rem > 2) {
592-
tmp |= (last_32b_bound[2] << 16);
593-
}
660+
tmp |= last_32b_bound[0];
661+
if (to_xfer_rem > 1) {
662+
tmp |= (last_32b_bound[1] << 8);
663+
}
664+
if (to_xfer_rem > 2) {
665+
tmp |= (last_32b_bound[2] << 16);
666+
}
594667

595-
(*tx_fifo) = tmp;
668+
(*tx_fifo) = tmp;
669+
}
596670
}
597671
}
598672

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy