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:
parent
fc0209c445
commit
6d3a292f02
@ -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).
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
{
|
||||
usbtrace(TRACE_CLASSWRCOMPLETE, priv->nwrq);
|
||||
cdcacm_sndpacket(priv);
|
||||
}
|
||||
break;
|
||||
|
||||
case -ESHUTDOWN: /* Disconnection */
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRSHUTDOWN), priv->nwrq);
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRSHUTDOWN), priv->nwrq);
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* Some other error occurred */
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRUNEXPECTED), (uint16_t)-req->result);
|
||||
{
|
||||
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user