Commit 18fb3f9a authored by Aleksander Strzebonski's avatar Aleksander Strzebonski Committed by David Leach
Browse files

usb: dwc2: Allow for enabling USB if the cable is disconnected

Adds CONFIG_UDC_DWC2_USBHS_VBUS_READY_TIMEOUT_MS that allows
for waiting for a USBHS VBUS ready event for a specified
amount of time. Earlier it waited forever and because of that,
the udc_enable() was blocked forever if the USB cable was
disconnected. Now the function returns error on timeout.

Signed-off-by: default avatarAleksander Strzebonski <aleksander.strzebonski@nordicsemi.no>
parent ef454346
Loading
Loading
Loading
Loading
+10 −0
Changes for drivers/usb/udc/Kconfig.dwc2: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -38,3 +38,13 @@ config UDC_DWC2_THREAD_PRIORITY
	default 8
	help
	  DWC2 driver thread priority.

config UDC_DWC2_USBHS_VBUS_READY_TIMEOUT
	int "UDC DWC2 USBHS VBUS ready event timeout in ms"
	depends on UDC_DWC2
	depends on NRFS_HAS_VBUS_DETECTOR_SERVICE
	default 0
	help
	  UDC DWC2 USBHS VBUS ready event timeout. If the VBUS is not ready
	  and the Nordic USBHS controller is used, the udc_enable() is
	  blocked for this amount of time. Set it to zero to wait forever.
+12 −2
Changes for drivers/usb/udc/udc_dwc2_vendor_quirks.h: 12 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -121,7 +121,8 @@ DT_INST_FOREACH_STATUS_OKAY(QUIRK_STM32F4_FSOTG_DEFINE)
 * On USBHS, we cannot access the DWC2 register until VBUS is detected and
 * valid. If the user tries to force usbd_enable() and the corresponding
 * udc_enable() without a "VBUS ready" notification, the event wait will block
 * until a valid VBUS signal is detected.
 * until a valid VBUS signal is detected or until the
 * CONFIG_UDC_DWC2_USBHS_VBUS_READY_TIMEOUT timeout expires.
 */
static K_EVENT_DEFINE(usbhs_events);
#define USBHS_VBUS_READY	BIT(0)
@@ -182,10 +183,19 @@ static inline int usbhs_enable_nrfs_service(const struct device *dev)
static inline int usbhs_enable_core(const struct device *dev)
{
	NRF_USBHS_Type *wrapper = USBHS_DT_WRAPPER_REG_ADDR(0);
	k_timeout_t timeout = K_FOREVER;

	#if CONFIG_NRFS_HAS_VBUS_DETECTOR_SERVICE
	if (CONFIG_UDC_DWC2_USBHS_VBUS_READY_TIMEOUT) {
		timeout = K_MSEC(CONFIG_UDC_DWC2_USBHS_VBUS_READY_TIMEOUT);
	}
	#endif

	if (!k_event_wait(&usbhs_events, USBHS_VBUS_READY, false, K_NO_WAIT)) {
		LOG_WRN("VBUS is not ready, block udc_enable()");
		k_event_wait(&usbhs_events, USBHS_VBUS_READY, false, K_FOREVER);
		if (!k_event_wait(&usbhs_events, USBHS_VBUS_READY, false, timeout)) {
			return -ETIMEDOUT;
		}
	}

	wrapper->ENABLE = USBHS_ENABLE_PHY_Msk | USBHS_ENABLE_CORE_Msk;
+1 −0
Changes for include/zephyr/drivers/usb/udc.h: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -371,6 +371,7 @@ int udc_init(const struct device *dev,
 * @return 0 on success, all other values should be treated as error.
 * @retval -EPERM controller is not initialized
 * @retval -EALREADY already enabled
 * @retval -ETIMEDOUT enable operation timed out
 */
int udc_enable(const struct device *dev);