summaryrefslogtreecommitdiffstats
path: root/nuttx/arch/arm/src/lpc214x
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-10-09 21:47:13 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-10-09 21:47:13 +0000
commitc739cac8d1d04d0a381847ffc0f24f4498f46aa8 (patch)
tree39997431d4908ea9f052a1d86e101774f336ce41 /nuttx/arch/arm/src/lpc214x
parenta5636172fdb26638994cd56f023b986cc1c79fa3 (diff)
Pace sends to send complete interrupts
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@1018 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/arch/arm/src/lpc214x')
-rw-r--r--nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c99
1 files changed, 56 insertions, 43 deletions
diff --git a/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c b/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
index 0db5437a4b..a78c5022e7 100644
--- a/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
+++ b/nuttx/arch/arm/src/lpc214x/lpc214x_usbdev.c
@@ -307,8 +307,9 @@ struct lpc214x_ep_s
struct lpc214x_req_s *head; /* Request list for this endpoint */
struct lpc214x_req_s *tail;
ubyte epphy; /* Physical EP address */
- ubyte stalled:1; /* Endpoint is halted */
- ubyte halted:1; /* Endpoint feature halted */
+ ubyte stalled:1; /* 1: Endpoint is stalled */
+ ubyte halted:1; /* 1: Endpoint feature halted */
+ ubyte txbusy:1; /* 1: TX endpoint FIFO full */
ubyte txnullpkt:1; /* Null packet needed at end of transfer */
};
@@ -1034,59 +1035,62 @@ static int lpc214x_wrrequest(struct lpc214x_ep_s *privep)
/* Otherwise send the data in the packet (in the DMA on case, we
* may be resuming transfer already in progress.
*/
-#warning REVISIT... Unless the EP supports double buffering, only one packet may be sent
- for (;;)
+#warning REVISIT... If the EP supports double buffering, then we can do better
+
+ /* Get the number of bytes left to be sent in the packet */
+
+ bytesleft = privreq->req.len - privreq->req.xfrd;
+
+ /* Send the next packet if (1) there are more bytes to be sent, or
+ * (2) the last packet sent was exactly maxpacketsize (bytesleft == 0)
+ */
+
+ usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd);
+ if (bytesleft > 0 || privep->txnullpkt)
{
- /* Get the number of bytes left to be sent in the packet */
+ /* Indicate that there is data in the TX FIFO. This will be cleared
+ * when the EPIN interrupt is received
+ */
- bytesleft = privreq->req.len - privreq->req.xfrd;
+ privep->txbusy = 1;
- /* Send the next packet if (1) there are more bytes to be sent, or
- * (2) the last packet sent was exactly maxpacketsize (bytesleft == 0)
+ /* Try to send maxpacketsize -- unless we don't have that many
+ * bytes to send.
*/
- usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd);
- if (bytesleft > 0 || privep->txnullpkt)
+ if (bytesleft > privep->ep.maxpacket)
{
- /* Try to send maxpacketsize -- unless we don't have that many
- * bytes to send.
- */
-
- if (bytesleft > privep->ep.maxpacket)
- {
- nbytes = privep->ep.maxpacket;
- privep->txnullpkt = 0;
- }
- else
- {
- nbytes = bytesleft;
- privep->txnullpkt = (bytesleft == privep->ep.maxpacket);
- }
+ nbytes = privep->ep.maxpacket;
+ privep->txnullpkt = 0;
+ }
+ else
+ {
+ nbytes = bytesleft;
+ privep->txnullpkt = (bytesleft == privep->ep.maxpacket);
+ }
- /* Send the largest number of bytes that we can in this packet */
+ /* Send the largest number of bytes that we can in this packet */
- buf = privreq->req.buf + privreq->req.xfrd;
- lpc214x_epwrite(privep->epphy, buf, nbytes);
+ buf = privreq->req.buf + privreq->req.xfrd;
+ lpc214x_epwrite(privep->epphy, buf, nbytes);
- /* Update for the next time through the loop */
+ /* Update for the next time through the loop */
- privreq->req.xfrd += nbytes;
- }
+ privreq->req.xfrd += nbytes;
+ }
- /* If all of the bytes were sent (including any final null packet)
- * then we are finished with the transfer
- */
+ /* If all of the bytes were sent (including any final null packet)
+ * then we are finished with the transfer
+ */
- if (bytesleft <= 0 || !privep->txnullpkt)
- {
- usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
- privep->txnullpkt = 0;
- lpc214x_reqcomplete(privep, OK);
- return OK;
- }
+ if (bytesleft <= 0 || !privep->txnullpkt)
+ {
+ usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
+ privep->txnullpkt = 0;
+ lpc214x_reqcomplete(privep, OK);
}
- return OK; /* Won't get here */
+ return OK;
}
/*******************************************************************************
@@ -1944,7 +1948,9 @@ static inline void lpc214x_ep0dataininterrupt(struct lpc214x_usbdev_s *priv)
{
/* Process the next request action (if any) */
- lpc214x_wrrequest(&priv->eplist[LPC214X_EP0_IN]);
+ ep0 = &priv->eplist[LPC214X_EP0_IN];
+ ep0->txbusy = 0;
+ lpc214x_wrrequest(ep0);
}
break;
@@ -2210,6 +2216,7 @@ static int lpc214x_usbinterrupt(int irq, FAR void *context)
/* Write host data from the current write request (if any) */
+ privep->txbusy = 0;
lpc214x_wrrequest(privep);
}
else
@@ -2709,7 +2716,13 @@ static int lpc214x_epsubmit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s
lpc214x_rqenqueue(privep, privreq);
usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len);
- ret = lpc214x_wrrequest(privep);
+
+ /* If the IN endpoint FIFO is available, then transfer the data now */
+
+ if (privep->txbusy == 0)
+ {
+ ret = lpc214x_wrrequest(privep);
+ }
}
/* Handle OUT (host-to-device) requests */