summaryrefslogtreecommitdiff
path: root/nuttx/arch
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-10 21:45:29 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-10 21:45:29 +0000
commitc952b2e5ede8c4425ca5c41eb1e2853644838a51 (patch)
tree19c4d1f621248bcbc504f5fd0cc822175296b270 /nuttx/arch
parente2feecfd5f789ffe344334aae81c156b3d61d0f6 (diff)
downloadpx4-nuttx-c952b2e5ede8c4425ca5c41eb1e2853644838a51.tar.gz
px4-nuttx-c952b2e5ede8c4425ca5c41eb1e2853644838a51.tar.bz2
px4-nuttx-c952b2e5ede8c4425ca5c41eb1e2853644838a51.zip
Updated STM32 OTG FS device driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4584 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch')
-rwxr-xr-xnuttx/arch/arm/src/stm32/stm32_otgfsdev.c78
1 files changed, 69 insertions, 9 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
index 7e67556ce..aa55b2e70 100755
--- a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
+++ b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
@@ -810,10 +810,18 @@ static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv)
{
uint32_t regval;
+ /* Setup the hardware to perform the SETUP transfer */
+
regval = (USB_SIZEOF_CTRLREQ * 3 << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) |
(OTGFS_DOEPTSIZ0_PKTCNT) |
(3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT);
stm32_putreg(regval, STM32_OTGFS_DOEPTSIZ0);
+
+ /* Then clear NAKing and enable the transfer */
+
+ regval = stm32_getreg(STM32_OTGFS_DOEPCTL0);
+ regval |= (OTGFS_DOEPCTL0_CNAK | OTGFS_DOEPCTL0_EPENA);
+ stm32_putreg(regval, STM32_OTGFS_DOEPCTL0);
}
/****************************************************************************
@@ -2271,7 +2279,8 @@ static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv)
/* Endpoint disabled interrupt (ignored because this interrrupt is
* used in polled mode by the endpoint disable logic).
*/
-#if 0
+#if 1
+#warning "REVISIT"
if ((doepint & OTGFS_DOEPINT_EPDISD) != 0)
{
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_EPDISD), (uint16_t)doepint);
@@ -2834,6 +2843,7 @@ static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv)
*/
stm32_req_complete(privep, -EIO);
+#warning "Will clear OTGFS_DIEPCTL_USBAEP too"
stm32_epin_disable(privep);
break;
}
@@ -2915,6 +2925,7 @@ static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv)
*/
stm32_req_complete(privep, -EIO);
+#warning "Will clear OTGFS_DOEPCTL_USBAEP too"
stm32_epout_disable(privep);
break;
}
@@ -3178,7 +3189,9 @@ static void stm32_enablegonak(FAR struct stm32_ep_s *privep)
/* First, make sure that there is no GNOAKEFF interrupt pending. */
+#if 0
stm32_putreg(OTGFS_GINT_GONAKEFF, STM32_OTGFS_GINTSTS);
+#endif
/* Enable Global OUT NAK mode in the core. */
@@ -3187,11 +3200,23 @@ static void stm32_enablegonak(FAR struct stm32_ep_s *privep)
stm32_putreg(regval, STM32_OTGFS_DCTL);
/* Wait for the GONAKEFF interrupt that indicates that the OUT NAK
- * mode is in effect.
+ * mode is in effect. When the interrupt handler pops the OUTNAK word
+ * from the RxFIFO, the core sets the GONAKEFF interrupt.
*/
+#if 0
while ((stm32_getreg(STM32_OTGFS_GINTSTS) & OTGFS_GINT_GONAKEFF) == 0);
stm32_putreg(OTGFS_GINT_GONAKEFF, STM32_OTGFS_GINTSTS);
+
+ /* Since we are in the interrupt handler, we cannot wait inline for the
+ * GONAKEFF because it cannot occur until service th RXFLVL global interrupt
+ * and pop the OUTNAK word from the RxFIFO.
+ */
+
+#else
+#warning "REVISIT"
+ up_mdelay(50);
+#endif
}
/*******************************************************************************
@@ -3280,7 +3305,7 @@ static int stm32_epout_configure(FAR struct stm32_ep_s *privep, uint8_t eptype,
regaddr = STM32_OTGFS_DOEPCTL(privep->epphy);
regval = stm32_getreg(regaddr);
- if ((regval & OTGFS_DOEPCTL_USBAEP) != 0)
+ if ((regval & OTGFS_DOEPCTL_USBAEP) == 0)
{
regval &= ~(OTGFS_DOEPCTL_MPSIZ_MASK | OTGFS_DIEPCTL_EPTYP_MASK | OTGFS_DIEPCTL_TXFNUM_MASK);
regval |= mpsiz;
@@ -3372,7 +3397,7 @@ static int stm32_epin_configure(FAR struct stm32_ep_s *privep, uint8_t eptype,
regaddr = STM32_OTGFS_DIEPCTL(privep->epphy);
regval = stm32_getreg(regaddr);
- if ((regval & OTGFS_DIEPCTL_USBAEP) != 0)
+ if ((regval & OTGFS_DIEPCTL_USBAEP) == 0)
{
regval &= ~(OTGFS_DIEPCTL_MPSIZ_MASK | OTGFS_DIEPCTL_EPTYP_MASK | OTGFS_DIEPCTL_TXFNUM_MASK);
regval |= mpsiz;
@@ -3500,8 +3525,13 @@ static void stm32_epout_disable(FAR struct stm32_ep_s *privep)
* endpoint is completely disabled.
*/
- regaddr = STM32_OTGFS_DOEPINT_OFFSET(privep->epphy);
+#if 0 /* Doesn't happen */
+ regaddr = STM32_OTGFS_DOEPINT(privep->epphy);
while ((stm32_getreg(regaddr) & OTGFS_DOEPINT_EPDISD) == 0);
+#else
+# warning "REVISIT"
+ up_mdelay(50);
+#endif
/* Then disble the Global OUT NAK mode to continue receiving data
* from other non-disabled OUT endpoints.
@@ -3573,7 +3603,7 @@ static void stm32_epin_disable(FAR struct stm32_ep_s *privep)
* endpoint is completely disabled.
*/
- regaddr = STM32_OTGFS_DIEPINT_OFFSET(privep->epphy);
+ regaddr = STM32_OTGFS_DIEPINT(privep->epphy);
while ((stm32_getreg(regaddr) & OTGFS_DIEPINT_EPDISD) == 0);
/* Flush any data remaining in the TxFIFO */
@@ -3855,6 +3885,11 @@ static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *
static int stm32_epout_setstall(FAR struct stm32_ep_s *privep)
{
+#if 0
+ /* This implementation follows the requirements from the STM32 F4 reference
+ * manual.
+ */
+
uint32_t regaddr;
uint32_t regval;
@@ -3863,12 +3898,11 @@ static int stm32_epout_setstall(FAR struct stm32_ep_s *privep)
stm32_enablegonak(privep);
/* Disable and STALL the OUT endpoint by setting the EPDIS and STALL bits
- * int DOECPTL register.
+ * in the DOECPTL register.
*/
regaddr = STM32_OTGFS_DOEPCTL(privep->epphy);
regval = stm32_getreg(regaddr);
- regval &= ~OTGFS_DOEPCTL_USBAEP;
regval |= (OTGFS_DOEPCTL_EPDIS | OTGFS_DOEPCTL_STALL);
stm32_putreg(regval, regaddr);
@@ -3876,8 +3910,13 @@ static int stm32_epout_setstall(FAR struct stm32_ep_s *privep)
* endpoint is completely disabled.
*/
- regaddr = STM32_OTGFS_DOEPINT_OFFSET(privep->epphy);
+#if 0 /* Doesn't happen */
+ regaddr = STM32_OTGFS_DOEPINT(privep->epphy);
while ((stm32_getreg(regaddr) & OTGFS_DOEPINT_EPDISD) == 0);
+#else
+# warning "REVISIT"
+ up_mdelay(50);
+#endif
/* Disable Global OUT NAK mode */
@@ -3887,6 +3926,27 @@ static int stm32_epout_setstall(FAR struct stm32_ep_s *privep)
privep->stalled = true;
return OK;
+#else
+ /* This implementation follows the STMicro code example. */
+#warning "REVISIT"
+
+ uint32_t regaddr;
+ uint32_t regval;
+
+ /* Disable and STALL the OUT endpoint by setting the STALL bit
+ * int DOECPTL register.
+ */
+
+ regaddr = STM32_OTGFS_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+ regval |= OTGFS_DOEPCTL_STALL;
+ stm32_putreg(regval, regaddr);
+
+ /* The endpoint is now stalled */
+
+ privep->stalled = true;
+ return OK;
+#endif
}
/*******************************************************************************