30#if CFG_TUD_ENABLED && \
31 (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || \
32 CFG_TUSB_MCU == OPT_MCU_PIC32MK || CFG_TUSB_MCU == OPT_MCU_PIC24 || \
33 CFG_TUSB_MCU == OPT_MCU_DSPIC33)
40#if (CFG_TUSB_MCU == OPT_MCU_PIC32MX || CFG_TUSB_MCU == OPT_MCU_PIC32MM || CFG_TUSB_MCU == OPT_MCU_PIC32MK)
42#define TU_PIC_INT_SIZE 4
44#elif (CFG_TUSB_MCU == OPT_MCU_PIC24 || CFG_TUSB_MCU == OPT_MCU_DSPIC33)
46#define TU_PIC_INT_SIZE 2
50#error Unsupportd PIC MCU
55#if TU_PIC_INT_SIZE == 4
58#define KVA_TO_PA(kva) ((uint32_t)(kva) & 0x1fffffff)
62#define PA_TO_KVA1(pa) ((uint32_t)(pa) | 0xA0000000)
68#define KVA_TO_PA(kva) (kva)
72#define PA_TO_KVA1(pa) (pa)
89#if TU_PIC_INT_SIZE == 4
174#if TU_PIC_INT_SIZE == 4
184 uint8_t setup_packet[8];
194#if TU_PIC_INT_SIZE == 4
200#if TU_PIC_INT_SIZE == 4
201typedef uint32_t ep_reg_t;
202#elif TU_PIC_INT_SIZE == 2
203typedef uint16_t ep_reg_t;
206static inline volatile void *ep_addr(uint8_t rhport, uint8_t ep_num) {
207#if CFG_TUSB_MCU == OPT_MCU_PIC32MK
208 volatile void *ep_reg_base = rhport ? (&U2EP0) : (&U1EP0);
210 volatile void *ep_reg_base = &U1EP0;
212#if TU_PIC_INT_SIZE == 4
213 const size_t offset = 0x10;
215 const size_t offset = 0x2;
217 return ep_reg_base +
offset * ep_num;
220static inline ep_reg_t
ep_read(uint8_t rhport, uint8_t ep_num) {
221 volatile ep_reg_t *ep = ep_addr(rhport, ep_num);
225static inline void ep_write(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
226 volatile ep_reg_t *ep = ep_addr(rhport, ep_num);
230static inline void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
231#if TU_PIC_INT_SIZE == 4
232 volatile ep_reg_t *ep_clr = (ep_addr(rhport, ep_num) + 0x4);
235 ep_reg_t v =
ep_read(rhport, ep_num);
241static inline void ep_set(uint8_t rhport, uint8_t ep_num, ep_reg_t val) {
242#if TU_PIC_INT_SIZE == 4
243 volatile ep_reg_t *ep_s = (ep_addr(rhport, ep_num) + 0x8);
246 ep_reg_t v =
ep_read(rhport, ep_num);
253#if CFG_TUSB_MCU == OPT_MCU_PIC32MM
254 IEC0SET = _IEC0_USBIE_MASK;
255#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX
256 IEC1SET = _IEC1_USBIE_MASK;
257#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK
259 IEC1SET = _IEC1_USB1IE_MASK;
261 IEC7SET = _IEC7_USB2IE_MASK;
262#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33)
268#if CFG_TUSB_MCU == OPT_MCU_PIC32MM
269 IEC0CLR = _IEC0_USBIE_MASK;
270#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX
271 IEC1CLR = _IEC1_USBIE_MASK;
272#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK
274 IEC1CLR = _IEC1_USB1IE_MASK;
276 IEC7CLR = _IEC7_USB2IE_MASK;
277#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33)
283#if CFG_TUSB_MCU == OPT_MCU_PIC32MM
284 return IEC0bits.USBIE;
285#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX
286 return IEC1bits.USBIE;
287#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK
289 return IEC1bits.USB1IE;
291 return IEC7bits.USB2IE;
292#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33)
293 return IEC5bits.USB1IE;
298#if CFG_TUSB_MCU == OPT_MCU_PIC32MM
299 IFS0CLR = _IFS0_USBIF_MASK;
300#elif CFG_TUSB_MCU == OPT_MCU_PIC32MX
301 IFS1CLR = _IFS1_USBIF_MASK;
302#elif CFG_TUSB_MCU == OPT_MCU_PIC32MK
304 IFS1CLR = _IFS1_USB1IF_MASK;
306 IFS7CLR = _IFS7_USB2IF_MASK;
307#elif (CFG_TUSB_MCU == OPT_MCU_PIC24) || (CFG_TUSB_MCU == OPT_MCU_DSPIC33)
314 const unsigned out_odd =
_dcd.endpoint[0][0].odd;
315 const unsigned in_odd =
_dcd.endpoint[0][1].odd;
316 TU_ASSERT(0 ==
_dcd.bdt[0][0][out_odd].own, );
318 _dcd.bdt[0][0][out_odd].data = 0;
319 _dcd.bdt[0][0][out_odd ^ 1].data = 1;
320 _dcd.bdt[0][1][in_odd].data = 1;
321 _dcd.bdt[0][1][in_odd ^ 1].data = 0;
323 _dcd.setup_packet,
sizeof(
_dcd.setup_packet));
328 for (
int i = 0; i < 16; ++i) {
329 unsigned const endpt =
ep_read(rhport, i);
331 if (endpt & _U1EP0_EPSTALL_MASK) {
336 ep_clear(rhport, i, _U1EP0_EPSTALL_MASK);
345 U1IR = _U1IR_TRNIF_MASK;
347 uint8_t epnum = (s >> _U1STAT_ENDPT0_POSITION);
348 uint8_t dir = (s & _U1STAT_DIR_MASK) >> _U1STAT_DIR_POSITION;
349 unsigned odd = (s & _U1STAT_PPBI_MASK) ? 1 : 0;
355 const unsigned pid = bd->
tok_pid;
366#if TU_PIC_INT_SIZE == 4
367 U1CONCLR = _U1CON_PKTDIS_TOKBUSY_MASK;
369 U1CONbits.PKTDIS = 0;
374 const unsigned bc = bd->
bc;
375 const unsigned remaining = ep->remaining - bc;
376 if (remaining && bc == ep->max_packet_size) {
378 ep->remaining = remaining;
379 const int next_remaining = remaining - ep->max_packet_size;
380 if (next_remaining > 0) {
382 bd->
addr += ep->max_packet_size * 2;
383 bd->
bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining;
388 const unsigned length = ep->length;
392 if (0 == epnum && 0 == length) {
407#if TU_PIC_INT_SIZE == 4
408 U1PWRCCLR = _U1PWRC_USUSPEND_MASK;
409 U1CONSET = _U1CON_PPBRST_MASK;
411 U1PWRCbits.USUSPND = 0;
412 U1CONbits.PPBRST = 1;
416 U1IE = _U1IE_URSTIE_MASK | _U1IE_TRNIE_MASK | _U1IE_IDLEIE_MASK |
417 _U1IE_UERRIE_MASK | _U1IE_STALLIE_MASK;
419 U1EP0 = _U1EP0_EPHSHK_MASK | _U1EP0_EPRXEN_MASK | _U1EP0_EPTXEN_MASK;
421 for (
unsigned i = 1; i < 16; ++i) {
426 for (
unsigned i = 0; i <
sizeof(
_dcd.bdt)/
sizeof(*bd); ++i, ++bd) {
435 _dcd.endpoint[0][0] = ep0;
436 _dcd.endpoint[0][1] = ep0;
437 tu_memclr(
_dcd.endpoint[1],
sizeof(
_dcd.endpoint) -
sizeof(
_dcd.endpoint[0]));
440#if TU_PIC_INT_SIZE == 4
441 U1CONCLR = _U1CON_PPBRST_MASK;
443 U1CONbits.PPBRST = 0;
457#if TU_PIC_INT_SIZE == 4
458 U1PWRCCLR = _U1PWRC_USUSPEND_MASK;
459 U1IECLR = _U1IE_RESUMEIE_MASK;
460 U1IESET = _U1IE_IDLEIE_MASK;
462 U1PWRCbits.USUSPND = 0;
463 U1IEbits.RESUMEIE = 0;
478#if CFG_TUSB_MCU == OPT_MCU_PIC32MM
479 TRISBbits.TRISB6 = 1;
484#if TU_PIC_INT_SIZE == 4
485 U1PWRCSET = _U1PWRC_USBPWR_MASK;
487 U1PWRCbits.USBPWR = 1;
490#if TU_PIC_INT_SIZE == 4
491 uint32_t bdt_phys = KVA_TO_PA((uintptr_t)
_dcd.bdt);
493 U1BDTP1 = (uint8_t)(bdt_phys >> 8);
494 U1BDTP2 = (uint8_t)(bdt_phys >> 16);
495 U1BDTP3 = (uint8_t)(bdt_phys >> 24);
497 U1BDTP1 = (uint8_t)((uint16_t)(
void *)
_dcd.bdt >> 8);
502 U1IE = _U1IE_URSTIE_MASK;
527#if TU_PIC_INT_SIZE == 4
528 U1CONSET = _U1CON_RESUME_MASK;
530 U1CONbits.RESUME = 1;
532 unsigned cnt = 25000000 / 1000;
533 while (cnt--)
asm volatile(
"nop");
535#if TU_PIC_INT_SIZE == 4
536 U1CONCLR = _U1CON_RESUME_MASK;
538 U1CONbits.RESUME = 0;
544 while (!U1CONbits.USBEN) {
545#if TU_PIC_INT_SIZE == 4
546 U1CONSET = _U1CON_USBEN_SOFEN_MASK;
574 const unsigned odd = ep->
odd;
583 unsigned val = _U1EP0_EPCONDIS_MASK;
585 val |= dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK;
587 ep_reg_t tmp =
ep_read(rhport, epn);
595 bd[odd ^ 1].
data = 1;
606 for (
unsigned i = 1; i < 16; ++i) {
613 for (
unsigned i = 2; i <
sizeof(
_dcd.bdt)/
sizeof(*bd); ++i, ++bd) {
617 for (
unsigned i = 2; i <
sizeof(
_dcd.endpoint)/
sizeof(*ep); ++i, ++ep) {
631 const unsigned msk = dir ? _U1EP0_EPTXEN_MASK : _U1EP0_EPRXEN_MASK;
654 TU_ASSERT(0 == bd->
own);
669 next->
addr = (uint8_t *)KVA_TO_PA(
buffer + mps);
687 ep_set(rhport, epn, _U1EP0_EPSTALL_MASK);
690 const unsigned odd =
_dcd.endpoint[epn][dir].odd;
692 TU_ASSERT(0 == bd->
own,);
710 const unsigned odd =
_dcd.endpoint[epn][dir].odd;
712 TU_VERIFY(bd[odd].own,);
725 bd[odd ^ 1].
data = 1;
728 const unsigned endpt =
ep_read(rhport, epn);
729 if (endpt & _U1EP0_EPSTALL_MASK) {
730 ep_clear(rhport, endpt, _U1EP0_EPSTALL_MASK);
747 if (is & _U1IR_UERRIF_MASK) {
753 if (is & _U1IR_URSTIF_MASK) {
758 if (is & _U1IR_IDLEIF_MASK) {
761 U1IR = _U1IR_IDLEIF_MASK;
765 if (is & _U1IR_RESUMEIF_MASK) {
766 U1IR = _U1IR_RESUMEIF_MASK;
770 if (is & _U1IR_SOFIF_MASK) {
771 U1IR = _U1IR_SOFIF_MASK;
775 if (is & _U1IR_STALLIF_MASK) {
776 U1IR = _U1IR_STALLIF_MASK;
780 if (is & _U1IR_TRNIF_MASK) {
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 ep_reg_t ep_read(uint8_t rhport, uint8_t ep_num)
static void intr_enable(uint8_t rhport)
static void ep_clear(uint8_t rhport, uint8_t ep_num, ep_reg_t val)
static void intr_clear(uint8_t rhport)
static void process_bus_reset(uint8_t rhport)
struct TU_ATTR_PACKED endpoint_state_t
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
void dcd_int_handler(uint8_t rhport)
static void ep_write(uint8_t rhport, uint8_t ep_num, ep_reg_t val)
void dcd_disconnect(uint8_t rhport)
static void process_tokdne(uint8_t rhport)
void dcd_edpt_close_all(uint8_t rhport)
void dcd_int_disable(uint8_t rhport)
static int intr_is_enabled(uint8_t rhport)
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
TU_VERIFY_STATIC(sizeof(buffer_descriptor_t)==8, "size is not correct")
static void process_stall(uint8_t rhport)
void dcd_connect(uint8_t rhport)
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
static void intr_disable(uint8_t rhport)
static void prepare_next_setup_packet(uint8_t rhport)
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
struct TU_ATTR_PACKED buffer_descriptor_t
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
static void ep_set(uint8_t rhport, uint8_t ep_num, ep_reg_t val)
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) volatile
static void process_bus_sleep(uint8_t rhport)
void dcd_int_enable(uint8_t rhport)
void dcd_remote_wakeup(uint8_t rhport)
static void process_bus_resume(uint8_t rhport)
void dcd_sof_enable(uint8_t rhport, bool en)
AUDIO Channel Cluster Descriptor (4.1)
uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]
uint8_t bmAttributes
See: audio_clock_source_attribute_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)