summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-04 17:38:00 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-03-04 17:38:00 +0000
commit68c754f4ee2a45e89b2f8952c1926e73f2147146 (patch)
tree4c7840655e4f2bccac1f8dcf1ae41be17bdd0234
parent8e1975393114d786b3699f926a416c3945ec3dfd (diff)
downloadnuttx-68c754f4ee2a45e89b2f8952c1926e73f2147146.tar.gz
nuttx-68c754f4ee2a45e89b2f8952c1926e73f2147146.tar.bz2
nuttx-68c754f4ee2a45e89b2f8952c1926e73f2147146.zip
Several fixes to the PIC32 USB device OUT path logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4451 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/examples/usbterm/usbterm.h2
-rw-r--r--apps/examples/usbterm/usbterm_main.c32
-rw-r--r--nuttx/Documentation/NuttX.html9
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c318
4 files changed, 226 insertions, 135 deletions
diff --git a/apps/examples/usbterm/usbterm.h b/apps/examples/usbterm/usbterm.h
index a889c886d..2534c2f3c 100644
--- a/apps/examples/usbterm/usbterm.h
+++ b/apps/examples/usbterm/usbterm.h
@@ -132,6 +132,8 @@ struct usbterm_globals_s
FILE *instream; /* Stream for incoming USB data */
FILE *outstream; /* Stream for outgoing USB data */
pthread_t listener; /* USB terminal listener thread */
+ bool peer; /* True: A peer is connected to the serial port on
+ * the remote host */
/* Buffers for incoming and outgoing data */
diff --git a/apps/examples/usbterm/usbterm_main.c b/apps/examples/usbterm/usbterm_main.c
index ba723e91b..170585624 100644
--- a/apps/examples/usbterm/usbterm_main.c
+++ b/apps/examples/usbterm/usbterm_main.c
@@ -127,15 +127,27 @@ FAR void *usbterm_listener(FAR void *parameter)
message("usbterm_listener: Waiting for remote input\n");
for (;;)
{
- /* Display the prompt string on the remote USB serial connection */
+ /* Display the prompt string on the remote USB serial connection -- only
+ * if we know that there is someone listening at the other end. The
+ * remote side must initiate the the conversation.
+ */
- fputs("\rusbterm> ", g_usbterm.outstream);
- fflush(g_usbterm.outstream);
+ if (g_usbterm.peer)
+ {
+ fputs("\rusbterm> ", g_usbterm.outstream);
+ fflush(g_usbterm.outstream);
+ }
/* Get the next line of input from the remote USB serial connection */
if (fgets(g_usbterm.inbuffer, CONFIG_EXAMPLES_USBTERM_BUFLEN, g_usbterm.instream))
{
+ /* If we receive anything, then we can be assured that there is someone
+ * with the serial driver open on the remote host.
+ */
+
+ g_usbterm.peer = true;
+
/* Echo the line on the local stdout */
fputs(g_usbterm.inbuffer, stdout);
@@ -181,6 +193,10 @@ int MAIN_NAME(int argc, char *argv[])
pthread_attr_t attr;
int ret;
+ /* Initialize global data */
+
+ memset(&g_usbterm, 0, sizeof(struct usbterm_globals_s));
+
/* Initialization of the USB hardware may be performed by logic external to
* this test.
*/
@@ -324,9 +340,11 @@ int MAIN_NAME(int argc, char *argv[])
return 1;
}
#endif
- else
+ /* Is there anyone listening on the other end? */
+
+ else if (g_usbterm.peer)
{
- /* Send the line of input via USB */
+ /* Yes.. Send the line of input via USB */
fputs(g_usbterm.outbuffer, g_usbterm.outstream);
@@ -335,6 +353,10 @@ int MAIN_NAME(int argc, char *argv[])
fputs("\rusbterm> ", g_usbterm.outstream);
fflush(g_usbterm.outstream);
}
+ else
+ {
+ printf("Still waiting for remote peer. Please try again later.\n", ret);
+ }
/* If USB tracing is enabled, then dump all collected trace data to stdout */
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 32f118f7b..9d4a78f0e 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -152,10 +152,11 @@
to support a rich, multi-threaded development environment for deeply embedded
processors.
</p>
- NON-GOALS: (1) It is not a goal to provide the rich level of OS
- features like those provided with Linux.
- Small footprint is more important than features.
- Standard compliance is more important than small footprint.
+ NON-GOALS: (1) It is not a goal to provide the level of OS features like those provided by Linux.
+ In order to work with smaller MCUs, small footprint must be more important than an extensive feature set.
+ But standard compliance is more important than small footprint.
+ Surely a smaller RTOS could be produced by ignoring standards.
+ Think of NuttX is a tiny Linux work-alike with a much reduced feature set.
(2) There is no MMU-based support for processes.
At present, NuttX assumes a flat address space.
</p>
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c
index 9d8e68553..6b7f519a2 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c
+++ b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c
@@ -341,9 +341,9 @@ union wb_u
struct pic32mx_req_s
{
- struct usbdev_req_s req; /* Standard USB request */
- uint16_t inflight; /* The number of bytes "in-flight" */
- struct pic32mx_req_s *flink; /* Supports a singly linked list */
+ struct usbdev_req_s req; /* Standard USB request */
+ uint16_t inflight; /* The number of bytes "in-flight" */
+ struct pic32mx_req_s *flink; /* Supports a singly linked list */
};
/* This is the internal representation of an endpoint */
@@ -355,18 +355,18 @@ struct pic32mx_ep_s
* to struct pic32mx_ep_s.
*/
- struct usbdev_ep_s ep; /* Standard endpoint structure */
+ struct usbdev_ep_s ep; /* Standard endpoint structure */
/* PIC32MX-specific fields */
- struct pic32mx_usbdev_s *dev; /* Reference to private driver data */
- struct pic32mx_req_s *head; /* Request list for this endpoint */
+ struct pic32mx_usbdev_s *dev; /* Reference to private driver data */
+ struct pic32mx_req_s *head; /* Request list for this endpoint */
struct pic32mx_req_s *tail;
- uint8_t stalled:1; /* true: Endpoint is stalled */
- uint8_t halted:1; /* true: Endpoint feature halted */
- uint8_t txbusy:1; /* true: TX endpoint FIFO full */
- uint8_t rxoverrun:1; /* true: RX data overrun */
- uint8_t txnullpkt:1; /* Null packet needed at end of transfer */
+ uint8_t stalled:1; /* true: Endpoint is stalled */
+ uint8_t halted:1; /* true: Endpoint feature halted */
+ uint8_t txbusy:1; /* true: TX endpoint FIFO full */
+ uint8_t txnullpkt:1; /* Null packet needed at end of TX transfer */
+ uint8_t rxdata1:1; /* Data0/1 of next RX transfer */
volatile struct usbotg_bdtentry_s *bdtin; /* BDT entry for the IN transaction*/
volatile struct usbotg_bdtentry_s *bdtout; /* BDT entry for the OUT transaction */
};
@@ -439,8 +439,8 @@ static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv,
struct pic32mx_ep_s *privep);
static int pic32mx_ep0rdsetup(struct pic32mx_usbdev_s *priv,
uint8_t *dest, int readlen);
-static int pic32mx_rdsetup(struct pic32mx_usbdev_s *priv,
- struct pic32mx_ep_s *privep, uint8_t *dest, int readlen);
+static int pic32mx_rdsetup(struct pic32mx_ep_s *privep, uint8_t *dest,
+ int readlen);
static int pic32mx_rdrequest(struct pic32mx_usbdev_s *priv,
struct pic32mx_ep_s *privep);
static void pic32mx_cancelrequests(struct pic32mx_ep_s *privep);
@@ -450,14 +450,14 @@ static void pic32mx_cancelrequests(struct pic32mx_ep_s *privep);
static void pic32mx_dispatchrequest(struct pic32mx_usbdev_s *priv);
static void pic32mx_ep0stall(struct pic32mx_usbdev_s *priv);
static void pic32mx_eptransfer(struct pic32mx_usbdev_s *priv, uint8_t epno,
- uint16_t status);
+ uint16_t ustat);
static void pic32mx_ep0nextsetup(struct pic32mx_usbdev_s *priv);
static void pic32mx_ep0rdcomplete(struct pic32mx_usbdev_s *priv);
static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv);
static void pic32mx_ep0outcomplete(struct pic32mx_usbdev_s *priv);
static void pic32mx_ep0incomplete(struct pic32mx_usbdev_s *priv);
static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv,
- uint16_t status);
+ uint16_t ustat);
static int pic32mx_interrupt(int irq, void *context);
/* Endpoint helpers *********************************************************/
@@ -980,7 +980,7 @@ 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 *bdt = privep->bdtout;
+ volatile struct usbotg_bdtentry_s *bdtout = privep->bdtout;
struct pic32mx_req_s *privreq;
int readlen;
@@ -996,13 +996,14 @@ static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv,
return -EINVAL;
}
- ullvdbg("EP%d: len=%d xfrd=%d BDT={%08x, %08x}\n",
- USB_EPNO(privep->ep.eplog), privreq->req.len, privreq->req.xfrd,
- bdt->status, bdt->addr);
+ ullvdbg("EP%d: len=%d xfrd=%d [%p]\n",
+ USB_EPNO(privep->ep.eplog), 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);
/* Get the length of the data received from the BDT */
- readlen = (bdt->status & USB_BDT_BYTECOUNT_MASK) >> USB_BDT_BYTECOUNT_SHIFT;
+ readlen = (bdtout->status & USB_BDT_BYTECOUNT_MASK) >> USB_BDT_BYTECOUNT_SHIFT;
/* If the receive buffer is full or this is a partial packet,
* then we are finished with the transfer
@@ -1031,50 +1032,92 @@ static int pic32mx_rdcomplete(struct pic32mx_usbdev_s *priv,
static int pic32mx_ep0rdsetup(struct pic32mx_usbdev_s *priv, uint8_t *dest,
int readlen)
{
- volatile struct usbotg_bdtentry_s *bdt = priv->eplist[EP0].bdtout;
- uint16_t status;
+ volatile struct usbotg_bdtentry_s *bdtout;
+ volatile struct usbotg_bdtentry_s *otherbdt;
+ struct pic32mx_ep_s *privep;
+ uint32_t status;
- /* Clear status bits (making sure that UOWN is cleared before doing anything
- * else). Preserve only the toggled data indication only.
- */
+ /* bdtout refers to the next ping-pong BDT to use. */
- status = bdt->status;
- status &= USB_BDT_DATA01;
- status ^= USB_BDT_DATA01;
- bdt->status = status;
+ privep = &priv->eplist[EP0];
+ bdtout = privep->bdtout;
+
+ /* Get the other BDT. Check if the current BDT the EVEN BDT? */
+
+ otherbdt = &g_bdt[EP_OUT_EVEN(EP0)];
+ if (bdtout == otherbdt)
+ {
+ /* Yes.. then the other BDT is the ODD BDT. */
+
+ otherbdt++;
+ }
/* If there is no RX transfer in progress, then the other BDT is setup
* to receive the next setup packet. There is a race condition here!
* Stop any setup packet.
*/
-#warning REVISIT
+
if (!priv->rxbusy)
{
/* Reset the other BDT to zero... this will cause any attempted use
- * of the BDT to be NAKed.
+ * of the other BDT to be NAKed. Set the first DATA0/1 value to 1.
*/
- if (bdt == &g_bdt[EP0_OUT_EVEN])
- {
- g_bdt[EP0_OUT_ODD].status = 0;
- }
- else
+ otherbdt->status = 0;
+ privep->rxdata1 = 1;
+ }
+
+ /* Otherwise, there are RX transfers in progress. bdtout may be
+ * unavailable now. In that case, we are free to setup the other BDT
+ * in order to improve performance.
+ */
+
+ if ((bdtout->status & USB_BDT_UOWN) != USB_BDT_COWN)
+ {
+ /* bdtout is not available. Is the other BDT available? */
+
+ if ((otherbdt->status & USB_BDT_UOWN) != USB_BDT_COWN)
{
- DEBUGASSERT(bdt == &g_bdt[EP0_OUT_ODD]);
- g_bdt[EP0_OUT_EVEN].status = 0;
+ /* Neither are available... we cannot accept the request now */
+
+ return -EBUSY;
}
+
+ /* Use the other BDT */
+
+ bdtout = otherbdt;
+ }
+
+ usbtrace(TRACE_READ(EP0), readlen);
+
+ /* Clear status bits (making sure that UOWN is cleared before doing anything
+ * else).
+ */
+
+ bdtout->status = 0;
+
+ /* Get the correct data toggle (as well as other BDT bits) */
+
+ if (privep->rxdata1)
+ {
+ status = (USB_BDT_UOWN | USB_BDT_DATA1 | USB_BDT_DTS);
+ privep->rxdata1 = 0;
}
-
+ else
+ {
+ status = (USB_BDT_UOWN | USB_BDT_DATA0 | USB_BDT_DTS);
+ privep->rxdata1 = 1;
+ }
+
/* Set the data pointer, data length, and enable the endpoint */
- bdt->addr = (uint8_t *)PHYS_ADDR(dest);
- status |= (readlen << USB_BDT_BYTECOUNT_SHIFT);
+ bdtout->addr = (uint8_t *)PHYS_ADDR(dest);
+ status |= ((uint32_t)readlen << USB_BDT_BYTECOUNT_SHIFT);
/* Then give the BDT to the USB */
- status |= (USB_BDT_UOWN | USB_BDT_DTS);
- bdtdbg("EP0 BDT OUT [%p] {%08x, %08x}\n", bdt, status, bdt->addr);
- bdt->status = status;
+ bdtdbg("EP0 BDT OUT [%p] {%08x, %08x}\n", bdtout, status, bdtout->addr);
+ bdtout->status = status;
priv->ctrlstate = CTRLSTATE_RDREQUEST;
priv->rxbusy = 1;
@@ -1085,35 +1128,85 @@ static int pic32mx_ep0rdsetup(struct pic32mx_usbdev_s *priv, uint8_t *dest,
* Name: pic32mx_rdsetup
****************************************************************************/
-static int pic32mx_rdsetup(struct pic32mx_usbdev_s *priv,
- struct pic32mx_ep_s *privep, uint8_t *dest, int readlen)
+static int pic32mx_rdsetup(struct pic32mx_ep_s *privep, uint8_t *dest, int readlen)
{
- volatile struct usbotg_bdtentry_s *bdt = privep->bdtout;
- uint16_t status;
+ volatile struct usbotg_bdtentry_s *bdtout;
+ volatile struct usbotg_bdtentry_s *otherbdt;
+ uint32_t status;
+ int epno;
+
+ /* Select a BDT. Check both the even and the ODD BDT and use the first one
+ * that we own.
+ */
+
+ epno = USB_EPNO(privep->ep.eplog);
+
+ /* bdtout refers to the next ping-pong BDT to use. However, bdtout may be
+ * unavailable now. But, in that case, we are free to setup the other BDT
+ * in order to improve performance.
+ */
+
+ bdtout = privep->bdtout;
+ if ((bdtout->status & USB_BDT_UOWN) != USB_BDT_COWN)
+ {
+ /* Is the current BDT the EVEN BDT? */
+
+ otherbdt = &g_bdt[EP_OUT_EVEN(epno)];
+ if (bdtout == otherbdt)
+ {
+ /* Yes.. select the ODD BDT */
+
+ otherbdt++;
+ }
+
+ /* Is the other BDT available? */
+
+ if ((otherbdt->status & USB_BDT_UOWN) != USB_BDT_COWN)
+ {
+ /* Neither are available... we cannot accept the request now */
+
+ return -EBUSY;
+ }
+
+ /* Use the other BDT */
+
+ bdtout = otherbdt;
+ }
+
+ usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), readlen);
/* Clear status bits (making sure that UOWN is cleared before doing anything
* else). The DATA01 is (only) is preserved.
*/
- status = bdt->status & USB_BDT_DATA01;
- bdt->status = status;
+ bdtout->status = 0;
/* Set the data pointer, data length, and enable the endpoint */
- bdt->addr = (uint8_t *)PHYS_ADDR(dest);
+ bdtout->addr = (uint8_t *)PHYS_ADDR(dest);
+
+ /* Get the correct data toggle (as well as other BDT bits) */
+
+ if (privep->rxdata1)
+ {
+ status = (USB_BDT_UOWN | USB_BDT_DATA1 | USB_BDT_DTS);
+ privep->rxdata1 = 0;
+ }
+ else
+ {
+ status = (USB_BDT_UOWN | USB_BDT_DATA0 | USB_BDT_DTS);
+ privep->rxdata1 = 1;
+ }
/* Set the data length (preserving the data toggle). */
- status |= (readlen << USB_BDT_BYTECOUNT_SHIFT) | USB_BDT_DTS;
+ status |= ((uint32_t)readlen << USB_BDT_BYTECOUNT_SHIFT);
/* Then give the BDT to the USB */
- status |= USB_BDT_UOWN;
-
- bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n",
- USB_EPNO(privep->ep.eplog), bdt, status, bdt->addr);
+ bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdtout, status, bdtout->addr);
- bdt->status = status;
+ bdtout->status = status;
return OK;
}
@@ -1165,11 +1258,9 @@ static int pic32mx_rdrequest(struct pic32mx_usbdev_s *priv,
return OK;
}
- usbtrace(TRACE_READ(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
-
/* Get the destination transfer address and size */
- dest = privreq->req.buf + privreq->req.xfrd;
+ dest = privreq->req.buf + privreq->req.xfrd;
readlen = MIN(privreq->req.len, privep->ep.maxpacket);
/* Handle EP0 in a few special ways */
@@ -1180,7 +1271,7 @@ static int pic32mx_rdrequest(struct pic32mx_usbdev_s *priv,
}
else
{
- ret = pic32mx_rdsetup(priv, privep, dest, readlen);
+ ret = pic32mx_rdsetup(privep, dest, readlen);
}
return ret;
}
@@ -1250,7 +1341,7 @@ static void pic32mx_ep0stall(struct pic32mx_usbdev_s *priv)
{
/* Set ep0 BDT status to stall also */
- uint16_t status = (USB_BDT_UOWN| USB_BDT_DATA0 | USB_BDT_DTS | USB_BDT_BSTALL);
+ uint32_t status = (USB_BDT_UOWN| USB_BDT_DATA0 | USB_BDT_DTS | USB_BDT_BSTALL);
bdtdbg("EP0 BDT OUT [%p] {%08x, %08x}\n",
ep0->bdtout, status, ep0->bdtout->addr);
@@ -1270,7 +1361,7 @@ static void pic32mx_ep0stall(struct pic32mx_usbdev_s *priv)
****************************************************************************/
static void pic32mx_eptransfer(struct pic32mx_usbdev_s *priv, uint8_t epno,
- uint16_t status)
+ uint16_t ustat)
{
struct pic32mx_ep_s *privep;
@@ -1280,11 +1371,11 @@ static void pic32mx_eptransfer(struct pic32mx_usbdev_s *priv, uint8_t epno,
/* Check if the last transaction was an EP0 OUT transaction */
- if ((status & USB_STAT_DIR) == USB_STAT_DIR_OUT)
+ if ((ustat & USB_STAT_DIR) == USB_STAT_DIR_OUT)
{
/* OUT: host-to-device */
- usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPOUTDONE), status);
+ usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPOUTDONE), ustat);
/* Handle read requests. First check if a read request is available to
* accept the host data.
@@ -1302,21 +1393,13 @@ static void pic32mx_eptransfer(struct pic32mx_usbdev_s *priv, uint8_t epno,
if (pic32mx_rqempty(privep))
{
usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPOUTPENDING), (uint16_t)epno);
-
- /* Set the RX overrun condition. And do not give ownerhsip of
- * of the packet to USB. If more OUT tokens are received, the
- * hardware will NAK further requests.
- */
-
- privep->rxoverrun = true;
-#warning "Missing logic"
}
}
else
{
/* IN: device-to-host */
- usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPINDONE), status);
+ usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EPINDONE), ustat);
/* An outgoing IN packet has completed. Update the number of bytes transferred
* and check for completion of the transfer.
@@ -2140,7 +2223,7 @@ static void pic32mx_ep0outcomplete(struct pic32mx_usbdev_s *priv)
* Name: pic32mx_ep0transfer
****************************************************************************/
-static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, uint16_t status)
+static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, uint16_t ustat)
{
volatile struct usbotg_bdtentry_s *bdt;
@@ -2155,13 +2238,13 @@ static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, uint16_t status)
/* Check if the last transaction was an EP0 OUT transaction */
- if ((status & USB_STAT_DIR) == USB_STAT_DIR_OUT)
+ if ((ustat & USB_STAT_DIR) == USB_STAT_DIR_OUT)
{
int index;
/* It was an EP0 OUT transaction. Get the index to the BDT. */
- index = ((status & USB_STAT_PPBI) == 0 ? EP0_OUT_EVEN : EP0_OUT_ODD);
+ index = ((ustat & USB_STAT_PPBI) == 0 ? EP0_OUT_EVEN : EP0_OUT_ODD);
bdt = &g_bdt[index];
priv->eplist[0].bdtout = bdt;
@@ -2193,7 +2276,7 @@ static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, uint16_t status)
{
/* Handle the data OUT transfer */
- usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0OUTDONE), status);
+ usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0OUTDONE), ustat);
pic32mx_ep0outcomplete(priv);
}
}
@@ -2202,7 +2285,7 @@ static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, uint16_t status)
else /* if ((status & USB_STAT_DIR) == USB_STAT_DIR_IN) */
{
- usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0INDONE), status);
+ usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_EP0INDONE), ustat);
/* Handle the IN transfer complete */
@@ -2657,21 +2740,19 @@ static void pic32mx_ep0configure(struct pic32mx_usbdev_s *priv)
bdt->status = (USB_BDT_UOWN | bytecount);
priv->eplist[EP0].bdtout = bdt;
- bdt = &g_bdt[EP0_OUT_ODD];
+ bdt++;
bdt->status = (USB_BDT_UOWN | bytecount);
bdt->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl);
- /* Configure the IN BDTs. Set DATA0 in the EVEN BDT because the first
- * thing we will do when transmitting is toggle the bit
- */
+ /* Configure the IN BDTs. */
bdt = &g_bdt[EP0_IN_EVEN];
- bdt->status = (USB_BDT_DATA0 | USB_BDT_DTS | USB_BDT_BSTALL);
+ bdt->status = 0;
bdt->addr = 0;
priv->eplist[EP0].bdtin = bdt;
- bdt = &g_bdt[EP0_IN_ODD];
- bdt->status = (USB_BDT_DATA0 | USB_BDT_DTS | USB_BDT_BSTALL);
+ bdt++;
+ bdt->status = 0;
bdt->addr = 0;
}
@@ -2690,7 +2771,6 @@ static int pic32mx_epconfigure(struct usbdev_ep_s *ep,
volatile struct usbotg_bdtentry_s *bdt;
uint16_t maxpacket;
uint16_t regval;
- uint16_t status;
uint8_t epno;
bool epin;
bool bidi;
@@ -2755,28 +2835,18 @@ static int pic32mx_epconfigure(struct usbdev_ep_s *ep,
/* Mark that we own the entry */
- status = bdt->status;
- status &= ~USB_BDT_UOWN;
+ bdt->status = 0;
+ bdt->addr = 0;
- /* Set DATA1 to one because the first thing we will do when transmitting is
- * toggle the bit
- */
-
- status |= USB_BDT_DATA1;
- bdt->status = status;
+ bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr);
- bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, status, bdt->addr);
+ /* Now do the same for the other buffer. */
- /* Now do the same for the other buffer. The only difference is the
- * we clear DATA1 (making it DATA0)
- */
+ bdt++;
+ bdt->status = 0;
+ bdt->addr = 0;
- bdt = &g_bdt[index+1];
- status = bdt->status;
- status &= ~(USB_BDT_UOWN | USB_BDT_DATA01);
- bdt->status = status;
-
- bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, status, bdt->addr);
+ bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr);
}
if (!epin || bidi)
@@ -2787,29 +2857,18 @@ static int pic32mx_epconfigure(struct usbdev_ep_s *ep,
/* Mark that we own the entry */
- status = bdt->status;
- status &= ~USB_BDT_UOWN;
-
- /* Set DATA1 to one because the first thing we will do when transmitting is
- * toggle the bit
- */
-
- status |= USB_BDT_DATA1;
- bdt->status = status;
-
- bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, status, bdt->addr);
+ bdt->status = 0;
+ bdt->addr = 0;
- /* Now do the same for the other buffer. The only difference is the
- * we clear DATA1 (making it DATA0)
- */
+ bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr);
- bdt = &g_bdt[index+1];
- status = bdt->status & ~USB_BDT_UOWN;
+ /* Now do the same for the other buffer. */
- status &= ~USB_BDT_DATA01;
- bdt->status = status;
+ bdt++;
+ bdt->status = 0;
+ bdt->addr = 0;
- bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, status, bdt->addr);
+ bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr);
}
/* Get the maxpacket size of the endpoint. */
@@ -3010,6 +3069,14 @@ static int pic32mx_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
privep->txnullpkt = 0;
pic32mx_rqenqueue(privep, privreq);
usbtrace(TRACE_OUTREQQUEUED(epno), req->len);
+
+ /* Set up the read operation. Because the PIC32MX supports ping-pong
+ * buffering. There may be two pending read requests. The following
+ * call will attempt to setup a read using this request for this
+ * endpoint. It is not harmful if this fails.
+ */
+
+ (void)pic32mx_rdrequest(priv, privep);
}
irqrestore(flags);
@@ -3052,9 +3119,9 @@ static int pic32mx_epbdtstall(struct usbdev_ep_s *ep,
{
struct pic32mx_ep_s *privep;
struct pic32mx_usbdev_s *priv;
+ uint32_t status;
uint32_t regaddr;
uint16_t regval;
- uint16_t status;
uint8_t epno;
/* Recover pointers */
@@ -3605,7 +3672,6 @@ static void pic32mx_swreset(struct pic32mx_usbdev_s *priv)
privep->stalled = false;
privep->halted = false;
privep->txbusy = false;
- privep->rxoverrun = false;
privep->txnullpkt = false;
}