aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-15 18:44:29 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-15 18:44:29 +0000
commit60d8f68906f28d369f35b624e129deee5092c86d (patch)
tree5c45e6bea6107dca69f8e3095a6ddda4e7c219a6 /os/hal
parent35ff7323526f5225d1a00c7812291e9fcdbfafac (diff)
downloadChibiOS-60d8f68906f28d369f35b624e129deee5092c86d.tar.gz
ChibiOS-60d8f68906f28d369f35b624e129deee5092c86d.tar.bz2
ChibiOS-60d8f68906f28d369f35b624e129deee5092c86d.zip
More improvements to the generic USB driver, implemented suspend and wakeup handling in the STM32 USB driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2742 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/usb.h92
-rw-r--r--os/hal/platforms/STM32/usb_lld.c33
-rw-r--r--os/hal/platforms/STM32/usb_lld.h7
3 files changed, 129 insertions, 3 deletions
diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h
index a7b183fe4..d569a6031 100644
--- a/os/hal/include/usb.h
+++ b/os/hal/include/usb.h
@@ -77,6 +77,96 @@
#define USB_LATE_SET_ADDRESS 1
/**
+ * @brief Helper macro for index values into descriptor strings.
+ */
+#define USB_DESC_INDEX(i) ((uint8_t)(i))
+
+/**
+ * @brief Helper macro for byte values into descriptor strings.
+ */
+#define USB_DESC_BYTE(b) ((uint8_t)(b))
+
+/**
+ * @brief Helper macro for word values into descriptor strings.
+ */
+#define USB_DESC_WORD(w) \
+ (uint8_t)((w) & 255), \
+ (uint8_t)(((w) >> 8) & 255)
+
+/**
+ * @brief Helper macro for BCD values into descriptor strings.
+ */
+#define USB_DESC_BCD(bcd) \
+ (uint8_t)((bcd) & 255), \
+ (uint8_t)(((bcd) >> 8) & 255)
+
+/**
+ * @brief Device Descriptor helper macro.
+ */
+#define USB_DESC_DEVICE(bcdUSB, bDeviceClass, bDeviceSubClass, \
+ bDeviceProtocol, bMaxPacketSize, idVendor, \
+ idProduct, bcdDevice, iManufacturer, \
+ iProduct, iSerialNumber, bNumConfigurations) \
+ USB_DESC_BYTE(18), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_DEVICE), \
+ USB_DESC_BCD(bcdUSB), \
+ USB_DESC_BYTE(bDeviceClass), \
+ USB_DESC_BYTE(bDeviceSubClass), \
+ USB_DESC_BYTE(bDeviceProtocol), \
+ USB_DESC_BYTE(bMaxPacketSize), \
+ USB_DESC_WORD(idVendor), \
+ USB_DESC_WORD(idProduct), \
+ USB_DESC_BCD(bcdDevice), \
+ USB_DESC_INDEX(iManufacturer), \
+ USB_DESC_INDEX(iProduct), \
+ USB_DESC_INDEX(iSerialNumber), \
+ USB_DESC_BYTE(bNumConfigurations)
+
+/**
+ * @brief Configuration Descriptor helper macro.
+ */
+#define USB_DESC_CONFIGURATION(wTotalLength, bNumInterfaces, \
+ bConfigurationValue, iConfiguration, \
+ bmAttributes, bMaxPower) \
+ USB_DESC_BYTE(9), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_CONFIGURATION), \
+ USB_DESC_WORD(wTotalLength), \
+ USB_DESC_BYTE(bNumInterfaces), \
+ USB_DESC_BYTE(bConfigurationValue), \
+ USB_DESC_INDEX(iConfiguration), \
+ USB_DESC_BYTE(bmAttributes), \
+ USB_DESC_BYTE(bMaxPower)
+
+/**
+ * @brief Interface Descriptor helper macro.
+ */
+#define USB_DESC_INTERFACE(bInterfaceNumber, bAlternateSetting, \
+ bNumEndpoints, bInterfaceClass, \
+ bInterfaceSubClass, bInterfaceProtocol, \
+ iInterface) \
+ USB_DESC_BYTE(9), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_INTERFACE), \
+ USB_DESC_BYTE(bInterfaceNumber), \
+ USB_DESC_BYTE(bAlternateSetting), \
+ USB_DESC_BYTE(bNumEndpoints), \
+ USB_DESC_BYTE(bInterfaceClass), \
+ USB_DESC_BYTE(bInterfaceSubClass), \
+ USB_DESC_BYTE(bInterfaceProtocol), \
+ USB_DESC_INDEX(iInterface)
+
+/**
+ * @brief Endpoint Descriptor helper macro.
+ */
+#define USB_DESC_ENDPOINT(bEndpointAddress, bmAttributes, wMaxPacketSize, \
+ bInterval) \
+ USB_DESC_BYTE(7), \
+ USB_DESC_BYTE(USB_DESCRIPTOR_ENDPOINT), \
+ USB_DESC_BYTE(bEndpointAddress), \
+ USB_DESC_BYTE(bmAttributes), \
+ USB_DESC_WORD(wMaxPacketSize), \
+ USB_DESC_BYTE(bInterval)
+
+/**
* @brief Returned by some functions to report a busy endpoint.
*/
#define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF)
@@ -151,7 +241,7 @@ typedef enum {
USB_EVENT_ADDRESS = 1, /**< Address assigned. */
USB_EVENT_CONFIGURED = 2, /**< Configuration selected. */
USB_EVENT_SUSPEND = 3, /**< Entering suspend mode. */
- USB_EVENT_RESUME = 4, /**< Leaving suspend mode. */
+ USB_EVENT_WAKEUP = 4, /**< Leaving suspend mode. */
USB_EVENT_STALLED = 5, /**< Endpoint 0 error, stalled. */
} usbevent_t;
diff --git a/os/hal/platforms/STM32/usb_lld.c b/os/hal/platforms/STM32/usb_lld.c
index f3bfa15f4..eb3d6ab7a 100644
--- a/os/hal/platforms/STM32/usb_lld.c
+++ b/os/hal/platforms/STM32/usb_lld.c
@@ -199,6 +199,35 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
STM32_USB->ISTR = ~ISTR_RESET;
}
+ /* USB bus SUSPEND condition handling.*/
+ if (istr & ISTR_SUSP) {
+ STM32_USB->CNTR |= CNTR_FSUSP;
+ if (usbp->config->event_cb)
+ usbp->config->event_cb(usbp, USB_EVENT_SUSPEND);
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+#endif
+ STM32_USB->ISTR = ~ISTR_SUSP;
+ }
+
+ /* USB bus WAKEUP condition handling.*/
+ if (istr & ISTR_WKUP) {
+ uint32_t fnr = STM32_USB->FNR;
+ if (!(fnr & FNR_RXDP)) {
+ STM32_USB->CNTR &= ~CNTR_FSUSP;
+ if (usbp->config->event_cb)
+ usbp->config->event_cb(usbp, USB_EVENT_WAKEUP);
+ }
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ else {
+ /* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
+ table 169.*/
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+ }
+#endif
+ STM32_USB->ISTR = ~ISTR_WKUP;
+ }
+
/* SOF handling.*/
if (istr & ISTR_SOF) {
if (usbp->config->sof_cb)
@@ -371,8 +400,8 @@ void usb_lld_reset(USBDriver *usbp) {
STM32_USB->BTABLE = 0;
STM32_USB->ISTR = 0;
STM32_USB->DADDR = DADDR_EF;
- cntr = /*CNTR_ESOFM | */ CNTR_RESETM | /*CNTR_SUSPM |*/
- /*CNTR_WKUPM | CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
+ cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM |
+ CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
/* The SOF interrupt is only enabled if a callback is defined for
this service because it is an high rate source.*/
if (usbp->config->sof_cb != NULL)
diff --git a/os/hal/platforms/STM32/usb_lld.h b/os/hal/platforms/STM32/usb_lld.h
index 42f32560e..a505e3e08 100644
--- a/os/hal/platforms/STM32/usb_lld.h
+++ b/os/hal/platforms/STM32/usb_lld.h
@@ -60,6 +60,13 @@
#endif
/**
+ * @brief Enables the USB device low power mode on suspend.
+ */
+#if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__)
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#endif
+
+/**
* @brief USB1 interrupt priority level setting.
*/
#if !defined(STM32_USB_USB1_HP_IRQ_PRIORITY) || defined(__DOXYGEN__)