From 9035b0400a4588070594e3e43086a207acf325bf Mon Sep 17 00:00:00 2001 From: Ilya Stolyarov Date: Sun, 7 Jul 2019 20:28:04 +0300 Subject: FIX: [usb] Delay after RCC enable --- include/libopencm3/usb/dwc/otg_hs.h | 12 +++++++++- include/libopencm3/usb/usbd.h | 4 +++- lib/usb/usb_dwc.c | 44 ++++++++++++++++++++++++------------- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/include/libopencm3/usb/dwc/otg_hs.h b/include/libopencm3/usb/dwc/otg_hs.h index 99b24a9b..b85d7c61 100644 --- a/include/libopencm3/usb/dwc/otg_hs.h +++ b/include/libopencm3/usb/dwc/otg_hs.h @@ -183,6 +183,16 @@ #define OTG_GUSBCFG_PHYLPCS (1 << 15) /* OTG device configuration register (OTG_DCFG) */ -#define OTG_DCFG_DSPD_FS_EXT (0x2 << 0) +#define OTG_DCFG_DSPD_HS_EXT (0x0 << 0) +#define OTG_DCFG_DSPD_FS_EXT (0x1 << 0) + +/* OTG AHB configuration register (OTG_GAHBCFG) */ +#define OTG_GAHBCFG_HBSTLEN_MASK (0xf << 1) +#define OTG_GAHBCFG_HBSTLEN_SINGLE (0b0000 << 1) +#define OTG_GAHBCFG_HBSTLEN_INCR (0b0001 << 1) +#define OTG_GAHBCFG_HBSTLEN_INCR4 (0b0011 << 1) +#define OTG_GAHBCFG_HBSTLEN_INCR8 (0b0101 << 1) +#define OTG_GAHBCFG_HBSTLEN_INCR16 (0b0111 << 1) +#define OTG_GAHBCFG_DMAEN (1 << 5) #endif diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index a213eeb4..3decd762 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -55,11 +55,13 @@ typedef struct _usbd_device usbd_device; extern const usbd_driver st_usbfs_v1_usb_driver; extern const usbd_driver stm32f107_usb_driver; extern const usbd_driver stm32f207_usb_driver; +extern const usbd_driver stm32_dwc_usb_driver; extern const usbd_driver stm32_dwc_usb_driver_ulpi; extern const usbd_driver st_usbfs_v2_usb_driver; #define otgfs_usb_driver stm32f107_usb_driver #define otghs_usb_driver stm32f207_usb_driver -#define otghs_usb_driver_ulpi stm32_dwc_usb_driver_ulpi +#define otghs_usb_driver_dwc stm32_dwc_usb_driver +#define otghs_usb_driver_dwc_ulpi stm32_dwc_usb_driver_ulpi extern const usbd_driver efm32lg_usb_driver; extern const usbd_driver efm32hg_usb_driver; extern const usbd_driver lm4f_usb_driver; diff --git a/lib/usb/usb_dwc.c b/lib/usb/usb_dwc.c index bb58baa7..8da22959 100644 --- a/lib/usb/usb_dwc.c +++ b/lib/usb/usb_dwc.c @@ -25,6 +25,7 @@ #include #include "usb_private.h" #include "usb_dwc_common.h" +#include "libopencm3/stm32/memorymap.h" /* Receive FIFO size in 32-bit words. */ #define RX_FIFO_SIZE 512 @@ -113,16 +114,9 @@ static usbd_device *stm32_dwc_usbd_init(void) static usbd_device *stm32_dwc_ulpi_usbd_init(void) { rcc_periph_clock_enable(RCC_OTGHS); - OTG_HS_GINTSTS = OTG_GINTSTS_MMIS; - - /* Disable internal PHY */ - OTG_HS_GCCFG &= ~(OTG_GCCFG_PWRDWN); - - /* Init The ULPI Interface */ - OTG_HS_GUSBCFG &= ~(OTG_GUSBCFG_TSDPS | OTG_GUSBCFG_ULPIFSLS | OTG_GUSBCFG_PHYSEL); - - /* Select vbus source */ - OTG_HS_GUSBCFG &= ~(OTG_GUSBCFG_ULPIEVBUSD | OTG_GUSBCFG_ULPIEVBUSI); + __asm__("dsb"); // Errata RCC peripheral limitation + rcc_periph_clock_enable(RCC_OTGHSULPI); + __asm__("dsb"); // Errata RCC peripheral limitation /* Wait for AHB idle. */ while (!(OTG_HS_GRSTCTL & OTG_GRSTCTL_AHBIDL)); @@ -131,16 +125,35 @@ static usbd_device *stm32_dwc_ulpi_usbd_init(void) while (OTG_HS_GRSTCTL & OTG_GRSTCTL_CSRST); /* Force peripheral only mode. */ - OTG_HS_GUSBCFG |= OTG_GUSBCFG_FDMOD | OTG_GUSBCFG_TRDT_MASK; - + OTG_HS_GUSBCFG |= OTG_GUSBCFG_FDMOD; /* Full speed external ULPI PHY device. */ - OTG_HS_DCFG |= OTG_DCFG_DSPD_FS_EXT; + OTG_HS_DCFG |= OTG_DCFG_DSPD_HS_EXT; /* Restart the PHY clock. */ OTG_HS_PCGCCTL = 0; - OTG_HS_GRXFSIZ = stm32_dwc_usb_driver.rx_fifo_size; - usbd_dev.fifo_mem_top = stm32_dwc_usb_driver.rx_fifo_size; + OTG_HS_GRXFSIZ = stm32_dwc_usb_driver_ulpi.rx_fifo_size; + usbd_dev.fifo_mem_top = stm32_dwc_usb_driver_ulpi.rx_fifo_size; + + /* Flush the FIFOs */ + OTG_HS_GRSTCTL = (OTG_GRSTCTL_TXFFLSH | (0x10U << 6)); + while ((OTG_HS_GRSTCTL & OTG_GRSTCTL_TXFFLSH) == OTG_GRSTCTL_TXFFLSH) + ; + + OTG_HS_GRSTCTL = OTG_GRSTCTL_RXFFLSH; + while ((OTG_HS_GRSTCTL & OTG_GRSTCTL_RXFFLSH) == OTG_GRSTCTL_RXFFLSH) + ; + + /* Clear all pending Device Interrupts */ + OTG_HS_DIEPMSK = 0U; + OTG_HS_DOEPMSK = 0U; + OTG_HS_DAINTMSK = 0U; + + /* Disable all interrupts. */ + OTG_HS_GINTMSK = 0U; + + /* Clear any pending interrupts */ + OTG_HS_GINTSTS = 0xBFFFFFFFU; /* Unmask interrupts for TX and RX. */ OTG_HS_GAHBCFG |= OTG_GAHBCFG_GINT; @@ -149,6 +162,7 @@ static usbd_device *stm32_dwc_ulpi_usbd_init(void) OTG_GINTMSK_IEPINT | OTG_GINTMSK_USBSUSPM | OTG_GINTMSK_WUIM; + OTG_HS_DAINTMSK = 0xF; OTG_HS_DIEPMSK = OTG_DIEPMSK_XFRCM; -- cgit v1.2.3