38#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_NUC505)
41#include "NUC505Series.h"
51#define USBD_BUF_SIZE 2048
52#define USBD_MAX_DMA_LEN 0x1000
125 USBD->PHYCTL |= USBD_PHYCTL_DPPUEN_Msk;
130 USBD->PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk;
135 USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk;
137 USBD->CEPINTEN = USBD_CEPINTEN_STSDONEIEN_Msk;
149 ep_index++,
xfer++, ep++)
154 if (0 == (ep->EPCFG & USBD_EPCFG_EPEN_Msk))
return ep;
169 uint16_t
const bytes_now =
tu_min16(
xfer->in_remaining_bytes,
xfer->max_packet_size);
172 xfer->in_remaining_bytes -= bytes_now;
178 if (0 ==
xfer->in_remaining_bytes)
180 ep->EPINTSTS = USBD_EPINTSTS_TXPKIF_Msk;
181 ep->EPINTEN = USBD_EPINTEN_TXPKIEN_Msk;
193 uint16_t countdown = bytes_now;
194 while (countdown > 3)
200 xfer->data_ptr += 4; countdown -= 4;
203 while (countdown--) ep->EPDAT_BYTE = *
xfer->data_ptr++;
207 if (bytes_now !=
xfer->max_packet_size) ep->EPRSPCTL = USBD_EPRSPCTL_SHORTTXEN_Msk;
215 USBD->EP[ep_index].EPCFG = 0;
220 USBD->DMACTL = USBD_DMACTL_DMARST_Msk;
225 USBD->CEPBUFSTART = 0;
226 USBD->CEPBUFEND = 0 + CFG_TUD_ENDPOINT0_SIZE - 1;
250 uint16_t
const available_bytes = ep->EPDATCNT & USBD_EPDATCNT_DATCNT_Msk;
252 if (!
xfer->dma_requested || !available_bytes)
259 USBD->DMACTL =
xfer->ep_addr & USBD_DMACTL_EPNUM_Msk;
260 USBD->DMAADDR = (uint32_t)
xfer->data_ptr;
261 USBD->DMACNT = available_bytes;
262 USBD->BUSINTSTS = USBD_BUSINTSTS_DMADONEIF_Msk;
263 xfer->out_bytes_so_far += available_bytes;
265 USBD->DMACTL |= USBD_DMACTL_DMAEN_Msk;
274 USBD_GINTEN_EPAIEN_Msk | USBD_GINTEN_EPBIEN_Msk | USBD_GINTEN_EPCIEN_Msk | USBD_GINTEN_EPDIEN_Msk | USBD_GINTEN_EPEIEN_Msk | USBD_GINTEN_EPFIEN_Msk | \
275 USBD_GINTEN_EPGIEN_Msk | USBD_GINTEN_EPHIEN_Msk | USBD_GINTEN_EPIIEN_Msk | USBD_GINTEN_EPJIEN_Msk | USBD_GINTEN_EPKIEN_Msk | USBD_GINTEN_EPLIEN_Msk | \
276 USBD_GINTEN_CEPIEN_Msk;
288 USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_VBUSDETIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk;
301 NVIC_EnableIRQ(USBD_IRQn);
307 NVIC_DisableIRQ(USBD_IRQn);
320 USBD->OPER |= USBD_OPER_RESUMEEN_Msk;
349 cfg |= USBD_EPCFG_EPDIR_Msk;
354 xfer->max_packet_size = size;
374 USBD->CEPCTL = USBD_CEPCTL_FLUSH_Msk;
378 USBD->CEPINTSTS = USBD_CEPINTSTS_INTKIF_Msk;
379 USBD->CEPINTEN = USBD_CEPINTEN_INTKIEN_Msk;
391 while (total_bytes < USBD->CEPRXCNT);
393 *
buffer++ = USBD->CEPDAT_BYTE;
414 ep->EPINTEN = USBD_EPINTEN_BUFEMPTYIEN_Msk;
418 xfer->out_bytes_so_far = 0;
419 ep->EPINTEN = USBD_EPINTEN_RXPKIEN_Msk;
439 xfer->data_ptr = NULL;
446 ep->EPINTEN = USBD_EPINTEN_BUFEMPTYIEN_Msk;
450 xfer->out_bytes_so_far = 0;
451 ep->EPINTEN = USBD_EPINTEN_RXPKIEN_Msk;
466 ep->EPRSPCTL = (ep->EPRSPCTL & 0xf7) | USBD_EPRSPCTL_HALT_Msk;
470 USBD->CEPCTL = USBD_CEPCTL_STALLEN_Msk;
482 ep->EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk;
490 uint32_t status = USBD->GINTSTS;
493 if (status & USBD_GINTSTS_USBIF_Msk)
495 uint32_t bus_state = USBD->BUSINTSTS;
497 if (bus_state & USBD_BUSINTSTS_SOFIF_Msk)
503 if (bus_state & USBD_BUSINTSTS_RSTIF_Msk)
507 USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk;
508 USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_SUSPENDIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk;
509 USBD->CEPINTSTS = 0x1ffc;
515 if (bus_state & USBD_BUSINTSTS_RESUMEIF_Msk)
517 USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_SUSPENDIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk;
521 if (bus_state & USBD_BUSINTSTS_SUSPENDIF_Msk)
523 USBD->BUSINTEN = USBD_BUSINTEN_RSTIEN_Msk | USBD_BUSINTEN_RESUMEIEN_Msk | USBD_BUSINTEN_DMADONEIEN_Msk;
527 if (bus_state & USBD_BUSINTSTS_HISPDIF_Msk)
529 USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk;
532 if (bus_state & USBD_BUSINTSTS_DMADONEIF_Msk)
539 uint16_t available_bytes = USBD->DMACNT & USBD_DMACNT_DMACNT_Msk;
553 if (bus_state & USBD_BUSINTSTS_VBUSDETIF_Msk)
555 if (USBD->PHYCTL & USBD_PHYCTL_VBUSDET_Msk)
558 USBD->PHYCTL |= USBD_PHYCTL_PHYEN_Msk | USBD_PHYCTL_DPPUEN_Msk;
563 USBD->PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk;
567 USBD->BUSINTSTS = bus_state & (USBD_BUSINTSTS_SOFIF_Msk | USBD_BUSINTSTS_RSTIF_Msk | USBD_BUSINTSTS_RESUMEIF_Msk | USBD_BUSINTSTS_SUSPENDIF_Msk | USBD_BUSINTSTS_HISPDIF_Msk | USBD_BUSINTSTS_DMADONEIF_Msk | USBD_BUSINTSTS_PHYCLKVLDIF_Msk | USBD_BUSINTSTS_VBUSDETIF_Msk);
570 if (status & USBD_GINTSTS_CEPIF_Msk)
572 uint32_t cep_state = USBD->CEPINTSTS & USBD->CEPINTEN;
574 if (cep_state & USBD_CEPINTSTS_SETUPPKIF_Msk)
577 uint8_t setup_packet[8];
578 setup_packet[0] = (uint8_t)(USBD->SETUP1_0 >> 0);
579 setup_packet[1] = (uint8_t)(USBD->SETUP1_0 >> 8);
580 setup_packet[2] = (uint8_t)(USBD->SETUP3_2 >> 0);
581 setup_packet[3] = (uint8_t)(USBD->SETUP3_2 >> 8);
582 setup_packet[4] = (uint8_t)(USBD->SETUP5_4 >> 0);
583 setup_packet[5] = (uint8_t)(USBD->SETUP5_4 >> 8);
584 setup_packet[6] = (uint8_t)(USBD->SETUP7_6 >> 0);
585 setup_packet[7] = (uint8_t)(USBD->SETUP7_6 >> 8);
588 else if (cep_state & USBD_CEPINTSTS_INTKIF_Msk)
590 USBD->CEPINTSTS = USBD_CEPINTSTS_TXPKIF_Msk;
592 if (!(cep_state & USBD_CEPINTSTS_STSDONEIF_Msk))
594 USBD->CEPINTEN = USBD_CEPINTEN_TXPKIEN_Msk;
596 for (
int count = 0; count < bytes_now; count++)
599 USBD_START_CEP_IN(bytes_now);
603 USBD->CEPINTEN = USBD_CEPINTEN_TXPKIEN_Msk | USBD_CEPINTEN_STSDONEIEN_Msk;
606 else if (cep_state & USBD_CEPINTSTS_TXPKIF_Msk)
608 USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk;
609 USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR);
617 USBD->CEPINTSTS = USBD_CEPINTSTS_INTKIF_Msk;
618 USBD->CEPINTEN = USBD_CEPINTEN_INTKIEN_Msk;
623 if (0 ==
ctrl_in_xfer.total_bytes) USBD->CEPCTL = USBD_CEPCTL_ZEROLEN_Msk;
625 USBD->CEPINTSTS = USBD_CEPINTSTS_STSDONEIF_Msk;
626 USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk | USBD_CEPINTEN_STSDONEIEN_Msk;
629 else if (cep_state & USBD_CEPINTSTS_STSDONEIF_Msk)
638 if (USBD->EP[ep_index].EPCFG & USBD_EPCFG_EPEN_Msk) USBD->EP[ep_index].EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk;
642 USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk;
645 USBD->CEPINTSTS = cep_state;
650 if (status & (USBD_GINTSTS_EPAIF_Msk | USBD_GINTSTS_EPBIF_Msk | USBD_GINTSTS_EPCIF_Msk | USBD_GINTSTS_EPDIF_Msk | USBD_GINTSTS_EPEIF_Msk | USBD_GINTSTS_EPFIF_Msk | USBD_GINTSTS_EPGIF_Msk | USBD_GINTSTS_EPHIF_Msk | USBD_GINTSTS_EPIIF_Msk | USBD_GINTSTS_EPJIF_Msk | USBD_GINTSTS_EPKIF_Msk | USBD_GINTSTS_EPLIF_Msk))
663 uint32_t ep_state = ep->EPINTSTS & ep->EPINTEN;
668 xfer->dma_requested =
true;
671 uint16_t
const available_bytes = ep->EPDATCNT & USBD_EPDATCNT_DATCNT_Msk;
681 for (
int count = 0; (count < available_bytes) && (
xfer->out_bytes_so_far <
xfer->total_bytes); count++,
xfer->out_bytes_so_far++)
683 *
xfer->data_ptr++ = ep->EPDAT_BYTE;
688 if ( (
xfer->total_bytes ==
xfer->out_bytes_so_far) || (available_bytes <
xfer->max_packet_size) )
695 else if (ep_state & USBD_EPINTSTS_BUFEMPTYIF_Msk)
700 else if (ep_state & USBD_EPINTSTS_TXPKIF_Msk)
707 ep->EPINTSTS = ep_state;
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)
xfer_td_t xfer[EP_CBI_COUNT+1][2]
static USBD_EP_T * ep_entry(uint8_t ep_addr, bool add)
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes)
static struct xfer_ctl_t xfer_table[PERIPH_MAX_EP]
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
static void usb_detach(void)
static void service_dma(void)
static void bus_reset(void)
static void usb_control_send_zlp(void)
void dcd_int_handler(uint8_t rhport)
void dcd_disconnect(uint8_t rhport)
void dcd_edpt_close_all(uint8_t rhport)
void dcd_int_disable(uint8_t rhport)
static volatile struct xfer_ctl_t * current_dma_xfer
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc)
static void usb_attach(void)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
static const uint8_t epcfg_eptype_table[]
void dcd_connect(uint8_t rhport)
static void dcd_userEP_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep)
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
static const uint32_t enabled_irqs
static uint32_t bufseg_addr
static volatile uint8_t assigned_address
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
static const uint8_t eprspctl_eptype_table[]
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
static struct @333 ctrl_in_xfer
uint16_t in_remaining_bytes
void dcd_int_enable(uint8_t rhport)
void dcd_remote_wakeup(uint8_t rhport)
void dcd_sof_enable(uint8_t rhport, bool en)
static void * memcpy(void *dst, const void *src, size_t n)
AUDIO Channel Cluster Descriptor (4.1)
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
uint16_t out_bytes_so_far
uint16_t in_remaining_bytes
static TU_ATTR_ALWAYS_INLINE uint16_t tu_min16(uint16_t x, uint16_t y)
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...
tusb_speed_t
defined base on EHCI specs value for Endpoint Speed
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)
tusb_xfer_type_t
defined base on USB Specs Endpoint's bmAttributes
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)