Lines Matching +full:underflow +full:- +full:control

4  * SPDX-License-Identifier: Apache-2.0
28 * @brief USB Driver Control Endpoint Finite State Machine states
30 * FSM states to keep tracking of control endpoint hidden states.
122 if (regs->UESTA[ep_idx] != dev_ep_sta_dbg[0][ep_idx]) { in usb_dc_sam_usbc_isr_sta_dbg()
123 dev_ep_sta_dbg[0][ep_idx] = regs->UESTA[ep_idx]; in usb_dc_sam_usbc_isr_sta_dbg()
128 regs->UDCON, regs->UDINT, regs->UDINTE, in usb_dc_sam_usbc_isr_sta_dbg()
129 regs->UECON[ep_idx], regs->UESTA[ep_idx], in usb_dc_sam_usbc_isr_sta_dbg()
136 regs->UDCON, regs->UDINT, regs->UDINTE, in usb_dc_sam_usbc_isr_sta_dbg()
137 regs->UECON[ep_idx], regs->UESTA[ep_idx]); in usb_dc_sam_usbc_isr_sta_dbg()
155 return USBC->USBCON & USBC_USBCON_FRZCLK; in usb_dc_sam_usbc_is_frozen_clk()
160 USBC->USBCON |= USBC_USBCON_FRZCLK; in usb_dc_sam_usbc_freeze_clk()
165 USBC->USBCON &= ~USBC_USBCON_FRZCLK; in usb_dc_sam_usbc_unfreeze_clk()
167 while (USBC->USBCON & USBC_USBCON_FRZCLK) { in usb_dc_sam_usbc_unfreeze_clk()
177 (regs->UESTA[ep_idx] & USBC_UESTA0_CURRBK(1)) > 0) { in usb_dc_sam_usbc_ep_curr_bank()
186 return (regs->UDCON & USBC_UDCON_DETACH) == 0; in usb_dc_is_attached()
191 int reg = regs->UERST; in usb_dc_ep_is_enabled()
204 return -EINVAL; in usb_dc_sam_usbc_ep_alloc_buf()
227 return -ENOMEM; in usb_dc_sam_usbc_ep_alloc_buf()
230 for (int i = NUM_OF_EP_MAX - 1; i >= ep_idx; i--) { in usb_dc_sam_usbc_ep_alloc_buf()
257 ep_desc_bk->ep_pipe_addr = ((uint8_t *) USBC_RAM_ADDR) in usb_dc_sam_usbc_ep_alloc_buf()
259 ep_desc_bk->sizes = 0; in usb_dc_sam_usbc_ep_alloc_buf()
260 ep_desc_bk->bk_ctrl_stat = 0; in usb_dc_sam_usbc_ep_alloc_buf()
261 ep_desc_bk->ep_ctrl_stat = 0; in usb_dc_sam_usbc_ep_alloc_buf()
271 ep_desc_bk->ep_pipe_addr = ((uint8_t *) USBC_RAM_ADDR) in usb_dc_sam_usbc_ep_alloc_buf()
276 ep_desc_bk->sizes = 0; in usb_dc_sam_usbc_ep_alloc_buf()
277 ep_desc_bk->bk_ctrl_stat = 0; in usb_dc_sam_usbc_ep_alloc_buf()
278 ep_desc_bk->ep_ctrl_stat = 0; in usb_dc_sam_usbc_ep_alloc_buf()
298 /* Control endpoint: enable SETUP */ in usb_dc_ep_enable_interrupts()
299 regs->UECONSET[ep_idx] = USBC_UECON0SET_RXSTPES; in usb_dc_ep_enable_interrupts()
300 } else if (regs->UECFG[ep_idx] & USBC_UECFG0_EPDIR_IN) { in usb_dc_ep_enable_interrupts()
301 /* TX - IN direction: acknowledge FIFO empty interrupt */ in usb_dc_ep_enable_interrupts()
302 regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_TXINIC; in usb_dc_ep_enable_interrupts()
303 regs->UECONSET[ep_idx] = USBC_UECON0SET_TXINES; in usb_dc_ep_enable_interrupts()
305 /* RX - OUT direction */ in usb_dc_ep_enable_interrupts()
306 regs->UECONSET[ep_idx] = USBC_UECON0SET_RXOUTES; in usb_dc_ep_enable_interrupts()
312 uint32_t sr = regs->UESTA[ep_idx]; in usb_dc_ep_isr_sta()
317 regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_RAMACERIC; in usb_dc_ep_isr_sta()
324 LOG_INF("STP - INIT"); in usb_dc_ctrl_init()
332 regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC; in usb_dc_ctrl_init()
335 regs->UESTACLR[0] = USBC_UESTA0CLR_RXOUTIC; in usb_dc_ctrl_init()
336 regs->UECONCLR[0] = USBC_UECON0CLR_RXOUTEC in usb_dc_ctrl_init()
345 LOG_INF("STP - STALL"); in usb_dc_ctrl_stall_data()
349 regs->UECONSET[0] = USBC_UECON0SET_STALLRQS; in usb_dc_ctrl_stall_data()
350 regs->UESTACLR[0] = flags; in usb_dc_ctrl_stall_data()
357 LOG_INF("STP - ZLP IN"); in usb_dc_ctrl_send_zlp_in()
361 /* Validate and send empty IN packet on control endpoint */ in usb_dc_ctrl_send_zlp_in()
367 regs->UESTACLR[0] = USBC_UESTA0CLR_TXINIC; in usb_dc_ctrl_send_zlp_in()
368 regs->UECONSET[0] = USBC_UECON0SET_TXINES; in usb_dc_ctrl_send_zlp_in()
371 regs->UESTACLR[0] = USBC_UESTA0CLR_NAKOUTIC; in usb_dc_ctrl_send_zlp_in()
372 regs->UECONSET[0] = USBC_UECON0SET_NAKOUTES; in usb_dc_ctrl_send_zlp_in()
380 LOG_INF("STP - ZLP OUT"); in usb_dc_ctrl_send_zlp_out()
386 regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC; in usb_dc_ctrl_send_zlp_out()
387 regs->UECONSET[0] = USBC_UECON0SET_NAKINES; in usb_dc_ctrl_send_zlp_out()
393 uint32_t sr = regs->UESTA[0]; in usb_dc_ep0_isr()
394 uint32_t dev_ctrl = regs->UDCON; in usb_dc_ep0_isr()
398 regs->UECONCLR[0] = USBC_UECON0CLR_NAKINEC; in usb_dc_ep0_isr()
399 regs->UECONCLR[0] = USBC_UECON0CLR_NAKOUTEC; in usb_dc_ep0_isr()
404 /* Reinitializes control endpoint management */ in usb_dc_ep0_isr()
421 * - Data IN Phase aborted, in usb_dc_ep0_isr()
422 * - or last Data IN Phase hidden by ZLP OUT in usb_dc_ep0_isr()
424 * - or ZLP OUT received normally. in usb_dc_ep0_isr()
443 (regs->UECON[0] & USBC_UECON0_TXINE)) { in usb_dc_ep0_isr()
447 regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC; in usb_dc_ep0_isr()
456 regs->UDCON |= USBC_UDCON_ADDEN; in usb_dc_ep0_isr()
473 regs->UESTACLR[0] = USBC_UESTA0CLR_NAKOUTIC; in usb_dc_ep0_isr()
475 if (regs->UESTA[0] & USBC_UESTA0_TXINI) { in usb_dc_ep0_isr()
484 regs->UECONSET[0] = USBC_UECON0SET_STALLRQS; in usb_dc_ep0_isr()
493 regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC; in usb_dc_ep0_isr()
495 if (regs->UESTA[0] & USBC_UESTA0_RXOUTI) { in usb_dc_ep0_isr()
496 /** underflow ignored if OUT data is received */ in usb_dc_ep0_isr()
509 regs->UECONSET[0] = USBC_UECON0SET_STALLRQS; in usb_dc_ep0_isr()
519 uint32_t sr = regs->UESTA[ep_idx]; in usb_dc_ep_isr()
526 regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_RXOUTIC; in usb_dc_ep_isr()
534 regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_TXINIC; in usb_dc_ep_isr()
543 uint32_t sr = regs->UDINT; in usb_dc_sam_usbc_isr()
549 regs->UDINTCLR = USBC_UDINTCLR_SOFC; in usb_dc_sam_usbc_isr()
579 regs->UDINTCLR = USBC_UDINTCLR_EORSMC; in usb_dc_sam_usbc_isr()
590 regs->UDINTCLR = USBC_UDINTCLR_EORSTC; in usb_dc_sam_usbc_isr()
594 * when it receives the EORST. Re-enable interrupts. in usb_dc_sam_usbc_isr()
608 if (sr & USBC_UDINT_SUSP && regs->UDINTE & USBC_UDINTE_SUSPE) { in usb_dc_sam_usbc_isr()
611 regs->UDINTCLR = USBC_UDINTCLR_SUSPC; in usb_dc_sam_usbc_isr()
620 while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) { in usb_dc_sam_usbc_isr()
624 regs->UDINTECLR = USBC_UDINTECLR_SUSPEC; in usb_dc_sam_usbc_isr()
625 regs->UDINTCLR = USBC_UDINTCLR_WAKEUPC; in usb_dc_sam_usbc_isr()
626 regs->UDINTESET = USBC_UDINTESET_WAKEUPES; in usb_dc_sam_usbc_isr()
636 if (sr & USBC_UDINT_WAKEUP && regs->UDINTE & USBC_UDINTE_WAKEUPE) { in usb_dc_sam_usbc_isr()
639 regs->UDINTCLR = USBC_UDINTCLR_WAKEUPC; in usb_dc_sam_usbc_isr()
648 while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) { in usb_dc_sam_usbc_isr()
652 regs->UDINTECLR = USBC_UDINTECLR_WAKEUPEC; in usb_dc_sam_usbc_isr()
653 regs->UDINTCLR = USBC_UDINTCLR_SUSPC; in usb_dc_sam_usbc_isr()
654 regs->UDINTESET = USBC_UDINTESET_SUSPES; in usb_dc_sam_usbc_isr()
668 /* Enable USBC asynchronous wake-up source */ in usb_dc_attach()
669 PM->AWEN |= BIT(PM_AWEN_USBC); in usb_dc_attach()
674 pmcon = BPM->PMCON | BPM_PMCON_FASTWKUP; in usb_dc_attach()
675 BPM->UNLOCK = BPM_UNLOCK_KEY(0xAAu) in usb_dc_attach()
676 | BPM_UNLOCK_ADDR((uint32_t)&BPM->PMCON - (uint32_t)BPM); in usb_dc_attach()
677 BPM->PMCON = pmcon; in usb_dc_attach()
686 SCIF->GCCTRL[GEN_CLK_USBC] = 0; in usb_dc_attach()
687 SCIF->GCCTRL[GEN_CLK_USBC] = SCIF_GCCTRL_OSCSEL(SCIF_GC_USES_CLK_HSB) in usb_dc_attach()
691 while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) { in usb_dc_attach()
701 regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_USBE; in usb_dc_attach()
705 regs->UDESC = USBC_UDESC_UDESCA((int) &dev_desc); in usb_dc_attach()
724 regs->UDCON = regval; in usb_dc_attach()
731 * WAKEUP Wake-Up Interrupt in usb_dc_attach()
733 regs->UDINTCLR = USBC_UDINTCLR_EORSMC in usb_dc_attach()
739 regs->UDINTESET = USBC_UDINTESET_EORSMES in usb_dc_attach()
745 regs->UDINTESET |= USBC_UDINTESET_SOFES; in usb_dc_attach()
754 regs->UDCON &= ~USBC_UDCON_DETACH; in usb_dc_attach()
760 regs->UDINTSET = USBC_UDINTSET_SUSPS; in usb_dc_attach()
772 regs->UDCON |= USBC_UDCON_DETACH; in usb_dc_detach()
775 regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_FRZCLK; in usb_dc_detach()
778 SCIF->GCCTRL[GEN_CLK_USBC] = 0; in usb_dc_detach()
780 /* Disable USBC asynchronous wake-up source */ in usb_dc_detach()
781 PM->AWEN &= ~(BIT(PM_AWEN_USBC)); in usb_dc_detach()
801 regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_FRZCLK; in usb_dc_reset()
819 regs->UDCON &= ~USBC_UDCON_ADDEN; in usb_dc_set_address()
820 regs->UDCON |= USBC_UDCON_UADD(addr); in usb_dc_set_address()
828 regs->UDINTECLR = USBC_UDINTECLR_MASK; in usb_dc_set_status_callback()
829 regs->UDINTCLR = USBC_UDINTCLR_MASK; in usb_dc_set_status_callback()
841 uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr); in usb_dc_ep_check_cap()
845 return -EINVAL; in usb_dc_ep_check_cap()
849 if (cfg->ep_type != USB_DC_EP_CONTROL) { in usb_dc_ep_check_cap()
850 LOG_ERR("pre-selected as control endpoint"); in usb_dc_ep_check_cap()
851 return -EINVAL; in usb_dc_ep_check_cap()
854 if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) { in usb_dc_ep_check_cap()
855 LOG_INF("pre-selected as IN endpoint"); in usb_dc_ep_check_cap()
856 return -EINVAL; in usb_dc_ep_check_cap()
859 if (USB_EP_DIR_IS_IN(cfg->ep_addr)) { in usb_dc_ep_check_cap()
860 LOG_INF("pre-selected as OUT endpoint"); in usb_dc_ep_check_cap()
861 return -EINVAL; in usb_dc_ep_check_cap()
865 if (cfg->ep_mps < 1 || cfg->ep_mps > 1024 || in usb_dc_ep_check_cap()
866 (cfg->ep_type == USB_DC_EP_CONTROL && cfg->ep_mps > 64)) { in usb_dc_ep_check_cap()
868 return -EINVAL; in usb_dc_ep_check_cap()
875 uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr); in usb_dc_ep_configure()
880 return -EINVAL; in usb_dc_ep_configure()
885 return -ENODEV; in usb_dc_ep_configure()
888 /* Allow re-configure any endpoint */ in usb_dc_ep_configure()
894 cfg->ep_addr, cfg->ep_mps, cfg->ep_type); in usb_dc_ep_configure()
896 switch (cfg->ep_type) { in usb_dc_ep_configure()
910 return -EINVAL; in usb_dc_ep_configure()
913 if (USB_EP_DIR_IS_OUT(cfg->ep_addr) || in usb_dc_ep_configure()
914 cfg->ep_type == USB_DC_EP_CONTROL) { in usb_dc_ep_configure()
924 log2ceil_mps = 32 - __builtin_clz((MAX(cfg->ep_mps, 8) << 1) - 1) - 1; in usb_dc_ep_configure()
925 regval |= USBC_UECFG0_EPSIZE(log2ceil_mps - 3); in usb_dc_ep_configure()
926 dev_data.ep_data[ep_idx].mps = cfg->ep_mps; in usb_dc_ep_configure()
929 if (cfg->ep_type != USB_DC_EP_CONTROL) { in usb_dc_ep_configure()
938 regs->UDCON |= USBC_UDCON_GNAK; in usb_dc_ep_configure()
941 regs->UDCON &= ~USBC_UDCON_GNAK; in usb_dc_ep_configure()
942 return -ENOMEM; in usb_dc_ep_configure()
944 regs->UDCON &= ~USBC_UDCON_GNAK; in usb_dc_ep_configure()
948 regs->UECFG[ep_idx] = regval; in usb_dc_ep_configure()
950 LOG_DBG("ep 0x%02x configured", cfg->ep_addr); in usb_dc_ep_configure()
960 return -EINVAL; in usb_dc_ep_set_stall()
973 regs->UECONSET[ep_idx] = USBC_UECON0SET_STALLRQS; in usb_dc_ep_set_stall()
987 return -EINVAL; in usb_dc_ep_clear_stall()
990 if (regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) { in usb_dc_ep_clear_stall()
995 regs->UECONCLR[ep_idx] = USBC_UECON0CLR_STALLRQC; in usb_dc_ep_clear_stall()
996 if (regs->UESTA[ep_idx] & USBC_UESTA0_STALLEDI) { in usb_dc_ep_clear_stall()
997 regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_STALLEDIC; in usb_dc_ep_clear_stall()
998 regs->UECONSET[ep_idx] = USBC_UECON0SET_RSTDTS; in usb_dc_ep_clear_stall()
1014 return -EINVAL; in usb_dc_ep_is_stalled()
1018 return -EINVAL; in usb_dc_ep_is_stalled()
1021 *stalled = ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0); in usb_dc_ep_is_stalled()
1039 return -EINVAL; in usb_dc_ep_enable()
1044 return -ENODEV; in usb_dc_ep_enable()
1051 regs->UERST |= BIT(USBC_UERST_EPEN0_Pos + ep_idx); in usb_dc_ep_enable()
1053 regs->UDINTESET = (USBC_UDINTESET_EP0INTES << ep_idx); in usb_dc_ep_enable()
1069 return -EINVAL; in usb_dc_ep_disable()
1075 regs->UDINTECLR = BIT(USBC_UDINTESET_EP0INTES_Pos + ep_idx); in usb_dc_ep_disable()
1078 regs->UERST &= ~BIT(USBC_UERST_EPEN0_Pos + ep_idx); in usb_dc_ep_disable()
1093 return -EINVAL; in usb_dc_ep_flush()
1098 return -ENODEV; in usb_dc_ep_flush()
1104 regs->UECONCLR[ep_idx] = USBC_UECON0CLR_TXINEC; in usb_dc_ep_flush()
1107 regs->UERST &= ~(BIT(ep_idx)); in usb_dc_ep_flush()
1108 regs->UERST |= BIT(ep_idx); in usb_dc_ep_flush()
1112 /* Re-enable interrupts */ in usb_dc_ep_flush()
1127 return -EINVAL; in usb_dc_ep_set_callback()
1147 regs->UESTACLR[0] = USBC_UESTA0CLR_RXSTPIC; in usb_dc_ep_write_stp()
1152 regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC; in usb_dc_ep_write_stp()
1178 if (regs->UESTA[0] & USBC_UESTA0_RXOUTI) { in usb_dc_ep_write_stp()
1195 * Control endpoint: clear the interrupt flag to send in usb_dc_ep_write_stp()
1196 * the data, and re-enable the interrupts to trigger in usb_dc_ep_write_stp()
1199 regs->UESTACLR[0] = USBC_UESTA0CLR_TXINIC; in usb_dc_ep_write_stp()
1200 regs->UECONSET[0] = USBC_UECON0SET_TXINES; in usb_dc_ep_write_stp()
1218 return -EPERM; in usb_dc_ep_write_stp()
1232 return -EINVAL; in usb_dc_ep_write()
1237 return -ENODEV; in usb_dc_ep_write()
1242 return -EINVAL; in usb_dc_ep_write()
1245 if ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0) { in usb_dc_ep_write()
1247 return -EBUSY; in usb_dc_ep_write()
1252 if ((regs->UECON[ep_idx] & USBC_UECON0_FIFOCON) == 0) { in usb_dc_ep_write()
1253 return -EAGAIN; in usb_dc_ep_write()
1267 return -EPERM; in usb_dc_ep_write()
1277 * Other endpoint types: clear the FIFO control flag to send in usb_dc_ep_write()
1280 regs->UECONCLR[ep_idx] = USBC_UECON0CLR_FIFOCONC; in usb_dc_ep_write()
1294 if (regs->UESTA[0] & USBC_UESTA0_CTRLDIR) { in usb_dc_ep_read_ex_stp()
1297 regs->UESTACLR[0] = USBC_UESTA0CLR_RXSTPIC; in usb_dc_ep_read_ex_stp()
1310 regs->UECONSET[0] = USBC_UECON0SET_RXOUTES; in usb_dc_ep_read_ex_stp()
1315 regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC; in usb_dc_ep_read_ex_stp()
1317 regs->UECONSET[0] = USBC_UECON0SET_NAKINES; in usb_dc_ep_read_ex_stp()
1321 regs->UESTACLR[0] = USBC_UESTA0CLR_RXOUTIC; in usb_dc_ep_read_ex_stp()
1326 regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC; in usb_dc_ep_read_ex_stp()
1328 regs->UECONSET[0] = USBC_UECON0SET_NAKINES; in usb_dc_ep_read_ex_stp()
1333 return -EPERM; in usb_dc_ep_read_ex_stp()
1351 return -EINVAL; in usb_dc_ep_read_ex()
1356 return -ENODEV; in usb_dc_ep_read_ex()
1361 return -EINVAL; in usb_dc_ep_read_ex()
1364 if ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0) { in usb_dc_ep_read_ex()
1366 return -EBUSY; in usb_dc_ep_read_ex()
1381 remaining = data_len - dev_data.ep_data[ep_idx].out_at; in usb_dc_ep_read_ex()
1402 setup->wLength); in usb_dc_ep_read_ex()
1422 return -EINVAL; in usb_dc_ep_read_continue()
1427 return -ENODEV; in usb_dc_ep_read_continue()
1432 return -EINVAL; in usb_dc_ep_read_continue()
1435 regs->UECONCLR[ep_idx] = USBC_UECON0CLR_FIFOCONC; in usb_dc_ep_read_continue()
1457 return -EINVAL; in usb_dc_ep_mps()
1471 regs->UDCON |= USBC_UDCON_RMWKUP; in usb_dc_wakeup_request()