31#if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED)
34#include "xtensa/xtensa_api.h"
36#include "esp_intr_alloc.h"
38#include "soc/dport_reg.h"
39#include "soc/gpio_sig_map.h"
40#include "soc/usb_periph.h"
41#include "soc/usb_reg.h"
42#include "soc/usb_struct.h"
43#include "soc/periph_defs.h"
48#define USB_OUT_EP_NUM ((int) (sizeof(USB0.out_ep_reg) / sizeof(USB0.out_ep_reg[0])))
52#define USB_IN_EP_NUM ((int) (sizeof(USB0.in_ep_reg) / sizeof(USB0.in_ep_reg[0])))
58#define EP_MAX USB_OUT_EP_NUM
61#define EP_FIFO_SIZE 1024
76static const char *
TAG =
"TUSB:DCD";
82#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir]
98 for (
int ep_num = 0; ep_num < USB_OUT_EP_NUM; ep_num++) {
99 USB0.out_ep_reg[ep_num].doepctl |= USB_DO_SNAK0_M;
103 USB0.dcfg &= ~USB_DEVADDR_M;
105 USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M;
106 USB0.doepmsk = USB_SETUPMSK_M | USB_XFERCOMPLMSK;
107 USB0.diepmsk = USB_TIMEOUTMSK_M | USB_DI_XFERCOMPLMSK_M ;
137 USB0.grstctl |= 0x10 << USB_TXFNUM_S;
138 USB0.grstctl |= USB_TXFFLSH_M;
142 USB0.gnptxfsiz = (16 << USB_NPTXFDEP_S) | (USB0.grxfsiz & 0x0000ffffUL);
145 USB0.out_ep_reg[0].doeptsiz |= USB_SUPCNT0_M;
147 USB0.gintmsk |= USB_IEPINTMSK_M | USB_OEPINTMSK_M;
152 ESP_EARLY_LOGV(
TAG,
"dcd_int_handler - Speed enumeration done! Sending DCD_EVENT_BUS_RESET then");
155 uint32_t enum_spd = (USB0.dsts >> USB_ENUMSPD_S) & (USB_ENUMSPD_V);
158 if (enum_spd == 0x03) {
159 USB0.in_ep_reg[0].diepctl &= ~USB_D_MPS0_V;
160 USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M;
164 USB0.in_ep_reg[0].diepctl |= USB_D_MPS0_V;
165 USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M;
177 ESP_LOGV(
TAG,
"DCD init - Start");
180 ESP_LOGV(
TAG,
"DCD init - Soft DISCONNECT and Setting up");
181 USB0.dctl |= USB_SFTDISCON_M;
186 USB0.dcfg |= USB_NZSTSOUTHSHK_M |
189 USB0.gahbcfg |= USB_NPTXFEMPLVL_M | USB_GLBLLNTRMSK_M;
190 USB0.gusbcfg |= USB_FORCEDEVMODE_M;
191 USB0.gotgctl &= ~(USB_BVALIDOVVAL_M | USB_BVALIDOVEN_M | USB_VBVALIDOVVAL_M);
194 for (
int n = 0; n < USB_OUT_EP_NUM; n++) {
195 USB0.out_ep_reg[n].doepctl |= USB_DO_SNAK0_M;
202 USB0.gintmsk = USB_OTGINTMSK_M |
220 ESP_LOGV(
TAG,
"DCD init - Set address : %u",
dev_addr);
221 USB0.dcfg |= ((
dev_addr & USB_DEVADDR_V) << USB_DEVADDR_S);
231 USB0.dctl |= USB_RMTWKUPSIG_M;
234 USB0.gintsts = USB_SOF_M;
235 USB0.gintmsk |= USB_SOFMSK_M;
238 vTaskDelay(pdMS_TO_TICKS(1));
240 USB0.dctl &= ~USB_RMTWKUPSIG_M;
247 USB0.dctl &= ~USB_SFTDISCON_M;
254 USB0.dctl |= USB_SFTDISCON_M;
271 ESP_LOGV(
TAG,
"DCD endpoint opened");
274 usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]);
275 usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]);
280 TU_ASSERT(epnum < EP_MAX);
287 out_ep[epnum].doepctl |= USB_USBACTEP1_M |
290 xfer->max_size << USB_MPS1_S;
291 USB0.daintmsk |= (1 << (16 + epnum));
317 TU_ASSERT(fifo_num != 0);
319 in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M);
320 in_ep[epnum].diepctl |= USB_D_USBACTEP1_M |
321 fifo_num << USB_D_TXFNUM1_S |
326 USB0.daintmsk |= (1 << (0 + epnum));
330 uint16_t
const allocated_size = (USB0.grxfsiz & 0x0000ffff) + 16;
331 uint16_t
const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_FIFO_NUM-1);
332 uint32_t
const fifo_offset = allocated_size + fifo_size*(fifo_num-1);
335 USB0.dieptxf[epnum - 1] = (fifo_size << USB_NPTXFDEP_S) | fifo_offset;
344 usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]);
345 usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]);
348 USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M;
350 for(uint8_t n = 1; n < EP_MAX; n++)
353 out_ep[n].doepctl = 0;
357 in_ep[n].diepctl = 0;
375 xfer->queued_len = 0;
376 xfer->short_packet =
false;
386 ESP_LOGV(
TAG,
"Transfer <-> EP%i, %s, pkgs: %i, bytes: %i",
387 epnum, ((dir ==
TUSB_DIR_IN) ?
"USB0.HOST (in)" :
"HOST->DEV (out)"),
394 USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) |
total_bytes;
395 USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M;
398 if ((USB0.in_ep_reg[epnum].diepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) &&
xfer->interval == 1) {
400 uint32_t
const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S));
401 USB0.in_ep_reg[epnum].diepctl |= (odd_frame_now ? USB_DI_SETD0PID1 : USB_DI_SETD1PID1);
406 USB0.dtknqr4_fifoemptymsk |= (1 << epnum);
410 USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((
xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S);
411 USB0.out_ep_reg[epnum].doepctl |= USB_EPENA0_M | USB_CNAK0_M;
414 if ((USB0.out_ep_reg[epnum].doepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) &&
xfer->interval == 1) {
416 uint32_t
const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S));
417 USB0.out_ep_reg[epnum].doepctl |= (odd_frame_now ? USB_DO_SETD0PID1 : USB_DO_SETD1PID1);
434 usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]);
435 usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]);
442 if ((epnum == 0) || !(in_ep[epnum].diepctl & USB_D_EPENA1_M)) {
443 in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M);
446 in_ep[epnum].diepctl |= USB_DI_SNAK1_M;
447 while ((in_ep[epnum].diepint & USB_DI_SNAK1_M) == 0) ;
450 in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M | USB_D_EPDIS1_M);
451 while ((in_ep[epnum].diepint & USB_D_EPDISBLD0_M) == 0) ;
452 in_ep[epnum].diepint = USB_D_EPDISBLD0_M;
456 uint8_t
const fifo_num = ((in_ep[epnum].diepctl >> USB_D_TXFNUM1_S) & USB_D_TXFNUM1_V);
457 USB0.grstctl |= (fifo_num << USB_TXFNUM_S);
458 USB0.grstctl |= USB_TXFFLSH_M;
459 while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ;
462 if ((epnum == 0) || !(out_ep[epnum].doepctl & USB_EPENA0_M)) {
463 out_ep[epnum].doepctl |= USB_STALL0_M;
469 USB0.dctl |= USB_SGOUTNAK_M;
470 while ((USB0.gintsts & USB_GOUTNAKEFF_M) == 0) ;
474 out_ep[epnum].doepctl |= (USB_STALL0_M | USB_EPDIS0_M);
475 while ((out_ep[epnum].doepint & USB_EPDISBLD0_M) == 0) ;
476 out_ep[epnum].doepint = USB_EPDISBLD0_M;
479 USB0.dctl |= USB_CGOUTNAK_M;
488 usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]);
489 usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]);
495 in_ep[epnum].diepctl &= ~USB_D_STALL1_M;
497 uint8_t eptype = (in_ep[epnum].diepctl & USB_D_EPTYPE1_M) >> USB_D_EPTYPE1_S;
500 if (eptype == 2 || eptype == 3) {
501 in_ep[epnum].diepctl |= USB_DI_SETD0PID1_M;
504 out_ep[epnum].doepctl &= ~USB_STALL1_M;
506 uint8_t eptype = (out_ep[epnum].doepctl & USB_EPTYPE1_M) >> USB_EPTYPE1_S;
509 if (eptype == 2 || eptype == 3) {
510 out_ep[epnum].doepctl |= USB_DO_SETD0PID1_M;
519 ESP_EARLY_LOGV(
TAG,
"USB - receive_packet");
520 volatile uint32_t *rx_fifo = USB0.fifo[0];
527 uint16_t to_recv_size;
529 if (remaining <= xfer->max_size) {
531 to_recv_size = (xfer_size > remaining) ? remaining : xfer_size;
535 to_recv_size = (xfer_size >
xfer->max_size) ?
xfer->max_size : xfer_size;
548 uint8_t to_recv_rem = to_recv_size % 4;
549 uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem;
556 if (to_recv_size >= 4) {
557 for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) {
558 uint32_t tmp = (*rx_fifo);
559 base[i] = tmp & 0x000000FF;
560 base[i + 1] = (tmp & 0x0000FF00) >> 8;
561 base[i + 2] = (tmp & 0x00FF0000) >> 16;
562 base[i + 3] = (tmp & 0xFF000000) >> 24;
567 if (to_recv_rem != 0) {
568 uint32_t tmp = (*rx_fifo);
569 uint8_t *last_32b_bound = base + to_recv_size_aligned;
571 last_32b_bound[0] = tmp & 0x000000FF;
572 if (to_recv_rem > 1) {
573 last_32b_bound[1] = (tmp & 0x0000FF00) >> 8;
575 if (to_recv_rem > 2) {
576 last_32b_bound[2] = (tmp & 0x00FF0000) >> 16;
581 xfer->queued_len += xfer_size;
585 xfer->short_packet = (xfer_size <
xfer->max_size);
590 ESP_EARLY_LOGV(
TAG,
"USB - transmit_packet");
591 volatile uint32_t *tx_fifo = USB0.fifo[fifo_num];
593 uint16_t remaining = (in_ep->dieptsiz & 0x7FFFFU) >> USB_D_XFERSIZE0_S;
596 uint16_t to_xfer_size = (remaining >
xfer->max_size) ?
xfer->max_size : remaining;
606 uint8_t to_xfer_rem = to_xfer_size % 4;
607 uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem;
615 if (to_xfer_size >= 4) {
616 for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) {
617 uint32_t tmp = base[i] | (base[i + 1] << 8) |
618 (base[i + 2] << 16) | (base[i + 3] << 24);
624 if (to_xfer_rem != 0) {
626 uint8_t *last_32b_bound = base + to_xfer_size_aligned;
628 tmp |= last_32b_bound[0];
629 if (to_xfer_rem > 1) {
630 tmp |= (last_32b_bound[1] << 8);
632 if (to_xfer_rem > 2) {
633 tmp |= (last_32b_bound[2] << 16);
645 uint32_t
const ctl_word = USB0.grxstsp;
646 uint8_t
const pktsts = (ctl_word & USB_PKTSTS_M) >> USB_PKTSTS_S;
647 uint8_t
const epnum = (ctl_word & USB_CHNUM_M ) >> USB_CHNUM_S;
648 uint16_t
const bcnt = (ctl_word & USB_BCNT_M ) >> USB_BCNT_S;
652 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - RX type : Global OUT NAK");
656 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - RX type : Out packet");
663 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - RX type : Out packet done");
668 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - RX : Setup packet done");
669 USB0.out_ep_reg[epnum].doeptsiz |= USB_SUPCNT0_M;
673 volatile uint32_t *rx_fifo = USB0.fifo[0];
695 for (
int n = 0; n < USB_OUT_EP_NUM; n++) {
698 if (USB0.daint & (1 << (16 + n))) {
700 if ((USB0.out_ep_reg[n].doepint & USB_SETUP0_M)) {
701 USB0.out_ep_reg[n].doepint = USB_STUPPKTRCVD0_M | USB_SETUP0_M;
706 if (USB0.out_ep_reg[n].doepint & USB_XFERCOMPL0_M) {
708 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - EP OUT - XFER complete (single packet)");
709 USB0.out_ep_reg[n].doepint = USB_XFERCOMPL0_M;
713 xfer->short_packet =
false;
717 USB0.out_ep_reg[n].doeptsiz |= USB_PKTCNT0_M | ((
xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S);
718 USB0.out_ep_reg[n].doepctl |= USB_EPENA0_M | USB_CNAK0_M;
730 for (uint32_t n = 0; n < USB_IN_EP_NUM; n++) {
733 if (USB0.daint & (1 << (0 + n))) {
734 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - EP IN %u", n);
736 if (USB0.in_ep_reg[n].diepint & USB_D_XFERCOMPL0_M) {
737 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - IN XFER complete!");
738 USB0.in_ep_reg[n].diepint = USB_D_XFERCOMPL0_M;
743 if (USB0.in_ep_reg[n].diepint & USB_D_TXFEMP0_M) {
744 ESP_EARLY_LOGV(
TAG,
"TUSB IRQ - IN XFER FIFO empty!");
745 USB0.in_ep_reg[n].diepint = USB_D_TXFEMP0_M;
751 USB0.dtknqr4_fifoemptymsk &= ~(1 << n);
756 if (USB0.in_ep_reg[n].diepint & USB_D_TIMEOUT0_M) {
758 USB0.in_ep_reg[n].diepint = USB_D_TIMEOUT0_M;
769 uint8_t
const rhport = 0;
771 const uint32_t int_msk = USB0.gintmsk;
772 const uint32_t int_status = USB0.gintsts & int_msk;
774 if (int_status & USB_USBRST_M) {
776 ESP_EARLY_LOGV(
TAG,
"dcd_int_handler - reset");
777 USB0.gintsts = USB_USBRST_M;
783 if (int_status & USB_RESETDET_M) {
784 ESP_EARLY_LOGV(
TAG,
"dcd_int_handler - reset while suspend");
785 USB0.gintsts = USB_RESETDET_M;
789 if (int_status & USB_ENUMDONE_M) {
793 USB0.gintsts = USB_ENUMDONE_M;
798 if(int_status & USB_USBSUSP_M)
800 USB0.gintsts = USB_USBSUSP_M;
804 if(int_status & USB_WKUPINT_M)
806 USB0.gintsts = USB_WKUPINT_M;
810 if (int_status & USB_OTGINT_M)
813 ESP_EARLY_LOGV(
TAG,
"dcd_int_handler - disconnected");
815 uint32_t
const otg_int = USB0.gotgint;
817 if (otg_int & USB_SESENDDET_M)
822 USB0.gotgint = otg_int;
825 if (int_status & USB_SOF_M) {
826 USB0.gintsts = USB_SOF_M;
829 USB0.gintmsk &= ~USB_SOFMSK_M;
835 if (int_status & USB_RXFLVI_M) {
837 ESP_EARLY_LOGV(
TAG,
"dcd_int_handler - rx!");
840 USB0.gintmsk &= ~USB_RXFLVIMSK_M;
842 USB0.gintmsk |= USB_RXFLVIMSK_M;
846 if (int_status & USB_OEPINT_M) {
848 ESP_EARLY_LOGV(
TAG,
"dcd_int_handler - OUT endpoint!");
853 if (int_status & USB_IEPINT_M) {
855 ESP_EARLY_LOGV(
TAG,
"dcd_int_handler - IN endpoint!");
860 USB0.gintsts |= USB_CURMOD_INT_M |
880 esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t)
_dcd_int_handler, NULL, &
usb_ih);
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_signal(uint8_t rhport, dcd_eventid_t eid, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_xfer_complete(uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_setup_received(uint8_t rhport, uint8_t const *setup, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_reset(uint8_t rhport, tusb_speed_t speed, bool in_isr)
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes)
static uint32_t _setup_packet[2]
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
static void transmit_packet(xfer_ctl_t *xfer, volatile usb_in_endpoint_t *in_ep, uint8_t fifo_num)
static void bus_reset(void)
void dcd_disconnect(uint8_t rhport)
static void receive_packet(xfer_ctl_t *xfer, uint16_t xfer_size)
static xfer_ctl_t xfer_status[EP_MAX][2]
void dcd_edpt_close_all(uint8_t rhport)
void dcd_int_disable(uint8_t rhport)
static void handle_epout_ints(void)
static void _dcd_int_handler(void *arg)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
void dcd_connect(uint8_t rhport)
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
static void read_rx_fifo(void)
static uint8_t _allocated_fifos
static void handle_epin_ints(void)
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
static void enum_done_processing(void)
static intr_handle_t usb_ih
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
static uint8_t get_free_fifo(void)
void dcd_int_enable(uint8_t rhport)
void dcd_remote_wakeup(uint8_t rhport)
void dcd_sof_enable(uint8_t rhport, bool en)
xfer_td_t xfer[EP_CBI_COUNT+1][2]
AUDIO Channel Cluster Descriptor (4.1)
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t *f, const void *data, uint16_t n)
This function will write n elements into the array index specified by the write pointer and increment...
uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t *f, void *buffer, uint16_t n)
This function will read n elements from the array index specified by the read pointer and increment t...
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)