summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-04 18:01:00 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-04 18:01:00 +0000
commitd5f7e9864a455f3e0a3c34ff29b5a8604cd655b5 (patch)
treedb87bf10dc5cc7764f8b8cdfcdf686742c65b500 /nuttx
parentb9764fdea3cd940533d60fee3aa12971ea3cb7c9 (diff)
downloadnuttx-d5f7e9864a455f3e0a3c34ff29b5a8604cd655b5.tar.gz
nuttx-d5f7e9864a455f3e0a3c34ff29b5a8604cd655b5.tar.bz2
nuttx-d5f7e9864a455f3e0a3c34ff29b5a8604cd655b5.zip
Add STM32 OTG FS device endpoint stall logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4556 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/Documentation/NuttShell.html2
-rwxr-xr-xnuttx/arch/arm/src/stm32/stm32_otgfsdev.c182
2 files changed, 159 insertions, 25 deletions
diff --git a/nuttx/Documentation/NuttShell.html b/nuttx/Documentation/NuttShell.html
index ea851026d..409d191a7 100644
--- a/nuttx/Documentation/NuttShell.html
+++ b/nuttx/Documentation/NuttShell.html
@@ -511,7 +511,7 @@ fi
<table width ="100%">
<tr bgcolor="#e4e4e4">
<td>
- <a name="startupscript"><h2>1.7 NSH Start-Up Scrip</h2></a>
+ <a name="startupscript"><h2>1.7 NSH Start-Up Script</h2></a>
</td>
</tr>
</table>
diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
index c33fb409a..56622e9a0 100755
--- a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
+++ b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
@@ -508,7 +508,17 @@ static int stm32_epsubmit(FAR struct usbdev_ep_s *ep,
struct usbdev_req_s *req);
static int stm32_epcancel(FAR struct usbdev_ep_s *ep,
struct usbdev_req_s *req);
+
+/* Stall handling */
+
+static int stm32_epsetstall(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep);
+static int stm32_epclrstall(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep)
static int stm32_epstall(FAR struct usbdev_ep_s *ep, bool resume);
+static void stm32_ep0stall(FAR struct stm32_usbdev_s *priv);
+
+/* Endpoint allocation */
static FAR struct usbdev_ep_s *stm32_allocep(FAR struct usbdev_s *dev,
uint8_t epno, bool in, uint8_t eptype);
@@ -1415,7 +1425,7 @@ static inline void stm32_stdrequest(struct stm32_usbdev_s *priv,
else if (priv->paddrset != 0 && ctrlreq->value == USB_FEATURE_ENDPOINTHALT && ctrlreq->len == 0 &&
(privep = stm32_epfindbyaddr(priv, ctrlreq->index)) != NULL)
{
- stm32_epstall(&privep->ep, true);
+ stm32_epclrstall(priv, &privep->ep);
stm32_ep0state(priv, EP0STATE_NAK_IN);
}
else
@@ -1447,7 +1457,7 @@ static inline void stm32_stdrequest(struct stm32_usbdev_s *priv,
else if (priv->paddrset != 0 && ctrlreq->value == USB_FEATURE_ENDPOINTHALT && ctrlreq->len == 0 &&
(privep = stm32_epfindbyaddr(priv, ctrlreq->index)) != NULL)
{
- stm32_epstall(&privep->ep, false);
+ stm32_epsetstall(priv, privep);
stm32_ep0state(priv, EP0STATE_NAK_IN);
}
else
@@ -1663,8 +1673,7 @@ static inline void stm32_ep0setup(struct stm32_usbdev_s *priv)
if (priv->stalled)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state);
- stm32_epstall(&priv->epin[STM32_EP0_IN].ep, false);
- stm32_epstall(&priv->epin[STM32_EP0_OUT].ep, false);
+ stm32_ep0stall(priv);
}
}
@@ -1745,8 +1754,7 @@ static void stm32_ep0complete(struct stm32_usbdev_s *priv, uint8_t epphy)
if (priv->stalled)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state);
- stm32_epstall(&priv->epin[STM32_EP0_IN].ep, false);
- stm32_epstall(&priv->epin[STM32_EP0_OUT].ep, false);
+ stm32_ep0stall(priv);
}
}
@@ -2627,47 +2635,173 @@ static int stm32_epcancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *r
}
/*******************************************************************************
- * Name: stm32_epstall
+ * Name: stm32_epsetstall
*
* Description:
- * Stall or resume and endpoint
+ * Stall an endpoint
*
*******************************************************************************/
-static int stm32_epstall(FAR struct usbdev_ep_s *ep, bool resume)
+static int stm32_epsetstall(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep)
{
- FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
- irqstate_t flags;
+ uint32_t regaddr;
+ uint32_t regval;
- /* STALL or RESUME the endpoint */
+ usbtrace(TRACE_EPSTALL, privep->epphy);
- flags = irqsave();
- usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, privep->epphy);
+ /* Is this an IN endpoint? */
- uint32_t addr = STM32_USBDEV_ENDPTCTRL(privep->epphy);
- uint32_t ctrl_xs = STM32_EPPHYIN(privep->epphy) ? USBDEV_ENDPTCTRL_TXS : USBDEV_ENDPTCTRL_RXS;
- uint32_t ctrl_xr = STM32_EPPHYIN(privep->epphy) ? USBDEV_ENDPTCTRL_TXR : USBDEV_ENDPTCTRL_RXR;
+ if (privep->isin == 1)
+ {
+ /* Get the IN endpoint device control register */
- if (resume)
+ regaddr = STM32_OTGFS_DIEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+
+ /* Is the endpoint enabled? */
+
+ if ((regval & OTGFS_DIEPCTL_EPENA) != 0)
+ {
+ /* Yes.. the endpoint is enabled, disable it */
+
+ regval = OTGFS_DIEPCTL_EPDIS;
+ }
+ else
+ {
+ regval = 0;
+ }
+
+ /* Then stall the endpoint */
+
+ regval |= OTGFS_DIEPCTL_STALL;
+ stm32_putreg(regval, regaddr);
+ }
+ else
{
- privep->stalled = false;
+ /* Get the OUT endpoint device control register */
+
+ regaddr = STM32_OTGFS_DOEPCTL(privep->epphy);
+ regval = stm32_getreg(regaddr);
+
+ /* Then stall the endpoint */
+
+ regval |= OTGFS_DOEPCTL_STALL;
+ stm32_putreg(regval, regaddr);
+ }
+
+ /* The endpoint is now stalled */
+
+ privep->stalled = true;
+ return OK;
+}
+
+/*******************************************************************************
+ * Name: stm32_epclrstall
+ *
+ * Description:
+ * Resume a stalled endpoint
+ *
+ *******************************************************************************/
+
+static int stm32_epclrstall(FAR struct stm32_usbdev_s *priv,
+ FAR struct stm32_ep_s *privep)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t stallbit;
+ uint32_t data0bit;
+
+ usbtrace(TRACE_EPRESUME, privep->epphy);
+
+ /* Is this an IN endpoint? */
- /* Clear stall and reset the data toggle */
+ if (privep->isin == 1)
+ {
+ /* Clear the stall bit in the IN endpoint device control register */
- stm32_chgbits (ctrl_xs | ctrl_xr, ctrl_xr, addr);
+ regaddr = STM32_OTGFS_DIEPCTL(privep->epphy);
+ stallbit = OTGFS_DIEPCTL_STALL;
+ data0bit = OTGFS_DIEPCTL_SD0PID;
}
else
{
- privep->stalled = true;
+ /* Clear the stall bit in the IN endpoint device control register */
- stm32_setbits (ctrl_xs, addr);
+ regaddr = STM32_OTGFS_DOEPCTL(privep->epphy);
+ stallbit = OTGFS_DOEPCTL_STALL;
+ data0bit = OTGFS_DOEPCTL_SD0PID;
}
- irqrestore(flags);
+ /* Clear the stall bit */
+
+ regval = stm32_getreg(regaddr);
+ regval &= ~stallbit;
+
+ /* Set the DATA0 pid for interrupt and bulk endpoints */
+
+ if (privep->eptype == USB_EP_ATTR_XFER_INT ||
+ privep->eptype == USB_EP_ATTR_XFER_BULK)
+ {
+ /* Writing this bit sets the DATA0 PID */
+
+ regval |= data0bit;
+ }
+
+ stm32_putreg(regval, regaddr);
+
+ /* The endpoint is no longer stalled */
+
+ privep->stalled = false;
return OK;
}
/*******************************************************************************
+ * Name: stm32_epstall
+ *
+ * Description:
+ * Stall or resume an endpoint
+ *
+ *******************************************************************************/
+
+static int stm32_epstall(FAR struct usbdev_ep_s *ep, bool resume)
+{
+ FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep;
+ irqstate_t flags;
+ int ret;
+
+ /* Set or clear the stall condition as requested */
+
+ flags = irqsave();
+ if (resume)
+ {
+ ret = stm32_epclrstall(priv, privep);
+ }
+ else
+ {
+ ret = stm32_epsetstall(priv, privep);
+ }
+ irqrestore(flags);
+
+ return ret;
+}
+
+/*******************************************************************************
+ * Name: stm32_ep0stall
+ *
+ * Description:
+ * Stall endpoint 0
+ *
+ *******************************************************************************/
+
+static void stm32_ep0stall(FAR struct stm32_usbdev_s *priv)
+{
+ stm32_epsetstall(priv, &priv->epin[EP0]);
+ stm32_epsetstall(priv, &priv->epout[EP0]);
+ stm32_ep0outstart(priv);
+}
+
+/*******************************************************************************
* Device operations
*******************************************************************************/