Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions drivers/usb/udc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ config UDC_BUF_FORCE_NOCACHE
Place the buffer pools in the nocache memory region if the driver
cannot handle buffers in cached memory.

config UDC_ENABLE_SOF
bool "SOF interrupt processing"
help
Enabled SoF interrupts can cause a very high CPU load on high-speed
controllers because the interrupt rate would be 125 µs.

config UDC_WORKQUEUE
bool "Use a dedicate work queue for UDC drivers"
help
Expand Down
7 changes: 4 additions & 3 deletions drivers/usb/udc/udc_ambiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,9 @@ static void udc_ambiq_evt_callback(const struct device *dev, am_hal_usb_dev_even
case AM_HAL_USB_DEV_EVT_BUS_RESET:
/* enable usb bus interrupts */
am_hal_usb_intr_usb_enable(priv->usb_handle,
USB_CFG2_SOFE_Msk | USB_CFG2_ResumeE_Msk |
USB_CFG2_SuspendE_Msk | USB_CFG2_ResetE_Msk);
IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (USB_CFG2_SOFE_Msk |))
USB_CFG2_ResumeE_Msk |
USB_CFG2_SuspendE_Msk | USB_CFG2_ResetE_Msk);
/* init the endpoint */
am_hal_usb_ep_init(priv->usb_handle, 0, 0, EP0_MPS);
/* Set USB device speed to HAL */
Expand All @@ -174,7 +175,7 @@ static void udc_ambiq_evt_callback(const struct device *dev, am_hal_usb_dev_even
udc_submit_event(dev, UDC_EVT_RESUME, 0);
break;
case AM_HAL_USB_DEV_EVT_SOF:
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
break;
case AM_HAL_USB_DEV_EVT_SUSPEND:
/* Handle USB Suspend event, then set device state to suspended */
Expand Down
23 changes: 23 additions & 0 deletions drivers/usb/udc/udc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,29 @@ int udc_submit_event(const struct device *dev,
int udc_submit_ep_event(const struct device *dev,
struct net_buf *const buf,
const int err);

/**
* @brief Helper function to send UDC SOF event to a higher level.
*
* Type of this event is hardcoded to UDC_EVT_SOF.
*
* @param[in] dev Pointer to device struct of the driver instance
*/
#if defined(CONFIG_UDC_ENABLE_SOF)
static inline void udc_submit_sof_event(const struct device *dev)
{
struct udc_data *data = dev->data;
struct udc_event drv_evt = {
.type = UDC_EVT_SOF,
.dev = dev,
};

(void)data->event_cb(dev, &drv_evt);
}
#else
#define udc_submit_sof_event(dev) ARG_UNUSED(dev)
#endif

/**
* @brief Helper function to enable endpoint.
*
Expand Down
20 changes: 12 additions & 8 deletions drivers/usb/udc/udc_dwc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2162,11 +2162,12 @@ static int udc_dwc2_init_controller(const struct device *dev)
}

/* Unmask interrupts */
sys_write32(USB_DWC2_GINTSTS_OEPINT | USB_DWC2_GINTSTS_IEPINT |
sys_write32(IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (USB_DWC2_GINTSTS_SOF |
USB_DWC2_GINTSTS_INCOMPISOOUT |
USB_DWC2_GINTSTS_INCOMPISOIN |))
USB_DWC2_GINTSTS_OEPINT | USB_DWC2_GINTSTS_IEPINT |
USB_DWC2_GINTSTS_ENUMDONE | USB_DWC2_GINTSTS_USBRST |
USB_DWC2_GINTSTS_WKUPINT | USB_DWC2_GINTSTS_USBSUSP |
USB_DWC2_GINTSTS_INCOMPISOOUT | USB_DWC2_GINTSTS_INCOMPISOIN |
USB_DWC2_GINTSTS_SOF,
USB_DWC2_GINTSTS_WKUPINT | USB_DWC2_GINTSTS_USBSUSP,
(mem_addr_t)&base->gintmsk);

return 0;
Expand Down Expand Up @@ -2890,15 +2891,16 @@ static void udc_dwc2_isr_handler(const struct device *dev)

LOG_DBG("GINTSTS 0x%x", int_status);

if (int_status & USB_DWC2_GINTSTS_SOF) {
if (IS_ENABLED(CONFIG_UDC_ENABLE_SOF) &&
int_status & USB_DWC2_GINTSTS_SOF) {
uint32_t dsts;

/* Clear USB SOF interrupt. */
sys_write32(USB_DWC2_GINTSTS_SOF, gintsts_reg);

dsts = sys_read32((mem_addr_t)&base->dsts);
priv->sof_num = usb_dwc2_get_dsts_soffn(dsts);
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
}

if (int_status & USB_DWC2_GINTSTS_USBRST) {
Expand Down Expand Up @@ -2941,11 +2943,13 @@ static void udc_dwc2_isr_handler(const struct device *dev)
dwc2_handle_oepint(dev);
}

if (int_status & USB_DWC2_GINTSTS_INCOMPISOIN) {
if (IS_ENABLED(CONFIG_UDC_ENABLE_SOF) &&
int_status & USB_DWC2_GINTSTS_INCOMPISOIN) {
dwc2_handle_incompisoin(dev);
}

if (int_status & USB_DWC2_GINTSTS_INCOMPISOOUT) {
if (IS_ENABLED(CONFIG_UDC_ENABLE_SOF) &&
int_status & USB_DWC2_GINTSTS_INCOMPISOOUT) {
dwc2_handle_incompisoout(dev);
}

Expand Down
9 changes: 3 additions & 6 deletions drivers/usb/udc/udc_it82xx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ LOG_MODULE_REGISTER(udc_it82xx2, CONFIG_UDC_DRIVER_LOG_LEVEL);

#define DT_DRV_COMPAT ite_it82xx2_usb

/* TODO: Replace this definition by Kconfig option */
#define USB_DEVICE_CONFIG_SOF_NOTIFICATIONS (0U)

#define IT8XXX2_IS_EXTEND_ENDPOINT(n) (USB_EP_GET_IDX(n) >= 4)

#define IT82xx2_STATE_OUT_SHARED_FIFO_BUSY 0
Expand Down Expand Up @@ -1357,11 +1354,11 @@ static void it82xx2_usb_dc_isr(const void *arg)

/* sof received */
if (status & DC_SOF_RECEIVED) {
if (!USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) {
if (!IS_ENABLED(CONFIG_UDC_ENABLE_SOF)) {
it82xx2_enable_sof_int(dev, false);
} else {
usb_regs->dc_interrupt_status = DC_SOF_RECEIVED;
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
}
it82xx2_enable_resume_int(dev, false);
emit_resume_event(dev);
Expand Down Expand Up @@ -1411,7 +1408,7 @@ static void suspended_handler(struct k_work *item)

it82xx2_enable_resume_int(dev, true);

if (!USB_DEVICE_CONFIG_SOF_NOTIFICATIONS) {
if (!IS_ENABLED(CONFIG_UDC_ENABLE_SOF)) {
it82xx2_enable_sof_int(dev, true);
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/udc/udc_kinetis.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ static void usbfsotg_isr_handler(const struct device *dev)
}

if (istatus == USB_ISTAT_SOFTOK_MASK) {
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
}

if (istatus == USB_ISTAT_ERROR_MASK) {
Expand Down Expand Up @@ -1016,7 +1016,7 @@ static int usbfsotg_init(const struct device *dev)
base->INTEN = (USB_INTEN_SLEEPEN_MASK |
USB_INTEN_STALLEN_MASK |
USB_INTEN_TOKDNEEN_MASK |
USB_INTEN_SOFTOKEN_MASK |
IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (USB_INTEN_SOFTOKEN_MASK |))
USB_INTEN_ERROREN_MASK |
USB_INTEN_USBRSTEN_MASK);

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/udc_max32.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ static int udc_max32_event_callback(maxusb_event_t event, void *cbdata)
case MAXUSB_EVENT_DPACT:
LOG_DBG("DPACT event occurred");
udc_set_suspended(dev, false);
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
break;
case MAXUSB_EVENT_BRST:
LOG_DBG("BRST event occurred");
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/udc_mcux_ehci.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
udc_submit_event(dev, UDC_EVT_VBUS_READY, 0);
break;
case kUSB_DeviceNotifySOF:
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
break;
default:
udc_mcux_event_submit(dev, mcux_msg);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/udc_mcux_ip3511.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
udc_submit_event(dev, UDC_EVT_VBUS_READY, 0);
break;
case kUSB_DeviceNotifySOF:
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
break;
default:
udc_mcux_event_submit(dev, mcux_msg);
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/udc/udc_nrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ static void ev_sof_handler(void)

m_ep_armed &= ~USBD_EPISO_BIT_MASK;

udc_submit_event(udc_nrf_dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(udc_nrf_dev);
}

static void usbd_in_packet_sent(uint8_t ep)
Expand Down Expand Up @@ -1547,7 +1547,7 @@ static void udc_nrf_power_handler(nrfx_power_usb_evt_t pwr_evt)
break;
case NRFX_POWER_USB_EVT_READY:
LOG_DBG("POWER event ready");
nrf_usbd_legacy_start(true);
nrf_usbd_legacy_start(IS_ENABLED(CONFIG_UDC_ENABLE_SOF));
break;
case NRFX_POWER_USB_EVT_REMOVED:
LOG_DBG("POWER event removed");
Expand Down
6 changes: 4 additions & 2 deletions drivers/usb/udc/udc_numaker.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ static inline void numaker_usbd_sw_connect(const struct device *dev)
base->INTSTS = base->INTSTS;

/* Enable relevant interrupts */
base->INTEN = USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP | USBD_INT_SOF;
base->INTEN = USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET |
IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (USBD_INT_SOF |))
USBD_INT_WAKEUP;

/* Clear SE0 for connect */
base->SE0 &= ~USBD_DRVSE0;
Expand Down Expand Up @@ -1298,7 +1300,7 @@ static void numaker_udbd_isr(const struct device *dev)
base->INTSTS = USBD_INTSTS_SOFIF_Msk;

/* UDC stack would handle bottom-half processing */
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
}

/* USB Setup/EP */
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/udc_renesas_ra.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static void udc_renesas_ra_event_handler(usbd_callback_arg_t *p_args)
break;

case USBD_EVENT_SOF:
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
break;

default:
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/udc/udc_rpi_pico.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ static void rpi_pico_isr_handler(const struct device *dev)

if (status & USB_INTS_DEV_SOF_BITS) {
handled |= USB_INTS_DEV_SOF_BITS;
sys_read32((mm_reg_t)&base->sof_rd);
udc_submit_sof_event(dev);
}

if (status & USB_INTS_DEV_CONN_DIS_BITS) {
Expand Down Expand Up @@ -1048,7 +1048,7 @@ static int udc_rpi_pico_enable(const struct device *dev)
sys_write32(USB_SIE_CTRL_EP0_INT_1BUF_BITS, (mm_reg_t)&base->sie_ctrl);

/* Enable interrupts */
sys_write32(USB_INTE_DEV_SOF_BITS |
sys_write32(IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (USB_INTE_DEV_SOF_BITS |))
USB_INTE_SETUP_REQ_BITS |
USB_INTE_DEV_RESUME_FROM_HOST_BITS |
USB_INTE_DEV_SUSPEND_BITS |
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/udc_sam0.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ static void sam0_isr_handler(const struct device *dev)
base->INTFLAG.reg = intflag;

if (intflag & USB_DEVICE_INTFLAG_SOF) {
udc_submit_event(dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(dev);
}

if (intflag & USB_DEVICE_INTFLAG_EORST) {
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/udc/udc_skeleton.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ static int udc_skeleton_init(const struct device *dev)
return -EIO;
}

if (IS_ENABLED(CONFIG_UDC_ENABLE_SOF)) {
LOG_INF("Enable SOF interrupt");
}

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/udc/udc_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
{
struct udc_stm32_data *priv = hpcd2data(hpcd);

udc_submit_event(priv->dev, UDC_EVT_SOF, 0);
udc_submit_sof_event(priv->dev);
}

static int usbd_ctrl_feed_dout(const struct device *dev, const size_t length)
Expand Down
1 change: 1 addition & 0 deletions subsys/usb/device_next/class/Kconfig.uac2
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

config USBD_AUDIO2_CLASS
bool "USB Audio 2 class support [EXPERIMENTAL]"
select UDC_ENABLE_SOF
help
USB Audio 2 device class support.

Expand Down
1 change: 1 addition & 0 deletions tests/drivers/udc/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ CONFIG_LOG=y
CONFIG_ZTEST=y

CONFIG_UDC_DRIVER=y
CONFIG_UDC_ENABLE_SOF=y
CONFIG_UDC_BUF_COUNT=16
CONFIG_UDC_BUF_POOL_SIZE=16384
CONFIG_UDC_DRIVER_LOG_LEVEL_INF=y
1 change: 1 addition & 0 deletions tests/subsys/usb/device_next/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ CONFIG_ZTEST=y

CONFIG_USB_DEVICE_STACK_NEXT=y
CONFIG_USBD_LOOPBACK_CLASS=y
CONFIG_UDC_ENABLE_SOF=y

CONFIG_UHC_DRIVER=y
CONFIG_USB_HOST_STACK=y