From 24f6e5ca625bca50d593429ac7fc420f2658adc6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 17 Feb 2013 13:34:37 +0000 Subject: Fixed bug 3603362. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5220 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/OTGv1/stm32_otg.h | 2 + os/hal/platforms/STM32/OTGv1/usb_lld.c | 87 ++++++++++++++++++++++++++------ os/hal/platforms/STM32/OTGv1/usb_lld.h | 7 +++ 3 files changed, 80 insertions(+), 16 deletions(-) (limited to 'os') diff --git a/os/hal/platforms/STM32/OTGv1/stm32_otg.h b/os/hal/platforms/STM32/OTGv1/stm32_otg.h index 842ec80ea..9a28c7f08 100644 --- a/os/hal/platforms/STM32/OTGv1/stm32_otg.h +++ b/os/hal/platforms/STM32/OTGv1/stm32_otg.h @@ -238,6 +238,7 @@ typedef struct { #define GUSBCFG_CTXPKT (1U<<31) /**< Corrupt Tx packet. */ #define GUSBCFG_FDMOD (1U<<30) /**< Force Device Mode. */ #define GUSBCFG_FHMOD (1U<<29) /**< Force Host Mode. */ +#define GUSBCFG_ULPIEVBUSD (1U<<20) /**< ULPI External VBUS Drive */ #define GUSBCFG_TRDT_MASK (15U<<10) /**< USB Turnaround time field mask. */ #define GUSBCFG_TRDT(n) ((n)<<10) /**< USB Turnaround time field @@ -679,6 +680,7 @@ typedef struct { #define DSTS_ENUMSPD_MASK (3U<<1) /**< Enumerated speed mask. */ #define DSTS_ENUMSPD_FS_48 (3U<<1) /**< Full speed (PHY clock is running at 48 MHz). */ +#define DSTS_ENUMSPD_HS_480 (0U<<1) /**< High speed */ #define DSTS_SUSPSTS (1U<<0) /**< Suspend status. */ /** @} */ diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.c b/os/hal/platforms/STM32/OTGv1/usb_lld.c index 1bb29beae..119b5b610 100644 --- a/os/hal/platforms/STM32/OTGv1/usb_lld.c +++ b/os/hal/platforms/STM32/OTGv1/usb_lld.c @@ -37,7 +37,8 @@ /* Driver local definitions. */ /*===========================================================================*/ -#define TRDT_VALUE 5 +#define TRDT_VALUE 5 +#define TRDT_HS_VALUE 9 /*===========================================================================*/ /* Driver exported variables. */ @@ -605,11 +606,28 @@ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) { */ static void usb_lld_serve_interrupt(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; - uint32_t sts, src; + uint32_t sts, src, dsts_enumspd; sts = otgp->GINTSTS & otgp->GINTMSK; + /* Writing 1's to this register clears those respective interrupt flags.*/ otgp->GINTSTS = sts; + if (sts & GINTSTS_WKUPINT) { + /* If clocks are gated off, turn them back on (may be the case if coming out + of suspend mode).*/ + if (otgp->PCGCCTL & (PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK)) { + /* Set to zero to un-gate the USB core clocks.*/ + otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK); + } + + /* Clear the Remote Wake-up Signaling */ + otgp->DCTL |= DCTL_RWUSIG; + } + + if (sts & GINTSTS_USBSUSP) { + /* Implement suspend mode.*/ + } + /* Reset interrupt handling.*/ if (sts & GINTSTS_USBRST) { _usb_reset(usbp); @@ -618,7 +636,13 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) { /* Enumeration done.*/ if (sts & GINTSTS_ENUMDNE) { - (void)otgp->DSTS; + /* Full or High speed timing selection */ + dsts_enumspd = (otgp->DSTS & DSTS_ENUMSPD_MASK); + if( dsts_enumspd == DSTS_ENUMSPD_HS_480 ) { + otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) | GUSBCFG_TRDT(TRDT_HS_VALUE); + } else { + otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) | GUSBCFG_TRDT(TRDT_VALUE); + } } /* SOF interrupt handling.*/ @@ -858,6 +882,12 @@ void usb_lld_start(USBDriver *usbp) { #if STM32_USB_USE_OTG2 if (&USBD2 == usbp) { /* OTG HS clock enable and reset.*/ +#if STM32_USE_USB_OTG2_ULPI + rccEnableAHB1((RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIOHEN | RCC_AHB1ENR_GPIOIEN), + FALSE); + rccEnableAHB1(RCC_AHB1ENR_OTGHSULPIEN, FALSE); +#endif rccEnableOTG_HS(FALSE); rccResetOTG_HS(); @@ -878,18 +908,39 @@ void usb_lld_start(USBDriver *usbp) { usbp); /* - Forced device mode. - - USB turn-around time = TRDT_VALUE. - - Full Speed 1.1 PHY.*/ + - USB turn-around time = TRDT_VALUE. */ +#if STM32_USE_USB_OTG2_ULPI + /* High speed ULPI PHY */ + otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_SRPCAP | GUSBCFG_HNPCAP; +#else + /* - Full Speed 1.1 PHY.*/ otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL; +#endif + +#if STM32_USE_USB_OTG2_HS + /* USB 2.0 High Speed PHY.*/ + otgp->DCFG = 0x02200000 | DCFG_DSPD_HS; +#else /* 48MHz 1.1 PHY.*/ otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11; +#endif /* PHY enabled.*/ otgp->PCGCCTL = 0; - /* Internal FS PHY activation.*/ - otgp->GCCFG = GCCFG_VBUSASEN | GCCFG_VBUSBSEN | GCCFG_PWRDWN; + if (&USBD2 == usbp) { +#if STM32_USE_USB_OTG2_ULPI + otgp->GCCFG = 0; +#else + otgp->GCCFG = GCCFG_VBUSASEN | GCCFG_VBUSBSEN | GCCFG_PWRDWN; +#endif + } else { + /* Internal FS PHY activation.*/ + otgp->GCCFG = GCCFG_VBUSASEN | GCCFG_VBUSBSEN | GCCFG_PWRDWN; + } + + /* Soft core reset.*/ otg_core_reset(usbp); @@ -905,12 +956,13 @@ void usb_lld_start(USBDriver *usbp) { otgp->DIEPMSK = 0; otgp->DOEPMSK = 0; otgp->DAINTMSK = 0; - if (usbp->config->sof_cb == NULL) - otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | - GINTMSK_ESUSPM |*/; - else - otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | - GINTMSK_ESUSPM */ | GINTMSK_SOFM; + if (usbp->config->sof_cb == NULL) { + otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM | + GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM; + } else { + otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM | + GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM | GINTMSK_SOFM; + } otgp->GINTSTS = 0xFFFFFFFF; /* Clears all pending IRQs, if any. */ /* Global interrupts enable.*/ @@ -937,17 +989,20 @@ void usb_lld_stop(USBDriver *usbp) { otgp->GAHBCFG = 0; otgp->GCCFG = 0; -#if STM32_USB_USE_USB1 +#if STM32_USB_USE_OTG1 if (&USBD1 == usbp) { nvicDisableVector(STM32_OTG1_NUMBER); rccDisableOTG1(FALSE); } #endif -#if STM32_USB_USE_USB2 +#if STM32_USB_USE_OTG2 if (&USBD2 == usbp) { nvicDisableVector(STM32_OTG2_NUMBER); - rccDisableOTG2(FALSE); + rccDisableOTG_HS(FALSE); +#if STM32_USE_USB_OTG2_ULPI + rccDisableAHB1(RCC_AHB1ENR_OTGHSULPIEN, FALSE); +#endif } #endif } diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.h b/os/hal/platforms/STM32/OTGv1/usb_lld.h index 1ab3c0f0c..a95f45842 100644 --- a/os/hal/platforms/STM32/OTGv1/usb_lld.h +++ b/os/hal/platforms/STM32/OTGv1/usb_lld.h @@ -73,6 +73,13 @@ #define STM32_USB_USE_OTG2 FALSE #endif +/** + * @brief ULPI support for OTH-HS. + */ +#if !defined(STM32_USE_USB_OTG2_ULPI) || defined(__DOXYGEN__) +#define STM32_USE_USB_OTG2_ULPI FALSE +#endif + /** * @brief OTG1 interrupt priority level setting. */ -- cgit v1.2.3