From f083a30ce8d6b93c9fa23c94874e4488e79d053f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 28 Mar 2012 14:19:40 +0000 Subject: More work on the STM32 OTG driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4059 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/usb.h | 4 +++ os/hal/platforms/STM32/OTGv1/stm32_otg.h | 6 ++-- os/hal/platforms/STM32/OTGv1/usb_lld.c | 59 +++++++++++++++++++++++++++----- os/hal/platforms/STM32/OTGv1/usb_lld.h | 16 ++++++++- os/hal/platforms/STM32F2xx/platform.mk | 6 ++-- os/hal/platforms/STM32F2xx/stm32_rcc.h | 30 ++++++++++++++++ os/hal/platforms/STM32F4xx/platform.mk | 4 ++- os/hal/platforms/STM32F4xx/stm32_rcc.h | 31 +++++++++++++++++ 8 files changed, 139 insertions(+), 17 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index e261e9486..7b68d0eeb 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -323,11 +323,15 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp, */ /** * @brief Connects the USB device. + * + * @api */ #define usbConnectBus(usbp) usb_lld_connect_bus(usbp) /** * @brief Disconnect the USB device. + * + * @api */ #define usbDisconnectBus(usbp) usb_lld_disconnect_bus(usbp) diff --git a/os/hal/platforms/STM32/OTGv1/stm32_otg.h b/os/hal/platforms/STM32/OTGv1/stm32_otg.h index 2dbe8bb66..dd4820ed9 100644 --- a/os/hal/platforms/STM32/OTGv1/stm32_otg.h +++ b/os/hal/platforms/STM32/OTGv1/stm32_otg.h @@ -85,7 +85,7 @@ typedef struct { volatile uint32_t resvd14; volatile uint32_t resvd18; volatile uint32_t resvd1C; -} stm32_t_out_ep_t; +} stm32_otg_out_ep_t; /** * @brief USB registers memory map. @@ -161,7 +161,7 @@ typedef struct { volatile uint32_t resvd880[16]; volatile uint32_t resvd8C0[16]; stm32_otg_in_ep_t ie[16]; /**< @brief Input endpoints. */ - stm32_t_out_ep_t oe[16]; /**< @brief Output endpoints. */ + stm32_otg_out_ep_t oe[16]; /**< @brief Output endpoints. */ volatile uint32_t resvdD00[64]; volatile uint32_t PCGCCTL; /**< @brief Power and clock gating control register. */ @@ -860,7 +860,7 @@ typedef struct { * @brief Returns a FIFO address. */ #define OTG_FIFO(n) ((volatile uint32_t *)(OTG_ADDR + \ - 0x1000 + + 0x1000 + \ (0x1000 * (n)))) #endif /* _STM32_OTG_H_ */ diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.c b/os/hal/platforms/STM32/OTGv1/usb_lld.c index 6bf22e6f8..35b6dbc96 100644 --- a/os/hal/platforms/STM32/OTGv1/usb_lld.c +++ b/os/hal/platforms/STM32/OTGv1/usb_lld.c @@ -86,6 +86,45 @@ static const USBEndpointConfig ep0config = { /* Driver local functions. */ /*===========================================================================*/ +static void otg_reset_ep(void) { + unsigned i; + + for (i = 0; i <= USB_MAX_ENDPOINTS; i++) { + /* Disable only if enabled because this sentence in the manual: + "The application must set this bit only if Endpoint Enable is + already set for this endpoint".*/ + if ((OTG->ie[i].DIEPCTL & DIEPCTL_EPENA) != 0) { + OTG->ie[i].DIEPCTL = DIEPCTL_EPDIS; + /* Wait for endpoint disable.*/ + while (!(OTG->ie[i].DIEPINT & DIEPINT_EPDISD)) + ; + } + else + OTG->ie[i].DIEPCTL = 0; + OTG->ie[i].DIEPTSIZ = 0; + OTG->ie[i].DIEPINT = DIEPINT_INEPNE | DIEPINT_ITTXFE | + DIEPINT_TOC | DIEPINT_EPDISD | + DIEPINT_XFRC; + /* Disable only if enabled because this sentence in the manual: + "The application must set this bit only if Endpoint Enable is + already set for this endpoint". + Note that the attempt to disable the OUT EP0 is ignored by the + hardware but the code is simpler this way.*/ + if ((OTG->oe[i].DOEPCTL & DOEPCTL_EPENA) != 0) { + OTG->oe[i].DOEPCTL = DOEPCTL_EPDIS; + /* Wait for endpoint disable.*/ + while (!(OTG->oe[i].DOEPINT & DOEPINT_OTEPDIS)) + ; + } + else + OTG->oe[i].DOEPCTL = 0; + OTG->oe[i].DOEPTSIZ = 0; + OTG->oe[i].DOEPINT = DOEPINT_B2BSTUP | DOEPINT_OTEPDIS | + DOEPINT_STUP | DOEPINT_EPDISD | + DOEPINT_XFRC; + } +} + /** * @brief Resets the RX FIFO memory allocator. * @@ -141,6 +180,9 @@ void usb_lld_init(void) { /** * @brief Configures and activates the USB peripheral. + * @note Starting the ORG cell can be a slow operation carried out with + * interrupts disabled, perform it before starting time-critical + * operations. * * @param[in] usbp pointer to the @p USBDriver object * @@ -153,8 +195,8 @@ void usb_lld_start(USBDriver *usbp) { #if STM32_USB_USE_OTG1 if (&USBD1 == usbp) { /* OTG FS clock enable and reset.*/ - rccEnableOTG1(FALSE); - rccResetOTG1(); + rccEnableOTG_FS(FALSE); + rccResetOTG_FS(); /* Enables IRQ vector.*/ nvicEnableVector(OTG_FS_IRQn, @@ -173,7 +215,7 @@ void usb_lld_start(USBDriver *usbp) { halPolledDelay(12); /* - Forced device mode. - - USB turnaroudn time = TRDT_VALUE. + - USB turn-around time = TRDT_VALUE. - Full Speed 1.1 PHY.*/ OTG->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL; @@ -189,22 +231,21 @@ void usb_lld_start(USBDriver *usbp) { /* Receive FIFO size initialization, the address is always zero.*/ OTG->GRXFSIZ = STM32_USB_OTG1_RX_FIFO_SIZE / 4; - /* EP0 TX FIFO initialization.*/ - - /* Endpoints reinitialization.*/ + /* Endpoints re-initialization.*/ + otg_reset_ep(); /* Clear all pending Device Interrupts, only the USB Reset interrupt is required initially.*/ OTG->DIEPMSK = 0; OTG->DOEPMSK = 0; OTG->DAINTMSK = 0; - OTG->GINTMSK = GINTMSK_USBRSTM; - OTG->GINTSTS = 0xFFFFFFFF; + OTG->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM | + GINTMSK_ESUSPM | GINTMSK_SOFM; + OTG->GINTSTS = 0xFFFFFFFF; /* Clears all pending IRQs, if any. */ /* Global interrupts enable.*/ OTG->GAHBCFG |= GAHBCFG_GINTMSK; } - /* Configuration.*/ } /** diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.h b/os/hal/platforms/STM32/OTGv1/usb_lld.h index 7c724a47c..4ef236ea0 100644 --- a/os/hal/platforms/STM32/OTGv1/usb_lld.h +++ b/os/hal/platforms/STM32/OTGv1/usb_lld.h @@ -31,7 +31,7 @@ #if HAL_USE_USB || defined(__DOXYGEN__) -#include "stm32_usb.h" +#include "stm32_otg.h" /*===========================================================================*/ /* Driver constants. */ @@ -332,6 +332,20 @@ struct USBDriver { #define usb_lld_get_transaction_size(usbp, ep) \ ((usbp)->epc[ep]->out_state->rxcnt) +/** + * @brief Connects the USB device. + * + * @api + */ +#define usb_lld_connect_bus(usbp) (OTG->GCCFG |= GCCFG_VBUSBSEN) + +/** + * @brief Disconnect the USB device. + * + * @api + */ +#define usb_lld_disconnect_bus(usbp) (OTG->GCCFG &= ~GCCFG_VBUSBSEN) + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F2xx/platform.mk b/os/hal/platforms/STM32F2xx/platform.mk index 37b37bc93..e9aee9817 100644 --- a/os/hal/platforms/STM32F2xx/platform.mk +++ b/os/hal/platforms/STM32F2xx/platform.mk @@ -11,12 +11,12 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F2xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/OTGv1/usb_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F2xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \ - ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \ - - + ${CHIBIOS}/os/hal/platforms/STM32/OTGv1 \ + ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 diff --git a/os/hal/platforms/STM32F2xx/stm32_rcc.h b/os/hal/platforms/STM32F2xx/stm32_rcc.h index fefbf656b..af070d814 100644 --- a/os/hal/platforms/STM32F2xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F2xx/stm32_rcc.h @@ -538,6 +538,36 @@ #define rccResetI2C3() rccResetAPB1(RCC_APB1RSTR_I2C3RST) /** @} */ +/** + * @name OTG peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the OTG_FS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp) + +/** + * @brief Disables the OTG_FS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp) + +/** + * @brief Resets the OTG_FS peripheral. + * + * @api + */ +#define rccResetOTG_FS() rccResetAHB2(RCC_AHB2RSTR_OTGFSRST) +/** @} */ + /** * @name SPI peripherals specific RCC operations * @{ diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index 475a5b35c..2decebca4 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -11,10 +11,12 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/OTGv1/usb_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F4xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \ - ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \ No newline at end of file + ${CHIBIOS}/os/hal/platforms/STM32/OTGv1 \ + ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 diff --git a/os/hal/platforms/STM32F4xx/stm32_rcc.h b/os/hal/platforms/STM32F4xx/stm32_rcc.h index f459c192a..de8f1a11e 100644 --- a/os/hal/platforms/STM32F4xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F4xx/stm32_rcc.h @@ -538,6 +538,37 @@ #define rccResetI2C3() rccResetAPB1(RCC_APB1RSTR_I2C3RST) /** @} */ + +/** + * @name OTG peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the OTG_FS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp) + +/** + * @brief Disables the OTG_FS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableOTG_FS(lp) rccEnableAHB2(RCC_AHB2LPENR_OTGFSLPEN, lp) + +/** + * @brief Resets the OTG_FS peripheral. + * + * @api + */ +#define rccResetOTG_FS() rccResetAHB2(RCC_AHB2RSTR_OTGFSRST) +/** @} */ + /** * @name SPI peripherals specific RCC operations * @{ -- cgit v1.2.3