Some fixes for the PIC32 USB IN processing -- still some issues

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4452 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-03-04 19:31:10 +00:00
parent 40f49928b0
commit 4129b430d6
1 changed files with 73 additions and 29 deletions

View File

@ -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.
/* Yes.. Then the other BDT is the ODD BDT */
privep->bdtin++;
}
/* 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
*/
if (bytesleft == 0 && !privep->txnullpkt)
{
/* The transfer is complete. Give the completed request back to
* the class driver.
*/
privreq->req.xfrd += privreq->inflight;
privreq->inflight = 0;
bytesleft = privreq->req.len - privreq->req.xfrd;
usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)), privreq->req.xfrd);
pic32mx_reqcomplete(privep, OK);
/* If all of the bytes were sent (bytesleft == 0) and no NULL packet is
* needed (!txnullpkt), then we are finished with the transfer
/* 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 (bytesleft == 0 && !privep->txnullpkt)
if (USB_EPNO(privep->ep.eplog) == 0)
{
/* 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);
/* 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;
}
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);