Lines Matching +full:interrupt +full:- +full:endpoint

4  * SPDX-License-Identifier: Apache-2.0
30 * The new Atmel DFP headers provide mode-specific interrupt register field
54 BUILD_ASSERT(USB_MAXIMUM_SPEED, "low-speed is not supported");
75 PMC->CKGR_UCKR |= CKGR_UCKR_UPLLEN; in usb_dc_enable_clock()
78 while (!(PMC->PMC_SR & PMC_SR_LOCKU)) { in usb_dc_enable_clock()
83 if ((USBHS->USBHS_DEVCTRL & USBHS_DEVCTRL_SPDCONF_Msk) in usb_dc_enable_clock()
86 PMC->PMC_MCKR &= ~PMC_MCKR_UPLLDIV2; in usb_dc_enable_clock()
87 PMC->PMC_USB = PMC_USB_USBDIV(9) | PMC_USB_USBS; in usb_dc_enable_clock()
90 PMC->PMC_SCER |= PMC_SCER_USBCLK; in usb_dc_enable_clock()
98 PMC->PMC_SCER &= ~PMC_SCER_USBCLK; in usb_dc_disable_clock()
101 PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN; in usb_dc_disable_clock()
107 return (USBHS->USBHS_DEVCTRL & USBHS_DEVCTRL_DETACH) == 0; in usb_dc_is_attached()
110 /* Check if an endpoint is configured */
113 return USBHS->USBHS_DEVEPTISR[ep_idx] & USBHS_DEVEPTISR_CFGOK; in usb_dc_ep_is_configured()
116 /* Check if an endpoint is enabled */
119 return USBHS->USBHS_DEVEPT & BIT(USBHS_DEVEPT_EPEN0_Pos + ep_idx); in usb_dc_ep_is_enabled()
122 /* Reset and endpoint */
125 USBHS->USBHS_DEVEPT |= BIT(USBHS_DEVEPT_EPRST0_Pos + ep_idx); in usb_dc_ep_reset()
126 USBHS->USBHS_DEVEPT &= ~BIT(USBHS_DEVEPT_EPRST0_Pos + ep_idx); in usb_dc_ep_reset()
130 /* Enable endpoint interrupts, depending of the type and direction */
134 /* Control endpoint: enable SETUP and OUT */ in usb_dc_ep_enable_interrupts()
135 USBHS->USBHS_DEVEPTIER[ep_idx] = USBHS_DEVEPTIER_CTRL_RXSTPES; in usb_dc_ep_enable_interrupts()
136 USBHS->USBHS_DEVEPTIER[ep_idx] = USBHS_DEVEPTIER_RXOUTES; in usb_dc_ep_enable_interrupts()
137 } else if ((USBHS->USBHS_DEVEPTCFG[ep_idx] & USBHS_DEVEPTCFG_EPDIR_Msk) in usb_dc_ep_enable_interrupts()
139 /* IN direction: acknowledge FIFO empty interrupt */ in usb_dc_ep_enable_interrupts()
140 USBHS->USBHS_DEVEPTICR[ep_idx] = USBHS_DEVEPTICR_TXINIC; in usb_dc_ep_enable_interrupts()
141 USBHS->USBHS_DEVEPTIER[ep_idx] = USBHS_DEVEPTIER_TXINES; in usb_dc_ep_enable_interrupts()
144 USBHS->USBHS_DEVEPTIER[ep_idx] = USBHS_DEVEPTIER_RXOUTES; in usb_dc_ep_enable_interrupts()
148 /* Reset the endpoint FIFO pointer to the beginning of the endpoint memory */
157 /* Fetch a byte from the endpoint FIFO */
163 /* Put a byte from the endpoint FIFO */
169 /* Handle interrupts on a control endpoint */
172 uint32_t sr = USBHS->USBHS_DEVEPTISR[0] & USBHS->USBHS_DEVEPTIMR[0]; in usb_dc_ep0_isr()
173 uint32_t dev_ctrl = USBHS->USBHS_DEVCTRL; in usb_dc_ep0_isr()
186 /* Disable the interrupt */ in usb_dc_ep0_isr()
187 USBHS->USBHS_DEVEPTIDR[0] = USBHS_DEVEPTIDR_TXINEC; in usb_dc_ep0_isr()
199 USBHS->USBHS_DEVCTRL = dev_ctrl | USBHS_DEVCTRL_ADDEN; in usb_dc_ep0_isr()
204 /* Handle interrupts on a non-control endpoint */
207 uint32_t sr = USBHS->USBHS_DEVEPTISR[ep_idx] & in usb_dc_ep_isr()
208 USBHS->USBHS_DEVEPTIMR[ep_idx]; in usb_dc_ep_isr()
213 /* Acknowledge the interrupt */ in usb_dc_ep_isr()
214 USBHS->USBHS_DEVEPTICR[ep_idx] = USBHS_DEVEPTICR_RXOUTIC; in usb_dc_ep_isr()
223 /* Acknowledge the interrupt */ in usb_dc_ep_isr()
224 USBHS->USBHS_DEVEPTICR[ep_idx] = USBHS_DEVEPTICR_TXINIC; in usb_dc_ep_isr()
232 /* Top level interrupt handler */
235 uint32_t sr = USBHS->USBHS_DEVISR & USBHS->USBHS_DEVIMR; in usb_dc_isr()
237 /* End of resume interrupt */ in usb_dc_isr()
239 /* Acknowledge the interrupt */ in usb_dc_isr()
240 USBHS->USBHS_DEVICR = USBHS_DEVICR_EORSMC; in usb_dc_isr()
246 /* End of reset interrupt */ in usb_dc_isr()
248 /* Acknowledge the interrupt */ in usb_dc_isr()
249 USBHS->USBHS_DEVICR = USBHS_DEVICR_EORSTC; in usb_dc_isr()
263 * when it receives the EORST. Re-enable interrupts. in usb_dc_isr()
268 /* Free all endpoint memory */ in usb_dc_isr()
271 USBHS->USBHS_DEVEPTCFG[idx] &= ~USBHS_DEVEPTCFG_ALLOC; in usb_dc_isr()
278 /* Suspend interrupt */ in usb_dc_isr()
280 /* Acknowledge the interrupt */ in usb_dc_isr()
281 USBHS->USBHS_DEVICR = USBHS_DEVICR_SUSPC; in usb_dc_isr()
288 /* SOF interrupt */ in usb_dc_isr()
290 /* Acknowledge the interrupt */ in usb_dc_isr()
291 USBHS->USBHS_DEVICR = USBHS_DEVICR_SOFC; in usb_dc_isr()
298 /* EP0 endpoint interrupt */ in usb_dc_isr()
303 /* Other endpoints interrupt */ in usb_dc_isr()
322 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD | USBHS_CTRL_USBE | in usb_dc_attach()
329 /* high-speed */ in usb_dc_attach()
332 /* full-speed */ in usb_dc_attach()
335 USBHS->USBHS_DEVCTRL = regval; in usb_dc_attach()
341 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD | USBHS_CTRL_USBE; in usb_dc_attach()
344 USBHS->USBHS_DEVIER = USBHS_DEVIER_EORSMES; in usb_dc_attach()
345 USBHS->USBHS_DEVIER = USBHS_DEVIER_EORSTES; in usb_dc_attach()
346 USBHS->USBHS_DEVIER = USBHS_DEVIER_SUSPES; in usb_dc_attach()
348 USBHS->USBHS_DEVIER = USBHS_DEVIER_SOFES; in usb_dc_attach()
351 /* Connect and enable the interrupt */ in usb_dc_attach()
357 USBHS->USBHS_DEVCTRL &= ~USBHS_DEVCTRL_DETACH; in usb_dc_attach()
369 USBHS->USBHS_DEVCTRL |= USBHS_DEVCTRL_DETACH; in usb_dc_detach()
375 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD | USBHS_CTRL_FRZCLK; in usb_dc_detach()
381 /* Disable interrupt */ in usb_dc_detach()
392 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD | USBHS_CTRL_FRZCLK; in usb_dc_reset()
408 USBHS->USBHS_DEVCTRL &= ~(USBHS_DEVCTRL_UADD_Msk | USBHS_DEVCTRL_ADDEN); in usb_dc_set_address()
409 USBHS->USBHS_DEVCTRL |= USBHS_DEVCTRL_UADD(addr); in usb_dc_set_address()
423 /* Check endpoint capabilities */
426 uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr); in usb_dc_ep_check_cap()
429 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_check_cap()
430 return -1; in usb_dc_ep_check_cap()
434 if (cfg->ep_type != USB_DC_EP_CONTROL) { in usb_dc_ep_check_cap()
435 LOG_ERR("pre-selected as control endpoint"); in usb_dc_ep_check_cap()
436 return -1; in usb_dc_ep_check_cap()
439 if (USB_EP_GET_DIR(cfg->ep_addr) != USB_EP_DIR_IN) { in usb_dc_ep_check_cap()
440 LOG_INF("pre-selected as IN endpoint"); in usb_dc_ep_check_cap()
441 return -1; in usb_dc_ep_check_cap()
444 if (USB_EP_GET_DIR(cfg->ep_addr) != USB_EP_DIR_OUT) { in usb_dc_ep_check_cap()
445 LOG_INF("pre-selected as OUT endpoint"); in usb_dc_ep_check_cap()
446 return -1; in usb_dc_ep_check_cap()
450 if (cfg->ep_mps < 1 || cfg->ep_mps > 1024 || in usb_dc_ep_check_cap()
451 (cfg->ep_type == USB_DC_EP_CONTROL && cfg->ep_mps > 64)) { in usb_dc_ep_check_cap()
452 LOG_ERR("invalid endpoint size"); in usb_dc_ep_check_cap()
453 return -1; in usb_dc_ep_check_cap()
459 /* Configure endpoint */
462 uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr); in usb_dc_ep_configure()
469 return -EINVAL; in usb_dc_ep_configure()
474 return -ENODEV; in usb_dc_ep_configure()
478 LOG_WRN("endpoint already configured & enabled 0x%x", ep_idx); in usb_dc_ep_configure()
479 return -EBUSY; in usb_dc_ep_configure()
482 LOG_INF("Configure ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps, in usb_dc_ep_configure()
483 cfg->ep_type); in usb_dc_ep_configure()
485 /* Reset the endpoint */ in usb_dc_ep_configure()
487 /* Initialize the endpoint FIFO */ in usb_dc_ep_configure()
490 /* Map the endpoint type */ in usb_dc_ep_configure()
491 switch (cfg->ep_type) { in usb_dc_ep_configure()
505 return -EINVAL; in usb_dc_ep_configure()
508 /* Map the endpoint direction */ in usb_dc_ep_configure()
509 if (USB_EP_DIR_IS_OUT(cfg->ep_addr) || in usb_dc_ep_configure()
510 cfg->ep_type == USB_DC_EP_CONTROL) { in usb_dc_ep_configure()
517 * Map the endpoint size to the buffer size. Only power of 2 buffer in usb_dc_ep_configure()
520 log2ceil_mps = 32 - __builtin_clz((MAX(cfg->ep_mps, 8) << 1) - 1) - 1; in usb_dc_ep_configure()
521 regval |= USBHS_DEVEPTCFG_EPSIZE(log2ceil_mps - 3); in usb_dc_ep_configure()
522 dev_data.ep_data[ep_idx].mps = cfg->ep_mps; in usb_dc_ep_configure()
525 if (cfg->ep_type == USB_DC_EP_ISOCHRONOUS) { in usb_dc_ep_configure()
531 /* Configure the endpoint */ in usb_dc_ep_configure()
532 USBHS->USBHS_DEVEPTCFG[ep_idx] = regval; in usb_dc_ep_configure()
541 for (int i = NUM_OF_EP_MAX - 1; i > ep_idx; i--) { in usb_dc_ep_configure()
550 USBHS->USBHS_DEVEPTCFG[i] &= ~USBHS_DEVEPTCFG_ALLOC; in usb_dc_ep_configure()
557 USBHS->USBHS_DEVEPTCFG[i] |= USBHS_DEVEPTCFG_ALLOC; in usb_dc_ep_configure()
564 /* Check that the endpoint is correctly configured */ in usb_dc_ep_configure()
566 LOG_ERR("endpoint configuration failed"); in usb_dc_ep_configure()
567 return -EINVAL; in usb_dc_ep_configure()
573 /* Set stall condition for the selected endpoint */
579 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_set_stall()
580 return -EINVAL; in usb_dc_ep_set_stall()
583 USBHS->USBHS_DEVEPTIER[ep_idx] = USBHS_DEVEPTIER_CTRL_STALLRQS; in usb_dc_ep_set_stall()
589 /* Clear stall condition for the selected endpoint */
595 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_clear_stall()
596 return -EINVAL; in usb_dc_ep_clear_stall()
599 USBHS->USBHS_DEVEPTIDR[ep_idx] = USBHS_DEVEPTIDR_CTRL_STALLRQC; in usb_dc_ep_clear_stall()
605 /* Check if the selected endpoint is stalled */
611 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_is_stalled()
612 return -EINVAL; in usb_dc_ep_is_stalled()
616 return -EINVAL; in usb_dc_ep_is_stalled()
619 *stalled = (USBHS->USBHS_DEVEPTIMR[ep_idx] & in usb_dc_ep_is_stalled()
626 /* Halt the selected endpoint */
632 /* Enable the selected endpoint */
638 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_enable()
639 return -EINVAL; in usb_dc_ep_enable()
643 LOG_ERR("endpoint not configured"); in usb_dc_ep_enable()
644 return -ENODEV; in usb_dc_ep_enable()
647 /* Enable endpoint */ in usb_dc_ep_enable()
648 USBHS->USBHS_DEVEPT |= BIT(USBHS_DEVEPT_EPEN0_Pos + ep_idx); in usb_dc_ep_enable()
650 /* Enable endpoint interrupts */ in usb_dc_ep_enable()
651 USBHS->USBHS_DEVIER = BIT(USBHS_DEVIER_PEP_0_Pos + ep_idx); in usb_dc_ep_enable()
653 /* Enable SETUP, IN or OUT endpoint interrupts */ in usb_dc_ep_enable()
661 /* Disable the selected endpoint */
667 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_disable()
668 return -EINVAL; in usb_dc_ep_disable()
671 /* Disable endpoint interrupt */ in usb_dc_ep_disable()
672 USBHS->USBHS_DEVIDR = BIT(USBHS_DEVIDR_PEP_0_Pos + ep_idx); in usb_dc_ep_disable()
674 /* Disable endpoint and SETUP, IN or OUT interrupts */ in usb_dc_ep_disable()
675 USBHS->USBHS_DEVEPT &= ~BIT(USBHS_DEVEPT_EPEN0_Pos + ep_idx); in usb_dc_ep_disable()
682 /* Flush the selected endpoint */
688 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_flush()
689 return -EINVAL; in usb_dc_ep_flush()
693 LOG_ERR("endpoint not enabled"); in usb_dc_ep_flush()
694 return -ENODEV; in usb_dc_ep_flush()
697 /* Disable the IN interrupt */ in usb_dc_ep_flush()
698 USBHS->USBHS_DEVEPTIDR[ep_idx] = USBHS_DEVEPTIDR_TXINEC; in usb_dc_ep_flush()
701 if (USBHS->USBHS_DEVEPTISR[ep_idx] & USBHS_DEVEPTISR_NBUSYBK_Msk) { in usb_dc_ep_flush()
702 USBHS->USBHS_DEVEPTIER[ep_idx] = USBHS_DEVEPTIER_KILLBKS; in usb_dc_ep_flush()
704 while (USBHS->USBHS_DEVEPTIMR[ep_idx] & in usb_dc_ep_flush()
710 /* Reset the endpoint */ in usb_dc_ep_flush()
713 /* Re-enable interrupts */ in usb_dc_ep_flush()
720 /* Write data to the specified endpoint */
727 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_write()
728 return -EINVAL; in usb_dc_ep_write()
732 LOG_ERR("endpoint not enabled"); in usb_dc_ep_write()
733 return -ENODEV; in usb_dc_ep_write()
737 LOG_ERR("wrong endpoint direction"); in usb_dc_ep_write()
738 return -EINVAL; in usb_dc_ep_write()
741 if ((USBHS->USBHS_DEVEPTIMR[ep_idx] & USBHS_DEVEPTIMR_CTRL_STALLRQ) in usb_dc_ep_write()
743 LOG_WRN("endpoint is stalled"); in usb_dc_ep_write()
744 return -EBUSY; in usb_dc_ep_write()
756 * Control endpoint: clear the interrupt flag to send the data, in usb_dc_ep_write()
757 * and re-enable the interrupts to trigger an interrupt at the in usb_dc_ep_write()
760 USBHS->USBHS_DEVEPTICR[ep_idx] = USBHS_DEVEPTICR_TXINIC; in usb_dc_ep_write()
761 USBHS->USBHS_DEVEPTIER[ep_idx] = USBHS_DEVEPTIER_TXINES; in usb_dc_ep_write()
764 * Other endpoint types: clear the FIFO control flag to send in usb_dc_ep_write()
767 USBHS->USBHS_DEVEPTIDR[ep_idx] = USBHS_DEVEPTIDR_FIFOCONC; in usb_dc_ep_write()
778 /* Read data from the specified endpoint */
798 if (!(USBHS->USBHS_DEVEPTISR[ep_idx] & USBHS_DEVEPTISR_RWALL)) { in usb_dc_ep_read()
806 /* Set callback function for the specified endpoint */
812 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_set_callback()
813 return -EINVAL; in usb_dc_ep_set_callback()
826 /* Read data from the specified endpoint */
831 uint32_t data_len = (USBHS->USBHS_DEVEPTISR[ep_idx] & in usb_dc_ep_read_wait()
835 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_read_wait()
836 return -EINVAL; in usb_dc_ep_read_wait()
840 LOG_ERR("endpoint not enabled"); in usb_dc_ep_read_wait()
841 return -ENODEV; in usb_dc_ep_read_wait()
845 LOG_ERR("wrong endpoint direction"); in usb_dc_ep_read_wait()
846 return -EINVAL; in usb_dc_ep_read_wait()
849 if ((USBHS->USBHS_DEVEPTIMR[ep_idx] & USBHS_DEVEPTIMR_CTRL_STALLRQ) in usb_dc_ep_read_wait()
851 LOG_WRN("endpoint is stalled"); in usb_dc_ep_read_wait()
852 return -EBUSY; in usb_dc_ep_read_wait()
885 /* Continue reading data from the endpoint */
891 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_read_continue()
892 return -EINVAL; in usb_dc_ep_read_continue()
896 LOG_ERR("endpoint not enabled"); in usb_dc_ep_read_continue()
897 return -ENODEV; in usb_dc_ep_read_continue()
901 LOG_ERR("wrong endpoint direction"); in usb_dc_ep_read_continue()
902 return -EINVAL; in usb_dc_ep_read_continue()
907 * Control endpoint: clear the interrupt flag to send the data. in usb_dc_ep_read_continue()
911 USBHS->USBHS_DEVEPTICR[ep_idx] = USBHS_DEVEPTICR_RXOUTIC; in usb_dc_ep_read_continue()
912 USBHS->USBHS_DEVEPTICR[ep_idx] = USBHS_DEVEPTICR_CTRL_RXSTPIC; in usb_dc_ep_read_continue()
915 * Other endpoint types: clear the FIFO control flag to in usb_dc_ep_read_continue()
918 USBHS->USBHS_DEVEPTIDR[ep_idx] = USBHS_DEVEPTIDR_FIFOCONC; in usb_dc_ep_read_continue()
925 /* Endpoint max packet size (mps) */
931 LOG_ERR("wrong endpoint index/address"); in usb_dc_ep_mps()
932 return -EINVAL; in usb_dc_ep_mps()