diff --git a/os/hal/include/hal_usb.h b/os/hal/include/hal_usb.h index 25ef63aa3..653a058ae 100644 --- a/os/hal/include/hal_usb.h +++ b/os/hal/include/hal_usb.h @@ -245,10 +245,21 @@ #define USB_USE_WAIT FALSE #endif +/** + * @brief Host wake-up procedure duration. + */ +#if !defined(USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__) +#define USB_HOST_WAKEUP_DURATION 2 +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ +#if (USB_HOST_WAKEUP_DURATION < 2) || (USB_HOST_WAKEUP_DURATION > 15) +#error "invalid USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -620,6 +631,7 @@ extern "C" { #endif bool usbStallReceiveI(USBDriver *usbp, usbep_t ep); bool usbStallTransmitI(USBDriver *usbp, usbep_t ep); + void usbWakeupHost(USBDriver *usbp); void _usb_reset(USBDriver *usbp); void _usb_suspend(USBDriver *usbp); void _usb_wakeup(USBDriver *usbp); diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c index b1802bc71..7cf690f5d 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c @@ -556,9 +556,6 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); } - /* Clear the Remote Wake-up Signaling.*/ - otgp->DCTL |= DCTL_RWUSIG; - _usb_wakeup(usbp); } diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h index 5f94a67ab..4c4177133 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h +++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h @@ -541,7 +541,7 @@ struct USBDriver { /** * @brief Connects the USB device. * - * @api + * @notapi */ #if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__) #define usb_lld_connect_bus(usbp) ((usbp)->otg->GCCFG |= GCCFG_VBUSBSEN) @@ -552,7 +552,7 @@ struct USBDriver { /** * @brief Disconnect the USB device. * - * @api + * @notapi */ #if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__) #define usb_lld_disconnect_bus(usbp) ((usbp)->otg->GCCFG &= ~GCCFG_VBUSBSEN) @@ -560,6 +560,20 @@ struct USBDriver { #define usb_lld_disconnect_bus(usbp) ((usbp)->otg->DCTL |= DCTL_SDIS) #endif +/** + * @brief Start of host wake-up procedure. + * + * @notapi + */ +#define usb_lld_start_wakeup_host(usbp) ((usbp)->otg->DCTL |= DCTL_RWUSIG) + +/** + * @brief Stop of host wake-up procedure. + * + * @notapi + */ +#define usb_lld_stop_wakeup_host(usbp) ((usbp)->otg->DCTL &= ~DCTL_RWUSIG) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h index 7971189ae..db199e33d 100644 --- a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h +++ b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h @@ -422,7 +422,7 @@ struct USBDriver { /** * @brief Connects the USB device. * - * @api + * @notapi */ #if !defined(usb_lld_connect_bus) #define usb_lld_connect_bus(usbp) (STM32_USB->BCDR |= USB_BCDR_DPPU) @@ -431,7 +431,7 @@ struct USBDriver { /** * @brief Disconnect the USB device. * - * @api + * @notapi */ #if !defined(usb_lld_disconnect_bus) #define usb_lld_disconnect_bus(usbp) (STM32_USB->BCDR &= ~USB_BCDR_DPPU) @@ -448,6 +448,20 @@ struct USBDriver { #endif #endif /* STM32L1XX */ +/** + * @brief Start of host wake-up procedure. + * + * @notapi + */ +#define usb_lld_start_wakeup_host(usbp) (STM32_USB->CNTR |= USB_CNTR_RESUME) + +/** + * @brief Stop of host wake-up procedure. + * + * @notapi + */ +#define usb_lld_stop_wakeup_host(usbp) (STM32_USB->CNTR &= ~USB_CNTR_RESUME) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/src/hal_usb.c b/os/hal/src/hal_usb.c index b32bfc09f..61f03d832 100644 --- a/os/hal/src/hal_usb.c +++ b/os/hal/src/hal_usb.c @@ -631,6 +631,29 @@ bool usbStallTransmitI(USBDriver *usbp, usbep_t ep) { return false; } +/** + * @brief Host wake-up procedure. + * @note It is silently ignored if the USB device is not in the + * @p USB_SUSPENDED state. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @api + */ +void usbWakeupHost(USBDriver *usbp) { + + if (usbp->state == USB_SUSPENDED) { + /* Starting host wakeup procedure.*/ + usb_lld_start_wakeup_host(usbp); + + /* Holding it for the configured time, it must be 2..15 msecs.*/ + osalThreadSleepMilliseconds(USB_HOST_WAKEUP_DURATION); + + /* Stopping host wake up procedure.*/ + usb_lld_stop_wakeup_host(usbp); + } +} + /** * @brief USB reset routine. * @details This function must be invoked when an USB bus reset condition is