From aa7557a5f206124dc232343be2010f7d9b82e267 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 8 Sep 2015 10:43:31 +0000 Subject: USB suspend mode. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8286 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/usb.h | 13 ++++--- os/hal/ports/STM32/LLD/OTGv1/usb_lld.c | 8 ++-- os/hal/src/usb.c | 45 +++++++++++++++++++++- readme.txt | 3 ++ .../STM32F7xx-USB_CDC (OpenOCD, Just Run).launch | 2 +- 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index 267c519ba..9f7cbf630 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -258,11 +258,12 @@ typedef uint8_t usbep_t; * @brief Type of a driver state machine possible states. */ typedef enum { - USB_UNINIT = 0, /**< Not initialized. */ - USB_STOP = 1, /**< Stopped. */ - USB_READY = 2, /**< Ready, after bus reset. */ - USB_SELECTED = 3, /**< Address assigned. */ - USB_ACTIVE = 4 /**< Active, configuration selected.*/ + USB_UNINIT = 0, /**< Not initialized. */ + USB_STOP = 1, /**< Stopped. */ + USB_READY = 2, /**< Ready, after bus reset. */ + USB_SELECTED = 3, /**< Address assigned. */ + USB_ACTIVE = 4, /**< Active, configuration selected.*/ + USB_SUSPENDED = 5 /**< Suspended, low power mode. */ } usbstate_t; /** @@ -583,6 +584,8 @@ extern "C" { bool usbStallReceiveI(USBDriver *usbp, usbep_t ep); bool usbStallTransmitI(USBDriver *usbp, usbep_t ep); void _usb_reset(USBDriver *usbp); + void _usb_suspend(USBDriver *usbp); + void _usb_wakeup(USBDriver *usbp); void _usb_ep0setup(USBDriver *usbp, usbep_t ep); void _usb_ep0in(USBDriver *usbp, usbep_t ep); void _usb_ep0out(USBDriver *usbp, usbep_t ep); diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c index 33f3b43c4..b6d2f1cdd 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c @@ -589,21 +589,19 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { /* Clear the Remote Wake-up Signaling.*/ otgp->DCTL |= DCTL_RWUSIG; - /* Signaling the wakeup event.*/ - _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP); + _usb_wakeup(usbp); } /* Suspend handling.*/ if (sts & GINTSTS_USBSUSP) { - /* Signaling the suspend event.*/ - _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND); + _usb_suspend(usbp); } /* Reset interrupt handling.*/ if (sts & GINTSTS_USBRST) { + _usb_reset(usbp); - _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET); } /* Enumeration done.*/ diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index c563d5fea..c4f612d0f 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -314,7 +314,8 @@ void usbStop(USBDriver *usbp) { osalSysLock(); osalDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY) || - (usbp->state == USB_SELECTED) || (usbp->state == USB_ACTIVE), + (usbp->state == USB_SELECTED) || (usbp->state == USB_ACTIVE) || + (usbp->state == USB_SUSPENDED), "invalid state"); usb_lld_stop(usbp); usbp->state = USB_STOP; @@ -607,7 +608,10 @@ bool usbStallTransmitI(USBDriver *usbp, usbep_t ep) { void _usb_reset(USBDriver *usbp) { unsigned i; + /* State transition.*/ usbp->state = USB_READY; + + /* Resetting internal state.*/ usbp->status = 0; usbp->address = 0; usbp->configuration = 0; @@ -624,6 +628,45 @@ void _usb_reset(USBDriver *usbp) { /* Low level reset.*/ usb_lld_reset(usbp); + + /* Notification of reset event.*/ + _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET); +} + +/** + * @brief USB suspend routine. + * @details This function must be invoked when an USB bus suspend condition is + * detected. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void _usb_suspend(USBDriver *usbp) { + + /* State transition.*/ + usbp->state = USB_SUSPENDED; + + /* Notification of suspend event.*/ + _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND); +} + +/** + * @brief USB wake-up routine. + * @details This function must be invoked when an USB bus wake-up condition is + * detected. + * + * @param[in] usbp pointer to the @p USBDriver object + * + * @notapi + */ +void _usb_wakeup(USBDriver *usbp) { + + /* State transition.*/ + usbp->state = USB_ACTIVE; + + /* Notification of suspend event.*/ + _usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP); } /** diff --git a/readme.txt b/readme.txt index f7765b938..576aeecf5 100644 --- a/readme.txt +++ b/readme.txt @@ -73,6 +73,9 @@ ***************************************************************************** *** 3.1.0 *** +- HAL: Modified the USB driver to have a separate USB_SUSPENDED state, this + allows the application to detect if the USB is communicating or if + it is disconnected or powered down. - HAL: Added wake-up and suspend events to the STM32 OTGv1 driver. - HAL: STM32 USB/OTG buffers and queues do not more require to be aligned in position and size. diff --git a/testhal/STM32/STM32F7xx/USB_CDC/debug/STM32F7xx-USB_CDC (OpenOCD, Just Run).launch b/testhal/STM32/STM32F7xx/USB_CDC/debug/STM32F7xx-USB_CDC (OpenOCD, Just Run).launch index 0f4360bab..bc6f16628 100644 --- a/testhal/STM32/STM32F7xx/USB_CDC/debug/STM32F7xx-USB_CDC (OpenOCD, Just Run).launch +++ b/testhal/STM32/STM32F7xx/USB_CDC/debug/STM32F7xx-USB_CDC (OpenOCD, Just Run).launch @@ -33,7 +33,7 @@ - + -- cgit v1.2.3