Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/thirdpin/libopencm3.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Stolyarov <i.stolyarov@thirdpin.ru>2019-07-07 20:28:04 +0300
committerIlya Stolyarov <i.stolyarov@thirdpin.ru>2019-07-07 20:28:04 +0300
commit9035b0400a4588070594e3e43086a207acf325bf (patch)
tree3285187c362d65667008fbeca279c0640ce5f29e
parent184f9e4e6d8ea1030580bd2595b4828a0f93a41e (diff)
FIX: [usb] Delay after RCC enable
-rw-r--r--include/libopencm3/usb/dwc/otg_hs.h12
-rw-r--r--include/libopencm3/usb/usbd.h4
-rw-r--r--lib/usb/usb_dwc.c44
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 <libopencm3/usb/dwc/otg_hs.h>
#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;