Lines Matching +full:interrupt +full:- +full:endpoint
4 * SPDX-License-Identifier: Apache-2.0
32 /* The endpoint size stored in USB.PCKSIZE.SIZE */
76 /* Handles interrupts on an endpoint */
80 UsbDevice *regs = ®S->DEVICE; in usb_sam0_ep_isr()
81 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep]; in usb_sam0_ep_isr() local
82 uint32_t intflag = endpoint->EPINTFLAG.reg; in usb_sam0_ep_isr()
84 endpoint->EPINTFLAG.reg = intflag; in usb_sam0_ep_isr()
88 data->ep_cb[0][ep](ep, USB_DC_EP_SETUP); in usb_sam0_ep_isr()
93 data->ep_cb[0][ep](ep, USB_DC_EP_DATA_OUT); in usb_sam0_ep_isr()
98 data->ep_cb[1][ep](ep | USB_SAM0_IN_EP, USB_DC_EP_DATA_IN); in usb_sam0_ep_isr()
100 if (data->addr != 0U) { in usb_sam0_ep_isr()
105 regs->DADD.reg = data->addr; in usb_sam0_ep_isr()
106 data->addr = 0U; in usb_sam0_ep_isr()
111 /* Top level interrupt handler */
115 UsbDevice *regs = ®S->DEVICE; in usb_sam0_isr()
116 uint32_t intflag = regs->INTFLAG.reg; in usb_sam0_isr()
117 uint32_t epint = regs->EPINTSMRY.reg; in usb_sam0_isr()
121 regs->INTFLAG.reg = intflag; in usb_sam0_isr()
124 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[0]; in usb_sam0_isr() local
127 * when it receives the EORST. Re-enable interrupts. in usb_sam0_isr()
129 endpoint->EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | in usb_sam0_isr()
133 data->cb(USB_DC_RESET, NULL); in usb_sam0_isr()
136 /* Dispatch the endpoint interrupts */ in usb_sam0_isr()
138 /* Scan bit-by-bit as the Cortex-M0 doesn't have ffs */ in usb_sam0_isr()
149 UsbDevice *regs = ®S->DEVICE; in usb_sam0_wait_syncbusy()
151 while (regs->SYNCBUSY.reg != 0) { in usb_sam0_wait_syncbusy()
155 /* Load the pad calibration from the built-in fuses */
158 UsbDevice *regs = ®S->DEVICE; in usb_sam0_load_padcal()
169 ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); in usb_sam0_load_padcal()
176 regs->PADCAL.bit.TRANSN = pad_transn; in usb_sam0_load_padcal()
184 ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); in usb_sam0_load_padcal()
191 regs->PADCAL.bit.TRANSP = pad_transp; in usb_sam0_load_padcal()
199 ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); in usb_sam0_load_padcal()
206 regs->PADCAL.bit.TRIM = pad_trim; in usb_sam0_load_padcal()
220 UsbDevice *regs = ®S->DEVICE; in usb_dc_attach()
226 MCLK->APBBMASK.bit.USB_ = 1; in usb_dc_attach()
228 /* Enable the GCLK - use 48 MHz source */ in usb_dc_attach()
229 GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN(2) in usb_dc_attach()
232 while (GCLK->SYNCBUSY.reg) { in usb_dc_attach()
236 PM->APBBMASK.bit.USB_ = 1; in usb_dc_attach()
239 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_USB | GCLK_CLKCTRL_GEN_GCLK0 | in usb_dc_attach()
242 while (GCLK->STATUS.bit.SYNCBUSY) { in usb_dc_attach()
247 regs->CTRLA.bit.SWRST = 1; in usb_dc_attach()
253 regs->QOSCTRL.bit.CQOS = 2; in usb_dc_attach()
254 regs->QOSCTRL.bit.DQOS = 2; in usb_dc_attach()
263 regs->CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_RUNSTDBY; in usb_dc_attach()
264 regs->CTRLB.reg = USB_DEVICE_CTRLB_SPDCONF_HS; in usb_dc_attach()
266 (void)memset(data->descriptors, 0, sizeof(data->descriptors)); in usb_dc_attach()
267 regs->DESCADD.reg = (uintptr_t)&data->descriptors[0]; in usb_dc_attach()
269 regs->INTENSET.reg = USB_DEVICE_INTENSET_EORST; in usb_dc_attach()
271 /* Connect and enable the interrupt */ in usb_dc_attach()
286 regs->CTRLA.bit.ENABLE = 1; in usb_dc_attach()
288 regs->CTRLB.bit.DETACH = 0; in usb_dc_attach()
300 for (int i = 0; i < ARRAY_SIZE(data->descriptors); i++) { in usb_dc_release_buffers()
301 for (int j = 0; j < ARRAY_SIZE(data->descriptors[0].DeviceDescBank); j++) { in usb_dc_release_buffers()
302 bank = &data->descriptors[i].DeviceDescBank[j]; in usb_dc_release_buffers()
303 buf = (void *)bank->ADDR.reg; in usb_dc_release_buffers()
312 bank->ADDR.reg = (uintptr_t) NULL; in usb_dc_release_buffers()
321 UsbDevice *regs = ®S->DEVICE; in usb_dc_detach()
323 regs->CTRLB.bit.DETACH = 1; in usb_dc_detach()
331 /* Remove the interrupt and reset the device */
334 UsbDevice *regs = ®S->DEVICE; in usb_dc_reset()
338 regs->CTRLA.bit.SWRST = 1; in usb_dc_reset()
351 data->addr = addr | USB_DEVICE_DADD_ADDEN; in usb_dc_set_address()
360 data->cb = cb; in usb_dc_set_status_callback()
365 uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr); in usb_dc_ep_check_cap()
367 if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) { in usb_dc_ep_check_cap()
368 LOG_ERR("invalid endpoint configuration"); in usb_dc_ep_check_cap()
369 return -1; in usb_dc_ep_check_cap()
373 LOG_ERR("endpoint index/address too high"); in usb_dc_ep_check_cap()
374 return -1; in usb_dc_ep_check_cap()
383 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_configure()
384 uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr); in usb_dc_ep_configure()
385 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_configure() local
386 UsbDeviceDescriptor *desc = &data->descriptors[ep_idx]; in usb_dc_ep_configure()
390 int size = -1; in usb_dc_ep_configure()
394 switch (cfg->ep_type) { in usb_dc_ep_configure()
408 return -EINVAL; in usb_dc_ep_configure()
411 /* Map the endpoint size to native size */ in usb_dc_ep_configure()
413 if (usb_sam0_pcksize_bytes[i] == cfg->ep_mps) { in usb_dc_ep_configure()
420 return -EINVAL; in usb_dc_ep_configure()
423 if (USB_EP_DIR_IS_IN(cfg->ep_addr)) { in usb_dc_ep_configure()
424 bank = &desc->DeviceDescBank[1]; in usb_dc_ep_configure()
426 bank = &desc->DeviceDescBank[0]; in usb_dc_ep_configure()
429 buf = (void *)bank->ADDR.reg; in usb_dc_ep_configure()
431 if (bank->PCKSIZE.bit.SIZE != size || buf == NULL) { in usb_dc_ep_configure()
435 buf = k_malloc(cfg->ep_mps); in usb_dc_ep_configure()
437 return -ENOMEM; in usb_dc_ep_configure()
439 bank->PCKSIZE.bit.SIZE = size; in usb_dc_ep_configure()
440 bank->ADDR.reg = (uintptr_t)buf; in usb_dc_ep_configure()
443 if (USB_EP_DIR_IS_IN(cfg->ep_addr)) { in usb_dc_ep_configure()
444 endpoint->EPCFG.bit.EPTYPE1 = type; in usb_dc_ep_configure()
445 endpoint->EPSTATUSCLR.bit.BK1RDY = 1; in usb_dc_ep_configure()
447 endpoint->EPCFG.bit.EPTYPE0 = type; in usb_dc_ep_configure()
448 endpoint->EPSTATUSCLR.bit.BK0RDY = 1; in usb_dc_ep_configure()
456 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_set_stall()
459 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_set_stall() local
462 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_set_stall()
463 return -1; in usb_dc_ep_set_stall()
467 endpoint->EPSTATUSSET.bit.STALLRQ1 = 1; in usb_dc_ep_set_stall()
469 endpoint->EPSTATUSSET.bit.STALLRQ0 = 1; in usb_dc_ep_set_stall()
477 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_clear_stall()
480 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_clear_stall() local
483 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_clear_stall()
484 return -1; in usb_dc_ep_clear_stall()
488 endpoint->EPSTATUSCLR.bit.STALLRQ1 = 1; in usb_dc_ep_clear_stall()
490 endpoint->EPSTATUSCLR.bit.STALLRQ0 = 1; in usb_dc_ep_clear_stall()
498 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_is_stalled()
501 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_is_stalled() local
504 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_is_stalled()
505 return -1; in usb_dc_ep_is_stalled()
510 return -1; in usb_dc_ep_is_stalled()
514 *stalled = endpoint->EPSTATUS.bit.STALLRQ1; in usb_dc_ep_is_stalled()
516 *stalled = endpoint->EPSTATUS.bit.STALLRQ0; in usb_dc_ep_is_stalled()
522 /* Halt the selected endpoint */
528 /* Flush the selected endpoint */
534 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_flush()
535 return -1; in usb_dc_ep_flush()
544 /* Enable an endpoint and the endpoint interrupts */
547 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_enable()
550 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_enable() local
553 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_enable()
554 return -EINVAL; in usb_dc_ep_enable()
558 endpoint->EPSTATUSCLR.bit.BK1RDY = 1; in usb_dc_ep_enable()
560 endpoint->EPSTATUSCLR.bit.BK0RDY = 1; in usb_dc_ep_enable()
563 endpoint->EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | in usb_dc_ep_enable()
570 /* Disable the selected endpoint */
573 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_disable()
575 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_disable() local
578 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_disable()
579 return -EINVAL; in usb_dc_ep_disable()
582 endpoint->EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0 in usb_dc_ep_disable()
589 /* Write a single payload to the IN buffer on the endpoint */
593 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_write()
595 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_write() local
596 UsbDeviceDescriptor *desc = &data->descriptors[ep_idx]; in usb_dc_ep_write()
597 uint32_t addr = desc->DeviceDescBank[1].ADDR.reg; in usb_dc_ep_write()
599 desc->DeviceDescBank[1].PCKSIZE.bit.SIZE]; in usb_dc_ep_write()
602 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_write()
603 return -1; in usb_dc_ep_write()
606 if (endpoint->EPSTATUS.bit.BK1RDY) { in usb_dc_ep_write()
608 return -EAGAIN; in usb_dc_ep_write()
614 * multi-packet and automatic zero-length packet features as in usb_dc_ep_write()
618 desc->DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; in usb_dc_ep_write()
619 desc->DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = len; in usb_dc_ep_write()
620 endpoint->EPINTFLAG.reg = in usb_dc_ep_write()
622 endpoint->EPSTATUSSET.bit.BK1RDY = 1; in usb_dc_ep_write()
631 /* Read data from an OUT endpoint */
636 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_read_ex()
638 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_read_ex() local
639 UsbDeviceDescriptor *desc = &data->descriptors[ep_idx]; in usb_dc_ep_read_ex()
640 uint32_t addr = desc->DeviceDescBank[0].ADDR.reg; in usb_dc_ep_read_ex()
641 uint32_t bytes = desc->DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT; in usb_dc_ep_read_ex()
646 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_read_ex()
647 return -1; in usb_dc_ep_read_ex()
650 if (!endpoint->EPSTATUS.bit.BK0RDY) { in usb_dc_ep_read_ex()
651 return -EAGAIN; in usb_dc_ep_read_ex()
661 data->out_at = 0U; in usb_dc_ep_read_ex()
670 remain = bytes - data->out_at; in usb_dc_ep_read_ex()
672 memcpy(buf, (uint8_t *)addr + data->out_at, take); in usb_dc_ep_read_ex()
680 endpoint->EPSTATUSCLR.bit.BK0RDY = 1; in usb_dc_ep_read_ex()
681 data->out_at = 0U; in usb_dc_ep_read_ex()
684 data->out_at += take; in usb_dc_ep_read_ex()
704 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_read_continue()
706 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_read_continue() local
709 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_read_continue()
710 return -1; in usb_dc_ep_read_continue()
713 endpoint->EPSTATUSCLR.bit.BK0RDY = 1; in usb_dc_ep_read_continue()
714 data->out_at = 0U; in usb_dc_ep_read_continue()
726 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_set_callback()
727 return -1; in usb_dc_ep_set_callback()
730 data->ep_cb[for_in ? 1 : 0][ep_idx] = cb; in usb_dc_ep_set_callback()
738 UsbDevice *regs = ®S->DEVICE; in usb_dc_ep_mps()
741 UsbDeviceDescriptor *desc = &data->descriptors[ep_idx]; in usb_dc_ep_mps()
742 UsbDeviceEndpoint *endpoint = ®s->DeviceEndpoint[ep_idx]; in usb_dc_ep_mps() local
745 LOG_ERR("endpoint index/address out of range"); in usb_dc_ep_mps()
746 return -1; in usb_dc_ep_mps()
750 /* if endpoint is not configured, this should return 0 */ in usb_dc_ep_mps()
751 if (endpoint->EPCFG.bit.EPTYPE1 == 0) { in usb_dc_ep_mps()
756 desc->DeviceDescBank[1].PCKSIZE.bit.SIZE]; in usb_dc_ep_mps()
758 /* if endpoint is not configured, this should return 0 */ in usb_dc_ep_mps()
759 if (endpoint->EPCFG.bit.EPTYPE0 == 0) { in usb_dc_ep_mps()
764 desc->DeviceDescBank[0].PCKSIZE.bit.SIZE]; in usb_dc_ep_mps()