29#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_PIC32MZ
37#define USB_REGS ((usbhs_registers_t *) (_USB_BASE_ADDRESS))
65 uint16_t max_packet_size;
70 uint16_t last_packet_size;
91 .bEndpointAddress = 0x00,
93 .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE,
102 .bEndpointAddress = 0x80,
104 .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE,
108#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir]
117 return _dcd.ep0_stage;
126 USB_REGS->INTRRXEbits.w = 0;
127 USB_REGS->INTRTXEbits.w = 0;
129 USB_REGS->INTRUSBEbits.w = 7;
139 USBCRCONbits.USBIE = 1;
146 USBCRCONbits.USBIE = 0;
157 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
164 USB_REGS->POWERbits.RESUME = 1;
165#if CFG_TUSB_OS != OPT_OS_NONE
170 while (cnt--) __asm__(
"nop");
172 USB_REGS->POWERbits.RESUME = 0;
179 USB_REGS->POWERbits.HSEN = TUD_OPT_HIGH_SPEED ? 1 : 0;
180 USB_REGS->POWERbits.SOFTCONN = 1;
187 USB_REGS->POWERbits.SOFTCONN = 1;
200 return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0;
204 uint16_t fifoAddress, uint8_t fifoSize,
205 uint32_t transferType)
207 uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
210 USB_REGS->INDEXbits.ENDPOINT = endpoint;
213 USB_REGS->INDEXED_EPCSR.RXMAXPbits.RXMAXP = endpointSize;
216 USB_REGS->RXFIFOADDbits.RXFIFOAD = fifoAddress;
219 USB_REGS->INDEXED_EPCSR.RXCSRL_DEVICEbits.CLRDT = 1;
222 USB_REGS->RXFIFOSZbits.RXFIFOSZ = fifoSize;
224 USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.ISO = transferType == 1 ? 1 : 0;
226 USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.DISNYET = transferType == 3 ? 1 : 0;
229 USB_REGS->INDEXbits.ENDPOINT = old_index;
232 USB_REGS->INTRRXEbits.w |= (1 << endpoint);
236 uint16_t fifoAddress, uint8_t fifoSize,
237 uint32_t transferType)
239 uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
242 USB_REGS->INDEXbits.ENDPOINT = endpoint;
245 USB_REGS->INDEXED_EPCSR.TXMAXPbits.TXMAXP = endpointSize;
248 USB_REGS->TXFIFOADDbits.TXFIFOAD = fifoAddress;
251 USB_REGS->INDEXED_EPCSR.TXCSRL_DEVICEbits.CLRDT = 1;
254 USB_REGS->TXFIFOSZbits.TXFIFOSZ = fifoSize;
256 USB_REGS->INDEXED_EPCSR.TXCSRH_DEVICEbits.ISO = 1 == transferType ? 1 : 0;
259 USB_REGS->INDEXbits.ENDPOINT = old_index;
262 USB_REGS->INTRTXEbits.w |= (1 << endpoint);
268 volatile uint8_t * fifo_reg;
270 fifo_reg = (
volatile uint8_t *) (&USB_REGS->FIFO[endpoint]);
272 for (i = 0; i < count; i++)
282 volatile uint8_t * fifo_reg;
284 fifo_reg = (
volatile uint8_t *) (&USB_REGS->FIFO[epnum]);
286 count = USB_REGS->EPCSR[epnum].RXCOUNTbits.RXCNT;
288 for (i = 0; i < count; i++)
290 buffer[i] = fifo_reg[i & 3];
321 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1;
325 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
329 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
343 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1;
359 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.TXPKTRDY = 1;
368 switch (
_dcd.ep0_stage)
373 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
381 switch (
_dcd.ep0_stage)
413 TU_ASSERT(epnum < EP_MAX);
416 xfer->fifo_size =
xfer->max_packet_size;
424 _dcd.fifo_addr_top += (
xfer->fifo_size + 7) >> 3;
429 _dcd.fifo_addr_top += (
xfer->fifo_size + 7) >> 3;
440 _dcd.fifo_addr_top = 64 >> 3;
441 for (
int i = 1; i < EP_MAX; ++i)
443 tu_memclr(&
_dcd.xfer_status[i],
sizeof(
_dcd.xfer_status[i]));
462 xfer->last_packet_size = 0;
463 xfer->transferred = 0;
471 USB_REGS->INTRRXEbits.w |= (1u << epnum);
489 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 1;
495 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.SENDSTALL = 1;
499 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.SENDSTALL = 1;
512 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 0;
518 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_RX_SENT_STALL | USBHS_EP_DEVICE_RX_SEND_STALL);
519 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.CLRDT = 1;
523 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_TX_SENT_STALL | USBHS_EP_DEVICE_TX_SEND_STALL);
524 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.CLRDT = 1;
541 xfer->transferred += transferred;
550 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
560 ep_status = USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w;
561 if (ep_status & USBHS_EP_DEVICE_RX_SENT_STALL)
563 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_RX_SENT_STALL;
566 if (ep_status & USBHS_EP0_HOST_RXPKTRDY)
571 USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0;
572 xfer->transferred += transferred;
576 USB_REGS->INTRRXEbits.w &= ~(1u << epnum);
584 uint8_t ep_status = USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w;
587 if (ep_status & USBHS_EP_DEVICE_TX_SENT_STALL)
589 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_TX_SENT_STALL;
593 xfer->transferred +=
xfer->last_packet_size;
597 xfer->last_packet_size = 0;
612 uint32_t setup_buffer[2];
615 uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
618 USB_REGS->INDEXbits.ENDPOINT = 0;
620 ep0_status = USB_REGS->EPCSR[0].CSR0L_DEVICEbits;
622 if (ep0_status.SENTSTALL)
627 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENTSTALL = 0;
630 if (ep0_status.SETUPEND)
637 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVSSETEND = 1;
641 if (ep0_status.RXPKTRDY)
650 setup_packet.setup_buffer[0] = USB_REGS->FIFO[0];
651 setup_packet.setup_buffer[1] = USB_REGS->FIFO[0];
652 if (setup_packet.request.bmRequestType_bit.direction ==
TUSB_DIR_OUT)
660 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
689 USB_REGS->FADDRbits.FUNC =
_dcd.dev_addr;
697 USB_REGS->INDEXbits.ENDPOINT = old_index;
704 __USBCSR2bits_t csr2_bits;
705 uint16_t rxints = USB_REGS->INTRRX & USB_REGS->INTRRXEbits.w;
706 uint16_t txints = USB_REGS->INTRTX;
707 csr2_bits = USBCSR2bits;
710 IFS4CLR = _IFS4_USBIF_MASK;
712 if (csr2_bits.SOFIF && csr2_bits.SOFIE)
716 if (csr2_bits.RESETIF)
722 if (csr2_bits.SUSPIF)
726 if (csr2_bits.RESUMEIF)
736 for (mask = 0x02, i = 1; rxints != 0 && mask != 0; mask <<= 1, ++i)
744 for (mask = 0x02, i = 1; txints != 0 && mask != 0; mask <<= 1, ++i)
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 void ep0_set_stage(ep0_stage_t stage)
static ep0_stage_t ep0_get_stage(void)
static int rx_fifo_read(uint8_t epnum, uint8_t *buffer)
static void ep0_handle_int(void)
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
static void xfer_complete(xfer_ctl_t *xfer, uint8_t result, bool in_isr)
@ EP0_STAGE_DATA_OUT_COMPLETE
@ EP0_STAGE_ADDRESS_CHANGE
@ EP0_STAGE_SETUP_OUT_DATA
@ EP0_STAGE_SETUP_OUT_NO_DATA
@ EP0_STAGE_DATA_IN_LAST_PACKET_FILLED
@ EP0_STAGE_SETUP_IN_DATA
static void epn_handle_tx_int(uint8_t epnum)
void dcd_int_handler(uint8_t rhport)
void dcd_disconnect(uint8_t rhport)
static bool ep0_xfer(xfer_ctl_t *xfer, int dir)
xfer_ctl_t xfer_status[EP_MAX][2]
void dcd_edpt_close_all(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE bool is_in_isr(void)
void dcd_int_disable(uint8_t rhport)
static void epn_tx_configure(uint8_t endpoint, uint16_t endpointSize, uint16_t fifoAddress, uint8_t fifoSize, uint32_t transferType)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
static void ep0_handle_rx(void)
static void ep0_fill_tx(xfer_ctl_t *xfer_in)
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 epn_fill_tx(xfer_ctl_t *xfer_in, uint8_t epnum)
static void epn_handle_rx_int(uint8_t epnum)
static tusb_desc_endpoint_t const ep0OUT_desc
static void tx_fifo_write(uint8_t endpoint, uint8_t const *buffer, size_t count)
static tusb_desc_endpoint_t const ep0IN_desc
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
static void epn_rx_configure(uint8_t endpoint, uint16_t endpointSize, uint16_t fifoAddress, uint8_t fifoSize, uint32_t transferType)
void dcd_int_enable(uint8_t rhport)
void dcd_remote_wakeup(uint8_t rhport)
void dcd_sof_enable(uint8_t rhport, bool en)
static TU_ATTR_ALWAYS_INLINE unsigned __builtin_ctz(unsigned int value)
TU_ATTR_WEAK void osal_task_delay(uint32_t msec)
AUDIO Channel Cluster Descriptor (4.1)
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
uint8_t bLength
Size of this descriptor in bytes: 9.
uint16_t last_packet_size
static TU_ATTR_ALWAYS_INLINE uint16_t tu_min16(uint16_t x, uint16_t y)
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)
struct TU_ATTR_PACKED tusb_desc_endpoint_t
USB Endpoint Descriptor.
CFG_TUH_MEM_ALIGN tusb_control_request_t request