diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-02-29 21:53:28 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-02-29 21:53:28 +0000 |
commit | 5faa1bd9cefb4e7a2319faaa5b36da9140aba16a (patch) | |
tree | 358673f55511cec814532fbf08a11847936c38cf | |
parent | 286b14b0c9d2dbad599e80cac9c269c9cd96b408 (diff) | |
download | nuttx-5faa1bd9cefb4e7a2319faaa5b36da9140aba16a.tar.gz nuttx-5faa1bd9cefb4e7a2319faaa5b36da9140aba16a.tar.bz2 nuttx-5faa1bd9cefb4e7a2319faaa5b36da9140aba16a.zip |
A little more work (but not much progress) on the PIC32 USB device driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4440 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | apps/examples/README.txt | 34 | ||||
-rw-r--r-- | apps/examples/cdcacm/cdcacm.h | 42 | ||||
-rw-r--r-- | apps/examples/cdcacm/cdcacm_main.c | 15 | ||||
-rw-r--r-- | apps/examples/composite/composite.h | 2 | ||||
-rw-r--r-- | apps/examples/usbserial/host.c | 6 | ||||
-rw-r--r-- | apps/examples/usbserial/main.c | 18 | ||||
-rw-r--r-- | apps/examples/usbterm/usbterm.h | 6 | ||||
-rw-r--r-- | apps/examples/usbterm/usbterm_main.c | 8 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c | 150 | ||||
-rw-r--r-- | nuttx/configs/sure-pic32mx/README.txt | 32 | ||||
-rw-r--r-- | nuttx/configs/sure-pic32mx/nsh/appconfig | 39 | ||||
-rw-r--r-- | nuttx/configs/sure-pic32mx/nsh/defconfig | 39 |
12 files changed, 292 insertions, 99 deletions
diff --git a/apps/examples/README.txt b/apps/examples/README.txt index fb947cd71..86edc6e33 100644 --- a/apps/examples/README.txt +++ b/apps/examples/README.txt @@ -132,6 +132,28 @@ examples/cdcacm CONFIG_EXAMPLES_CDCACM_DEVMINOR : The minor number of the CDC/ACM device. : i.e., the 'x' in /dev/ttyACMx + If CONFIG_USBDEV_TRACE is enabled (or CONFIG_DEBUG and CONFIG_DEBUG_USB, or + CONFIG_USBDEV_TRACE), then the example code will also initialize the USB trace + output. The amount of trace output can be controlled using: + + CONFIG_EXAMPLES_CDCACM_TRACEINIT + Show initialization events + CONFIG_EXAMPLES_CDCACM_TRACECLASS + Show class driver events + CONFIG_EXAMPLES_CDCACM_TRACETRANSFERS + Show data transfer events + CONFIG_EXAMPLES_CDCACM_TRACECONTROLLER + Show controller events + CONFIG_EXAMPLES_CDCACM_TRACEINTERRUPTS + Show interrupt-related events. + + Note: This example is only enables or disable USB CDC/ACM via the NSH + 'sercon' and 'serdis' command. It will enable and disable tracing per + the settings before enabling and after disabling the CDC/ACM device. It + will not, however, monitor buffered trace data in the interim. If + CONFIG_USBDEV_TRACE is defined (and the debug options are not), other + application logic will need to monitor the buffered trace data. + examples/composite ^^^^^^^^^^^^^^^^^^ @@ -188,9 +210,10 @@ examples/composite CONFIG_EXAMPLES_COMPOSITE_BUFLEN. Default 256. CONFIG_EXAMPLES_COMPOSITE_TTYUSB - The minor number of the USB serial device. - Default is zero (corresponding to /dev/ttyUSB0. Default is zero. + Default is zero (corresponding to /dev/ttyUSB0 or /dev/ttyACM0). Default is zero. CCONFIG_EXAMPLES_COMPOSITE_SERDEV - The string corresponding to - CONFIG_EXAMPLES_COMPOSITE_TTYUSB. The default is "/dev/ttyUSB0". + CONFIG_EXAMPLES_COMPOSITE_TTYUSB. The default is "/dev/ttyUSB0" (for the PL2303 + emulation) or "/dev/ttyACM0" (for the CDC/ACM serial device). CONFIG_EXAMPLES_COMPOSITE_BUFSIZE - The size of the serial I/O buffer in bytes. Default 256 bytes. @@ -1274,7 +1297,8 @@ examples/usbserial At the end of the dmesg output, you should see the serial device was successfully idenfied and assigned to a tty device, - probably /dev/ttyUSB0. + probably /dev/ttyUSB0 or /dev/ttyACM0 (depending on the configured + USB serial driver). 3. Then start the host application: @@ -1282,7 +1306,9 @@ examples/usbserial Where: - <tty-dev> is the USB TTY device to use. The default is /dev/ttyUSB0. + <tty-dev> is the USB TTY device to use. The default is + "/dev/ttyUSB0" (for the PL2303 emulation) or "/dev/ttyACM0" (for + the CDC/ACM serial device). The host and target will exchange are variety of very small and very large serial messages. diff --git a/apps/examples/cdcacm/cdcacm.h b/apps/examples/cdcacm/cdcacm.h index 60eada896..ce40e1a93 100644 --- a/apps/examples/cdcacm/cdcacm.h +++ b/apps/examples/cdcacm/cdcacm.h @@ -41,12 +41,14 @@ ****************************************************************************/ #include <nuttx/config.h> + #include <stdlib.h> +#include <nuttx/usb/usbdev_trace.h> + /**************************************************************************** * Pre-Processor Definitions ****************************************************************************/ - /* Configuration ************************************************************/ /* Prerequisites */ @@ -68,6 +70,44 @@ # define CONFIG_EXAMPLES_CDCACM_DEVMINOR 0 #endif +/* Trace Configuration ******************************************************/ + +#ifdef CONFIG_EXAMPLES_CDCACM_TRACEINIT +# define TRACE_INIT_BITS (TRACE_INIT_BIT) +#else +# define TRACE_INIT_BITS (0) +#endif + +#define TRACE_ERROR_BITS (TRACE_DEVERROR_BIT|TRACE_CLSERROR_BIT) + +#ifdef CONFIG_EXAMPLES_CDCACM_TRACECLASS +# define TRACE_CLASS_BITS (TRACE_CLASS_BIT|TRACE_CLASSAPI_BIT|TRACE_CLASSSTATE_BIT) +#else +# define TRACE_CLASS_BITS (0) +#endif + +#ifdef CONFIG_EXAMPLES_CDCACM_TRACETRANSFERS +# define TRACE_TRANSFER_BITS (TRACE_OUTREQQUEUED_BIT|TRACE_INREQQUEUED_BIT|TRACE_READ_BIT|\ + TRACE_WRITE_BIT|TRACE_COMPLETE_BIT) +#else +# define TRACE_TRANSFER_BITS (0) +#endif + +#ifdef CONFIG_EXAMPLES_CDCACM_TRACECONTROLLER +# define TRACE_CONTROLLER_BITS (TRACE_EP_BIT|TRACE_DEV_BIT) +#else +# define TRACE_CONTROLLER_BITS (0) +#endif + +#ifdef CONFIG_EXAMPLES_CDCACM_TRACEINTERRUPTS +# define TRACE_INTERRUPT_BITS (TRACE_INTENTRY_BIT|TRACE_INTDECODE_BIT|TRACE_INTEXIT_BIT) +#else +# define TRACE_INTERRUPT_BITS (0) +#endif + +#define TRACE_BITSET (TRACE_INIT_BITS|TRACE_ERROR_BITS|TRACE_CLASS_BITS|\ + TRACE_TRANSFER_BITS|TRACE_CONTROLLER_BITS|TRACE_INTERRUPT_BITS) + /* Debug ********************************************************************/ #ifdef CONFIG_CPP_HAVE_VARARGS diff --git a/apps/examples/cdcacm/cdcacm_main.c b/apps/examples/cdcacm/cdcacm_main.c index 94afe3a58..aeb7a9e74 100644 --- a/apps/examples/cdcacm/cdcacm_main.c +++ b/apps/examples/cdcacm/cdcacm_main.c @@ -81,7 +81,6 @@ struct cdcacm_state_s g_cdcacm; int sercon_main(int argc, char *argv[]) { - FAR void *handle; int ret; /* Check if there is a non-NULL USB mass storage device handle (meaning that the @@ -94,7 +93,13 @@ int sercon_main(int argc, char *argv[]) return EXIT_FAILURE; } - /* Initialize the USB serial driver */ + /* Then, in any event, enable trace data collection as configured BEFORE + * enabling the CDC/ACM device. + */ + + usbtrace_enable(TRACE_BITSET); + + /* Initialize the USB CDC/ACM serial driver */ message("sercon: Registering CDC/ACM serial driver\n"); ret = cdcacm_initialize(CONFIG_EXAMPLES_CDCACM_DEVMINOR, &g_cdcacm.handle); @@ -127,6 +132,12 @@ int serdis_main(int argc, char *argv[]) return EXIT_FAILURE; } + /* Then, in any event, disable trace data collection as configured BEFORE + * enabling the CDC/ACM device. + */ + + usbtrace_enable(0); + /* Then disconnect the device and uninitialize the USB mass storage driver */ cdcacm_uninitialize(g_cdcacm.handle); diff --git a/apps/examples/composite/composite.h b/apps/examples/composite/composite.h index 48e4b155f..fab498c9f 100644 --- a/apps/examples/composite/composite.h +++ b/apps/examples/composite/composite.h @@ -120,6 +120,8 @@ #ifndef CONFIG_EXAMPLES_COMPOSITE_SERDEV # if CONFIG_EXAMPLES_COMPOSITE_TTYUSB != 0 # error "Serial device unknown (CONFIG_EXAMPLES_COMPOSITE_SERDEV)" +# elif defined(CONFIG_CDCACM) +# define CONFIG_EXAMPLES_COMPOSITE_SERDEV "/dev/ttyACM0" # else # define CONFIG_EXAMPLES_COMPOSITE_SERDEV "/dev/ttyUSB0" # endif diff --git a/apps/examples/usbserial/host.c b/apps/examples/usbserial/host.c index 751b7530c..dfa288f44 100644 --- a/apps/examples/usbserial/host.c +++ b/apps/examples/usbserial/host.c @@ -66,7 +66,11 @@ # endif #endif -#define DEFAULT_TTYDEV "/dev/ttyUSB0" +#ifdef CONFIG_CDCACM +# define DEFAULT_TTYDEV "/dev/ttyACM0" +#else +# define DEFAULT_TTYDEV "/dev/ttyUSB0" +#endif #define BUFFER_SIZE 1024 /**************************************************************************** diff --git a/apps/examples/usbserial/main.c b/apps/examples/usbserial/main.c index 7ad9d0d9c..eea905c98 100644 --- a/apps/examples/usbserial/main.c +++ b/apps/examples/usbserial/main.c @@ -125,6 +125,12 @@ # endif #endif +#ifdef CONFIG_CDCACM +# define USBSER_DEVNAME "/dev/ttyACM0" +#else +# define USBSER_DEVNAME "/dev/ttyUSB0" +#endif + #define IOBUFFER_SIZE 256 /**************************************************************************** @@ -246,11 +252,11 @@ int user_start(int argc, char *argv[]) do { message("user_start: Opening USB serial driver\n"); - outfd = open("/dev/ttyUSB0", O_WRONLY); + outfd = open(USBSER_DEVNAME, O_WRONLY); if (outfd < 0) { int errcode = errno; - message("user_start: ERROR: Failed to open /dev/ttyUSB0 for writing: %d\n", errcode); + message("user_start: ERROR: Failed to open " USBSER_DEVNAME " for writing: %d\n", errcode); /* ENOTCONN means that the USB device is not yet connected */ @@ -279,21 +285,21 @@ int user_start(int argc, char *argv[]) #ifndef CONFIG_EXAMPLES_USBSERIAL_INONLY #ifndef CONFIG_EXAMPLES_USBSERIAL_OUTONLY - infd = open("/dev/ttyUSB0", O_RDONLY|O_NONBLOCK); + infd = open(USBSER_DEVNAME, O_RDONLY|O_NONBLOCK); if (infd < 0) { - message("user_start: ERROR: Failed to open /dev/ttyUSB0 for reading: %d\n", errno); + message("user_start: ERROR: Failed to open " USBSER_DEVNAME " for reading: %d\n", errno); close(outfd); return 3; } #else do { - infd = open("/dev/ttyUSB0", O_RDONLY|O_NONBLOCK); + infd = open(USBSER_DEVNAME, O_RDONLY|O_NONBLOCK); if (infd < 0) { int errcode = errno; - message("user_start: ERROR: Failed to open /dev/ttyUSB0 for reading: %d\n", errno); + message("user_start: ERROR: Failed to open " USBSER_DEVNAME " for reading: %d\n", errno); /* ENOTCONN means that the USB device is not yet connected */ diff --git a/apps/examples/usbterm/usbterm.h b/apps/examples/usbterm/usbterm.h index 1dc2085dd..a889c886d 100644 --- a/apps/examples/usbterm/usbterm.h +++ b/apps/examples/usbterm/usbterm.h @@ -91,6 +91,12 @@ #define TRACE_BITSET (TRACE_INIT_BITS|TRACE_ERROR_BITS|TRACE_CLASS_BITS|\ TRACE_TRANSFER_BITS|TRACE_CONTROLLER_BITS|TRACE_INTERRUPT_BITS) +#ifdef CONFIG_CDCACM +# define USBTERM_DEVNAME "/dev/ttyACM0" +#else +# define USBTERM_DEVNAME "/dev/ttyUSB0" +#endif + /* Debug ********************************************************************/ #ifdef CONFIG_CPP_HAVE_VARARGS diff --git a/apps/examples/usbterm/usbterm_main.c b/apps/examples/usbterm/usbterm_main.c index 5bad8fffe..ba723e91b 100644 --- a/apps/examples/usbterm/usbterm_main.c +++ b/apps/examples/usbterm/usbterm_main.c @@ -229,11 +229,11 @@ int MAIN_NAME(int argc, char *argv[]) { message(MAIN_STRING "Opening USB serial driver\n"); - g_usbterm.outstream = fopen("/dev/ttyUSB0", "w"); + g_usbterm.outstream = fopen(USBTERM_DEVNAME, "w"); if (g_usbterm.outstream == NULL) { int errcode = errno; - message(MAIN_STRING "ERROR: Failed to open /dev/ttyUSB0 for writing: %d\n", + message(MAIN_STRING "ERROR: Failed to open " USBTERM_DEVNAME " for writing: %d\n", errcode); /* ENOTCONN means that the USB device is not yet connected */ @@ -261,10 +261,10 @@ int MAIN_NAME(int argc, char *argv[]) * should not fail. */ - g_usbterm.instream = fopen("/dev/ttyUSB0", "r"); + g_usbterm.instream = fopen(USBTERM_DEVNAME, "r"); if (g_usbterm.instream == NULL) { - message(MAIN_STRING "ERROR: Failed to open /dev/ttyUSB0 for reading: %d\n", errno); + message(MAIN_STRING "ERROR: Failed to open " USBTERM_DEVNAME " for reading: %d\n", errno); goto errout_with_outstream; } diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c index d84df0aac..c33a39ea6 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c @@ -118,7 +118,7 @@ /* Endpoint Definitions */ -#ifndef CONFIG_USB_PINGPONG +#ifndef CONFIG_PIC32MX_USBDEV_PINGPONG # define USB_NEXT_PINGPONG (0) # define EP0_OUT_EVEN (0) # define EP0_OUT_ODD (0) @@ -221,20 +221,21 @@ #define PIC32MX_TRACEINTID_GETSTATUS 0x0013 #define PIC32MX_TRACEINTID_IFGETSTATUS 0x0014 #define PIC32MX_TRACEINTID_TRNC 0x0015 -#define PIC32MX_TRACEINTID_INTERRUPT 0x0016 -#define PIC32MX_TRACEINTID_NOSTDREQ 0x0017 -#define PIC32MX_TRACEINTID_RESET 0x0018 -#define PIC32MX_TRACEINTID_SETCONFIG 0x0019 -#define PIC32MX_TRACEINTID_SETFEATURE 0x001a -#define PIC32MX_TRACEINTID_IDLE 0x001b -#define PIC32MX_TRACEINTID_SYNCHFRAME 0x001c -#define PIC32MX_TRACEINTID_WKUP 0x001d -#define PIC32MX_TRACEINTID_T1MSEC 0x001e -#define PIC32MX_TRACEINTID_OTGID 0x001f -#define PIC32MX_TRACEINTID_STALL 0x0020 -#define PIC32MX_TRACEINTID_UERR 0x0021 -#define PIC32MX_TRACEINTID_SUSPENDED 0x0022 -#define PIC32MX_TRACEINTID_WAITRESET 0x0023 +#define PIC32MX_TRACEINTID_TRNCS 0x0016 +#define PIC32MX_TRACEINTID_INTERRUPT 0x0017 +#define PIC32MX_TRACEINTID_NOSTDREQ 0x0018 +#define PIC32MX_TRACEINTID_RESET 0x0019 +#define PIC32MX_TRACEINTID_SETCONFIG 0x001a +#define PIC32MX_TRACEINTID_SETFEATURE 0x001b +#define PIC32MX_TRACEINTID_IDLE 0x001c +#define PIC32MX_TRACEINTID_SYNCHFRAME 0x001d +#define PIC32MX_TRACEINTID_WKUP 0x001e +#define PIC32MX_TRACEINTID_T1MSEC 0x001f +#define PIC32MX_TRACEINTID_OTGID 0x0020 +#define PIC32MX_TRACEINTID_STALL 0x0021 +#define PIC32MX_TRACEINTID_UERR 0x0022 +#define PIC32MX_TRACEINTID_SUSPENDED 0x0023 +#define PIC32MX_TRACEINTID_WAITRESET 0x0024 /* Misc Helper Macros *******************************************************/ @@ -351,20 +352,17 @@ 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_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 txnullpkt:1; /* Null packet needed at end of transfer */ -#ifdef CONFIG_USB_PINGPONG - uint8_t ep0ready:1 /* EP0 OUT already prepared */ -#endif + 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 txnullpkt:1; /* Null packet needed at end of 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 */ }; @@ -389,6 +387,9 @@ struct pic32mx_usbdev_s uint8_t ctrlstate; /* Control EP state (see enum pic32mx_ctrlstate_e) */ uint8_t selfpowered:1; /* 1: Device is self powered */ uint8_t rwakeup:1; /* 1: Device supports remote wakeup */ +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG + uint8_t ep0ready:1; /* EP0 OUT already prepared */ +#endif uint16_t epavail; /* Bitset of available endpoints */ /* The endpoint list */ @@ -535,7 +536,7 @@ static const struct usbdev_ops_s g_devops = /* Buffer Descriptor Table */ -#ifndef CONFIG_USB_PINGPONG +#ifndef CONFIG_PIC32MX_USBDEV_PINGPONG volatile struct usbotg_bdtentry_s g_bdt[(PIC32MX_NENDPOINTS + 1) * 2] __attribute__ ((aligned(512))); #else @@ -747,7 +748,7 @@ static void pic32mx_epwrite(struct pic32mx_ep_s *privep, const uint8_t *src, /* Clear status and toggle the DTS bit if required */ -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG /* Clear all bits in the status but preserve the data toggle bit */ status = bdt->status & USB_BDT_DATA01; @@ -779,7 +780,7 @@ static void pic32mx_epwrite(struct pic32mx_ep_s *privep, const uint8_t *src, /* Point to the next ping pong buffer. */ -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG status ^= USB_NEXT_PINGPONG; #endif @@ -1044,7 +1045,9 @@ static int pic32mx_ep0rdsetup(struct pic32mx_usbdev_s *priv, uint8_t *dest, * else. */ - status = bdt->status & ~(USB_BDT_UOWN|USB_BDT_BYTECOUNT_MASK|USB_BDT_DATA01); + status = bdt->status; + status &= ~(USB_BDT_BSTALL | USB_BDT_NINC | USB_BDT_KEEP| USB_BDT_UOWN | + USB_BDT_BYTECOUNT_MASK | USB_BDT_DATA01); bdt->status = status; /* Set the data pointer, data length, and enable the endpoint */ @@ -1091,7 +1094,7 @@ static int pic32mx_rdsetup(struct pic32mx_usbdev_s *priv, /* Toggle the DATA01 bit if required for ping pong support */ -#ifndef CONFIG_USB_PINGPONG +#ifndef CONFIG_PIC32MX_USBDEV_PINGPONG status ^= USB_BDT_DATA01; #endif @@ -1105,7 +1108,7 @@ static int pic32mx_rdsetup(struct pic32mx_usbdev_s *priv, /* Point to the next ping pong buffer. */ -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG status ^= USB_NEXT_PINGPONG; #endif @@ -1332,7 +1335,7 @@ static void pic32mx_ep0nextsetup(struct pic32mx_usbdev_s *priv) status = bdt->status & ~USB_BDT_UOWN; -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG status ^= USB_NEXT_PINGPONG; #endif status &= ~USB_BDT_UOWN; @@ -1351,7 +1354,7 @@ static void pic32mx_ep0done(struct pic32mx_usbdev_s *priv, { struct pic32mx_ep_s *ep0 = &priv->eplist[EP0]; volatile struct usbotg_bdtentry_s *bdtout; -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG volatile struct usbotg_bdtentry_s *bdtnext; #endif uint16_t status; @@ -1359,15 +1362,15 @@ static void pic32mx_ep0done(struct pic32mx_usbdev_s *priv, /* Which BDT are we working on new? Which one will be next */ bdtout = ep0->bdtout; -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG if (bdtout == &g_bdt[EP0_OUT_EVEN]) { - btdnext = &g_bdt[EP0_OUT_ODD] + bdtnext = &g_bdt[EP0_OUT_ODD]; } else { DEBUGASSERT(bdtout == &g_bdt[EP0_OUT_ODD]); - btdnext = &g_bdt[EP0_OUT_EVEN] + bdtnext = &g_bdt[EP0_OUT_EVEN]; } #endif @@ -1384,26 +1387,34 @@ static void pic32mx_ep0done(struct pic32mx_usbdev_s *priv, * buffer address should be pointed to priv->ctrl. */ - status = bdtout->status & ~(USB_BDT_BYTECOUNT_MASK | USB_BDT_DTS); + status = bdtout->status; + status &= ~(USB_BDT_BSTALL | USB_BDT_NINC | USB_BDT_KEEP | + USB_BDT_BYTECOUNT_MASK | USB_BDT_DTS); status |= (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); status |= USB_BDT_UOWN; /* Note: DTSEN is 0 */ bdtout->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); - bdtdbg("EP0 BDT OUT (Next) {%08x, %08x}\n", status, bdtout->addr); + bdtdbg("EP0 BDT OUT {%08x, %08x}\n", status, bdtout->addr); bdtout->status = status; -#ifdef CONFIG_USB_PINGPONG - status = btdnext->status & ~USB_BDT_BYTECOUNT_MASK; + /* In ping-pong mode, force a STALL if there is any access to the + * other buffer. + */ + +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG + status = bdtnext->status; + status &= ~USB_BDT_BYTECOUNT_MASK; status |= (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); - status |= USB_BDT_UOWN | USB_BDT_BSTALL; + status |= (USB_BDT_UOWN | USB_BDT_BSTALL); - btdnext->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); + bdtnext->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); - bdtdbg("EP0 BDT OUT {%08x, %08x}\n", status, btdnext->addr); + bdtdbg("EP0 BDT OUT (Next) {%08x, %08x}\n", status, bdtnext->addr); - btdnext->status = status; + bdtnext->status = status; + priv->ep0ready = 1; #endif } @@ -1451,11 +1462,10 @@ static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv) * ownership after a stall. */ + bdtdbg("EP0 BDT IN {%08x, %08x}\n", ep0->bdtin->status, ep0->bdtin->addr); ep0->bdtin->status &= ~USB_BDT_UOWN; } - bdtdbg("EP0 BDT IN {%08x, %08x}\n", ep0->bdtin->status, ep0->bdtin->addr); - /* Assume NOT stalled; no TX in progress */ ep0->stalled = 0; @@ -1987,7 +1997,7 @@ static void pic32mx_ep0in(struct pic32mx_usbdev_s *priv) /* Switch to the next ping pong buffer */ status = bdt->status; -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG status ^= USB_NEXT_PINGPONG; #endif @@ -2085,7 +2095,9 @@ static void pic32mx_ep0out(struct pic32mx_usbdev_s *priv) { /* Prepare EP0 OUT for the next SETUP transaction. */ - status = ep0->bdtout->status & ~(USB_BDT_BYTECOUNT_MASK|USB_BDT_DATA01); + status = ep0->bdtout->status; + status &= ~(USB_BDT_BSTALL | USB_BDT_NINC | USB_BDT_KEEP | + USB_BDT_BYTECOUNT_MASK | USB_BDT_DATA01); ep0->bdtout->status = status; ep0->bdtout->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); @@ -2122,11 +2134,13 @@ static void pic32mx_ep0out(struct pic32mx_usbdev_s *priv) pic32mx_ep0nextsetup(priv); -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG if (!priv->ep0ready) #endif { - status = ep0->bdtout->status & ~(USB_BDT_BYTECOUNT_MASK|USB_BDT_DATA01); + status = ep0->bdtout->status; + status &= ~(USB_BDT_BSTALL | USB_BDT_NINC | USB_BDT_KEEP | + USB_BDT_BYTECOUNT_MASK | USB_BDT_DATA01); ep0->bdtout->status = status; ep0->bdtout->addr = (uint8_t *)PHYS_ADDR(&priv->ctrl); @@ -2140,8 +2154,8 @@ static void pic32mx_ep0out(struct pic32mx_usbdev_s *priv) ep0->bdtout->status = status; } -#ifdef CONFIG_USB_PINGPONG - priv->ep0ready = 0; +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG + priv->ep0ready = 0; #endif } break; @@ -2182,7 +2196,7 @@ static void pic32mx_ep0transfer(struct pic32mx_usbdev_s *priv, uint16_t status) /* It was an EP0 OUT transaction. Get the index to the BDT. */ -#if CONFIG_USB_PINGPONG +#if CONFIG_PIC32MX_USBDEV_PINGPONG index = ((status & USB_STAT_PPBI) == 0 ? EP0_OUT_EVEN : EP0_OUT_ODD); #else index = EP0_OUT_EVEN; @@ -2469,13 +2483,15 @@ static int pic32mx_interrupt(int irq, void *context) { uint8_t epno; - /* Is token processing complete */ + /* Check the pending interrupt register. Is token processing complete. */ if ((pic32mx_getreg(PIC32MX_USB_IR) & USB_INT_TRN) != 0) { regval = pic32mx_getreg(PIC32MX_USB_STAT); pic32mx_putreg(USB_INT_TRN, PIC32MX_USB_IR); + usbtrace(TRACE_INTDECODE(PIC32MX_TRACEINTID_TRNCS), regval); + /* Handle the endpoint tranfer complete event. */ epno = (regval & USB_STAT_ENDPT_MASK) >> USB_STAT_ENDPT_SHIFT; @@ -2759,7 +2775,7 @@ static int pic32mx_epconfigure(struct usbdev_ep_s *ep, * The only difference is the we clear DATA1 (making it DATA0) */ -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG bdt = &g_bdt[index+1]; status = bdt->status & ~USB_BDT_UOWN; @@ -2793,7 +2809,7 @@ static int pic32mx_epconfigure(struct usbdev_ep_s *ep, * The only difference is the we clear DATA1 (making it DATA0) */ -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG bdt = &g_bdt[index+1]; status = bdt->status & ~USB_BDT_UOWN; @@ -2863,7 +2879,7 @@ static int pic32mx_epdisable(struct usbdev_ep_s *ep) /* Reset the BDTs */ ptr = (uint32_t*)&g_bdt[EP(epno, 0, 0)]; -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG for (i = 0; i < (4 * sizeof(struct usbotg_bdtentry_s) / sizeof(uint32_t)); i++) #else for (i = 0; i < (2 * sizeof(struct usbotg_bdtentry_s) / sizeof(uint32_t)); i++) @@ -3089,7 +3105,7 @@ static int pic32mx_epbdtstall(struct usbdev_ep_s *ep, /* Toggle over the to the next buffer */ -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG status ^= USB_NEXT_PINGPONG; #endif status |= (USB_BDT_UOWN | USB_BDT_DATA1); @@ -3117,7 +3133,7 @@ static int pic32mx_epbdtstall(struct usbdev_ep_s *ep, /* Toggle over the to the next buffer */ -#ifdef CONFIG_USB_PINGPONG +#ifdef CONFIG_PIC32MX_USBDEV_PINGPONG status ^= USB_NEXT_PINGPONG; #endif status |= (USB_BDT_UOWN | USB_BDT_DATA1 | USB_BDT_DTS); @@ -3561,6 +3577,7 @@ static void pic32mx_detach(struct pic32mx_usbdev_s *priv) static void pic32mx_hwreset(struct pic32mx_usbdev_s *priv) { + uint32_t physaddr; uint16_t regval; int i; @@ -3581,10 +3598,17 @@ static void pic32mx_hwreset(struct pic32mx_usbdev_s *priv) regval |= USB_PWRC_USBPWR; pic32mx_putreg(regval, PIC32MX_USB_PWRC); - /* Set the address of the buffer descriptor table (BDT) */ + /* Set the address of the buffer descriptor table (BDT) + * + * BDTP1: Bit 1-7: Bits 9-15 of the BDT base address + * BDTP2: Bit 0-7: Bits 16-23 of the BDT base address + * BDTP3: Bit 0-7: Bits 24-31 of the BDT base address + */ - regval = (uint16_t)((PHYS_ADDR(g_bdt)) >> 8); - pic32mx_putreg(regval, PIC32MX_USB_BDTP1); + physaddr = (PHYS_ADDR(g_bdt)) >> 8; + pic32mx_putreg((uint16_t)((regval >> 8) & USB_BDTP1_MASK), PIC32MX_USB_BDTP1); + pic32mx_putreg((uint16_t)((regval >> 16) & USB_BDTP2_MASK), PIC32MX_USB_BDTP2); + pic32mx_putreg((uint16_t)((regval >> 24) & USB_BDTP3_MASK), PIC32MX_USB_BDTP3); /* Assert reset request to all of the Ping Pong buffer pointers */ diff --git a/nuttx/configs/sure-pic32mx/README.txt b/nuttx/configs/sure-pic32mx/README.txt index 0c91f3289..dabdd541d 100644 --- a/nuttx/configs/sure-pic32mx/README.txt +++ b/nuttx/configs/sure-pic32mx/README.txt @@ -459,8 +459,32 @@ Where <subdir> is one of the following: Configures the NuttShell (nsh) located at apps/examples/nsh. The Configuration enables only the serial NSH interface. - The examples/usbterm program can be included as an NSH built-in - function by defined the following in your .config file: + Several USB device configurations can be enabled and included + as NSH built-in built in functions. All require the following + basic setup in your .config to enable USB device support: + + CONFIG_USBEV=y : Enable basic USB device support + CONFIG_PIC32MX_USBDEV=y : Enable PIC32 USB device support - CONFIG_USBEV=y : Enable basic USB device support - CONFIG_PIC32MX_USBDEV=y : Enable PIC32 USB device support + examples/usbterm - This option can be enabled by uncommenting + the following line in the appconfig file: + + CONFIGURED_APPS += examples/usbterm + + And by enabling one of the USB serial devices: + + CONFIG_PL2303=y : Enable the Prolifics PL2303 emulation + CONFIG_CDCACM=y : or the CDC/ACM serial driver (not both) + + examples/cdcacm - The examples/cdcacm program can be included as an + function by uncommenting the following line in the appconfig file: + + CONFIGURED_APPS += examples/cdcacm + + and defining the following in your .config file: + + CONFIG_CDCACM=y : Enable the CDCACM device + + examples/usbstorage - There are some hooks in the appconfig file + to enable the USB mass storage device. However, this device cannot + work until support for the SD card is also incorporated. diff --git a/nuttx/configs/sure-pic32mx/nsh/appconfig b/nuttx/configs/sure-pic32mx/nsh/appconfig index abf0b38a6..2263c5a3e 100644 --- a/nuttx/configs/sure-pic32mx/nsh/appconfig +++ b/nuttx/configs/sure-pic32mx/nsh/appconfig @@ -33,32 +33,45 @@ # ############################################################################ +############################################################################ # Path to example in apps/examples containing the user_start entry point +############################################################################ CONFIGURED_APPS += examples/nsh +############################################################################ # The NSH application library +############################################################################ CONFIGURED_APPS += system/readline CONFIGURED_APPS += nshlib -# Applications configured as an NX built-in commands +############################################################################ +# USB device configurations +############################################################################ -ifeq ($(CONFIG_NET),y) -CONFIGURED_APPS += netutils/uiplib -CONFIGURED_APPS += netutils/resolv -CONFIGURED_APPS += netutils/webclient -CONFIGURED_APPS += netutils/tftpc -endif +ifeq ($(CONFIG_PIC32MX_USBDEV),y) + +# USB Mass Storage Class device configurations -ifeq ($(CONFIG_PWM),y) -CONFIGURED_APPS += examples/pwm +ifeq ($(CONFIG_USBMSC),y) +# Uncomment to enable the examples/usbstorage built-in +# CONFIGURED_APPS += examples/usbstorage endif -ifeq ($(CONFIG_CAN),y) -CONFIGURED_APPS += examples/can +# USB CDC/ACM serial device configurations + +ifeq ($(CONFIG_CDCACM),y) +# Uncomment to enable the examples/cdcacm built-in +# CONFIGURED_APPS += examples/cdcacm +# Uncomment the following to enable the examples/usbterm built-in +# CONFIGURED_APPS += examples/usbterm endif -ifeq ($(CONFIG_PIC32MX_USBDEV),y) -CONFIGURED_APPS += examples/usbterm +# Prolifics PL2303 emulation configurations + +ifeq ($(CONFIG_PL2303),y) +# Uncomment the following to enable the examples/usbterm built-in +# CONFIGURED_APPS += examples/usbterm +endif endif diff --git a/nuttx/configs/sure-pic32mx/nsh/defconfig b/nuttx/configs/sure-pic32mx/nsh/defconfig index f90d09bcc..bd8e9a8b7 100644 --- a/nuttx/configs/sure-pic32mx/nsh/defconfig +++ b/nuttx/configs/sure-pic32mx/nsh/defconfig @@ -226,6 +226,13 @@ CONFIG_UART1_2STOP=0 CONFIG_UART2_2STOP=0 # +# PIC32MX-specific USB device setup +# +CONFIG_PIC32MX_USBDEV_REGDEBUG=n +CONFIG_PIC32MX_USBDEV_BDTDEBUG=n +CONFIG_PIC32MX_USBDEV_PINGPONG=n + +# # General build options # # CONFIG_RRLOAD_BINARY - make the rrload binary format used with @@ -349,7 +356,6 @@ CONFIG_DEBUG_VERBOSE=n CONFIG_DEBUG_SYMBOLS=n CONFIG_DEBUG_SCHED=n CONFIG_DEBUG_USB=n -CONFIG_PIC32MX_USBDEV_REGDEBUG=n CONFIG_HAVE_CXX=n CONFIG_HAVE_CXXINITIALIZE=n @@ -1032,6 +1038,37 @@ CONFIG_EXAMPLES_USBTERM_TRACECONTROLLER=n CONFIG_EXAMPLES_USBTERM_TRACEINTERRUPTS=n # +# Settings for examples/cdcacm +# +# Configuration prequisites: +# +# CONFIG_USBDEV=y : USB device support must be enabled +# CONFIG_CDCACM=y : The CDC/ACM driver must be built +# CONFIG_NSH_BUILTIN_APPS : NSH built-in application support must be enabled +# +# Configuration options specific to this example: +# +# CONFIG_EXAMPLES_CDCACM_DEVMINOR +# The minor number of the CDC/ACM device. +# CONFIG_EXAMPLES_CDCACM_TRACEINIT +# Show initialization events +# CONFIG_EXAMPLES_CDCACM_TRACECLASS +# Show class driver events +# CONFIG_EXAMPLES_CDCACM_TRACETRANSFERS +# Show data transfer events +# CONFIG_EXAMPLES_CDCACM_TRACECONTROLLER +# Show controller events +# CONFIG_EXAMPLES_CDCACM_TRACEINTERRUPTS +# Show interrupt-related events. +# +CONFIG_EXAMPLES_CDCACM_DEVMINOR=0 +CONFIG_EXAMPLES_CDCACM_TRACEINIT=n +CONFIG_EXAMPLES_CDCACM_TRACECLASS=n +CONFIG_EXAMPLES_CDCACM_TRACETRANSFERS=n +CONFIG_EXAMPLES_CDCACM_TRACECONTROLLER=n +CONFIG_EXAMPLES_CDCACM_TRACEINTERRUPTS=n + +# # Stack and heap information # # CONFIG_BOOT_RUNFROMFLASH - Some configurations support XIP |