summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-02-16 15:45:49 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-02-16 15:45:49 -0600
commit26c0c82e18286a284dd765ea03ec21cee2c047dc (patch)
tree81a8dd6d3a89f54853a6cd92ba45213e746a68d8
parent98895db17d83710abc2b2861f28bfc49d7dc28d0 (diff)
downloadnuttx-26c0c82e18286a284dd765ea03ec21cee2c047dc.tar.gz
nuttx-26c0c82e18286a284dd765ea03ec21cee2c047dc.tar.bz2
nuttx-26c0c82e18286a284dd765ea03ec21cee2c047dc.zip
EFM32 USB Device: Is not basically functional with this change. From Pierre-noel Bouteville.
-rw-r--r--nuttx/arch/arm/src/efm32/chip/efm32_usb.h16
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_usbdev.c58
2 files changed, 49 insertions, 25 deletions
diff --git a/nuttx/arch/arm/src/efm32/chip/efm32_usb.h b/nuttx/arch/arm/src/efm32/chip/efm32_usb.h
index 9de2d1231..92c53e77a 100644
--- a/nuttx/arch/arm/src/efm32/chip/efm32_usb.h
+++ b/nuttx/arch/arm/src/efm32/chip/efm32_usb.h
@@ -220,14 +220,14 @@
#define EFM32_USB_DIEP6DMAADDR_OFFSET 0x3c9d4 /* Device IN Endpoint 6 DMA Address Register */
#define EFM32_USB_DIEP6TXFSTS_OFFSET 0x3c9d8 /* Device IN Endpoint 6 Transmit FIFO Status Register */
-#define EFM32_USB_DOEP_OFFSET(n) (0x3c900 + ((n) << 5))
-#define EFM32_USB_DOEP0_OFFSET 0x3c900 /* Device OUT Endpoint 0 */
-#define EFM32_USB_DOEP1_OFFSET 0x3c920 /* Device OUT Endpoint 1 */
-#define EFM32_USB_DOEP2_OFFSET 0x3c940 /* Device OUT Endpoint 2 */
-#define EFM32_USB_DOEP3_OFFSET 0x3c960 /* Device OUT Endpoint 3 */
-#define EFM32_USB_DOEP4_OFFSET 0x3c980 /* Device OUT Endpoint 4 */
-#define EFM32_USB_DOEP5_OFFSET 0x3c9a0 /* Device OUT Endpoint 5 */
-#define EFM32_USB_DOEP6_OFFSET 0x3c9c0 /* Device OUT Endpoint 6 */
+#define EFM32_USB_DOEP_OFFSET(n) (0x3cb00 + ((n) << 5))
+#define EFM32_USB_DOEP0_OFFSET 0x3cb00 /* Device OUT Endpoint 0 */
+#define EFM32_USB_DOEP1_OFFSET 0x3cb20 /* Device OUT Endpoint 1 */
+#define EFM32_USB_DOEP2_OFFSET 0x3cb40 /* Device OUT Endpoint 2 */
+#define EFM32_USB_DOEP3_OFFSET 0x3cb60 /* Device OUT Endpoint 3 */
+#define EFM32_USB_DOEP4_OFFSET 0x3cb80 /* Device OUT Endpoint 4 */
+#define EFM32_USB_DOEP5_OFFSET 0x3cba0 /* Device OUT Endpoint 5 */
+#define EFM32_USB_DOEP6_OFFSET 0x3cbc0 /* Device OUT Endpoint 6 */
#define EFM32_USB_DOEPnCTL_OFFSET 0x00000 /* Device OUT Endpoint n Control Register */
#define EFM32_USB_DOEPnINT_OFFSET 0x00008 /* Device OUT Endpoint n Interrupt Register */
diff --git a/nuttx/arch/arm/src/efm32/efm32_usbdev.c b/nuttx/arch/arm/src/efm32/efm32_usbdev.c
index afe5e4780..0b6223ca6 100644
--- a/nuttx/arch/arm/src/efm32/efm32_usbdev.c
+++ b/nuttx/arch/arm/src/efm32/efm32_usbdev.c
@@ -60,6 +60,8 @@
#include "up_arch.h"
#include "up_internal.h"
+#include "chip/efm32_cmu.h"
+
#include "efm32_usb.h"
#if defined(CONFIG_USBDEV) && (defined(CONFIG_EFM32_OTGFS))
@@ -237,7 +239,7 @@
/* Number of endpoints */
-#define EFM32_NENDPOINTS (4) /* ep0-3 x 2 for IN and OUT */
+#define EFM32_NENDPOINTS (7) /* ep0-6 x 2 for IN and OUT */
/* Odd physical endpoint numbers are IN; even are OUT */
@@ -2719,7 +2721,7 @@ static inline void efm32_epout_interrupt(FAR struct efm32_usbdev_s *priv)
static inline void efm32_epin_runtestmode(FAR struct efm32_usbdev_s *priv)
{
uint32_t regval = efm32_getreg(EFM32_USB_DCTL);
- regval &= _USB_DCTL_TSTCTL_MASK;
+ regval &= ~_USB_DCTL_TSTCTL_MASK;
regval |= (uint32_t)priv->testmode << _USB_DCTL_TSTCTL_SHIFT;
efm32_putreg(regval , EFM32_USB_DCTL);
@@ -3505,7 +3507,8 @@ static int efm32_usbinterrupt(int irq, FAR void *context)
/* Assure that we are in device mode */
- DEBUGASSERT((efm32_getreg(EFM32_USB_GINTSTS) & USB_GINTSTS_CMOD) == USB_GINTSTS_DEVMODE);
+ DEBUGASSERT((efm32_getreg(EFM32_USB_GINTSTS) & USB_GINTSTS_CURMOD) ==
+ USB_GINTSTS_CURMOD_DEVICE);
/* Get the state of all enabled interrupts. We will do this repeatedly
* some interrupts (like RXFLVL) will generate additional interrupting
@@ -3537,7 +3540,6 @@ static int efm32_usbinterrupt(int irq, FAR void *context)
{
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPOUT), (uint16_t)regval);
efm32_epout_interrupt(priv);
- efm32_putreg(USB_GINTSTS_OEPINT, EFM32_USB_GINTSTS);
}
/* IN endpoint interrupt. The core sets this bit to indicate that
@@ -3548,16 +3550,15 @@ static int efm32_usbinterrupt(int irq, FAR void *context)
{
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN), (uint16_t)regval);
efm32_epin_interrupt(priv);
- efm32_putreg(USB_GINTSTS_IEPINT, EFM32_USB_GINTSTS);
}
/* Host/device mode mismatch error interrupt */
#ifdef CONFIG_DEBUG_USB
- if ((regval & USB_GINTSTS_MMIS) != 0)
+ if ((regval & USB_GINTSTS_MODEMIS) != 0)
{
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_MISMATCH), (uint16_t)regval);
- efm32_putreg(USB_GINTSTS_MMIS, EFM32_USB_GINTSTS);
+ efm32_putreg(USB_GINTSTS_MODEMIS, EFM32_USB_GINTSTS);
}
#endif
@@ -3597,7 +3598,6 @@ static int efm32_usbinterrupt(int irq, FAR void *context)
{
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_RXFIFO), (uint16_t)regval);
efm32_rxinterrupt(priv);
- efm32_putreg(USB_GINTSTS_RXFLVL, EFM32_USB_GINTSTS);
}
/* USB reset interrupt */
@@ -3658,20 +3658,19 @@ static int efm32_usbinterrupt(int irq, FAR void *context)
/* Session request/new session detected interrupt */
#ifdef CONFIG_USBDEV_VBUSSENSING
- if ((regval & USB_GINTSTS_SRQ) != 0)
+ if ((regval & USB_GINTSTS_SESSREQINT) != 0)
{
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SRQ), (uint16_t)regval);
efm32_sessioninterrupt(priv);
- efm32_putreg(USB_GINTSTS_SRQ, EFM32_USB_GINTSTS);
+ efm32_putreg(USB_GINTSTS_SESSREQINT, EFM32_USB_GINTSTS);
}
/* OTG interrupt */
- if ((regval & USB_GINTSTS_OTG) != 0)
+ if ((regval & USB_GINTSTS_OTGINT) != 0)
{
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OTG), (uint16_t)regval);
efm32_otginterrupt(priv);
- efm32_putreg(USB_GINTSTS_OTG, EFM32_USB_GINTSTS);
}
#endif
}
@@ -3919,7 +3918,8 @@ static int efm32_epin_configure(FAR struct efm32_ep_s *privep, uint8_t eptype,
regval |= USB_DIEPCTL_CNAK;
}
- regval &= ~(_USB_DIEPCTL_MPS_MASK | _USB_DIEPCTL_EPTYPE_MASK | _USB_DIEPCTL_TXFNUM_MASK);
+ regval &= ~(_USB_DIEPCTL_MPS_MASK | _USB_DIEPCTL_EPTYPE_MASK |
+ _USB_DIEPCTL_TXFNUM_MASK);
regval |= mpsiz;
regval |= (eptype << _USB_DIEPCTL_EPTYPE_SHIFT);
regval |= (eptype << _USB_DIEPCTL_TXFNUM_SHIFT);
@@ -5184,7 +5184,11 @@ static void efm32_hwinitialize(FAR struct efm32_usbdev_s *priv)
* OUT endpoint 0, to receive a SETUP packet.
* - USB_DOEP0CTL.EPENA = 1"
*/
-#warning Review for missing logic
+
+ /* First Turn on USB clocking */
+
+ modifyreg32(EFM32_CMU_HFCORECLKEN0,0,
+ CMU_HFCORECLKEN0_USB|CMU_HFCORECLKEN0_USBC);
/* At start-up the core is in FS mode. */
@@ -5193,7 +5197,18 @@ static void efm32_hwinitialize(FAR struct efm32_usbdev_s *priv)
* interrupts will occur when the TxFIFO is truly empty (not just half full).
*/
+ /* I never saw this in original EFM32 lib
+ * and in refrence manual I found:
+ * "Non-periodic TxFIFO Empty Level (can be enabled only when the core is
+ * operating in Slave mode as a host.)"
+ */
+
efm32_putreg(USB_GAHBCFG_NPTXFEMPLVL_EMPTY, EFM32_USB_GAHBCFG);
+ //efm32_putreg(0, EFM32_USB_GAHBCFG);
+
+ /* Enable PHY USB */
+
+ efm32_putreg(USB_ROUTE_PHYPEN, EFM32_USB_ROUTE);
/* Common USB OTG core initialization */
/* Reset after a PHY select and set Host mode. First, wait for AHB master
@@ -5229,7 +5244,7 @@ static void efm32_hwinitialize(FAR struct efm32_usbdev_s *priv)
/* Force Device Mode */
regval = efm32_getreg(EFM32_USB_GUSBCFG);
- regval &= ~_USB_GUSBCFG_FORCEHSTMODE_MASK;
+ regval &= ~(_USB_GUSBCFG_FORCEHSTMODE_MASK | _USB_GUSBCFG_CORRUPTTXPKT_MASK);
regval |= USB_GUSBCFG_FORCEDEVMODE;
efm32_putreg(regval, EFM32_USB_GUSBCFG);
up_mdelay(50);
@@ -5255,7 +5270,7 @@ static void efm32_hwinitialize(FAR struct efm32_usbdev_s *priv)
/* Set Rx FIFO size */
- efm32_putreg(EFM32_RXFIFO_WORDS, EFM32_USB_GRXFSIZ);
+ efm32_putreg(EFM32_RXFIFO_WORDS << _USB_GRXFSIZ_RXFDEP_SHIFT,EFM32_USB_GRXFSIZ);
/* EP0 TX */
@@ -5449,7 +5464,6 @@ void up_usbinitialize(void)
* non-zero value. This takes approximately 20 48-MHz cycles.
* 10. Start initializing the USB core ...
*/
-#warning Missing Logic
/* Uninitialize the hardware so that we know that we are starting from a
* known state. */
@@ -5514,6 +5528,11 @@ void up_usbuninitialize(void)
usbtrace(TRACE_DEVUNINIT, 0);
+ /* To be sure that usb ref are writen, turn on USB clocking */
+
+ modifyreg32(EFM32_CMU_HFCORECLKEN0, 0,
+ CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC);
+
if (priv->driver)
{
usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_DRIVERREGISTERED), 0);
@@ -5550,6 +5569,11 @@ void up_usbuninitialize(void)
efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_FALL);
efm32_rxfifo_flush();
+ /* Turn off USB clocking */
+
+ modifyreg32(EFM32_CMU_HFCORECLKEN0,
+ CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC, 0);
+
/* TODO: Turn off USB power and clocking */
priv->devstate = DEVSTATE_DEFAULT;