summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/stm32/stm32_usbdev.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-02-11 14:31:37 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-02-11 14:31:37 +0000
commit260d6c44c8f61cf6bae4b74291825c1eebd17651 (patch)
tree5f2e6cdaec264b3ef771a862c826eefde05450a5 /nuttx/arch/arm/src/stm32/stm32_usbdev.c
parent06b19cfdfc0a9c298ade22a468df8c5f45c6960e (diff)
downloadpx4-nuttx-260d6c44c8f61cf6bae4b74291825c1eebd17651.tar.gz
px4-nuttx-260d6c44c8f61cf6bae4b74291825c1eebd17651.tar.bz2
px4-nuttx-260d6c44c8f61cf6bae4b74291825c1eebd17651.zip
Fix some errors in how STM32 USB F3 state was being handled. Fix is correct, but does not change behavior
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5639 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/stm32/stm32_usbdev.c')
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_usbdev.c112
1 files changed, 59 insertions, 53 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_usbdev.c b/nuttx/arch/arm/src/stm32/stm32_usbdev.c
index 2dc8c1edf..6036eb3d5 100644
--- a/nuttx/arch/arm/src/stm32/stm32_usbdev.c
+++ b/nuttx/arch/arm/src/stm32/stm32_usbdev.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/stm32/stm32_usbdev.c
*
- * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.orgr>
*
* References:
@@ -266,12 +266,12 @@
/* The various states of a control pipe */
-enum stm32_devstate_e
+enum stm32_ep0state_e
{
- DEVSTATE_IDLE = 0, /* No request in progress */
- DEVSTATE_RDREQUEST, /* Read request in progress */
- DEVSTATE_WRREQUEST, /* Write request in progress */
- DEVSTATE_STALLED /* We are stalled */
+ EP0STATE_IDLE = 0, /* No request in progress */
+ EP0STATE_RDREQUEST, /* Read request in progress */
+ EP0STATE_WRREQUEST, /* Write request in progress */
+ EP0STATE_STALLED /* We are stalled */
};
/* Resume states */
@@ -336,7 +336,7 @@ struct stm32_usbdev_s
/* STM32-specific fields */
struct usb_ctrlreq_s ctrl; /* Last EP0 request */
- uint8_t devstate; /* Driver state (see enum stm32_devstate_e) */
+ uint8_t ep0state; /* State of EP0 (see enum stm32_ep0state_e) */
uint8_t rsmstate; /* Resume state (see enum stm32_rsmstate_e) */
uint8_t nesofs; /* ESOF counter (for resume support) */
uint8_t rxpending:1; /* 1: OUT data in PMA, but no read requests */
@@ -1158,7 +1158,7 @@ static void stm32_reqcomplete(struct stm32_ep_s *privep, int16_t result)
bool stalled = privep->stalled;
if (USB_EPNO(privep->ep.eplog) == EP0)
{
- privep->stalled = (privep->dev->devstate == DEVSTATE_STALLED);
+ privep->stalled = (privep->dev->ep0state == EP0STATE_STALLED);
}
/* Save the result in the request structure */
@@ -1238,8 +1238,7 @@ static int stm32_wrrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
*/
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPINQEMPTY), 0);
- priv->devstate = DEVSTATE_IDLE;
- return OK;
+ return -ENOENT;
}
epno = USB_EPNO(privep->ep.eplog);
@@ -1283,7 +1282,6 @@ static int stm32_wrrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
buf = privreq->req.buf + privreq->req.xfrd;
stm32_epwrite(priv, privep, buf, nbytes);
- priv->devstate = DEVSTATE_WRREQUEST;
/* Update for the next data IN interrupt */
@@ -1291,15 +1289,16 @@ static int stm32_wrrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
bytesleft = privreq->req.len - privreq->req.xfrd;
/* If all of the bytes were sent (including any final null packet)
- * then we are finished with the transfer
+ * then we are finished with the request buffer).
*/
if (bytesleft == 0 && !privep->txnullpkt)
{
+ /* Return the write request to the class driver */
+
usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
privep->txnullpkt = 0;
stm32_reqcomplete(privep, OK);
- priv->devstate = DEVSTATE_IDLE;
}
return OK;
@@ -1330,7 +1329,7 @@ static int stm32_rdrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
*/
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUTQEMPTY), epno);
- return OK;
+ return -ENOENT;
}
ullvdbg("EP%d: len=%d xfrd=%d\n", epno, privreq->req.len, privreq->req.xfrd);
@@ -1359,22 +1358,18 @@ static int stm32_rdrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
/* Receive the next packet */
stm32_copyfrompma(dest, src, readlen);
- priv->devstate = DEVSTATE_RDREQUEST;
/* If the receive buffer is full or this is a partial packet,
- * then we are finished with the transfer
+ * then we are finished with the request buffer).
*/
privreq->req.xfrd += readlen;
if (pmalen < privep->ep.maxpacket || privreq->req.xfrd >= privreq->req.len)
{
- /* Complete the transfer and mark the state IDLE. The endpoint
- * RX will be marked valid when the data phase completes.
- */
+ /* Return the read request to the class driver. */
usbtrace(TRACE_COMPLETE(epno), privreq->req.xfrd);
stm32_reqcomplete(privep, OK);
- priv->devstate = DEVSTATE_IDLE;
}
return OK;
@@ -1416,7 +1411,7 @@ static void stm32_dispatchrequest(struct stm32_usbdev_s *priv)
/* Stall on failure */
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DISPATCHSTALL), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
}
@@ -1452,7 +1447,7 @@ static void stm32_epdone(struct stm32_usbdev_s *priv, uint8_t epno)
{
/* Read host data into the current read request */
- stm32_rdrequest(priv, privep);
+ (void)stm32_rdrequest(priv, privep);
/* "After the received data is processed, the application software
* should set the STAT_RX bits to '11' (Valid) in the USB_EPnR,
@@ -1583,7 +1578,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
ullvdbg("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n",
priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w);
- priv->devstate = DEVSTATE_IDLE;
+ priv->ep0state = EP0STATE_IDLE;
/* Dispatch any non-standard requests */
@@ -1616,7 +1611,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
index.b[MSB] != 0 || value.w != 0)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
else
{
@@ -1629,7 +1624,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
if (epno >= STM32_NENDPOINTS)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), epno);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
else
{
@@ -1679,7 +1674,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
break;
@@ -1695,7 +1690,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
default:
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
break;
}
@@ -1736,7 +1731,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
}
@@ -1780,7 +1775,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
}
@@ -1799,7 +1794,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
index.w != 0 || len.w != 0 || value.w > 127)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
/* Note that setting of the device address will be deferred. A zero-length
@@ -1834,7 +1829,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
break;
@@ -1859,7 +1854,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
break;
@@ -1884,7 +1879,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
else
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
break;
@@ -1926,7 +1921,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
default:
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req);
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
break;
}
@@ -1938,9 +1933,9 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
* must be sent (may be a zero length packet).
* 2. The request was successfully handled by the class implementation. In
* case, the EP0 IN response has already been queued and the local variable
- * 'handled' will be set to true and devstate != DEVSTATE_STALLED;
+ * 'handled' will be set to true and ep0state != EP0STATE_STALLED;
* 3. An error was detected in either the above logic or by the class implementation
- * logic. In either case, priv->state will be set DEVSTATE_STALLED
+ * logic. In either case, priv->state will be set EP0STATE_STALLED
* to indicate this case.
*
* NOTE: Non-standard requests are a special case. They are handled by the
@@ -1948,7 +1943,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
* logic altogether.
*/
- if (priv->devstate != DEVSTATE_STALLED && !handled)
+ if (priv->ep0state != EP0STATE_STALLED && !handled)
{
/* We will response. First, restrict the data length to the length
* requested in the setup packet
@@ -1962,7 +1957,7 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
/* Send the response (might be a zero-length packet) */
stm32_epwrite(priv, ep0, response.b, nbytes);
- priv->devstate = DEVSTATE_IDLE;
+ priv->ep0state = EP0STATE_IDLE;
}
}
@@ -1972,6 +1967,8 @@ static void stm32_ep0setup(struct stm32_usbdev_s *priv)
static void stm32_ep0in(struct stm32_usbdev_s *priv)
{
+ int ret;
+
/* There is no longer anything in the EP0 TX packet memory */
priv->eplist[EP0].txbusy = false;
@@ -1980,14 +1977,15 @@ static void stm32_ep0in(struct stm32_usbdev_s *priv)
* from the class driver?
*/
- if (priv->devstate == DEVSTATE_WRREQUEST)
+ if (priv->ep0state == EP0STATE_WRREQUEST)
{
- stm32_wrrequest(priv, &priv->eplist[EP0]);
+ ret = stm32_wrrequest(priv, &priv->eplist[EP0]);
+ priv->ep0state = ((ret == OK) ? EP0STATE_WRREQUEST : EP0STATE_IDLE);
}
/* No.. Are we processing the completion of a status response? */
- else if (priv->devstate == DEVSTATE_IDLE)
+ else if (priv->ep0state == EP0STATE_IDLE)
{
/* Look at the saved SETUP command. Was it a SET ADDRESS request?
* If so, then now is the time to set the address.
@@ -2003,7 +2001,7 @@ static void stm32_ep0in(struct stm32_usbdev_s *priv)
}
else
{
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
}
}
@@ -2013,12 +2011,15 @@ static void stm32_ep0in(struct stm32_usbdev_s *priv)
static void stm32_ep0out(struct stm32_usbdev_s *priv)
{
+ int ret;
+
struct stm32_ep_s *privep = &priv->eplist[EP0];
- switch (priv->devstate)
+ switch (priv->ep0state)
{
- case DEVSTATE_RDREQUEST: /* Write request in progress */
- case DEVSTATE_IDLE: /* No transfer in progress */
- stm32_rdrequest(priv, privep);
+ case EP0STATE_RDREQUEST: /* Write request in progress */
+ case EP0STATE_IDLE: /* No transfer in progress */
+ ret = stm32_rdrequest(priv, privep);
+ priv->ep0state = ((ret == OK) ? EP0STATE_RDREQUEST : EP0STATE_IDLE);
break;
default:
@@ -2026,7 +2027,7 @@ static void stm32_ep0out(struct stm32_usbdev_s *priv)
* completed, STALL the endpoint in either case
*/
- priv->devstate = DEVSTATE_STALLED;
+ priv->ep0state = EP0STATE_STALLED;
break;
}
}
@@ -2119,7 +2120,7 @@ static inline void stm32_ep0done(struct stm32_usbdev_s *priv, uint16_t istr)
/* Now figure out the new RX/TX status. Here are all possible
* consequences of the above EP0 operations:
*
- * rxstatus txstatus devstate MEANING
+ * rxstatus txstatus ep0state MEANING
* -------- -------- --------- ---------------------------------
* NAK NAK IDLE Nothing happened
* NAK VALID IDLE EP0 response sent from USBDEV driver
@@ -2129,9 +2130,9 @@ static inline void stm32_ep0done(struct stm32_usbdev_s *priv, uint16_t istr)
* First handle the STALL condition:
*/
- if (priv->devstate == DEVSTATE_STALLED)
+ if (priv->ep0state == EP0STATE_STALLED)
{
- usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->devstate);
+ usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state);
priv->rxstatus = USB_EPR_STATRX_STALL;
priv->txstatus = USB_EPR_STATTX_STALL;
}
@@ -2859,7 +2860,7 @@ static int stm32_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
if (!privep->txbusy)
{
priv->txstatus = USB_EPR_STATTX_NAK;
- ret = stm32_wrrequest(priv, privep);
+ ret = stm32_wrrequest(priv, privep);
/* Set the new TX status */
@@ -2971,7 +2972,12 @@ static int stm32_epstall(struct usbdev_ep_s *ep, bool resume)
if (status == 0)
{
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPDISABLED), 0);
- priv->devstate = DEVSTATE_STALLED;
+
+ if (epno == 0)
+ {
+ priv->ep0state = EP0STATE_STALLED;
+ }
+
return -ENODEV;
}
@@ -3272,7 +3278,7 @@ static void stm32_reset(struct stm32_usbdev_s *priv)
/* Reset the device state structure */
- priv->devstate = DEVSTATE_IDLE;
+ priv->ep0state = EP0STATE_IDLE;
priv->rsmstate = RSMSTATE_IDLE;
priv->rxpending = false;