EFM32 USB Device: Is not basically functional with this change. From Pierre-noel Bouteville.

This commit is contained in:
Gregory Nutt 2015-02-16 15:45:49 -06:00
parent ff6b34967b
commit 56b29b00ea
2 changed files with 49 additions and 25 deletions

View File

@ -220,14 +220,14 @@
#define EFM32_USB_DIEP6DMAADDR_OFFSET 0x3c9d4 /* Device IN Endpoint 6 DMA Address Register */ #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_DIEP6TXFSTS_OFFSET 0x3c9d8 /* Device IN Endpoint 6 Transmit FIFO Status Register */
#define EFM32_USB_DOEP_OFFSET(n) (0x3c900 + ((n) << 5)) #define EFM32_USB_DOEP_OFFSET(n) (0x3cb00 + ((n) << 5))
#define EFM32_USB_DOEP0_OFFSET 0x3c900 /* Device OUT Endpoint 0 */ #define EFM32_USB_DOEP0_OFFSET 0x3cb00 /* Device OUT Endpoint 0 */
#define EFM32_USB_DOEP1_OFFSET 0x3c920 /* Device OUT Endpoint 1 */ #define EFM32_USB_DOEP1_OFFSET 0x3cb20 /* Device OUT Endpoint 1 */
#define EFM32_USB_DOEP2_OFFSET 0x3c940 /* Device OUT Endpoint 2 */ #define EFM32_USB_DOEP2_OFFSET 0x3cb40 /* Device OUT Endpoint 2 */
#define EFM32_USB_DOEP3_OFFSET 0x3c960 /* Device OUT Endpoint 3 */ #define EFM32_USB_DOEP3_OFFSET 0x3cb60 /* Device OUT Endpoint 3 */
#define EFM32_USB_DOEP4_OFFSET 0x3c980 /* Device OUT Endpoint 4 */ #define EFM32_USB_DOEP4_OFFSET 0x3cb80 /* Device OUT Endpoint 4 */
#define EFM32_USB_DOEP5_OFFSET 0x3c9a0 /* Device OUT Endpoint 5 */ #define EFM32_USB_DOEP5_OFFSET 0x3cba0 /* Device OUT Endpoint 5 */
#define EFM32_USB_DOEP6_OFFSET 0x3c9c0 /* Device OUT Endpoint 6 */ #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_DOEPnCTL_OFFSET 0x00000 /* Device OUT Endpoint n Control Register */
#define EFM32_USB_DOEPnINT_OFFSET 0x00008 /* Device OUT Endpoint n Interrupt Register */ #define EFM32_USB_DOEPnINT_OFFSET 0x00008 /* Device OUT Endpoint n Interrupt Register */

View File

@ -60,6 +60,8 @@
#include "up_arch.h" #include "up_arch.h"
#include "up_internal.h" #include "up_internal.h"
#include "chip/efm32_cmu.h"
#include "efm32_usb.h" #include "efm32_usb.h"
#if defined(CONFIG_USBDEV) && (defined(CONFIG_EFM32_OTGFS)) #if defined(CONFIG_USBDEV) && (defined(CONFIG_EFM32_OTGFS))
@ -237,7 +239,7 @@
/* Number of endpoints */ /* 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 */ /* 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) static inline void efm32_epin_runtestmode(FAR struct efm32_usbdev_s *priv)
{ {
uint32_t regval = efm32_getreg(EFM32_USB_DCTL); 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; regval |= (uint32_t)priv->testmode << _USB_DCTL_TSTCTL_SHIFT;
efm32_putreg(regval , EFM32_USB_DCTL); 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 */ /* 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 /* Get the state of all enabled interrupts. We will do this repeatedly
* some interrupts (like RXFLVL) will generate additional interrupting * 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); usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPOUT), (uint16_t)regval);
efm32_epout_interrupt(priv); efm32_epout_interrupt(priv);
efm32_putreg(USB_GINTSTS_OEPINT, EFM32_USB_GINTSTS);
} }
/* IN endpoint interrupt. The core sets this bit to indicate that /* 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); usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_EPIN), (uint16_t)regval);
efm32_epin_interrupt(priv); efm32_epin_interrupt(priv);
efm32_putreg(USB_GINTSTS_IEPINT, EFM32_USB_GINTSTS);
} }
/* Host/device mode mismatch error interrupt */ /* Host/device mode mismatch error interrupt */
#ifdef CONFIG_DEBUG_USB #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); 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 #endif
@ -3597,7 +3598,6 @@ static int efm32_usbinterrupt(int irq, FAR void *context)
{ {
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_RXFIFO), (uint16_t)regval); usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_RXFIFO), (uint16_t)regval);
efm32_rxinterrupt(priv); efm32_rxinterrupt(priv);
efm32_putreg(USB_GINTSTS_RXFLVL, EFM32_USB_GINTSTS);
} }
/* USB reset interrupt */ /* USB reset interrupt */
@ -3658,20 +3658,19 @@ static int efm32_usbinterrupt(int irq, FAR void *context)
/* Session request/new session detected interrupt */ /* Session request/new session detected interrupt */
#ifdef CONFIG_USBDEV_VBUSSENSING #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); usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_SRQ), (uint16_t)regval);
efm32_sessioninterrupt(priv); efm32_sessioninterrupt(priv);
efm32_putreg(USB_GINTSTS_SRQ, EFM32_USB_GINTSTS); efm32_putreg(USB_GINTSTS_SESSREQINT, EFM32_USB_GINTSTS);
} }
/* OTG interrupt */ /* OTG interrupt */
if ((regval & USB_GINTSTS_OTG) != 0) if ((regval & USB_GINTSTS_OTGINT) != 0)
{ {
usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OTG), (uint16_t)regval); usbtrace(TRACE_INTDECODE(EFM32_TRACEINTID_OTG), (uint16_t)regval);
efm32_otginterrupt(priv); efm32_otginterrupt(priv);
efm32_putreg(USB_GINTSTS_OTG, EFM32_USB_GINTSTS);
} }
#endif #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_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 |= mpsiz;
regval |= (eptype << _USB_DIEPCTL_EPTYPE_SHIFT); regval |= (eptype << _USB_DIEPCTL_EPTYPE_SHIFT);
regval |= (eptype << _USB_DIEPCTL_TXFNUM_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. * OUT endpoint 0, to receive a SETUP packet.
* - USB_DOEP0CTL.EPENA = 1" * - 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. */ /* 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). * 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(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 */ /* Common USB OTG core initialization */
/* Reset after a PHY select and set Host mode. First, wait for AHB master /* 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 */ /* Force Device Mode */
regval = efm32_getreg(EFM32_USB_GUSBCFG); regval = efm32_getreg(EFM32_USB_GUSBCFG);
regval &= ~_USB_GUSBCFG_FORCEHSTMODE_MASK; regval &= ~(_USB_GUSBCFG_FORCEHSTMODE_MASK | _USB_GUSBCFG_CORRUPTTXPKT_MASK);
regval |= USB_GUSBCFG_FORCEDEVMODE; regval |= USB_GUSBCFG_FORCEDEVMODE;
efm32_putreg(regval, EFM32_USB_GUSBCFG); efm32_putreg(regval, EFM32_USB_GUSBCFG);
up_mdelay(50); up_mdelay(50);
@ -5255,7 +5270,7 @@ static void efm32_hwinitialize(FAR struct efm32_usbdev_s *priv)
/* Set Rx FIFO size */ /* 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 */ /* EP0 TX */
@ -5449,7 +5464,6 @@ void up_usbinitialize(void)
* non-zero value. This takes approximately 20 48-MHz cycles. * non-zero value. This takes approximately 20 48-MHz cycles.
* 10. Start initializing the USB core ... * 10. Start initializing the USB core ...
*/ */
#warning Missing Logic
/* Uninitialize the hardware so that we know that we are starting from a /* Uninitialize the hardware so that we know that we are starting from a
* known state. */ * known state. */
@ -5514,6 +5528,11 @@ void up_usbuninitialize(void)
usbtrace(TRACE_DEVUNINIT, 0); 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) if (priv->driver)
{ {
usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_DRIVERREGISTERED), 0); usbtrace(TRACE_DEVERROR(EFM32_TRACEERR_DRIVERREGISTERED), 0);
@ -5550,6 +5569,11 @@ void up_usbuninitialize(void)
efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_FALL); efm32_txfifo_flush(USB_GRSTCTL_TXFNUM_FALL);
efm32_rxfifo_flush(); 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 */ /* TODO: Turn off USB power and clocking */
priv->devstate = DEVSTATE_DEFAULT; priv->devstate = DEVSTATE_DEFAULT;