summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-04 19:31:10 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-04 19:31:10 +0000
commit2ed7a733182a07899b8eababd037b6b8888b8342 (patch)
tree540affc3526df993d76d10166f82ceb6743a6ea2
parent68c754f4ee2a45e89b2f8952c1926e73f2147146 (diff)
downloadpx4-nuttx-2ed7a733182a07899b8eababd037b6b8888b8342.tar.gz
px4-nuttx-2ed7a733182a07899b8eababd037b6b8888b8342.tar.bz2
px4-nuttx-2ed7a733182a07899b8eababd037b6b8888b8342.zip
Some fixes for the PIC32 USB IN processing -- still some issues
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4452 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c100
1 files changed, 72 insertions, 28 deletions
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c
index 6b7f519a2..374a1dc6d 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c
+++ b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c
@@ -800,8 +800,10 @@ static void pic32mx_epwrite(struct pic32mx_ep_s *privep, const uint8_t *src,
static void pic32mx_wrcomplete(struct pic32mx_usbdev_s *priv,
struct pic32mx_ep_s *privep)
{
+ volatile struct usbotg_bdtentry_s *bdtin;
struct pic32mx_req_s *privreq;
int bytesleft;
+ int epno;
/* Check the request from the head of the endpoint request queue. Since
* we got here from a write completion event, the request queue should
@@ -809,38 +811,60 @@ static void pic32mx_wrcomplete(struct pic32mx_usbdev_s *priv,
*/
privreq = pic32mx_rqpeek(privep);
- if (privreq != NULL)
+ DEBUGASSERT(privreq != NULL);
+
+ /* An outgoing IN packet has completed. bdtin should point to the BDT
+ * that just completed.
+ */
+
+ bdtin = privep->bdtin;
+ epno = USB_EPNO(privep->ep.eplog);
+
+ ullvdbg("EP%d: len=%d xfrd=%d [%p]\n",
+ epno, privreq->req.len, privreq->req.xfrd);
+ bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n",
+ epno, bdtin, bdtin->status, bdtin->addr);
+
+ /* We should own the BDT that just completed */
+
+ DEBUGASSERT((bdtin->status & USB_BDT_UOWN) == USB_BDT_COWN);
+
+ /* Toggle bdtin to the other BDT. Is the current bdtin the EVEN bdt? */
+
+ privep->bdtin = &g_bdt[EP_IN_EVEN(epno)];
+ if (bdtin == privep->bdtin)
{
- /* An outgoing IN packet has completed. Update the number of bytes
- * transferred.
- */
-
- privreq->req.xfrd += privreq->inflight;
- privreq->inflight = 0;
- bytesleft = privreq->req.len - privreq->req.xfrd;
+ /* Yes.. Then the other BDT is the ODD BDT */
- /* If all of the bytes were sent (bytesleft == 0) and no NULL packet is
- * needed (!txnullpkt), then we are finished with the transfer
- */
+ privep->bdtin++;
+ }
- if (bytesleft == 0 && !privep->txnullpkt)
- {
+ /* Update the number of bytes transferred. */
+
+ privreq->req.xfrd += privreq->inflight;
+ privreq->inflight = 0;
+ bytesleft = privreq->req.len - privreq->req.xfrd;
+
+ /* If all of the bytes were sent (bytesleft == 0) and no NULL packet is
+ * needed (!txnullpkt), then we are finished with the transfer
+ */
- /* The transfer is complete. Give the completed request back to
- * the class driver.
- */
+ if (bytesleft == 0 && !privep->txnullpkt)
+ {
+ /* The transfer is complete. Give the completed request back to
+ * the class driver.
+ */
- usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
- pic32mx_reqcomplete(privep, OK);
+ usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
+ pic32mx_reqcomplete(privep, OK);
- /* Special case writes to endpoint zero. If there is no transfer in
- * progress, then we need to configure to received the next SETUP packet.
- */
+ /* Special case writes to endpoint zero. If there is no transfer in
+ * progress, then we need to configure to received the next SETUP packet.
+ */
- if (USB_EPNO(privep->ep.eplog) == 0)
- {
- priv->ctrlstate = CTRLSTATE_WAITSETUP;
- }
+ if (USB_EPNO(privep->ep.eplog) == 0)
+ {
+ priv->ctrlstate = CTRLSTATE_WAITSETUP;
}
}
}
@@ -980,8 +1004,9 @@ static int pic32mx_wrrequest(struct pic32mx_usbdev_s *priv, struct pic32mx_ep_s
static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv,
struct pic32mx_ep_s *privep)
{
- volatile struct usbotg_bdtentry_s *bdtout = privep->bdtout;
+ volatile struct usbotg_bdtentry_s *bdtout;
struct pic32mx_req_s *privreq;
+ int epno;
int readlen;
/* Check the request from the head of the endpoint request queue */
@@ -996,10 +1021,19 @@ static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv,
return -EINVAL;
}
+ /* bdtout should point to the BDT that just completed */
+
+ bdtout = privep->bdtout;
+ epno = USB_EPNO(privep->ep.eplog);
+
ullvdbg("EP%d: len=%d xfrd=%d [%p]\n",
- USB_EPNO(privep->ep.eplog), privreq->req.len, privreq->req.xfrd);
+ epno, privreq->req.len, privreq->req.xfrd);
bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n",
- USB_EPNO(privep->ep.eplog), bdtout, bdtout->status, bdtout->addr);
+ epno, bdtout, bdtout->status, bdtout->addr);
+
+ /* We should own the BDT that just completed */
+
+ DEBUGASSERT((bdtout->status & USB_BDT_UOWN) == USB_BDT_COWN);
/* Get the length of the data received from the BDT */
@@ -1020,6 +1054,16 @@ static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv,
pic32mx_reqcomplete(privep, OK);
}
+ /* Toggle bdtout to the other BDT. Is the current bdtout the EVEN bdt? */
+
+ privep->bdtout = &g_bdt[EP_OUT_EVEN(epno)];
+ if (bdtout == privep->bdtout)
+ {
+ /* Yes.. Then the other BDT is the ODD BDT */
+
+ privep->bdtout++;
+ }
+
/* Set up the next read operation */
return pic32mx_rdrequest(priv, privep);