Fix null packet handling in the PIC32 USB device driver. This is a critical bug fix for PIC32. Add support for the USB monitor to the Sure-PIC32MX configuration

This commit is contained in:
Gregory Nutt 2013-05-28 13:36:01 -06:00
parent fc0209c445
commit 6d3a292f02
6 changed files with 112 additions and 48 deletions

View File

@ -4817,3 +4817,9 @@
* configs/sure-pic32mx/pic32mx_lcd1602.c: This driver appears to
fully functional (at least to the extent that it has been tested)
(2013-5-27).
* arch/mips/src/pic32mx/pic32mx-usbdev.c: Fix NULL packet handling in
the PIC32 USB device driver. Without this fix the CDC/ACM driver
cannot be used reliably with the PIC32 USB. With this change the
configs/sure-pic32mx/usbnsh configuration works great (2013-5-28).
* configs/sure-pic32mx/src/pic32mx_nsh.c: The NSH configurations will
support the USB monitor applications (2013-5-28).

View File

@ -1154,7 +1154,7 @@ static int pic32mx_wrstart(struct pic32mx_usbdev_s *priv,
/* Even if the request is incomplete, transfer of all the requested
* bytes may already been started. NOTE: inflight[1] should be zero
* because we know that there is a BDT availalbe.
* because we know that there is a BDT available.
*/
#ifdef CONFIG_USBDEV_NOWRITEAHEAD
@ -1169,10 +1169,20 @@ static int pic32mx_wrstart(struct pic32mx_usbdev_s *priv,
xfrd += privreq->inflight[0];
bytesleft -= privreq->inflight[0];
}
/* Do we need to send a null packet after this packet? */
else if (privep->txnullpkt)
{
/* Yes... set up for the NULL packet transfer */
xfrd = privreq->req.len;
bytesleft = 0;
}
else
{
/* Yes.. we need to get the next request from the head of the
* pending request list.
/* No.. We are finished with this request. We need to get the
* next request from the head of the pending request list.
*/
privreq = NULL;
@ -1220,7 +1230,7 @@ static int pic32mx_wrstart(struct pic32mx_usbdev_s *priv,
/* Get the number of bytes left to be sent in the packet */
nbytes = bytesleft;
if (nbytes > 0)
if (nbytes > 0 || privep->txnullpkt)
{
/* Either send the maxpacketsize or all of the remaining data in
* the request.

View File

@ -79,7 +79,7 @@
# undef HAVE_USBMONITOR
#endif
/* Can't support USB device is USB device is not enabled */
/* Can't support USB device monitor if USB device is not enabled */
#ifndef CONFIG_USBDEV
# undef HAVE_USBDEV

View File

@ -30,6 +30,11 @@ DB-DP11212 PIC32 General Purpose Demo Board
- Three tactile switches
- Four user LEDs
NOTE: I see that Sure Electronics shows both of these boards at end-of-Life
(EOL). So I assume that these boards will no longer be generally available.
This work should still be useful, however, for other PIC32MX4-based boards
(2012-5-27).
Contents
========
@ -880,7 +885,40 @@ Where <subdir> is one of the following:
CONFIG_UART2_RXBUFSIZE=64
CONFIG_UART2_TXBUFSIZE=64
5. If you want to try this configuration on the DB-DP11212 PIC32 General
NOTE: Using the SYSLOG to get debug output has limitations. Among
those are that you cannot get debug output from interrupt handlers.
So, in particularly, debug output is not a useful way to debug the
USB device controller driver. Instead, use the USB monitor with
USB debug off and USB trance on (see below).
5. Enabling USB monitor SYSLOG output. If tracing is enabled, the USB
device will save encoded trace output in in-memory buffer; if the
USB monitor is enabled, that trace buffer will be periodically
emptied and dumped to the system logging device (UART2 in this
configuraion):
Device Drivers -> "USB Device Driver Support:
CONFIG_USBDEV_TRACE=y : Enable USB trace feature
CONFIG_USBDEV_TRACE_NRECORDS=256 : Buffer 128 records in memory
Application Configuration -> NSH LIbrary:
CONFIG_NSH_USBDEV_TRACE=n : No builtin tracing from NSH
CONFIG_NSH_ARCHINIT=y : Automatically start the USB monitor
Application Configuration -> System NSH Add-Ons:
CONFIG_SYSTEM_USBMONITOR=y : Enable the USB monitor daemon
CONFIG_SYSTEM_USBMONITOR_STACKSIZE=2048 : USB monitor daemon stack size
CONFIG_SYSTEM_USBMONITOR_PRIORITY=50 : USB monitor daemon priority
CONFIG_SYSTEM_USBMONITOR_INTERVAL=1 : Dump trace data every second
CONFIG_SYSTEM_USBMONITOR_TRACEINIT=y : Enable TRACE output
CONFIG_SYSTEM_USBMONITOR_TRACECLASS=y
CONFIG_SYSTEM_USBMONITOR_TRACETRANSFERS=y
CONFIG_SYSTEM_USBMONITOR_TRACECONTROLLER=y
CONFIG_SYSTEM_USBMONITOR_TRACEINTERRUPTS=y
NOTE: USB debug output should not be enabled in this case.
6. If you want to try this configuration on the DB-DP11212 PIC32 General
Purpose Demo Board", here are the changes that you should make:
Board Configuration:
@ -892,29 +930,3 @@ Where <subdir> is one of the following:
Device Drivers -> System Logging Device Options:
CONFIG_SYSLOG=n : Disable SYSLOG output
6. Enabling USB monitor SYSLOG output. If tracing is enabled, the USB
device will save encoded trace output in in-memory buffer; if the
USB monitor is enabled, that trace buffer will be periodically
emptied and dumped to the system loggin device (UART2 in this
configuraion):
Device Drivers -> "USB Device Driver Support:
CONFIG_USBDEV_TRACE=y : Enable USB trace feature
CONFIG_USBDEV_TRACE_NRECORDS=128 : Buffer 128 records in memory
Application Configuration -> NSH LIbrary:
CONFIG_NSH_USBDEV_TRACE=n : No builtin tracing from NSH
CONFIG_NSH_ARCHINIT=y : Automatically start the USB monitor
Application Configuration -> System NSH Add-Ons:
CONFIG_SYSTEM_USBMONITOR=y : Enable the USB monitor daemon
CONFIG_SYSTEM_USBMONITOR_STACKSIZE=2048 : USB monitor daemon stack size
CONFIG_SYSTEM_USBMONITOR_PRIORITY=50 : USB monitor daemon priority
CONFIG_SYSTEM_USBMONITOR_INTERVAL=2 : Dump trace data every 2 seconds
CONFIG_SYSTEM_USBMONITOR_TRACEINIT=y : Enable TRACE output
CONFIG_SYSTEM_USBMONITOR_TRACECLASS=y
CONFIG_SYSTEM_USBMONITOR_TRACETRANSFERS=y
CONFIG_SYSTEM_USBMONITOR_TRACECONTROLLER=y
CONFIG_SYSTEM_USBMONITOR_TRACEINTERRUPTS=y

View File

@ -49,6 +49,10 @@
#include <nuttx/lcd/hd4478ou.h>
#include <nuttx/usb/usbhost.h>
#ifdef CONFIG_SYSTEM_USBMONITOR
# include <apps/usbmonitor.h>
#endif
#include "pic32mx-internal.h"
#include "sure-pic32mx.h"
@ -60,24 +64,25 @@
/* PORT and SLOT number probably depend on the board configuration */
#define NSH_HAVEMMCSD 1
#define NSH_HAVEUSBHOST 1
#define NSH_HAVE_MMCSD 1
#define NSH_HAVE_USBHOST 1
#define NSH_HAVE_USBMONITOR 1
/* Can't support MMC/SD if SPI2 is not enabled */
#ifndef CONFIG_PIC32MX_SPI2
# undef NSH_HAVEMMCSD
# undef NSH_HAVE_MMCSD
#endif
/* Can't support MMC/SD features if mountpoints are disabled */
#if defined(CONFIG_DISABLE_MOUNTPOINT)
# undef NSH_HAVEMMCSD
# undef NSH_HAVE_MMCSD
#endif
/* MMC/SD configuration */
#ifdef NSH_HAVEMMCSD
#ifdef NSH_HAVE_MMCSD
# if !defined(CONFIG_NSH_MMCSDSPIPORTNO) || CONFIG_NSH_MMCSDSPIPORTNO != 2
# warning "The Sure PIC32MX MMC/SD is on SPI2"
# undef CONFIG_NSH_MMCSDSPIPORTNO
@ -110,10 +115,10 @@
#endif
#if !defined(CONFIG_USBHOST) || !defined(CONFIG_PIC32MX_USBHOST)
# undef NSH_HAVEUSBHOST
# undef NSH_HAVE_USBHOST
#endif
#ifdef NSH_HAVEUSBHOST
#ifdef NSH_HAVE_USBHOST
# ifndef CONFIG_USBHOST_DEFPRIO
# define CONFIG_USBHOST_DEFPRIO 50
# endif
@ -122,6 +127,20 @@
# endif
#endif
/* USB Monitor */
/* Can't support USB device monitor if USB device is not enabled */
#ifndef CONFIG_USBDEV
# undef NSH_HAVE_USBMONITOR
#endif
/* Check if we should enable the USB monitor before starting NSH */
#if !defined(CONFIG_USBDEV_TRACE) || !defined(CONFIG_SYSTEM_USBMONITOR)
# undef NSH_HAVE_USBMONITOR
#endif
/* Debug ********************************************************************/
#ifdef CONFIG_CPP_HAVE_VARARGS
@ -142,7 +161,7 @@
* Private Data
****************************************************************************/
#ifdef NSH_HAVEUSBHOST
#ifdef NSH_HAVE_USBHOST
static struct usbhost_driver_s *g_drvr;
#endif
@ -158,7 +177,7 @@ static struct usbhost_driver_s *g_drvr;
*
****************************************************************************/
#ifdef NSH_HAVEUSBHOST
#ifdef NSH_HAVE_USBHOST
static int nsh_waiter(int argc, char *argv[])
{
bool connected = false;
@ -199,7 +218,7 @@ static int nsh_waiter(int argc, char *argv[])
*
****************************************************************************/
#ifdef NSH_HAVEMMCSD
#ifdef NSH_HAVE_MMCSD
static int nsh_sdinitialize(void)
{
FAR struct spi_dev_s *spi;
@ -261,7 +280,7 @@ errout:
*
****************************************************************************/
#ifdef NSH_HAVEUSBHOST
#ifdef NSH_HAVE_USBHOST
static int nsh_usbhostinitialize(void)
{
int pid;
@ -368,5 +387,14 @@ int nsh_archinitialize(void)
ret = nsh_usbdevinitialize();
}
#ifdef NSH_HAVE_USBMONITOR
if (ret == OK)
{
/* Start the USB Monitor */
ret = usbmonitor_start(0, NULL);
}
#endif
return ret;
}

View File

@ -369,7 +369,7 @@ static int cdcacm_sndpacket(FAR struct cdcacm_dev_s *priv)
{
/* Peek at the request in the container at the head of the list */
reqcontainer = (struct cdcacm_req_s *)sq_peek(&priv->reqlist);
reqcontainer = (FAR struct cdcacm_req_s *)sq_peek(&priv->reqlist);
req = reqcontainer->req;
/* Fill the request with serial TX data */
@ -901,16 +901,22 @@ static void cdcacm_wrcomplete(FAR struct usbdev_ep_s *ep,
switch (req->result)
{
case OK: /* Normal completion */
{
usbtrace(TRACE_CLASSWRCOMPLETE, priv->nwrq);
cdcacm_sndpacket(priv);
}
break;
case -ESHUTDOWN: /* Disconnection */
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRSHUTDOWN), priv->nwrq);
}
break;
default: /* Some other error occurred */
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRUNEXPECTED), (uint16_t)-req->result);
}
break;
}
}
@ -1023,6 +1029,7 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
ret = -ENOMEM;
goto errout;
}
reqcontainer->req->priv = reqcontainer;
reqcontainer->req->callback = cdcacm_rdcomplete;
}
@ -1045,6 +1052,7 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
ret = -ENOMEM;
goto errout;
}
reqcontainer->req->priv = reqcontainer;
reqcontainer->req->callback = cdcacm_wrcomplete;