Several fixes to the PIC32 USB device OUT path logic

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4451 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-03-04 17:38:00 +00:00
parent 03c2be3856
commit 40f49928b0
4 changed files with 228 additions and 137 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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>

View File

@ -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
{
DEBUGASSERT(bdt == &g_bdt[EP0_OUT_ODD]);
g_bdt[EP0_OUT_EVEN].status = 0;
}
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)
{
/* 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", epno, bdtout, status, bdtout->addr);
bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n",
USB_EPNO(privep->ep.eplog), bdt, status, bdt->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
*/
bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr);
status |= USB_BDT_DATA1;
bdt->status = status;
/* Now do the same for the other buffer. */
bdtdbg("EP%d BDT IN [%p] {%08x, %08x}\n", epno, bdt, status, bdt->addr);
bdt++;
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)
*/
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;
bdt->status = 0;
bdt->addr = 0;
/* Set DATA1 to one because the first thing we will do when transmitting is
* toggle the bit
*/
bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, bdt->status, bdt->addr);
status |= USB_BDT_DATA1;
bdt->status = status;
/* Now do the same for the other buffer. */
bdtdbg("EP%d BDT OUT [%p] {%08x, %08x}\n", epno, bdt, status, bdt->addr);
bdt++;
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)
*/
bdt = &g_bdt[index+1];
status = bdt->status & ~USB_BDT_UOWN;
status &= ~USB_BDT_DATA01;
bdt->status = status;
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;
}