diff --git a/cherryusb_config_template.h b/cherryusb_config_template.h index 0e6334a2..f000d7e9 100644 --- a/cherryusb_config_template.h +++ b/cherryusb_config_template.h @@ -236,6 +236,8 @@ #define CONFIG_USBDEV_EP_NUM 8 #endif +// #define CONFIG_USBDEV_SOF_ENABLE + /* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. */ // #define CONFIG_USB_HS diff --git a/common/usb_dc.h b/common/usb_dc.h index dd85d7cb..42a332e7 100644 --- a/common/usb_dc.h +++ b/common/usb_dc.h @@ -138,6 +138,11 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t /* usb dcd irq callback, called by user */ +/** + * @brief Usb sof irq callback. + */ +void usbd_event_sof_handler(uint8_t busid); + /** * @brief Usb connect irq callback. */ diff --git a/core/usbd_core.c b/core/usbd_core.c index a2ec9ffb..10cfc8b0 100644 --- a/core/usbd_core.c +++ b/core/usbd_core.c @@ -1090,6 +1090,11 @@ static void usbd_class_event_notify_handler(uint8_t busid, uint8_t event, void * } } +void usbd_event_sof_handler(uint8_t busid) +{ + g_usbd_core[busid].event_handler(busid, USBD_EVENT_SOF); +} + void usbd_event_connect_handler(uint8_t busid) { g_usbd_core[busid].event_handler(busid, USBD_EVENT_CONNECTED); diff --git a/port/chipidea/usb_dc_chipidea.c b/port/chipidea/usb_dc_chipidea.c index 9616dcc2..4a4f52f0 100644 --- a/port/chipidea/usb_dc_chipidea.c +++ b/port/chipidea/usb_dc_chipidea.c @@ -462,6 +462,10 @@ int usb_dc_init(uint8_t busid) /* Clear status */ USB_OTG_DEV->USBSTS = USB_OTG_DEV->USBSTS; +#ifdef CONFIG_USBDEV_SOF_ENABLE + int_mask |= USB_USBINTR_SRE_MASK; +#endif + /* Enable interrupt mask */ USB_OTG_DEV->USBINTR |= int_mask; @@ -630,6 +634,12 @@ void USBD_IRQHandler(uint8_t busid) USB_LOG_ERR("usbd intr error!\r\n"); } +#ifdef CONFIG_USBDEV_SOF_ENABLE + if (int_status & intr_sof) { + usbd_event_sof_handler(busid); + } +#endif + if (int_status & intr_reset) { g_chipidea_udc[busid].is_suspend = false; memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM); diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c index 88813991..90c3c0b0 100644 --- a/port/dwc2/usb_dc_dwc2.c +++ b/port/dwc2/usb_dc_dwc2.c @@ -598,7 +598,7 @@ int usb_dc_init(uint8_t busid) #if CONFIG_DWC2_VBUS_SENSING USB_OTG_GLB->GINTMSK |= (USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_SRQIM); #endif -#if 0 +#ifdef CONFIG_USBDEV_SOF_ENABLE USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_SOFM; #endif @@ -1143,10 +1143,12 @@ void USBD_IRQHandler(uint8_t busid) if (gint_status & USB_OTG_GINTSTS_IISOIXFR) { USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_IISOIXFR; } - +#ifdef CONFIG_USBDEV_SOF_ENABLE if (gint_status & USB_OTG_GINTSTS_SOF) { USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_SOF; + usbd_event_sof_handler(busid); } +#endif if (gint_status & USB_OTG_GINTSTS_USBSUSP) { USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_USBSUSP; usbd_event_suspend_handler(busid); diff --git a/port/fsdev/usb_dc_fsdev.c b/port/fsdev/usb_dc_fsdev.c index d046aa93..ad5c228e 100644 --- a/port/fsdev/usb_dc_fsdev.c +++ b/port/fsdev/usb_dc_fsdev.c @@ -79,8 +79,11 @@ int usb_dc_init(uint8_t busid) /* Set winterruptmask variable */ winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM | - USB_CNTR_SOFM | USB_CNTR_ESOFM | - USB_CNTR_RESETM; + USB_CNTR_ESOFM | USB_CNTR_RESETM; + +#ifdef CONFIG_USBDEV_SOF_ENABLE + winterruptmask |= USB_CNTR_SOFM; +#endif /* Set interrupt mask */ USB->CNTR = (uint16_t)winterruptmask; @@ -482,9 +485,12 @@ void USBD_IRQHandler(uint8_t busid) USB->CNTR |= (uint16_t)USB_CNTR_LP_MODE; } +#ifdef CONFIG_USBDEV_SOF_ENABLE if (wIstr & USB_ISTR_SOF) { USB->ISTR &= (uint16_t)(~USB_ISTR_SOF); + usbd_event_sof_handler(0); } +#endif if (wIstr & USB_ISTR_ESOF) { USB->ISTR &= (uint16_t)(~USB_ISTR_ESOF); } diff --git a/port/hpm/usb_dc_hpm.c b/port/hpm/usb_dc_hpm.c index 3eb2511b..9caf40e0 100644 --- a/port/hpm/usb_dc_hpm.c +++ b/port/hpm/usb_dc_hpm.c @@ -95,6 +95,10 @@ int usb_dc_init(uint8_t busid) int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_SLE_MASK | USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK); +#ifdef CONFIG_USBDEV_SOF_ENABLE + int_mask |= USB_USBINTR_SRE_MASK; +#endif + usb_device_init(g_hpm_udc[busid].handle, int_mask); intc_m_enable_irq(_dcd_irqnum[busid]); @@ -274,6 +278,11 @@ void USBD_IRQHandler(uint8_t busid) USB_LOG_ERR("usbd intr error!\r\n"); } +#ifdef CONFIG_USBDEV_SOF_ENABLE + if (int_status & intr_sof) { + usbd_event_sof_handler(busid); + } +#endif if (int_status & intr_reset) { g_hpm_udc[busid].is_suspend = false; memset(g_hpm_udc[busid].in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); diff --git a/port/kinetis/usb_dc_kinetis.c b/port/kinetis/usb_dc_kinetis.c index eb819576..34109530 100644 --- a/port/kinetis/usb_dc_kinetis.c +++ b/port/kinetis/usb_dc_kinetis.c @@ -102,6 +102,10 @@ int usb_dc_init(uint8_t busid) USB_INTEN_SLEEPEN_MASK | USB_INTEN_RESUMEEN_MASK | USB_INTEN_ERROREN_MASK; +#ifdef CONFIG_USBDEV_SOF_ENABLE + USB_OTG_DEV->INTEN |= USB_INTEN_SOFTOKEN_MASK; +#endif + USB_OTG_DEV->CTL |= USB_CTL_USBENSOFEN_MASK; return 0; } @@ -380,11 +384,12 @@ void USBD_IRQHandler(uint8_t busid) if (is & USB_ISTAT_RESUME_MASK) { USB_OTG_DEV->ISTAT = USB_ISTAT_RESUME_MASK; } - +#ifdef CONFIG_USBDEV_SOF_ENABLE if (is & USB_ISTAT_SOFTOK_MASK) { USB_OTG_DEV->ISTAT = USB_ISTAT_SOFTOK_MASK; + usbd_event_sof_handler(busid); } - +#endif if (is & USB_ISTAT_STALL_MASK) { USB_OTG_DEV->ISTAT = USB_ISTAT_STALL_MASK; } diff --git a/port/musb/usb_dc_musb.c b/port/musb/usb_dc_musb.c index 0d759b58..74234667 100644 --- a/port/musb/usb_dc_musb.c +++ b/port/musb/usb_dc_musb.c @@ -273,6 +273,10 @@ int usb_dc_init(uint8_t busid) HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0; HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0; +#ifdef CONFIG_USBDEV_SOF_ENABLE + HWREGB(USB_BASE + MUSB_IE_OFFSET) |= USB_IE_SOF; +#endif + HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_SOFTCONN; return 0; } @@ -721,8 +725,11 @@ void USBD_IRQHandler(uint8_t busid) usb_ep0_state = USB_EP0_STATE_SETUP; } +#ifdef CONFIG_USBDEV_SOF_ENABLE if (is & USB_IS_SOF) { + usbd_event_sof_handler(0); } +#endif if (is & USB_IS_RESUME) { usbd_event_resume_handler(0); diff --git a/port/rp2040/usb_dc_rp2040.c b/port/rp2040/usb_dc_rp2040.c index 418bcd04..1a48c0c0 100644 --- a/port/rp2040/usb_dc_rp2040.c +++ b/port/rp2040/usb_dc_rp2040.c @@ -181,6 +181,10 @@ int usb_dc_init(uint8_t busid) USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS | (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); +#ifdef CONFIG_USBDEV_SOF_ENABLE + usb_hw->inte |= USB_INTS_DEV_SOF_BITS; +#endif + // Enable USB interrupt at processor irq_set_enabled(USBCTRL_IRQ, true); @@ -577,6 +581,13 @@ void USBD_IRQHandler(uint8_t busid) usbd_event_resume_handler(0); } +#ifdef CONFIG_USBDEV_SOF_ENABLE + if (status & USB_INTS_DEV_SOF_BITS) { + handled |= USB_INTS_DEV_SOF_BITS; + usbd_event_sof_handler(0); + } +#endif + if (status ^ handled) { USB_LOG_INFO("Unhandled IRQ 0x%x\n", (uint32_t)(status ^ handled)); }