Skip to content

Commit

Permalink
usb: dwc2: Allow for enabling USB if the cable is disconnected
Browse files Browse the repository at this point in the history
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: Aleksander Strzebonski <aleksander.strzebonski@nordicsemi.no>
  • Loading branch information
alstrzebonski authored and dleach02 committed Oct 16, 2024
1 parent ef45434 commit 18fb3f9
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
10 changes: 10 additions & 0 deletions drivers/usb/udc/Kconfig.dwc2
Original file line number Diff line number Diff line change
Expand Up @@ -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.
14 changes: 12 additions & 2 deletions drivers/usb/udc/udc_dwc2_vendor_quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/zephyr/drivers/usb/udc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 18fb3f9

Please sign in to comment.