Completes coding of the PWM module

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4200 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo
2011-12-19 19:24:09 +00:00
commit add995c32e
4394 changed files with 1077774 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
############################################################################
# drivers/usbdev/Make.defs
#
# Copyright (C) 2008, 2010-2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_USBDEV),y)
# Include USB device drivers
ifeq ($(CONFIG_USBSER),y)
CSRCS += usbdev_serial.c
endif
ifeq ($(CONFIG_CDCSER),y)
CSRCS += cdc_serial.c cdc_serdesc.c
endif
ifeq ($(CONFIG_USBSTRG),y)
CSRCS += usbdev_storage.c usbdev_stordesc.c usbdev_scsi.c
endif
ifeq ($(CONFIG_USBDEV_COMPOSITE),y)
CSRCS += usbdev_composite.c
endif
CSRCS += usbdev_trace.c usbdev_trprintf.c
# Include USB device build support
DEPPATH += --dep-path usbdev
VPATH += :usbdev
CFLAGS += ${shell $(TOPDIR)/tools/incdir.sh $(INCDIROPT) "$(CC)" $(TOPDIR)/drivers/usbdev}
endif
+590
View File
@@ -0,0 +1,590 @@
/****************************************************************************
* drivers/usbdev/cdc_serdesc.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/usb/usb.h>
#include <nuttx/usb/cdc.h>
#include <nuttx/usb/cdc_serial.h>
#include <nuttx/usb/usbdev_trace.h>
#include "cdc_serial.h"
/****************************************************************************
* Definitions
****************************************************************************/
/* Descriptors **************************************************************/
/* These settings are not modifiable via the NuttX configuration */
#define CDC_VERSIONNO 0x0110 /* CDC version number 1.10 (BCD) */
/* Device descriptor values */
#define CDCSER_VERSIONNO (0x0101) /* Device version number 1.1 (BCD) */
#define CDCSER_NCONFIGS (1) /* Number of configurations supported */
/* Configuration descriptor values */
#define CDCSER_NINTERFACES (2) /* Number of interfaces in the configuration */
/* String language */
#define CDCSER_STR_LANGUAGE (0x0409) /* en-us */
/* Descriptor strings */
#define CDCSER_MANUFACTURERSTRID (1)
#define CDCSER_PRODUCTSTRID (2)
#define CDCSER_SERIALSTRID (3)
#define CDCSER_CONFIGSTRID (4)
#define CDCSER_NOTIFSTRID (5)
#define CDCSER_DATAIFSTRID (6)
/* Number of individual descriptors in the configuration descriptor */
#define CDCSER_CFGGROUP_SIZE (9)
/* The size of the config descriptor: (9 + 2*9 + 3*7 + 4 + 5 + 5) = 62 */
#define SIZEOF_CDCSER_CFGDESC \
(USB_SIZEOF_CFGDESC + 2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + SIZEOF_ACM_FUNCDESC + SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
/****************************************************************************
* Private Types
****************************************************************************/
/* Describes one description in the group of descriptors forming the
* total configuration descriptor.
*/
struct cfgdecsc_group_s
{
uint16_t descsize; /* Size of the descriptor in bytes */
uint16_t hsepsize; /* High speed max packet size */
FAR void *desc; /* A pointer to the descriptor */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/* USB descriptor templates these will be copied and modified **************/
static const struct usb_devdesc_s g_devdesc =
{
USB_SIZEOF_DEVDESC, /* len */
USB_DESC_TYPE_DEVICE, /* type */
{ /* usb */
LSBYTE(0x0200),
MSBYTE(0x0200)
},
USB_CLASS_CDC, /* class */
CDC_SUBCLASS_NONE, /* subclass */
CDC_PROTO_NONE, /* protocol */
CONFIG_CDCSER_EP0MAXPACKET, /* maxpacketsize */
{
LSBYTE(CONFIG_CDCSER_VENDORID), /* vendor */
MSBYTE(CONFIG_CDCSER_VENDORID)
},
{
LSBYTE(CONFIG_CDCSER_PRODUCTID), /* product */
MSBYTE(CONFIG_CDCSER_PRODUCTID)
},
{
LSBYTE(CDCSER_VERSIONNO), /* device */
MSBYTE(CDCSER_VERSIONNO)
},
CDCSER_MANUFACTURERSTRID, /* imfgr */
CDCSER_PRODUCTSTRID, /* iproduct */
CDCSER_SERIALSTRID, /* serno */
CDCSER_NCONFIGS /* nconfigs */
};
/* Configuration descriptor */
static const struct usb_cfgdesc_s g_cfgdesc =
{
USB_SIZEOF_CFGDESC, /* len */
USB_DESC_TYPE_CONFIG, /* type */
{
LSBYTE(SIZEOF_CDCSER_CFGDESC), /* LS totallen */
MSBYTE(SIZEOF_CDCSER_CFGDESC) /* MS totallen */
},
CDCSER_NINTERFACES, /* ninterfaces */
CDCSER_CONFIGID, /* cfgvalue */
CDCSER_CONFIGSTRID, /* icfg */
USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
(CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
};
/* Notification interface */
static const struct usb_ifdesc_s g_notifdesc =
{
USB_SIZEOF_IFDESC, /* len */
USB_DESC_TYPE_INTERFACE, /* type */
0, /* ifno */
0, /* alt */
1, /* neps */
USB_CLASS_CDC, /* class */
CDC_SUBCLASS_ACM, /* subclass */
CDC_PROTO_ATM, /* proto */
#ifdef CONFIG_CDCSER_NOTIFSTR
CDCSER_NOTIFSTRID /* iif */
#else
0 /* iif */
#endif
};
/* Header functional descriptor */
static const struct cdc_hdr_funcdesc_s g_funchdr =
{
SIZEOF_HDR_FUNCDESC, /* size */
USB_DESC_TYPE_CSINTERFACE, /* type */
CDC_DSUBTYPE_HDR, /* subtype */
{
LSBYTE(CDC_VERSIONNO), /* LS cdc */
MSBYTE(CDC_VERSIONNO) /* MS cdc */
}
};
/* ACM functional descriptor */
static const struct cdc_acm_funcdesc_s g_acmfunc =
{
SIZEOF_ACM_FUNCDESC, /* size */
USB_DESC_TYPE_CSINTERFACE, /* type */
CDC_DSUBTYPE_ACM, /* subtype */
0x06 /* caps */
};
/* Union functional descriptor */
static const struct cdc_union_funcdesc_s g_unionfunc =
{
SIZEOF_UNION_FUNCDESC(1), /* size */
USB_DESC_TYPE_CSINTERFACE, /* type */
CDC_DSUBTYPE_UNION, /* subtype */
0, /* master */
{1} /* slave[0] */
};
/* Interrupt IN endpoint descriptor */
static const struct usb_epdesc_s g_epintindesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
CDCSER_EPINTIN_ADDR, /* addr */
CDCSER_EPINTIN_ATTR, /* attr */
{
LSBYTE(CONFIG_CDCSER_EPINTIN_FSSIZE), /* maxpacket (full speed) */
MSBYTE(CONFIG_CDCSER_EPINTIN_FSSIZE)
},
0xff /* interval */
};
/* Data interface descriptor */
static const struct usb_ifdesc_s g_dataifdesc =
{
USB_SIZEOF_IFDESC, /* len */
USB_DESC_TYPE_INTERFACE, /* type */
1, /* ifno */
0, /* alt */
2, /* neps */
USB_CLASS_CDC_DATA, /* class */
CDC_DATA_SUBCLASS_NONE, /* subclass */
CDC_DATA_PROTO_NONE, /* proto */
#ifdef CONFIG_CDCSER_DATAIFSTR
CDCSER_DATAIFSTRID /* iif */
#else
0 /* iif */
#endif
};
/* Bulk OUT endpoint descriptor */
static const struct usb_epdesc_s g_epbulkoutdesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
CDCSER_EPOUTBULK_ADDR, /* addr */
CDCSER_EPOUTBULK_ATTR, /* attr */
{
LSBYTE(CONFIG_CDCSER_EPBULKOUT_FSSIZE), /* maxpacket (full speed) */
MSBYTE(CONFIG_CDCSER_EPBULKOUT_FSSIZE)
},
1 /* interval */
};
/* Bulk IN endpoint descriptor */
static const struct usb_epdesc_s g_epbulkindesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
CDCSER_EPINBULK_ADDR, /* addr */
CDCSER_EPINBULK_ATTR, /* attr */
{
LSBYTE(CONFIG_CDCSER_EPBULKIN_FSSIZE), /* maxpacket (full speed) */
MSBYTE(CONFIG_CDCSER_EPBULKIN_FSSIZE)
},
1 /* interval */
};
/* The components of the the configuration descriptor are maintained as
* a collection of separate descriptor structure coordinated by the
* following array. These descriptors could have been combined into
* one larger "super" configuration descriptor structure. However, I
* have concerns about compiler-dependent alignment and packing. Since
* the individual structures consist only of byte types, alignment and
* packing is not an issue. And since the are concatentated at run time
* instead of compile time, there should no issues there either.
*/
static const struct cfgdecsc_group_s g_cfggroup[CDCSER_CFGGROUP_SIZE] = {
{
USB_SIZEOF_CFGDESC, /* 1. Configuration descriptor */
0,
(FAR void *)&g_cfgdesc
},
{
USB_SIZEOF_IFDESC, /* 2. Notification interface */
0,
(FAR void *)&g_notifdesc
},
{
SIZEOF_HDR_FUNCDESC, /* 3. Header functional descriptor */
0,
(FAR void *)&g_funchdr
},
{
SIZEOF_ACM_FUNCDESC, /* 4. ACM functional descriptor */
0,
(FAR void *)&g_acmfunc
},
{
SIZEOF_UNION_FUNCDESC(1), /* 5. Union functional descriptor */
0,
(FAR void *)&g_unionfunc
},
{
USB_SIZEOF_EPDESC, /* 6. Interrupt IN endpoint descriptor */
CONFIG_CDCSER_EPINTIN_HSSIZE,
(FAR void *)&g_epintindesc
},
{
USB_SIZEOF_IFDESC, /* 7. Data interface descriptor */
0,
(FAR void *)&g_dataifdesc
},
{
USB_SIZEOF_EPDESC, /* 8. Bulk OUT endpoint descriptor */
CONFIG_CDCSER_EPBULKOUT_HSSIZE,
(FAR void *)&g_epbulkoutdesc
},
{
USB_SIZEOF_EPDESC, /* 9. Bulk OUT endpoint descriptor */
CONFIG_CDCSER_EPBULKIN_HSSIZE,
(FAR void *)&g_epbulkindesc
}
};
#ifdef CONFIG_USBDEV_DUALSPEED
static const struct usb_qualdesc_s g_qualdesc =
{
USB_SIZEOF_QUALDESC, /* len */
USB_DESC_TYPE_DEVICEQUALIFIER, /* type */
{ /* usb */
LSBYTE(0x0200),
MSBYTE(0x0200)
},
USB_CLASS_VENDOR_SPEC, /* class */
0, /* subclass */
0, /* protocol */
CONFIG_CDCSER_EP0MAXPACKET, /* mxpacketsize */
CDCSER_NCONFIGS, /* nconfigs */
0, /* reserved */
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cdcser_mkstrdesc
*
* Description:
* Construct a string descriptor
*
****************************************************************************/
int cdcser_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
{
const char *str;
int len;
int ndata;
int i;
switch (id)
{
case 0:
{
/* Descriptor 0 is the language id */
strdesc->len = 4;
strdesc->type = USB_DESC_TYPE_STRING;
strdesc->data[0] = LSBYTE(CDCSER_STR_LANGUAGE);
strdesc->data[1] = MSBYTE(CDCSER_STR_LANGUAGE);
return 4;
}
case CDCSER_MANUFACTURERSTRID:
str = CONFIG_CDCSER_VENDORSTR;
break;
case CDCSER_PRODUCTSTRID:
str = CONFIG_CDCSER_PRODUCTSTR;
break;
case CDCSER_SERIALSTRID:
str = CONFIG_CDCSER_SERIALSTR;
break;
case CDCSER_CONFIGSTRID:
str = CONFIG_CDCSER_CONFIGSTR;
break;
#ifdef CONFIG_CDCSER_NOTIFSTR
case CDCSER_NOTIFSTRID:
str = CONFIG_CDCSER_NOTIFSTR;
break;
#endif
#ifdef CONFIG_CDCSER_DATAIFSTR
case CDCSER_DATAIFSTRID:
str = CONFIG_CDCSER_DATAIFSTR;
break;
#endif
default:
return -EINVAL;
}
/* The string is utf16-le. The poor man's utf-8 to utf16-le
* conversion below will only handle 7-bit en-us ascii
*/
len = strlen(str);
for (i = 0, ndata = 0; i < len; i++, ndata += 2)
{
strdesc->data[ndata] = str[i];
strdesc->data[ndata+1] = 0;
}
strdesc->len = ndata+2;
strdesc->type = USB_DESC_TYPE_STRING;
return strdesc->len;
}
/****************************************************************************
* Name: cdcser_getepdesc
*
* Description:
* Return a pointer to the raw device descriptor
*
****************************************************************************/
FAR const struct usb_devdesc_s *cdcser_getdevdesc(void)
{
return &g_devdesc;
}
/****************************************************************************
* Name: cdcser_getepdesc
*
* Description:
* Return a pointer to the raw endpoint struct (used for configuring
* endpoints)
*
****************************************************************************/
FAR const struct usb_epdesc_s *cdcser_getepdesc(enum cdcser_epdesc_e epid)
{
switch (epid)
{
case CDCSER_EPINTIN: /* Interrupt IN endpoint */
return &g_epintindesc;
case CDCSER_EPBULKOUT: /* Bulk OUT endpoint */
return &g_epbulkoutdesc;
case CDCSER_EPBULKIN: /* Bulk IN endpoint */
return &g_epbulkindesc;
default:
return NULL;
}
}
/****************************************************************************
* Name: cdcser_mkepdesc
*
* Description:
* Construct the endpoint descriptor using the correct max packet size.
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
void cdcser_mkepdesc(num cdcser_epdesc_e epid, uint16_t mxpacket,
FAR struct usb_epdesc_s *outdesc)
{
FAR const struct usb_epdesc_s *indesc;
/* Copy the "canned" descriptor */
indesc = cdcser_getepdesc(epid)
memcpy(outdesc, indesc, USB_SIZEOF_EPDESC);
/* Then add the correct max packet size */
outdesc->mxpacketsize[0] = LSBYTE(mxpacket);
outdesc->mxpacketsize[1] = MSBYTE(mxpacket);
}
#endif
/****************************************************************************
* Name: cdcser_mkcfgdesc
*
* Description:
* Construct the configuration descriptor
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t cdcser_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type)
#else
int16_t cdcser_mkcfgdesc(FAR uint8_t *buf)
#endif
{
FAR const struct cfgdecsc_group_s *group;
FAR uint8_t *dest = buf;
int i;
#ifdef CONFIG_USBDEV_DUALSPEED
bool hispeed = (speed == USB_SPEED_HIGH);
/* Check for switches between high and full speed */
if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
{
hispeed = !hispeed;
}
#endif
/* Copy all of the descriptors in the group */
for (i = 0, dest = buf; i < CDCSER_CFGGROUP_SIZE; i++)
{
group = &g_cfggroup[i];
/* The "canned" descriptors all have full speed endpoint maxpacket
* sizes. If high speed is selected, we will have to change the
* endpoint maxpacket size.
*
* Is there a alternative high speed maxpacket size in the table?
* If so, that is sufficient proof that the descriptor that we
* just copied is an endpoint descriptor and needs the fixup
*/
#ifdef CONFIG_USBDEV_DUALSPEED
if (highspeed && group->hsepsize != 0)
{
cdcser_mkepdesc(group->desc, group->hsepsize,
(FAR struct usb_epdesc_s*)dest);
}
else
#endif
/* Copy the "canned" descriptor with the full speed max packet
* size
*/
{
memcpy(dest, group->desc, group->descsize);
}
/* Advance to the destination location for the next descriptor */
dest += group->descsize;
}
return SIZEOF_CDCSER_CFGDESC;
}
/****************************************************************************
* Name: cdcser_getqualdesc
*
* Description:
* Return a pointer to the raw qual descriptor
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
FAR const struct usb_qualdesc_s *cdcser_getqualdesc(void)
{
return &g_qualdesc;
}
#endif
File diff suppressed because it is too large Load Diff
+196
View File
@@ -0,0 +1,196 @@
/****************************************************************************
* drivers/usbdev/cdc_serial.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __DRIVERS_USBDEV_USBDEV_CDC_SERIAL_H
#define __DRIVERS_USBDEV_USBDEV_CDC_SERIAL_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/usb/usbdev.h>
#include <nuttx/usb/usbdev_trace.h>
/****************************************************************************
* Definitions
****************************************************************************/
/* Descriptors **************************************************************/
/* These settings are not modifiable via the NuttX configuration */
#define CDCSER_CONFIGIDNONE (0) /* Config ID means to return to address mode */
#define CDCSER_INTERFACEID (0)
#define CDCSER_ALTINTERFACEID (0)
/* Configuration descriptor values */
#define CDCSER_CONFIGID (1) /* The only supported configuration ID */
/* Endpoint configuration */
#define CDCSER_EPINTIN_ADDR (USB_DIR_IN|CONFIG_CDCSER_EPINTIN)
#define CDCSER_EPINTIN_ATTR (USB_EP_ATTR_XFER_INT)
#define CDCSER_EPOUTBULK_ADDR (CONFIG_CDCSER_EPBULKOUT)
#define CDCSER_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
#define CDCSER_EPINBULK_ADDR (USB_DIR_IN|CONFIG_CDCSER_EPBULKIN)
#define CDCSER_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK)
/* Buffer big enough for any of our descriptors (the config descriptor is the
* biggest).
*/
#define CDCSER_MXDESCLEN (64)
/* Misc Macros **************************************************************/
/* min/max macros */
#ifndef min
# define min(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef max
# define max(a,b) ((a)>(b)?(a):(b))
#endif
/* Trace values *************************************************************/
#define CDCSER_CLASSAPI_SETUP TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SETUP)
#define CDCSER_CLASSAPI_SHUTDOWN TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SHUTDOWN)
#define CDCSER_CLASSAPI_ATTACH TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_ATTACH)
#define CDCSER_CLASSAPI_DETACH TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_DETACH)
#define CDCSER_CLASSAPI_IOCTL TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_IOCTL)
#define CDCSER_CLASSAPI_RECEIVE TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RECEIVE)
#define CDCSER_CLASSAPI_RXINT TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXINT)
#define CDCSER_CLASSAPI_RXAVAILABLE TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXAVAILABLE)
#define CDCSER_CLASSAPI_SEND TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SEND)
#define CDCSER_CLASSAPI_TXINT TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXINT)
#define CDCSER_CLASSAPI_TXREADY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXREADY)
#define CDCSER_CLASSAPI_TXEMPTY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXEMPTY)
/****************************************************************************
* Public Types
****************************************************************************/
enum cdcser_epdesc_e
{
CDCSER_EPINTIN = 0, /* Interrupt IN endpoint descriptor */
CDCSER_EPBULKOUT, /* Bulk OUT endpoint descriptor */
CDCSER_EPBULKIN /* Bulk IN endpoint descriptor */
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: cdcser_mkstrdesc
*
* Description:
* Construct a string descriptor
*
****************************************************************************/
int cdcser_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
/****************************************************************************
* Name: cdcser_getepdesc
*
* Description:
* Return a pointer to the raw device descriptor
*
****************************************************************************/
FAR const struct usb_devdesc_s *cdcser_getdevdesc(void);
/****************************************************************************
* Name: cdcser_getepdesc
*
* Description:
* Return a pointer to the raw endpoint descriptor (used for configuring
* endpoints)
*
****************************************************************************/
FAR const struct usb_epdesc_s *cdcser_getepdesc(enum cdcser_epdesc_e epid);
/****************************************************************************
* Name: cdcser_mkepdesc
*
* Description:
* Construct the endpoint descriptor using the correct max packet size.
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
void cdcser_mkepdesc(enum cdcser_epdesc_e epid,
uint16_t mxpacket, FAR struct usb_epdesc_s *outdesc);
#endif
/****************************************************************************
* Name: cdcser_mkcfgdesc
*
* Description:
* Construct the configuration descriptor
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t cdcser_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type);
#else
int16_t cdcser_mkcfgdesc(FAR uint8_t *buf);
#endif
/****************************************************************************
* Name: cdcser_getqualdesc
*
* Description:
* Return a pointer to the raw qual descriptor
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
FAR const struct usb_qualdesc_s *cdcser_getqualdesc(void);
#endif
#endif /* __DRIVERS_USBDEV_USBDEV_CDC_SERIAL_H */
+85
View File
@@ -0,0 +1,85 @@
/****************************************************************************
* drivers/usbdev/usbdev_composite.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/usb/usbdev_trace.h>
#include "usbdev_composite.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/*******************************************************************************
* Name:
*
* Description:
*
* Input Parameters:
*
* Returned Value:
*
*******************************************************************************/
+86
View File
@@ -0,0 +1,86 @@
/****************************************************************************
* drivers/usbdev/usbdev_composite.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __DRIVERS_USBDEV_USBDEV_COMPOSITE_H
#define __DRIVERS_USBDEV_USBDEV_COMPOSITE_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <nuttx/usb/usbdev_trace.h>
/****************************************************************************
* Definitions
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_USBDEV_TRACE_NRECORDS
# define CONFIG_USBDEV_TRACE_NRECORDS 128
#endif
#ifndef CONFIG_USBDEV_TRACE_INITIALIDSET
# define CONFIG_USBDEV_TRACE_INITIALIDSET 0
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/*******************************************************************************
* Name:
*
* Description:
*
* Input Parameters:
*
* Returned Value:
*
*******************************************************************************/
#endif /* __DRIVERS_USBDEV_USBDEV_COMPOSITE_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+608
View File
@@ -0,0 +1,608 @@
/****************************************************************************
* drivers/usbdev/usbdev_storage.h
*
* Copyright (C) 2008-2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Mass storage class device. Bulk-only with SCSI subclass.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __DRIVERS_USBDEV_USBDEV_STORAGE_H
#define __DRIVERS_USBDEV_USBDEV_STORAGE_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <queue.h>
#include <nuttx/fs.h>
#include <nuttx/usb/storage.h>
#include <nuttx/usb/usbdev.h>
/****************************************************************************
* Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Number of requests in the write queue */
#ifndef CONFIG_USBSTRG_NWRREQS
# define CONFIG_USBSTRG_NWRREQS 4
#endif
/* Number of requests in the read queue */
#ifndef CONFIG_USBSTRG_NRDREQS
# define CONFIG_USBSTRG_NRDREQS 4
#endif
/* Logical endpoint numbers / max packet sizes */
#ifndef CONFIG_USBSTRG_EPBULKOUT
# warning "EPBULKOUT not defined in the configuration"
# define CONFIG_USBSTRG_EPBULKOUT 2
#endif
#ifndef CONFIG_USBSTRG_EPBULKIN
# warning "EPBULKIN not defined in the configuration"
# define CONFIG_USBSTRG_EPBULKIN 3
#endif
/* Packet and request buffer sizes */
#ifndef CONFIG_USBSTRG_EP0MAXPACKET
# define CONFIG_USBSTRG_EP0MAXPACKET 64
#endif
#ifndef CONFIG_USBSTRG_BULKINREQLEN
# ifdef CONFIG_USBDEV_DUALSPEED
# define CONFIG_USBSTRG_BULKINREQLEN 512
# else
# define CONFIG_USBSTRG_BULKINREQLEN 64
# endif
#else
# ifdef CONFIG_USBDEV_DUALSPEED
# if CONFIG_USBSTRG_BULKINREQLEN < 512
# warning "Bulk in buffer size smaller than max packet"
# undef CONFIG_USBSTRG_BULKINREQLEN
# define CONFIG_USBSTRG_BULKINREQLEN 512
# endif
# else
# if CONFIG_USBSTRG_BULKINREQLEN < 64
# warning "Bulk in buffer size smaller than max packet"
# undef CONFIG_USBSTRG_BULKINREQLEN
# define CONFIG_USBSTRG_BULKINREQLEN 64
# endif
# endif
#endif
#ifndef CONFIG_USBSTRG_BULKOUTREQLEN
# ifdef CONFIG_USBDEV_DUALSPEED
# define CONFIG_USBSTRG_BULKOUTREQLEN 512
# else
# define CONFIG_USBSTRG_BULKOUTREQLEN 64
# endif
#else
# ifdef CONFIG_USBDEV_DUALSPEED
# if CONFIG_USBSTRG_BULKOUTREQLEN < 512
# warning "Bulk in buffer size smaller than max packet"
# undef CONFIG_USBSTRG_BULKOUTREQLEN
# define CONFIG_USBSTRG_BULKOUTREQLEN 512
# endif
# else
# if CONFIG_USBSTRG_BULKOUTREQLEN < 64
# warning "Bulk in buffer size smaller than max packet"
# undef CONFIG_USBSTRG_BULKOUTREQLEN
# define CONFIG_USBSTRG_BULKOUTREQLEN 64
# endif
# endif
#endif
/* Vendor and product IDs and strings */
#ifndef CONFIG_USBSTRG_VENDORID
# warning "CONFIG_USBSTRG_VENDORID not defined"
# define CONFIG_USBSTRG_VENDORID 0x584e
#endif
#ifndef CONFIG_USBSTRG_PRODUCTID
# warning "CONFIG_USBSTRG_PRODUCTID not defined"
# define CONFIG_USBSTRG_PRODUCTID 0x5342
#endif
#ifndef CONFIG_USBSTRG_VERSIONNO
# define CONFIG_USBSTRG_VERSIONNO (0x0399)
#endif
#ifndef CONFIG_USBSTRG_VENDORSTR
# warning "No Vendor string specified"
# define CONFIG_USBSTRG_VENDORSTR "NuttX"
#endif
#ifndef CONFIG_USBSTRG_PRODUCTSTR
# warning "No Product string specified"
# define CONFIG_USBSTRG_PRODUCTSTR "USBdev Storage"
#endif
#undef CONFIG_USBSTRG_SERIALSTR
#define CONFIG_USBSTRG_SERIALSTR "0101"
#undef CONFIG_USBSTRG_CONFIGSTR
#define CONFIG_USBSTRG_CONFIGSTR "Bulk"
/* Debug -- must be consistent with include/debug.h */
#ifdef CONFIG_CPP_HAVE_VARARGS
# ifdef CONFIG_DEBUG
# ifdef CONFIG_ARCH_LOWPUTC
# define dbgprintf(format, arg...) lib_lowprintf(format, ##arg)
# else
# define dbgprintf(format, arg...) lib_rawprintf(format, ##arg)
# endif
# else
# define dbgprintf(x...)
# endif
#else
# ifdef CONFIG_DEBUG
# ifdef CONFIG_ARCH_LOWPUTC
# define dbgprintf lib_lowprintf
# else
# define dbgprintf lib_rawprintf
# endif
# else
# define dbgprintf (void)
# endif
#endif
/* Packet and request buffer sizes */
#ifndef CONFIG_USBSTRG_EP0MAXPACKET
# define CONFIG_USBSTRG_EP0MAXPACKET 64
#endif
/* USB Controller */
#ifndef CONFIG_USBDEV_SELFPOWERED
# define SELFPOWERED USB_CONFIG_ATT_SELFPOWER
#else
# define SELFPOWERED (0)
#endif
#ifndef CONFIG_USBDEV_REMOTEWAKEUP
# define REMOTEWAKEUP USB_CONFIG_ATTR_WAKEUP
#else
# define REMOTEWAKEUP (0)
#endif
#ifndef CONFIG_USBDEV_MAXPOWER
# define CONFIG_USBDEV_MAXPOWER 100
#endif
/* Current state of the worker thread */
#define USBSTRG_STATE_NOTSTARTED (0) /* Thread has not yet been started */
#define USBSTRG_STATE_STARTED (1) /* Started, but is not yet initialized */
#define USBSTRG_STATE_IDLE (2) /* Started and waiting for commands */
#define USBSTRG_STATE_CMDPARSE (3) /* Processing a received command */
#define USBSTRG_STATE_CMDREAD (4) /* Processing a SCSI read command */
#define USBSTRG_STATE_CMDWRITE (5) /* Processing a SCSI write command */
#define USBSTRG_STATE_CMDFINISH (6) /* Finish command processing */
#define USBSTRG_STATE_CMDSTATUS (7) /* Processing the final status of the command */
#define USBSTRG_STATE_TERMINATED (8) /* Thread has exitted */
/* Event communicated to worker thread */
#define USBSTRG_EVENT_NOEVENTS (0) /* There are no outstanding events */
#define USBSTRG_EVENT_READY (1 << 0) /* Initialization is complete */
#define USBSTRG_EVENT_RDCOMPLETE (1 << 1) /* A read has completed there is data to be processed */
#define USBSTRG_EVENT_WRCOMPLETE (1 << 2) /* A write has completed and a request is available */
#define USBSTRG_EVENT_TERMINATEREQUEST (1 << 3) /* Shutdown requested */
#define USBSTRG_EVENT_DISCONNECT (1 << 4) /* USB disconnect received */
#define USBSTRG_EVENT_RESET (1 << 5) /* USB storage setup reset received */
#define USBSTRG_EVENT_CFGCHANGE (1 << 6) /* USB setup configuration change received */
#define USBSTRG_EVENT_IFCHANGE (1 << 7) /* USB setup interface change received */
#define USBSTRG_EVENT_ABORTBULKOUT (1 << 8) /* SCSI receive failure */
/* SCSI command flags (passed to usbstrg_setupcmd()) */
#define USBSTRG_FLAGS_DIRMASK (0x03) /* Bits 0-1: Data direction */
#define USBSTRG_FLAGS_DIRNONE (0x00) /* No data to send */
#define USBSTRG_FLAGS_DIRHOST2DEVICE (0x01) /* Host-to-device */
#define USBSTRG_FLAGS_DIRDEVICE2HOST (0x02) /* Device-to-host */
#define USBSTRG_FLAGS_BLOCKXFR (0x04) /* Bit 2: Command is a block transfer request */
#define USBSTRG_FLAGS_LUNNOTNEEDED (0x08) /* Bit 3: Command does not require a valid LUN */
#define USBSTRG_FLAGS_UACOKAY (0x10) /* Bit 4: Command OK if unit attention condition */
#define USBSTRG_FLAGS_RETAINSENSEDATA (0x20) /* Bit 5: Do not clear sense data */
/* Descriptors **************************************************************/
/* Big enough to hold our biggest descriptor */
#define USBSTRG_MXDESCLEN (64)
/* String language */
#define USBSTRG_STR_LANGUAGE (0x0409) /* en-us */
/* Descriptor strings */
#define USBSTRG_MANUFACTURERSTRID (1)
#define USBSTRG_PRODUCTSTRID (2)
#define USBSTRG_SERIALSTRID (3)
#define USBSTRG_CONFIGSTRID (4)
#define USBSTRG_NCONFIGS (1) /* Number of configurations supported */
/* Configuration Descriptor */
#define USBSTRG_NINTERFACES (1) /* Number of interfaces in the configuration */
#define USBSTRG_INTERFACEID (0)
#define USBSTRG_ALTINTERFACEID (0)
#define USBSTRG_CONFIGIDNONE (0) /* Config ID means to return to address mode */
#define USBSTRG_CONFIGID (1) /* The only supported configuration ID */
#define STRING_MANUFACTURER (1)
#define STRING_PRODUCT (2)
#define STRING_SERIAL (3)
#define USBSTRG_CONFIGID (1) /* There is only one configuration. */
/* Interface description */
#define USBSTRG_NENDPOINTS (2) /* Number of endpoints in the interface */
/* Endpoint configuration */
#define USBSTRG_EPOUTBULK_ADDR (CONFIG_USBSTRG_EPBULKOUT)
#define USBSTRG_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
#define USBSTRG_EPINBULK_ADDR (USB_DIR_IN|CONFIG_USBSTRG_EPBULKIN)
#define USBSTRG_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK)
#define USBSTRG_HSBULKMAXPACKET (512)
#define USBSTRG_HSBULKMXPKTSHIFT (9)
#define USBSTRG_HSBULKMXPKTMASK (0x000001ff)
#define USBSTRG_FSBULKMAXPACKET (64)
#define USBSTRG_FSBULKMXPKTSHIFT (6)
#define USBSTRG_FSBULKMXPKTMASK (0x0000003f)
/* Macros for dual speed vs. full speed only operation */
#ifdef CONFIG_USBDEV_DUALSPEED
# define USBSTRG_EPBULKINDESC(hs) \
usbstrg_getepdesc((hs) ? USBSTRG_EPHSBULKIN : USBSTRG_EPFSBULKIN)
# define USBSTRG_EPBULKOUTDESC(hs) \
usbstrg_getepdesc((hs) ? USBSTRG_EPHSBULKOUT : USBSTRG_EPFSBULKOUT)
# define USBSTRG_BULKMAXPACKET(hs) \
((hs) ? USBSTRG_HSBULKMAXPACKET : USBSTRG_FSBULKMAXPACKET)
# define USBSTRG_BULKMXPKTSHIFT(d) \
(((d)->speed==USB_SPEED_HIGH) ? USBSTRG_HSBULKMXPKTSHIFT : USBSTRG_FSBULKMXPKTSHIFT)
# define USBSTRG_BULKMXPKTMASK(d) \
(((d)->speed==USB_SPEED_HIGH) ? USBSTRG_HSBULKMXPKTMASK : USBSTRG_FSBULKMXPKTMASK)
#else
# define USBSTRG_EPBULKINDESC(d) usbstrg_getepdesc(USBSTRG_EPFSBULKIN)
# define USBSTRG_EPBULKOUTDESC(d) usbstrg_getepdesc(USBSTRG_EPFSBULKOUT)
# define USBSTRG_BULKMAXPACKET(hs) USBSTRG_FSBULKMAXPACKET
# define USBSTRG_BULKMXPKTSHIFT(d) USBSTRG_FSBULKMXPKTSHIFT
# define USBSTRG_BULKMXPKTMASK(d) USBSTRG_FSBULKMXPKTMASK
#endif
/* Block driver helpers *****************************************************/
#define USBSTRG_DRVR_READ(l,b,s,n) ((l)->inode->u.i_bops->read((l)->inode,b,s,n))
#define USBSTRG_DRVR_WRITE(l,b,s,n) ((l)->inode->u.i_bops->write((l)->inode,b,s,n))
#define USBSTRG_DRVR_GEOMETRY(l,g) ((l)->inode->u.i_bops->geometry((l)->inode,g))
/* Everpresent min/max macros ***********************************************/
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* Endpoint descriptors */
enum usbstrg_epdesc_e
{
USBSTRG_EPFSBULKOUT = 0, /* Full speed bulk OUT endpoint descriptor */
USBSTRG_EPFSBULKIN /* Full speed bulk IN endpoint descriptor */
#ifdef CONFIG_USBDEV_DUALSPEED
,
USBSTRG_EPHSBULKOUT, /* High speed bulk OUT endpoint descriptor */
USBSTRG_EPHSBULKIN /* High speed bulk IN endpoint descriptor */
#endif
};
/* Container to support a list of requests */
struct usbstrg_req_s
{
FAR struct usbstrg_req_s *flink; /* Implements a singly linked list */
FAR struct usbdev_req_s *req; /* The contained request */
};
/* This structure describes one LUN: */
struct usbstrg_lun_s
{
struct inode *inode; /* Inode structure of open'ed block driver */
uint8_t readonly:1; /* Media is read-only */
uint8_t locked:1; /* Media removal is prevented */
uint16_t sectorsize; /* The size of one sector */
uint32_t sd; /* Sense data */
uint32_t sdinfo; /* Sense data information */
uint32_t uad; /* Unit needs attention data */
off_t startsector; /* Sector offset to start of partition */
size_t nsectors; /* Number of sectors in the partition */
};
/* Describes the overall state of the driver */
struct usbstrg_dev_s
{
FAR struct usbdev_s *usbdev; /* usbdev driver pointer (Non-null if registered) */
/* Worker thread interface */
pthread_t thread; /* The worker thread */
pthread_mutex_t mutex; /* Mutually exclusive access to resources*/
pthread_cond_t cond; /* Used to signal worker thread */
volatile uint8_t thstate; /* State of the worker thread */
volatile uint16_t theventset; /* Set of pending events signaled to worker thread */
volatile uint8_t thvalue; /* Value passed with the event (must persist) */
/* Storage class configuration and state */
uint8_t nluns:4; /* Number of LUNs */
uint8_t config; /* Configuration number */
/* Endpoints */
FAR struct usbdev_ep_s *epbulkin; /* Bulk IN endpoint structure */
FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint structure */
FAR struct usbdev_req_s *ctrlreq; /* Control request (for ep0 setup responses) */
/* SCSI command processing */
struct usbstrg_lun_s *lun; /* Currently selected LUN */
struct usbstrg_lun_s *luntab; /* Allocated table of all LUNs */
uint8_t cdb[USBSTRG_MAXCDBLEN]; /* Command data (cdb[]) from CBW */
uint8_t phaseerror:1; /* Need to send phase sensing status */
uint8_t shortpacket:1; /* Host transmission stopped unexpectedly */
uint8_t cbwdir:2; /* Direction from CBW. See USBSTRG_FLAGS_DIR* definitions */
uint8_t cdblen; /* Length of cdb[] from CBW */
uint8_t cbwlun; /* LUN from the CBW */
uint16_t nsectbytes; /* Bytes buffered in iobuffer[] */
uint16_t nreqbytes; /* Bytes buffered in head write requests */
uint16_t iosize; /* Size of iobuffer[] */
uint32_t cbwlen; /* Length of data from CBW */
uint32_t cbwtag; /* Tag from the CBW */
union
{
uint32_t xfrlen; /* Read/Write: Sectors remaining to be transferred */
uint32_t alloclen; /* Other device-to-host: Host allocation length */
} u;
uint32_t sector; /* Current sector (relative to lun->startsector) */
uint32_t residue; /* Untransferred amount reported in the CSW */
uint8_t *iobuffer; /* Buffer for data transfers */
/* Write request list */
struct sq_queue_s wrreqlist; /* List of empty write request containers */
struct sq_queue_s rdreqlist; /* List of filled read request containers */
/* Pre-allocated write request containers. The write requests will
* be linked in a free list (wrreqlist), and used to send requests to
* EPBULKIN; Read requests will be queued in the EBULKOUT.
*/
struct usbstrg_req_s wrreqs[CONFIG_USBSTRG_NWRREQS];
struct usbstrg_req_s rdreqs[CONFIG_USBSTRG_NRDREQS];
};
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
# define EXTERN extern "C"
extern "C"
{
#else
# define EXTERN extern
#endif
/* String *******************************************************************/
EXTERN const char g_vendorstr[];
EXTERN const char g_productstr[];
EXTERN const char g_serialstr[];
/************************************************************************************
* Public Function Prototypes
************************************************************************************/
/************************************************************************************
* Name: usbstrg_mkstrdesc
*
* Description:
* Construct a string descriptor
*
************************************************************************************/
struct usb_strdesc_s;
int usbstrg_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
/************************************************************************************
* Name: usbstrg_getepdesc
*
* Description:
* Return a pointer to the raw device descriptor
*
************************************************************************************/
FAR const struct usb_devdesc_s *usbstrg_getdevdesc(void);
/************************************************************************************
* Name: usbstrg_getepdesc
*
* Description:
* Return a pointer to the raw endpoint descriptor (used for configuring endpoints)
*
************************************************************************************/
struct usb_epdesc_s;
FAR const struct usb_epdesc_s *usbstrg_getepdesc(enum usbstrg_epdesc_e epid);
/************************************************************************************
* Name: usbstrg_mkcfgdesc
*
* Description:
* Construct the configuration descriptor
*
************************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t usbstrg_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type);
#else
int16_t usbstrg_mkcfgdesc(FAR uint8_t *buf);
#endif
/************************************************************************************
* Name: usbstrg_getqualdesc
*
* Description:
* Return a pointer to the raw qual descriptor
*
************************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
FAR const struct usb_qualdesc_s *usbstrg_getqualdesc(void);
#endif
/****************************************************************************
* Name: usbstrg_workerthread
*
* Description:
* This is the main function of the USB storage worker thread. It loops
* until USB-related events occur, then processes those events accordingly
*
****************************************************************************/
EXTERN void *usbstrg_workerthread(void *arg);
/****************************************************************************
* Name: usbstrg_setconfig
*
* Description:
* Set the device configuration by allocating and configuring endpoints and
* by allocating and queue read and write requests.
*
****************************************************************************/
EXTERN int usbstrg_setconfig(FAR struct usbstrg_dev_s *priv, uint8_t config);
/****************************************************************************
* Name: usbstrg_resetconfig
*
* Description:
* Mark the device as not configured and disable all endpoints.
*
****************************************************************************/
EXTERN void usbstrg_resetconfig(FAR struct usbstrg_dev_s *priv);
/****************************************************************************
* Name: usbstrg_wrcomplete
*
* Description:
* Handle completion of write request. This function probably executes
* in the context of an interrupt handler.
*
****************************************************************************/
EXTERN void usbstrg_wrcomplete(FAR struct usbdev_ep_s *ep,
FAR struct usbdev_req_s *req);
/****************************************************************************
* Name: usbstrg_rdcomplete
*
* Description:
* Handle completion of read request on the bulk OUT endpoint. This
* is handled like the receipt of serial data on the "UART"
*
****************************************************************************/
EXTERN void usbstrg_rdcomplete(FAR struct usbdev_ep_s *ep,
FAR struct usbdev_req_s *req);
/****************************************************************************
* Name: usbstrg_deferredresponse
*
* Description:
* Some EP0 setup request cannot be responded to immediately becuase they
* require some asynchronous action from the SCSI worker thread. This
* function is provided for the SCSI thread to make that deferred response.
* The specific requests that require this deferred response are:
*
* 1. USB_REQ_SETCONFIGURATION,
* 2. USB_REQ_SETINTERFACE, or
* 3. USBSTRG_REQ_MSRESET
*
* In all cases, the success reponse is a zero-length packet; the failure
* response is an EP0 stall.
*
* Input parameters:
* priv - Private state structure for this USB storage instance
* stall - true is the action failed and a stall is required
*
****************************************************************************/
EXTERN void usbstrg_deferredresponse(FAR struct usbstrg_dev_s *priv, bool failed);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* #define __DRIVERS_USBDEV_USBDEV_STORAGE_H */
+408
View File
@@ -0,0 +1,408 @@
/****************************************************************************
* drivers/usbdev/usbdev_stordesc.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/usb/usb.h>
#include <nuttx/usb/usbdev_trace.h>
#include "usbdev_storage.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/* Descriptors **************************************************************/
/* Device descriptor */
static const struct usb_devdesc_s g_devdesc =
{
USB_SIZEOF_DEVDESC, /* len */
USB_DESC_TYPE_DEVICE, /* type */
{LSBYTE(0x0200), MSBYTE(0x0200)}, /* usb */
USB_CLASS_PER_INTERFACE, /* class */
0, /* subclass */
0, /* protocol */
CONFIG_USBSTRG_EP0MAXPACKET, /* maxpacketsize */
{ /* vendor */
LSBYTE(CONFIG_USBSTRG_VENDORID),
MSBYTE(CONFIG_USBSTRG_VENDORID)
},
{ /* product */
LSBYTE(CONFIG_USBSTRG_PRODUCTID),
MSBYTE(CONFIG_USBSTRG_PRODUCTID) },
{ /* device */
LSBYTE(CONFIG_USBSTRG_VERSIONNO),
MSBYTE(CONFIG_USBSTRG_VERSIONNO)
},
USBSTRG_MANUFACTURERSTRID, /* imfgr */
USBSTRG_PRODUCTSTRID, /* iproduct */
USBSTRG_SERIALSTRID, /* serno */
USBSTRG_NCONFIGS /* nconfigs */
};
/* Configuration descriptor */
static const struct usb_cfgdesc_s g_cfgdesc =
{
USB_SIZEOF_CFGDESC, /* len */
USB_DESC_TYPE_CONFIG, /* type */
{0, 0}, /* totallen -- to be provided */
USBSTRG_NINTERFACES, /* ninterfaces */
USBSTRG_CONFIGID, /* cfgvalue */
USBSTRG_CONFIGSTRID, /* icfg */
USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
(CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
};
/* Single interface descriptor */
static const struct usb_ifdesc_s g_ifdesc =
{
USB_SIZEOF_IFDESC, /* len */
USB_DESC_TYPE_INTERFACE, /* type */
USBSTRG_INTERFACEID, /* ifno */
USBSTRG_ALTINTERFACEID, /* alt */
USBSTRG_NENDPOINTS, /* neps */
USB_CLASS_MASS_STORAGE, /* class */
USBSTRG_SUBCLASS_SCSI, /* subclass */
USBSTRG_PROTO_BULKONLY, /* protocol */
USBSTRG_CONFIGSTRID /* iif */
};
/* Endpoint descriptors */
static const struct usb_epdesc_s g_fsepbulkoutdesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBSTRG_EPOUTBULK_ADDR, /* addr */
USBSTRG_EPOUTBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBSTRG_FSBULKMAXPACKET),
MSBYTE(USBSTRG_FSBULKMAXPACKET)
},
0 /* interval */
};
static const struct usb_epdesc_s g_fsepbulkindesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBSTRG_EPINBULK_ADDR, /* addr */
USBSTRG_EPINBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBSTRG_FSBULKMAXPACKET),
MSBYTE(USBSTRG_FSBULKMAXPACKET)
},
0 /* interval */
};
#ifdef CONFIG_USBDEV_DUALSPEED
static const struct usb_qualdesc_s g_qualdesc =
{
USB_SIZEOF_QUALDESC, /* len */
USB_DESC_TYPE_DEVICEQUALIFIER, /* type */
{ /* usb */
LSBYTE(0x0200),
MSBYTE(0x0200)
},
USB_CLASS_PER_INTERFACE, /* class */
0, /* subclass */
0, /* protocol */
CONFIG_USBSTRG_EP0MAXPACKET, /* mxpacketsize */
USBSTRG_NCONFIGS, /* nconfigs */
0, /* reserved */
};
static const struct usb_epdesc_s g_hsepbulkoutdesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBSTRG_EPOUTBULK_ADDR, /* addr */
USBSTRG_EPOUTBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBSTRG_HSBULKMAXPACKET),
MSBYTE(USBSTRG_HSBULKMAXPACKET)
},
0 /* interval */
};
static const struct usb_epdesc_s g_hsepbulkindesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBSTRG_EPINBULK_ADDR, /* addr */
USBSTRG_EPINBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBSTRG_HSBULKMAXPACKET),
MSBYTE(USBSTRG_HSBULKMAXPACKET)
},
0 /* interval */
};
#endif
/****************************************************************************
* Public Data
****************************************************************************/
/* Strings ******************************************************************/
const char g_vendorstr[] = CONFIG_USBSTRG_VENDORSTR;
const char g_productstr[] = CONFIG_USBSTRG_PRODUCTSTR;
const char g_serialstr[] = CONFIG_USBSTRG_SERIALSTR;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: usbstrg_mkstrdesc
*
* Description:
* Construct a string descriptor
*
****************************************************************************/
int usbstrg_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
{
const char *str;
int len;
int ndata;
int i;
switch (id)
{
case 0:
{
/* Descriptor 0 is the language id */
strdesc->len = 4;
strdesc->type = USB_DESC_TYPE_STRING;
strdesc->data[0] = LSBYTE(USBSTRG_STR_LANGUAGE);
strdesc->data[1] = MSBYTE(USBSTRG_STR_LANGUAGE);
return 4;
}
case USBSTRG_MANUFACTURERSTRID:
str = g_vendorstr;
break;
case USBSTRG_PRODUCTSTRID:
str = g_productstr;
break;
case USBSTRG_SERIALSTRID:
str = g_serialstr;
break;
case USBSTRG_CONFIGSTRID:
str = CONFIG_USBSTRG_CONFIGSTR;
break;
default:
return -EINVAL;
}
/* The string is utf16-le. The poor man's utf-8 to utf16-le
* conversion below will only handle 7-bit en-us ascii
*/
len = strlen(str);
for (i = 0, ndata = 0; i < len; i++, ndata += 2)
{
strdesc->data[ndata] = str[i];
strdesc->data[ndata+1] = 0;
}
strdesc->len = ndata+2;
strdesc->type = USB_DESC_TYPE_STRING;
return strdesc->len;
}
/****************************************************************************
* Name: usbstrg_getepdesc
*
* Description:
* Return a pointer to the raw device descriptor
*
****************************************************************************/
FAR const struct usb_devdesc_s *usbstrg_getdevdesc(void)
{
return &g_devdesc;
}
/****************************************************************************
* Name: usbstrg_getepdesc
*
* Description:
* Return a pointer to the raw endpoint descriptor (used for configuring
* endpoints)
*
****************************************************************************/
FAR const struct usb_epdesc_s *usbstrg_getepdesc(enum usbstrg_epdesc_e epid)
{
switch (epid)
{
case USBSTRG_EPFSBULKOUT: /* Full speed bulk OUT endpoint descriptor */
return &g_fsepbulkoutdesc;
case USBSTRG_EPFSBULKIN: /* Full speed bulk IN endpoint descriptor */
return &g_fsepbulkindesc;
#ifdef CONFIG_USBDEV_DUALSPEED
case USBSTRG_EPHSBULKOUT: /* High speed bulk OUT endpoint descriptor */
return &g_hsepbulkoutdesc;
case USBSTRG_EPHSBULKIN: /* High speed bulk IN endpoint descriptor */
return &g_hsepbulkindesc;
#endif
default:
return NULL;
}
};
/****************************************************************************
* Name: usbstrg_mkcfgdesc
*
* Description:
* Construct the configuration descriptor
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t usbstrg_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type)
#else
int16_t usbstrg_mkcfgdesc(uint8_t *buf)
#endif
{
FAR struct usb_cfgdesc_s *cfgdesc = (struct usb_cfgdesc_s*)buf;
#ifdef CONFIG_USBDEV_DUALSPEED
FAR const struct usb_epdesc_s *epdesc;
bool hispeed = (speed == USB_SPEED_HIGH);
uint16_t bulkmxpacket;
#endif
uint16_t totallen;
/* This is the total length of the configuration (not necessarily the
* size that we will be sending now.
*/
totallen = USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + USBSTRG_NENDPOINTS * USB_SIZEOF_EPDESC;
/* Configuration descriptor -- Copy the canned descriptor and fill in the
* type (we'll also need to update the size below
*/
memcpy(cfgdesc, &g_cfgdesc, USB_SIZEOF_CFGDESC);
buf += USB_SIZEOF_CFGDESC;
/* Copy the canned interface descriptor */
memcpy(buf, &g_ifdesc, USB_SIZEOF_IFDESC);
buf += USB_SIZEOF_IFDESC;
/* Make the two endpoint configurations */
#ifdef CONFIG_USBDEV_DUALSPEED
/* Check for switches between high and full speed */
hispeed = (speed == USB_SPEED_HIGH);
if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
{
hispeed = !hispeed;
}
bulkmxpacket = USBSTRG_BULKMAXPACKET(hispeed);
epdesc = USBSTRG_EPBULKINDESC(hispeed);
memcpy(buf, epdesc, USB_SIZEOF_EPDESC);
buf += USB_SIZEOF_EPDESC;
epdesc = USBSTRG_EPBULKOUTDESC(hispeed);
memcpy(buf, epdesc, USB_SIZEOF_EPDESC);
#else
memcpy(buf, &g_fsepbulkoutdesc, USB_SIZEOF_EPDESC);
buf += USB_SIZEOF_EPDESC;
memcpy(buf, &g_fsepbulkindesc, USB_SIZEOF_EPDESC);
#endif
/* Finally, fill in the total size of the configuration descriptor */
cfgdesc->totallen[0] = LSBYTE(totallen);
cfgdesc->totallen[1] = MSBYTE(totallen);
return totallen;
}
/****************************************************************************
* Name: usbstrg_getqualdesc
*
* Description:
* Return a pointer to the raw qual descriptor
*
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
FAR const struct usb_qualdesc_s *usbstrg_getqualdesc(void)
{
return &g_qualdesc;
}
#endif
+233
View File
@@ -0,0 +1,233 @@
/****************************************************************************
* drivers/usbdev/usbdev_trace.c
*
* Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <errno.h>
#include <debug.h>
#include <arch/irq.h>
#include <nuttx/usb/usbdev_trace.h>
#undef usbtrace
/****************************************************************************
* Definitions
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_USBDEV_TRACE_NRECORDS
# define CONFIG_USBDEV_TRACE_NRECORDS 128
#endif
#ifndef CONFIG_USBDEV_TRACE_INITIALIDSET
# define CONFIG_USBDEV_TRACE_INITIALIDSET 0
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_USBDEV_TRACE
static struct usbtrace_s g_trace[CONFIG_USBDEV_TRACE_NRECORDS];
static uint16_t g_head = 0;
static uint16_t g_tail = 0;
#endif
#if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB))
static usbtrace_idset_t g_maskedidset = CONFIG_USBDEV_TRACE_INITIALIDSET;
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/*******************************************************************************
* Name: usbtrace_enable
*
* Description:
* Enable/disable tracing per trace ID. The initial state is all IDs enabled.
*
* Input Parameters:
* idset - The bitset of IDs to be masked. TRACE_ALLIDS enables all IDS; zero
* masks all IDs.
*
* Returned Value:
* The previous idset value.
*
* Assumptions:
* - May be called from an interrupt handler
*
*******************************************************************************/
#if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB))
usbtrace_idset_t usbtrace_enable(usbtrace_idset_t idset)
{
irqstate_t flags;
usbtrace_idset_t ret;
/* The following read and write must be atomic */
flags = irqsave();
ret = g_maskedidset;
g_maskedidset = idset;
irqrestore(flags);
return ret;
}
#endif /* CONFIG_USBDEV_TRACE || CONFIG_DEBUG && CONFIG_DEBUG_USB */
/*******************************************************************************
* Name: usbtrace
*
* Description:
* Record a USB event (tracing must be enabled)
*
* Assumptions:
* May be called from an interrupt handler
*
*******************************************************************************/
#if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB))
void usbtrace(uint16_t event, uint16_t value)
{
irqstate_t flags;
/* Check if tracing is enabled for this ID */
flags = irqsave();
if ((g_maskedidset & TRACE_ID2BIT(event)) != 0)
{
#ifdef CONFIG_USBDEV_TRACE
/* Yes... save the new trace data at the head */
g_trace[g_head].event = event;
g_trace[g_head].value = value;
/* Increment the head and (probably) the tail index */
if (++g_head >= CONFIG_USBDEV_TRACE_NRECORDS)
{
g_head = 0;
}
if (g_head == g_tail)
{
if (++g_tail >= CONFIG_USBDEV_TRACE_NRECORDS)
{
g_tail = 0;
}
}
#else
/* Just print the data using lib_lowprintf */
usbtrace_trprintf((trprintf_t)lib_lowprintf, event, value);
#endif
}
irqrestore(flags);
}
#endif /* CONFIG_USBDEV_TRACE || CONFIG_DEBUG && CONFIG_DEBUG_USB */
/*******************************************************************************
* Name: usbtrace_enumerate
*
* Description:
* Enumerate all buffer trace data (will temporarily disable tracing)
*
* Assumptions:
* NEVER called from an interrupt handler
*
*******************************************************************************/
#ifdef CONFIG_USBDEV_TRACE
int usbtrace_enumerate(trace_callback_t callback, void *arg)
{
uint16_t ndx;
uint32_t idset;
int ret = OK;
/* Temporarily disable tracing */
idset = usbtrace_enable(0);
/* Visit every entry, starting with the tail */
for (ndx = g_tail; ndx != g_head; )
{
/* Call the user provided callback */
ret = callback(&g_trace[ndx], arg);
if (ret != OK)
{
/* Abort the enumeration */
break;
}
/* Increment the index */
if (++ndx >= CONFIG_USBDEV_TRACE_NRECORDS)
{
ndx = 0;
}
}
/* Discard the trace data after it has been reported */
g_tail = g_head;
/* Restore tracing state */
(void)usbtrace_enable(idset);
return ret;
}
#endif /* CONFIG_USBDEV_TRACE */
+253
View File
@@ -0,0 +1,253 @@
/****************************************************************************
* drivers/usbdev/usbdev_trprintf.c
*
* Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <debug.h>
#include <nuttx/usb/usbdev_trace.h>
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/*******************************************************************************
* Name: usbtrace_trprintf
*
* Description:
* Print the trace record using the supplied printing function
*
*******************************************************************************/
void usbtrace_trprintf(trprintf_t trprintf, uint16_t event, uint16_t value)
{
switch (event)
{
case TRACE_DEVINIT:
trprintf("USB controller initialization: %04x\n", value);
break;
case TRACE_DEVUNINIT:
trprintf("USB controller un-initialization: %04x\n", value);
break;
case TRACE_DEVREGISTER:
trprintf("usbdev_register(): %04x\n", value);
break;
case TRACE_DEVUNREGISTER:
trprintf("usbdev_unregister(): %04x\n", value);
break;
case TRACE_EPCONFIGURE:
trprintf("Endpoint configure(): %04x\n", value);
break;
case TRACE_EPDISABLE:
trprintf("Endpoint disable(): %04x\n", value);
break;
case TRACE_EPALLOCREQ:
trprintf("Endpoint allocreq(): %04x\n", value);
break;
case TRACE_EPFREEREQ:
trprintf("Endpoint freereq(): %04x\n", value);
break;
case TRACE_EPALLOCBUFFER:
trprintf("Endpoint allocbuffer(): %04x\n", value);
break;
case TRACE_EPFREEBUFFER:
trprintf("Endpoint freebuffer(): %04x\n", value);
break;
case TRACE_EPSUBMIT:
trprintf("Endpoint submit(): %04x\n", value);
break;
case TRACE_EPCANCEL:
trprintf("Endpoint cancel(): %04x\n", value);
break;
case TRACE_EPSTALL:
trprintf("Endpoint stall(true): %04x\n", value);
break;
case TRACE_EPRESUME:
trprintf("Endpoint stall(false): %04x\n", value);
break;
case TRACE_DEVALLOCEP:
trprintf("Device allocep(): %04x\n", value);
break;
case TRACE_DEVFREEEP:
trprintf("Device freeep(): %04x\n", value);
break;
case TRACE_DEVGETFRAME:
trprintf("Device getframe(): %04x\n", value);
break;
case TRACE_DEVWAKEUP:
trprintf("Device wakeup(): %04x\n", value);
break;
case TRACE_DEVSELFPOWERED:
trprintf("Device selfpowered(): %04x\n", value);
break;
case TRACE_DEVPULLUP:
trprintf("Device pullup(): %04x\n", value);
break;
case TRACE_CLASSBIND:
trprintf("Class bind(): %04x\n", value);
break;
case TRACE_CLASSUNBIND:
trprintf("Class unbind(): %04x\n", value);
break;
case TRACE_CLASSDISCONNECT:
trprintf("Class disconnect(): %04x\n", value);
break;
case TRACE_CLASSSETUP:
trprintf("Class setup(): %04x\n", value);
break;
case TRACE_CLASSSUSPEND:
trprintf("Class suspend(): %04x\n", value);
break;
case TRACE_CLASSRESUME:
trprintf("Class resume(): %04x\n", value);
break;
case TRACE_CLASSRDCOMPLETE:
trprintf("Class RD request complete: %04x\n", value);
break;
case TRACE_CLASSWRCOMPLETE:
trprintf("Class WR request complete: %04x\n", value);
break;
default:
switch (TRACE_ID(event))
{
case TRACE_CLASSAPI_ID: /* Other class driver system API calls */
trprintf("Class API call %d: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_CLASSSTATE_ID: /* Track class driver state changes */
trprintf("Class state %d: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_INTENTRY_ID: /* Interrupt handler entry */
trprintf("Interrupt %d entry: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_INTDECODE_ID: /* Decoded interrupt event */
trprintf("Interrupt decode %d: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_INTEXIT_ID: /* Interrupt handler exit */
trprintf("Interrupt %d exit: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_OUTREQQUEUED_ID: /* Request queued for OUT endpoint */
trprintf("EP%d OUT request queued: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_INREQQUEUED_ID: /* Request queued for IN endpoint */
trprintf("EP%d IN request queued: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_READ_ID: /* Read (OUT) action */
trprintf("EP%d OUT read: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_WRITE_ID: /* Write (IN) action */
trprintf("EP%d IN write: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_COMPLETE_ID: /* Request completed */
trprintf("EP%d request complete: %04x\n", TRACE_DATA(event), value);
break;
case TRACE_DEVERROR_ID: /* USB controller driver error event */
trprintf("Controller error: %02x:%04x\n", TRACE_DATA(event), value);
break;
case TRACE_CLSERROR_ID: /* USB class driver error event */
trprintf("Class error: %02x:%04x\n", TRACE_DATA(event), value);
break;
default:
trprintf("Unrecognized event: %02x:%02x:%04x\n",
TRACE_ID(event) >> 8, TRACE_DATA(event), value);
break;
}
}
}