Part II of the same big commit

This commit is contained in:
Frank Benkert 2017-06-01 14:58:04 -06:00 committed by Gregory Nutt
parent dcc9b07715
commit 7e6f481581
10 changed files with 551 additions and 543 deletions

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/composite.c
*
* Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2012, 2016-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -60,16 +60,6 @@
* Private Types
****************************************************************************/
/* This structure describes the internal state of the driver */
struct composite_dev_s
{
FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
uint8_t config; /* Configuration number */
FAR struct usbdev_req_s *ctrlreq; /* Allocated control request */
struct usbdevclass_driver_s *dev1; /* Device 1 class object */
struct usbdevclass_driver_s *dev2; /* Device 2 class object */
};
/* The internal version of the class driver */
@ -146,9 +136,6 @@ const char g_compserialstr[] = CONFIG_COMPOSITE_SERIALSTR;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Helpers
****************************************************************************/
/****************************************************************************
* Name: composite_ep0incomplete
@ -165,7 +152,8 @@ static void composite_ep0incomplete(FAR struct usbdev_ep_s *ep,
if (req->result || req->xfrd != req->len)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_REQRESULT), (uint16_t)-req->result);
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_REQRESULT),
(uint16_t)-req->result);
}
}
@ -185,17 +173,20 @@ static int composite_classsetup(FAR struct composite_dev_s *priv,
uint16_t index;
uint8_t interface;
int ret = -EOPNOTSUPP;
int i;
index = GETUINT16(ctrl->index);
interface = (uint8_t)(index & 0xff);
if (interface >= DEV1_FIRSTINTERFACE && interface < (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES))
for (i = 0; i < priv->ndevices; i++)
{
ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
}
else if (interface >= DEV2_FIRSTINTERFACE && interface < (DEV2_FIRSTINTERFACE + DEV2_NINTERFACES))
{
ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
if (interface >= priv->device[i].compdesc.devdesc.ifnobase &&
interface < (priv->device[i].compdesc.devdesc.ifnobase +
priv->device[i].compdesc.devdesc.ninterfaces))
{
ret = CLASS_SETUP(priv->device[i].dev, dev, ctrl, dataout, outlen);
break;
}
}
return ret;
@ -225,6 +216,7 @@ static struct usbdev_req_s *composite_allocreq(FAR struct usbdev_ep_s *ep,
req = NULL;
}
}
return req;
}
@ -245,6 +237,7 @@ static void composite_freereq(FAR struct usbdev_ep_s *ep,
{
EP_FREEBUFFER(ep, req->buf);
}
EP_FREEREQ(ep, req);
}
}
@ -266,6 +259,7 @@ static int composite_bind(FAR struct usbdevclass_driver_s *driver,
{
FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s *)driver)->dev;
int ret;
int i;
usbtrace(TRACE_CLASSBIND, 0);
@ -281,7 +275,7 @@ static int composite_bind(FAR struct usbdevclass_driver_s *driver,
/* Preallocate one control request */
priv->ctrlreq = composite_allocreq(dev->ep0, COMPOSITE_CFGDESCSIZE);
priv->ctrlreq = composite_allocreq(dev->ep0, priv->cfgdescsize);
if (priv->ctrlreq == NULL)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCCTRLREQ), 0);
@ -295,16 +289,13 @@ static int composite_bind(FAR struct usbdevclass_driver_s *driver,
/* Then bind each of the constituent class drivers */
ret = CLASS_BIND(priv->dev1, dev);
if (ret < 0)
for (i = 0; i < priv->ndevices; i++)
{
goto errout;
}
ret = CLASS_BIND(priv->dev2, dev);
if (ret < 0)
{
goto errout;
ret = CLASS_BIND(priv->device[i].dev, dev);
if (ret < 0)
{
goto errout;
}
}
/* Report if we are selfpowered */
@ -363,11 +354,15 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
if (priv != NULL)
{
int i;
/* Unbind the constituent class drivers */
flags = enter_critical_section();
CLASS_UNBIND(priv->dev1, dev);
CLASS_UNBIND(priv->dev2, dev);
for (i = 0; i < priv->ndevices; i++)
{
CLASS_UNBIND(priv->device[i].dev, dev);
}
/* Free the pre-allocated control request */
@ -377,6 +372,7 @@ static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
composite_freereq(dev->ep0, priv->ctrlreq);
priv->ctrlreq = NULL;
}
leave_critical_section(flags);
}
}
@ -423,6 +419,7 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
return -ENODEV;
}
#endif
ctrlreq = priv->ctrlreq;
/* Extract the little-endian 16-bit values to host order */
@ -472,10 +469,10 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
case USB_DESC_TYPE_CONFIG:
{
#ifdef CONFIG_USBDEV_DUALSPEED
ret = composite_mkcfgdesc(ctrlreq->buf, dev->speed,
ret = composite_mkcfgdesc(priv, ctrlreq->buf, dev->speed,
ctrl->value[1]);
#else
ret = composite_mkcfgdesc(ctrlreq->buf);
ret = composite_mkcfgdesc(priv, ctrlreq->buf);
#endif
}
break;
@ -491,18 +488,21 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
{
ret = composite_mkstrdesc(strid, buf);
}
#if DEV1_NSTRIDS > 0
else if (strid <= DEV1_STRIDBASE + DEV1_NSTRIDS)
else
{
ret = DEV1_MKSTRDESC(strid, buf);
int i;
for (i = 0; i < priv->ndevices; i++)
{
if (strid >= priv->device[i].compdesc.devdesc.strbase &&
strid < priv->device[i].compdesc.devdesc.strbase +
priv->device[i].compdesc.devdesc.nstrings)
{
ret = priv->device[i].compdesc.mkstrdesc(strid - priv->device[i].compdesc.devdesc.strbase, buf);
break;
}
}
}
#endif
#if DEV2_NSTRIDS > 0
else if (strid <= DEV2_STRIDBASE + DEV2_NSTRIDS)
{
ret = DEV2_MKSTRDESC(strid, buf);
}
#endif
}
break;
@ -519,19 +519,17 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
{
if (ctrl->type == 0)
{
int i;
/* Save the configuration and inform the constituent classes */
ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
dispatched = true;
if (ret >= 0)
for (i = 0; i < priv->ndevices; i++)
{
ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
if (ret >= 0)
{
priv->config = value;
}
ret = CLASS_SETUP(priv->device[i].dev, dev, ctrl, dataout, outlen);
}
dispatched = true;
priv->config = value;
}
}
break;
@ -635,6 +633,7 @@ static void composite_disconnect(FAR struct usbdevclass_driver_s *driver,
{
FAR struct composite_dev_s *priv;
irqstate_t flags;
int i;
usbtrace(TRACE_CLASSDISCONNECT, 0);
@ -664,8 +663,12 @@ static void composite_disconnect(FAR struct usbdevclass_driver_s *driver,
flags = enter_critical_section();
priv->config = COMPOSITE_CONFIGIDNONE;
CLASS_DISCONNECT(priv->dev1, dev);
CLASS_DISCONNECT(priv->dev2, dev);
for (i = 0; i < priv->ndevices; i++)
{
CLASS_DISCONNECT(priv->device[i].dev, dev);
}
leave_critical_section(flags);
/* Perform the soft connect function so that we will we can be
@ -688,6 +691,7 @@ static void composite_suspend(FAR struct usbdevclass_driver_s *driver,
{
FAR struct composite_dev_s *priv;
irqstate_t flags;
int i;
usbtrace(TRACE_CLASSSUSPEND, 0);
@ -714,8 +718,12 @@ static void composite_suspend(FAR struct usbdevclass_driver_s *driver,
/* Forward the suspend event to the constituent devices */
flags = enter_critical_section();
CLASS_SUSPEND(priv->dev1, priv->usbdev);
CLASS_SUSPEND(priv->dev2, priv->usbdev);
for (i = 0; i < priv->ndevices; i++)
{
CLASS_SUSPEND(priv->device[i].dev, priv->usbdev);
}
leave_critical_section(flags);
}
@ -732,6 +740,7 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver,
{
FAR struct composite_dev_s *priv = NULL;
irqstate_t flags;
int i;
#ifdef CONFIG_DEBUG_FEATURES
if (!dev)
@ -756,8 +765,12 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver,
/* Forward the resume event to the constituent devices */
flags = enter_critical_section();
CLASS_RESUME(priv->dev1, priv->usbdev);
CLASS_RESUME(priv->dev2, priv->usbdev);
for (i = 0; i < priv->ndevices; i++)
{
CLASS_RESUME(priv->device[i].dev, priv->usbdev);
}
leave_critical_section(flags);
}
@ -786,16 +799,20 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver,
*
****************************************************************************/
FAR void *composite_initialize(void)
FAR void *composite_initialize(uint8_t ndevices,
FAR struct composite_devdesc_s *pdevices)
{
FAR struct composite_alloc_s *alloc;
FAR struct composite_dev_s *priv;
FAR struct composite_driver_s *drvr;
int ret;
int i;
/* Allocate the structures needed */
alloc = (FAR struct composite_alloc_s *)kmm_malloc(sizeof(struct composite_alloc_s));
alloc = (FAR struct composite_alloc_s *)
kmm_malloc(sizeof(struct composite_alloc_s));
if (!alloc)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCDEVSTRUCT), 0);
@ -811,21 +828,31 @@ FAR void *composite_initialize(void)
memset(priv, 0, sizeof(struct composite_dev_s));
/* Get the constitueat class driver objects */
priv->cfgdescsize = USB_SIZEOF_CFGDESC;
priv->ninterfaces = 0;
ret = DEV1_CLASSOBJECT(&priv->dev1);
if (ret < 0)
/* Get the constituent class driver objects */
for (i = 0; i < ndevices; i++)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret);
goto errout_with_alloc;
memcpy(&priv->device[i].compdesc, &pdevices[i],
sizeof(struct composite_devdesc_s));
ret = priv->device[i].compdesc.board_classobject(priv->device[i].compdesc.minor,
&priv->device[i].compdesc.devdesc,
&priv->device[i].dev);
if (ret < 0)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT),
(uint16_t)-ret);
goto errout_with_alloc;
}
priv->cfgdescsize += priv->device[i].compdesc.cfgdescsize;
priv->ninterfaces += priv->device[i].compdesc.devdesc.ninterfaces;
}
ret = DEV2_CLASSOBJECT(&priv->dev2);
if (ret < 0)
{
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret);
goto errout_with_alloc;
}
priv->ndevices = ndevices;
/* Initialize the USB class driver structure */
@ -875,6 +902,7 @@ void composite_uninitialize(FAR void *handle)
{
FAR struct composite_alloc_s *alloc = (FAR struct composite_alloc_s *)handle;
FAR struct composite_dev_s *priv;
int i;
DEBUGASSERT(alloc != NULL);
@ -882,8 +910,10 @@ void composite_uninitialize(FAR void *handle)
priv = &alloc->dev;
DEV1_UNINITIALIZE(priv->dev1);
DEV2_UNINITIALIZE(priv->dev2);
for (i = 0; i < priv->ndevices; i++)
{
priv->device[i].compdesc.board_uninitialize(priv->device[i].dev);
}
/* Then unregister and destroy the composite class */
@ -894,8 +924,10 @@ void composite_uninitialize(FAR void *handle)
/* Second phase uninitialization: Clean up all memory resources */
DEV1_UNINITIALIZE(priv->dev1);
DEV2_UNINITIALIZE(priv->dev2);
for (i = 0; i < priv->ndevices; i++)
{
priv->device[i].compdesc.board_uninitialize(priv->device[i].dev);
}
/* Then free the composite driver state structure itself */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/composite.h
*
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -46,6 +46,7 @@
#include <stdint.h>
#include <nuttx/usb/usb.h>
#include <nuttx/usb/usbdev.h>
#include <nuttx/usb/usbdev_trace.h>
#ifdef CONFIG_USBDEV_COMPOSITE
@ -115,127 +116,12 @@
# define COMPOSITE_REMOTEWAKEUP (0)
#endif
/* Constituent devices ******************************************************/
#undef DEV1_IS_CDCACM
#undef DEV1_IS_USBMSC
#undef DEV2_IS_CDCACM
#undef DEV2_IS_USBMSC
/* Pick the first device in the composite. At present, this may only be
* the CDC serial device or the mass storage device.
*/
#if defined(CONFIG_CDCACM_COMPOSITE)
# define DEV1_IS_CDCACM 1
# define DEV1_MKCFGDESC cdcacm_mkcfgdesc
# define DEV1_MKSTRDESC cdcacm_mkstrdesc
# define DEV1_CLASSOBJECT board_cdcclassobject
# define DEV1_UNINITIALIZE board_cdcuninitialize
# define DEV1_NCONFIGS CDCACM_NCONFIGS
# define DEV1_CONFIGID CDCACM_CONFIGID
# define DEV1_FIRSTINTERFACE CONFIG_CDCACM_IFNOBASE
# define DEV1_NINTERFACES CDCACM_NINTERFACES
# define DEV1_STRIDBASE CONFIG_CDCACM_STRBASE
# define DEV1_NSTRIDS CDCACM_NSTRIDS
# define DEV1_CFGDESCSIZE SIZEOF_CDCACM_CFGDESC
#elif defined(CONFIG_USBMSC_COMPOSITE)
# define DEV1_IS_USBMSC 1
# define DEV1_MKCFGDESC usbmsc_mkcfgdesc
# define DEV1_MKSTRDESC usbmsc_mkstrdesc
# define DEV1_CLASSOBJECT board_mscclassobject
# define DEV1_UNINITIALIZE board_mscuninitialize
# define DEV1_NCONFIGS USBMSC_NCONFIGS
# define DEV1_CONFIGID USBMSC_CONFIGID
# define DEV1_FIRSTINTERFACE CONFIG_USBMSC_IFNOBASE
# define DEV1_NINTERFACES USBMSC_NINTERFACES
# define DEV1_STRIDBASE CONFIG_USBMSC_IFNOBASE
# define DEV1_NSTRIDS USBMSC_NSTRIDS
# define DEV1_CFGDESCSIZE SIZEOF_USBMSC_CFGDESC
#else
# error "No members of the composite defined"
#endif
/* Pick the second device in the composite. At present, this may only be
* the CDC serial device or the mass storage device.
*/
#if defined(CONFIG_CDCACM_COMPOSITE) && !defined(DEV1_IS_CDCACM)
# define DEV2_IS_CDCACM 1
# define DEV2_MKCFGDESC cdcacm_mkcfgdesc
# define DEV2_MKSTRDESC cdcacm_mkstrdesc
# define DEV2_CLASSOBJECT board_cdcclassobject
# define DEV2_UNINITIALIZE board_cdcuninitialize
# define DEV2_NCONFIGS CDCACM_NCONFIGS
# define DEV2_CONFIGID CDCACM_CONFIGID
# define DEV2_FIRSTINTERFACE CONFIG_CDCACM_IFNOBASE
# define DEV2_NINTERFACES CDCACM_NINTERFACES
# define DEV2_STRIDBASE CONFIG_CDCACM_STRBASE
# define DEV2_NSTRIDS CDCACM_NSTRIDS
# define DEV2_CFGDESCSIZE SIZEOF_CDCACM_CFGDESC
#elif defined(CONFIG_USBMSC_COMPOSITE) && !defined(DEV1_IS_USBMSC)
# define DEV2_IS_USBMSC 1
# define DEV2_MKCFGDESC usbmsc_mkcfgdesc
# define DEV2_MKSTRDESC usbmsc_mkstrdesc
# define DEV2_UNINITIALIZE board_mscuninitialize
# define DEV2_CLASSOBJECT board_mscclassobject
# define DEV2_NCONFIGS USBMSC_NCONFIGS
# define DEV2_CONFIGID USBMSC_CONFIGID
# define DEV2_FIRSTINTERFACE CONFIG_USBMSC_IFNOBASE
# define DEV2_NINTERFACES USBMSC_NINTERFACES
# define DEV2_STRIDBASE CONFIG_USBMSC_STRBASE
# define DEV2_NSTRIDS USBMSC_NSTRIDS
# define DEV2_CFGDESCSIZE SIZEOF_USBMSC_CFGDESC
#else
# error "Insufficient members of the composite defined"
#endif
/* Verify interface configuration */
#if DEV1_FIRSTINTERFACE != 0
# warning "The first interface number should be zero"
#endif
#if (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES) != DEV2_FIRSTINTERFACE
# warning "Interface numbers are not contiguous"
#endif
/* Check if an IAD is needed */
#ifdef CONFIG_COMPOSITE_IAD
# if DEV1_NINTERFACES == 1 && DEV2_NINTERFACES == 1
# warning "CONFIG_COMPOSITE_IAD not needed"
# endif
#endif
#if !defined(CONFIG_COMPOSITE_IAD) && DEV1_NINTERFACES > 1 && DEV2_NINTERFACES > 1
# warning "CONFIG_COMPOSITE_IAD may be needed"
#endif
/* Total size of the configuration descriptor: */
#define COMPOSITE_CFGDESCSIZE (USB_SIZEOF_CFGDESC + DEV1_CFGDESCSIZE + DEV2_CFGDESCSIZE)
/* The total number of interfaces */
#define COMPOSITE_NINTERFACES (DEV1_NINTERFACES + DEV2_NINTERFACES)
/* Composite configuration ID value */
#if DEV1_NCONFIGS != 1 || DEV1_CONFIGID != 1
# error "DEV1: Only a single configuration is supported"
#endif
#if DEV2_NCONFIGS != 1 || DEV2_CONFIGID != 1
# error "DEV2: Only a single configuration is supported"
#endif
#define NUM_DEVICES_TO_HANDLE (4)
/* Descriptors **************************************************************/
/* These settings are not modifiable via the NuttX configuration */
#define COMPOSITE_CONFIGIDNONE (0) /* Config ID = 0 means to return to address mode */
#define COMPOSITE_NCONFIGS (1) /* The number of configurations supported */
#define COMPOSITE_CONFIGID (1) /* The only supported configuration ID */
/* String language */
@ -248,17 +134,6 @@
#define COMPOSITE_PRODUCTSTRID (2)
#define COMPOSITE_SERIALSTRID (3)
#define COMPOSITE_CONFIGSTRID (4)
#define COMPOSITE_NSTRIDS (4)
/* Verify string configuration */
#if COMPOSITE_NSTRIDS != DEV1_STRIDBASE
# warning "The DEV1 string base should be COMPOSITE_NSTRIDS"
#endif
#if (DEV1_STRIDBASE + DEV1_NSTRIDS) != DEV2_STRIDBASE
# warning "String IDs are not contiguous"
#endif
/* Everpresent MIN/MAX macros ***********************************************/
@ -274,6 +149,34 @@
* Public Types
****************************************************************************/
struct composite_devobj_s
{
/* Device description given by the user code in the dynamic
* configuration.
*/
struct composite_devdesc_s compdesc;
/* Pointer to device class */
FAR struct usbdevclass_driver_s *dev;
};
/* This structure describes the internal state of the driver */
struct composite_dev_s
{
FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
uint8_t config; /* Configuration number */
FAR struct usbdev_req_s *ctrlreq; /* Allocated control request */
uint8_t ndevices; /* num devices in this composite device */
int cfgdescsize; /* Total size of the configuration descriptor: */
int ninterfaces; /* The total number of interfaces in this composite device */
struct composite_devobj_s device[NUM_DEVICES_TO_HANDLE]; /* Device class object */
};
/****************************************************************************
* Public Data
****************************************************************************/
@ -317,9 +220,10 @@ FAR const struct usb_devdesc_s *composite_getdevdesc(void);
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t composite_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type);
int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, uint8_t *buf,
uint8_t speed, uint8_t type);
#else
int16_t composite_mkcfgdesc(uint8_t *buf);
int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, uint8_t *buf);
#endif
/****************************************************************************

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/composite_desc.c
*
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -61,12 +61,6 @@
* Private Types
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf, uint8_t speed, uint8_t type);
#else
typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf);
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -74,6 +68,7 @@ typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf);
/****************************************************************************
* Private Data
****************************************************************************/
/* Device Descriptor */
static const struct usb_devdesc_s g_devdesc =
@ -84,7 +79,7 @@ static const struct usb_devdesc_s g_devdesc =
LSBYTE(0x0200),
MSBYTE(0x0200)
},
#ifdef CONFIG_COMPOSITE_IAD
#ifndef CONFIG_COMPOSITE_IAD
USB_CLASS_MISC, /* classid */
2, /* subclass */
1, /* protocol */
@ -112,25 +107,6 @@ static const struct usb_devdesc_s g_devdesc =
COMPOSITE_NCONFIGS /* nconfigs */
};
/* Configuration descriptor for the composite device */
static const struct usb_cfgdesc_s g_cfgdesc =
{
USB_SIZEOF_CFGDESC, /* len */
USB_DESC_TYPE_CONFIG, /* type */
{
LSBYTE(COMPOSITE_CFGDESCSIZE), /* LS totallen */
MSBYTE(COMPOSITE_CFGDESCSIZE) /* MS totallen */
},
COMPOSITE_NINTERFACES, /* ninterfaces */
COMPOSITE_CONFIGID, /* cfgvalue */
COMPOSITE_CONFIGSTRID, /* icfg */
USB_CONFIG_ATTR_ONE | /* attr */
COMPOSITE_SELFPOWERED |
COMPOSITE_REMOTEWAKEUP,
(CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
};
#ifdef CONFIG_USBDEV_DUALSPEED
static const struct usb_qualdesc_s g_qualdesc =
{
@ -243,35 +219,52 @@ FAR const struct usb_devdesc_s *composite_getdevdesc(void)
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t composite_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type)
int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, FAR uint8_t *buf,
uint8_t speed, uint8_t type)
#else
int16_t composite_mkcfgdesc(uint8_t *buf)
int16_t composite_mkcfgdesc(FAR struct composite_dev_s *priv, FAR uint8_t *buf)
#endif
{
FAR struct usb_cfgdesc_s *cfgdesc = (FAR struct usb_cfgdesc_s *)buf;
int16_t len;
int16_t total;
int i;
/* Configuration descriptor -- Copy the canned configuration descriptor. */
/* Configuration descriptor for the composite device */
/* Fill in the values directly into the buf */
cfgdesc->len = USB_SIZEOF_CFGDESC; /* Descriptor length */
cfgdesc->type = USB_DESC_TYPE_CONFIG; /* Descriptor type */
cfgdesc->totallen[0] = LSBYTE(priv->cfgdescsize); /* Lower Byte of Total length */
cfgdesc->totallen[1] = MSBYTE(priv->cfgdescsize); /* High Byte of Total length */
cfgdesc->ninterfaces = priv->ninterfaces; /* Number of interfaces */
cfgdesc->cfgvalue = COMPOSITE_CONFIGID; /* Configuration value */
cfgdesc->icfg = COMPOSITE_CONFIGSTRID; /* Configuration */
cfgdesc->attr = USB_CONFIG_ATTR_ONE | /* Attributes */
COMPOSITE_SELFPOWERED |
COMPOSITE_REMOTEWAKEUP;
cfgdesc->mxpower = (CONFIG_USBDEV_MAXPOWER + 1) / 2; /* Max power (mA/2) */
/* increment the size and buf to point right behind the information filled in */
memcpy(buf, &g_cfgdesc, USB_SIZEOF_CFGDESC);
total = USB_SIZEOF_CFGDESC;
buf += USB_SIZEOF_CFGDESC;
buf += USB_SIZEOF_CFGDESC;
/* Copy DEV1/DEV2 interface descriptors */
/* Copy all contained interface descriptors into the buffer too */
for (i = 0; i < priv->numDevices; i++)
{
#ifdef CONFIG_USBDEV_DUALSPEED
len = DEV1_MKCFGDESC(buf, speed, type);
total += len;
buf += len;
total += DEV2_MKCFGDESC(buf, speed, type);
len = priv->device[i].comp_devdesc.mkconfdesc(buf, &priv->device[i].comp_devdesc.usb_dev_desc, speed, type);
total += len;
buf += len;
#else
len = DEV1_MKCFGDESC(buf);
total += len;
buf += len;
total += DEV2_MKCFGDESC(buf);
len = priv->device[i].comp_devdesc.mkconfdesc(buf, &priv->device[i].comp_devdesc.usb_dev_desc);
total += len;
buf += len;
#endif
}
DEBUGASSERT(total == COMPOSITE_CFGDESCSIZE);
return total;
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/usbmsc.c
*
* Copyright (C) 2008-2012, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2012, 2016-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Mass storage class device. Bulk-only with SCSI subclass.
@ -307,7 +307,8 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
/* Pre-allocate the IN bulk endpoint */
priv->epbulkin = DEV_ALLOCEP(dev, USBMSC_EPINBULK_ADDR, true, USB_EP_ATTR_XFER_BULK);
priv->epbulkin = DEV_ALLOCEP(dev, USBMSC_MKEPBULKIN(&priv->usb_dev_desc),
true, USB_EP_ATTR_XFER_BULK);
if (!priv->epbulkin)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINALLOCFAIL), 0);
@ -319,7 +320,8 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
/* Pre-allocate the OUT bulk endpoint */
priv->epbulkout = DEV_ALLOCEP(dev, USBMSC_EPOUTBULK_ADDR, false, USB_EP_ATTR_XFER_BULK);
priv->epbulkout = DEV_ALLOCEP(dev, USBMSC_MKEPBULKOUT(&priv->usb_dev_desc),
false, USB_EP_ATTR_XFER_BULK);
if (!priv->epbulkout)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTALLOCFAIL), 0);
@ -334,7 +336,8 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++)
{
reqcontainer = &priv->rdreqs[i];
reqcontainer->req = usbmsc_allocreq(priv->epbulkout, CONFIG_USBMSC_BULKOUTREQLEN);
reqcontainer->req = usbmsc_allocreq(priv->epbulkout,
CONFIG_USBMSC_BULKOUTREQLEN);
if (reqcontainer->req == NULL)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDALLOCREQ),
@ -342,6 +345,7 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
ret = -ENOMEM;
goto errout;
}
reqcontainer->req->priv = reqcontainer;
reqcontainer->req->callback = usbmsc_rdcomplete;
}
@ -359,6 +363,7 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
ret = -ENOMEM;
goto errout;
}
reqcontainer->req->priv = reqcontainer;
reqcontainer->req->callback = usbmsc_wrcomplete;
@ -929,10 +934,8 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config)
{
FAR struct usbmsc_req_s *privreq;
FAR struct usbdev_req_s *req;
#ifdef CONFIG_USBDEV_DUALSPEED
FAR const struct usb_epdesc_s *epdesc;
bool hispeed = (priv->usbdev->speed == USB_SPEED_HIGH);
#endif
struct usb_epdesc_s epdesc;
bool hispeed = false;
int i;
int ret = 0;
@ -952,6 +955,10 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config)
return OK;
}
#ifdef CONFIG_USBDEV_DUALSPEED
hispeed = (priv->usbdev->speed == USB_SPEED_HIGH);
#endif
/* Discard the previous configuration data */
usbmsc_resetconfig(priv);
@ -974,13 +981,9 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config)
/* Configure the IN bulk endpoint */
#ifdef CONFIG_USBDEV_DUALSPEED
epdesc = USBMSC_EPBULKINDESC(hispeed);
ret = EP_CONFIGURE(priv->epbulkin, epdesc, false);
#else
ret = EP_CONFIGURE(priv->epbulkin,
usbmsc_getepdesc(USBMSC_EPFSBULKIN), false);
#endif
usbmsc_copy_epdesc(USBMSC_EPBULKIN, &epdesc, &priv->usb_dev_desc,
hispeed);
ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false);
if (ret < 0)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINCONFIGFAIL), 0);
@ -991,13 +994,9 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config)
/* Configure the OUT bulk endpoint */
#ifdef CONFIG_USBDEV_DUALSPEED
epdesc = USBMSC_EPBULKOUTDESC(hispeed);
ret = EP_CONFIGURE(priv->epbulkout, epdesc, true);
#else
ret = EP_CONFIGURE(priv->epbulkout,
usbmsc_getepdesc(USBMSC_EPFSBULKOUT), true);
#endif
usbmsc_copy_epdesc(USBMSC_EPBULKOUT, &epdesc, &priv->usb_dev_desc,
hispeed);
ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true);
if (ret < 0)
{
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTCONFIGFAIL), 0);
@ -1015,6 +1014,7 @@ int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config)
req->len = CONFIG_USBMSC_BULKOUTREQLEN;
req->priv = privreq;
req->callback = usbmsc_rdcomplete;
ret = EP_SUBMIT(priv->epbulkout, req);
if (ret < 0)
{
@ -1719,7 +1719,7 @@ errout_with_lock:
****************************************************************************/
#ifdef CONFIG_USBMSC_COMPOSITE
int usbmsc_classobject(FAR void *handle,
int usbmsc_classobject(FAR void *handle, FAR struct usbdev_description_s *usb_dev_desc,
FAR struct usbdevclass_driver_s **classdev)
{
FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
@ -1860,3 +1860,51 @@ void usbmsc_uninitialize(FAR void *handle)
kmm_free(priv);
#endif
}
/****************************************************************************
* Name: usbmsc_get_composite_devdesc
*
* Description:
* Helper function to fill in some constants into the composite
* configuration struct.
*
* Input Parameters:
* dev - Pointer to the configuration struct we should fill
*
* Returned Value:
* None
*
****************************************************************************/
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE)
void usbmsc_get_composite_devdesc(FAR struct composite_devdesc_s *dev)
{
/* The callback functions for the CDC/ACM class */
dev->mkconfdesc = usbmsc_mkcfgdesc;
dev->mkstrdesc = usbmsc_mkstrdesc;
dev->board_classobject = 0;
dev->board_uninitialize = 0;
dev->nconfigs = USBMSC_NCONFIGS; /* Number of configurations supported */
dev->configid = USBMSC_CONFIGID; /* The only supported configuration ID */
dev->cfgdescsize = SIZEOF_USBMSC_CFGDESC; /* The size of the config descriptor */
dev->minor = 0; /* The minor interface number */
/* Interfaces */
dev->usb_dev_desc.ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces in the configuration */
dev->usb_dev_desc.ifnobase = 0; /* Offset to Interface-IDs */
/* Strings */
dev->usb_dev_desc.nstrings = USBMSC_NSTRIDS; /* Number of Strings */
dev->usb_dev_desc.strbase = 0; /* Offset to String Numbers */
/* Endpoints */
dev->usb_dev_desc.nendpoints = USBMSC_NENDPOINTS;
dev->usb_dev_desc.epno[USBMSC_EP_BULKIN_IDX] = 0;
dev->usb_dev_desc.epno[USBMSC_EP_BULKOUT_IDX] = 0;
}
#endif

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/usbmsc.h
*
* Copyright (C) 2008-2013, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2013, 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Mass storage class device. Bulk-only with SCSI subclass.
@ -98,14 +98,18 @@
/* Logical endpoint numbers / max packet sizes */
#ifndef CONFIG_USBMSC_EPBULKOUT
# warning "EPBULKOUT not defined in the configuration"
# define CONFIG_USBMSC_EPBULKOUT 2
#ifndef CONFIG_USBMSC_COMPOSITE
# ifndef CONFIG_USBMSC_EPBULKOUT
# warning "EPBULKOUT not defined in the configuration"
# define CONFIG_USBMSC_EPBULKOUT 2
# endif
#endif
#ifndef CONFIG_USBMSC_EPBULKIN
# warning "EPBULKIN not defined in the configuration"
# define CONFIG_USBMSC_EPBULKIN 3
#ifndef CONFIG_USBMSC_COMPOSITE
# ifndef CONFIG_USBMSC_EPBULKIN
# warning "EPBULKIN not defined in the configuration"
# define CONFIG_USBMSC_EPBULKIN 3
# endif
#endif
/* Packet and request buffer sizes */
@ -293,27 +297,19 @@
#define USBMSC_LASTSTRID USBMSC_INTERFACESTRID
#define USBMSC_NSTRIDS (USBMSC_LASTSTRID - CONFIG_USBMSC_STRBASE)
#define USBMSC_NCONFIGS (1) /* Number of configurations supported */
/* Configuration Descriptor */
#define USBMSC_NINTERFACES (1) /* Number of interfaces in the configuration */
#define USBMSC_INTERFACEID (CONFIG_USBMSC_IFNOBASE+0)
#define USBMSC_ALTINTERFACEID (0)
#define USBMSC_CONFIGIDNONE (0) /* Config ID means to return to address mode */
#define USBMSC_CONFIGID (1) /* The only supported configuration ID */
/* Interface description */
#define USBMSC_NENDPOINTS (2) /* Number of endpoints in the interface */
/* Endpoint configuration */
#define USBMSC_EPOUTBULK_ADDR (CONFIG_USBMSC_EPBULKOUT)
#define USBMSC_MKEPBULKOUT(devDesc) ((devDesc)->epno[USBMSC_EP_BULKOUT_IDX])
#define USBMSC_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
#define USBMSC_EPINBULK_ADDR (USB_DIR_IN|CONFIG_USBMSC_EPBULKIN)
#define USBMSC_MKEPBULKIN(devDesc) (USB_DIR_IN | (devDesc)->epno[USBMSC_EP_BULKIN_IDX])
#define USBMSC_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK)
#define USBMSC_HSBULKMAXPACKET (512)
@ -323,38 +319,10 @@
#define USBMSC_FSBULKMXPKTSHIFT (6)
#define USBMSC_FSBULKMXPKTMASK (0x0000003f)
/* Macros for dual speed vs. full speed only operation */
#ifdef CONFIG_USBDEV_DUALSPEED
# define USBMSC_EPBULKINDESC(hs) \
usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKIN : USBMSC_EPFSBULKIN)
# define USBMSC_EPBULKOUTDESC(hs) \
usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKOUT : USBMSC_EPFSBULKOUT)
# define USBMSC_BULKMAXPACKET(hs) \
((hs) ? USBMSC_HSBULKMAXPACKET : USBMSC_FSBULKMAXPACKET)
# define USBMSC_BULKMXPKTSHIFT(d) \
(((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTSHIFT : USBMSC_FSBULKMXPKTSHIFT)
# define USBMSC_BULKMXPKTMASK(d) \
(((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTMASK : USBMSC_FSBULKMXPKTMASK)
#else
# define USBMSC_EPBULKINDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKIN)
# define USBMSC_EPBULKOUTDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKOUT)
# define USBMSC_BULKMAXPACKET(hs) USBMSC_FSBULKMAXPACKET
# define USBMSC_BULKMXPKTSHIFT(d) USBMSC_FSBULKMXPKTSHIFT
# define USBMSC_BULKMXPKTMASK(d) USBMSC_FSBULKMXPKTMASK
#endif
/* Configuration descriptor size */
#ifndef CONFIG_USBMSC_COMPOSITE
/* Number of individual descriptors in the configuration descriptor:
* (1) Configuration descriptor + (1) interface descriptor + (2) interface
* descriptors.
*/
# define USBMSC_CFGGROUP_SIZE (4)
/* The size of the config descriptor: (9 + 9 + 2*7) = 32 */
# define SIZEOF_USBMSC_CFGDESC \
@ -362,12 +330,6 @@
#else
/* Number of individual descriptors in the configuration descriptor:
* (1) interface descriptor + (2) interface descriptors.
*/
# define USBMSC_CFGGROUP_SIZE (3)
/* The size of the config descriptor: (9 + 2*7) = 23 */
# define SIZEOF_USBMSC_CFGDESC \
@ -398,13 +360,8 @@
enum usbmsc_epdesc_e
{
USBMSC_EPFSBULKOUT = 0, /* Full speed bulk OUT endpoint descriptor */
USBMSC_EPFSBULKIN /* Full speed bulk IN endpoint descriptor */
#ifdef CONFIG_USBDEV_DUALSPEED
,
USBMSC_EPHSBULKOUT, /* High speed bulk OUT endpoint descriptor */
USBMSC_EPHSBULKIN /* High speed bulk IN endpoint descriptor */
#endif
USBMSC_EPBULKOUT = 0, /* Bulk OUT endpoint descriptor */
USBMSC_EPBULKIN /* Bulk IN endpoint descriptor */
};
/* Container to support a list of requests */
@ -487,6 +444,8 @@ struct usbmsc_dev_s
struct sq_queue_s wrreqlist; /* List of empty write request containers */
struct sq_queue_s rdreqlist; /* List of filled read request containers */
struct usbdev_description_s devdesc;
/* 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.
@ -603,16 +562,19 @@ int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void);
#endif
/************************************************************************************
* Name: usbmsc_getepdesc
/****************************************************************************
* Name: usbmsc_copy_epdesc
*
* Description:
* Return a pointer to the raw endpoint descriptor (used for configuring endpoints)
* Copies the requested Endpoint Description into the buffer given.
* Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ).
*
************************************************************************************/
****************************************************************************/
struct usb_epdesc_s;
FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid);
int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid,
FAR struct usb_epdesc_s *epdesc,
FAR struct usbdev_description_s *devdesc,
bool hispeed);
/************************************************************************************
* Name: usbmsc_mkcfgdesc
@ -623,9 +585,10 @@ FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid);
************************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type);
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_description_s *devdesc,
uint8_t speed, uint8_t type);
#else
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf);
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_description_s *devdesc);
#endif
/************************************************************************************
@ -725,4 +688,4 @@ void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed);
}
#endif
#endif /* #define __DRIVERS_USBDEV_USBMSC_H */
#endif /* __DRIVERS_USBDEV_USBMSC_H */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/usbmsc_desc.c
*
* Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -54,6 +54,27 @@
* Pre-processor Definitions
****************************************************************************/
/* This little hack makes the compiler producing an error if the (constant)
* condition is not true.
*
* e.g.
* COMPILE_TIME_ASSERTION( sizeof(uint8_t) == 1 );
*
* when not true, the output is something like
*
* test.c:28:2: error: size of unnamed array is negative
* COMPILE_TIME_ASSERTION( sizeof(uint8_t) != 1 );
* ^
*
* else the compiler produces the (empty) statement
*
* ((void)sizeof(char[1]))
*
* which is optimized out.
*/
#define COMPILE_TIME_ASSERTION(condition) ((void)sizeof(char[1 - 2*!(condition)]))
/****************************************************************************
* Private Types
****************************************************************************/
@ -92,79 +113,13 @@ static const struct usb_devdesc_s g_devdesc =
LSBYTE(CONFIG_USBMSC_VERSIONNO),
MSBYTE(CONFIG_USBMSC_VERSIONNO)
},
USBMSC_MANUFACTURERSTRID, /* imfgr */
USBMSC_PRODUCTSTRID, /* iproduct */
USBMSC_SERIALSTRID, /* serno */
USBMSC_NCONFIGS /* nconfigs */
USBMSC_MANUFACTURERSTRID, /* imfgr */
USBMSC_PRODUCTSTRID, /* iproduct */
USBMSC_SERIALSTRID, /* serno */
USBMSC_NCONFIGS /* nconfigs */
};
#endif
/* Configuration descriptor If the USB mass storage device is configured as part
* of a composite device, then the configuration descriptor will be provided by the
* composite device logic.
*/
#ifndef CONFIG_USBMSC_COMPOSITE
static const struct usb_cfgdesc_s g_cfgdesc =
{
USB_SIZEOF_CFGDESC, /* len */
USB_DESC_TYPE_CONFIG, /* type */
{ /* totallen */
LSBYTE(SIZEOF_USBMSC_CFGDESC),
MSBYTE(SIZEOF_USBMSC_CFGDESC)
},
USBMSC_NINTERFACES, /* ninterfaces */
USBMSC_CONFIGID, /* cfgvalue */
USBMSC_CONFIGSTRID, /* icfg */
USB_CONFIG_ATTR_ONE | /* attr */
USBMSC_SELFPOWERED |
USBMSC_REMOTEWAKEUP,
(CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
};
#endif
/* Single interface descriptor */
static const struct usb_ifdesc_s g_ifdesc =
{
USB_SIZEOF_IFDESC, /* len */
USB_DESC_TYPE_INTERFACE, /* type */
USBMSC_INTERFACEID, /* ifno */
USBMSC_ALTINTERFACEID, /* alt */
USBMSC_NENDPOINTS, /* neps */
USB_CLASS_MASS_STORAGE, /* classid */
USBMSC_SUBCLASS_SCSI, /* subclass */
USBMSC_PROTO_BULKONLY, /* protocol */
USBMSC_INTERFACESTRID /* iif */
};
/* Endpoint descriptors */
static const struct usb_epdesc_s g_fsepbulkoutdesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBMSC_EPOUTBULK_ADDR, /* addr */
USBMSC_EPOUTBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBMSC_FSBULKMAXPACKET),
MSBYTE(USBMSC_FSBULKMAXPACKET)
},
0 /* interval */
};
static const struct usb_epdesc_s g_fsepbulkindesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBMSC_EPINBULK_ADDR, /* addr */
USBMSC_EPINBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBMSC_FSBULKMAXPACKET),
MSBYTE(USBMSC_FSBULKMAXPACKET)
},
0 /* interval */
};
#ifdef CONFIG_USBDEV_DUALSPEED
#ifndef CONFIG_USBMSC_COMPOSITE
@ -184,32 +139,6 @@ static const struct usb_qualdesc_s g_qualdesc =
0, /* reserved */
};
#endif
static const struct usb_epdesc_s g_hsepbulkoutdesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBMSC_EPOUTBULK_ADDR, /* addr */
USBMSC_EPOUTBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBMSC_HSBULKMAXPACKET),
MSBYTE(USBMSC_HSBULKMAXPACKET)
},
0 /* interval */
};
static const struct usb_epdesc_s g_hsepbulkindesc =
{
USB_SIZEOF_EPDESC, /* len */
USB_DESC_TYPE_ENDPOINT, /* type */
USBMSC_EPINBULK_ADDR, /* addr */
USBMSC_EPINBULK_ATTR, /* attr */
{ /* maxpacket */
LSBYTE(USBMSC_HSBULKMAXPACKET),
MSBYTE(USBMSC_HSBULKMAXPACKET)
},
0 /* interval */
};
#endif
/****************************************************************************
@ -304,7 +233,7 @@ int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
}
/****************************************************************************
* Name: usbmsc_getepdesc
* Name: usbmsc_getdevdesc
*
* Description:
* Return a pointer to the raw device descriptor
@ -319,35 +248,90 @@ FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void)
#endif
/****************************************************************************
* Name: usbmsc_getepdesc
* Name: usbmsc_copy_epdesc
*
* Description:
* Return a pointer to the raw endpoint descriptor (used for configuring
* endpoints)
* Copies the requested Endpoint Description into the buffer given.
* Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ).
*
****************************************************************************/
FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid)
int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid,
FAR struct usb_epdesc_s *epdesc,
FAR struct usbdev_description_s *devdesc,
bool hispeed)
{
switch (epid)
{
case USBMSC_EPFSBULKOUT: /* Full speed bulk OUT endpoint descriptor */
return &g_fsepbulkoutdesc;
#ifndef CONFIG_USBDEV_DUALSPEED
/* unused */
case USBMSC_EPFSBULKIN: /* Full speed bulk IN endpoint descriptor */
return &g_fsepbulkindesc;
#ifdef CONFIG_USBDEV_DUALSPEED
case USBMSC_EPHSBULKOUT: /* High speed bulk OUT endpoint descriptor */
return &g_hsepbulkoutdesc;
case USBMSC_EPHSBULKIN: /* High speed bulk IN endpoint descriptor */
return &g_hsepbulkindesc;
(void)hispeed;
#endif
default:
return NULL;
switch (epid)
{
case USBMSC_EPBULKOUT: /* Bulk OUT endpoint */
{
epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
epdesc->addr = USBMSC_MKEPBULKOUT(devdesc); /* Endpoint address */
epdesc->attr = USBMSC_EPOUTBULK_ATTR; /* Endpoint attributes */
#ifdef CONFIG_USBDEV_DUALSPEED
if (hispeed)
{
/* Maximum packet size (high speed) */
epdesc->mxpacketsize[0] = LSBYTE(USBMSC_HSBULKMAXPACKET);
epdesc->mxpacketsize[1] = MSBYTE(USBMSC_HSBULKMAXPACKET);
}
else
#endif
{
/* Maximum packet size (full speed) */
epdesc->mxpacketsize[0] = LSBYTE(USBMSC_FSBULKMAXPACKET);
epdesc->mxpacketsize[1] = MSBYTE(USBMSC_FSBULKMAXPACKET);
}
epdesc->interval = 0; /* Interval */
}
break;
case USBMSC_EPBULKIN: /* Bulk IN endpoint */
{
epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
epdesc->addr = USBMSC_MKEPBULKIN(devdesc); /* Endpoint address */
epdesc->attr = USBMSC_EPINBULK_ATTR; /* Endpoint attributes */
#ifdef CONFIG_USBDEV_DUALSPEED
if (hispeed)
{
/* Maximum packet size (high speed) */
epdesc->mxpacketsize[0] = LSBYTE(USBMSC_HSBULKMAXPACKET);
epdesc->mxpacketsize[1] = MSBYTE(USBMSC_HSBULKMAXPACKET);
}
else
#endif
{
/* Maximum packet size (full speed) */
epdesc->mxpacketsize[0] = LSBYTE(USBMSC_FSBULKMAXPACKET);
epdesc->mxpacketsize[1] = MSBYTE(USBMSC_FSBULKMAXPACKET);
}
epdesc->interval = 0; /* Interval */
}
break;
default:
return 0;
}
};
COMPILE_TIME_ASSERTION(sizeof(struct usb_epdesc_s) == USB_SIZEOF_EPDESC);
return sizeof(struct usb_epdesc_s);
}
/****************************************************************************
* Name: usbmsc_mkcfgdesc
@ -358,53 +342,108 @@ FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid)
****************************************************************************/
#ifdef CONFIG_USBDEV_DUALSPEED
int16_t usbmsc_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type)
int16_t usbmsc_mkcfgdesc(uint8_t *buf,
FAR struct usbdev_description_s *devdesc,
uint8_t speed, uint8_t type)
#else
int16_t usbmsc_mkcfgdesc(uint8_t *buf)
int16_t usbmsc_mkcfgdesc(uint8_t *buf,
FAR struct usbdev_description_s *devdesc)
#endif
{
int length = 0;
bool hispeed = false;
#ifdef CONFIG_USBDEV_DUALSPEED
FAR const struct usb_epdesc_s *epdesc;
bool hispeed;
hispeed = (speed == USB_SPEED_HIGH);
/* Check for switches between high and full speed */
if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
{
hispeed = !hispeed;
}
#endif
/* Fill in all descriptors directly to the buf */
/* Configuration descriptor. If the USB mass storage device is
* configured as part of a composite device, then the configuration
* descriptor will be provided by the composite device logic.
*/
#ifndef CONFIG_USBMSC_COMPOSITE
memcpy(buf, &g_cfgdesc, USB_SIZEOF_CFGDESC);
buf += USB_SIZEOF_CFGDESC;
{
/* Configuration descriptor If the USB mass storage device is configured as part
* of a composite device, then the configuration descriptor will be provided by the
* composite device logic.
*/
FAR struct usb_cfgdesc_s *dest = (FAR struct usb_cfgdesc_s *)buf;
dest->len = USB_SIZEOF_CFGDESC; /* Descriptor length */
dest->type = USB_DESC_TYPE_CONFIG; /* Descriptor type */
dest->totallen[0] = LSBYTE(SIZEOF_USBMSC_CFGDESC); /* LS Total length */
dest->totallen[1] = MSBYTE(SIZEOF_USBMSC_CFGDESC); /* MS Total length */
dest->ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces */
dest->cfgvalue = USBMSC_CONFIGID; /* Configuration value */
dest->icfg = USBMSC_CONFIGSTRID; /* Configuration */
dest->attr = USB_CONFIG_ATTR_ONE | /* Attributes */
USBMSC_SELFPOWERED |
USBMSC_REMOTEWAKEUP;
dest->mxpower = (CONFIG_USBDEV_MAXPOWER + 1) / 2; /* Max power (mA/2) */
COMPILE_TIME_ASSERTION(sizeof(struct usb_cfgdesc_s) == USB_SIZEOF_CFGDESC);
buf += sizeof(struct usb_cfgdesc_s);
length += sizeof(struct usb_cfgdesc_s);
}
#endif
/* Copy the canned interface descriptor */
memcpy(buf, &g_ifdesc, USB_SIZEOF_IFDESC);
buf += USB_SIZEOF_IFDESC;
{
/* Single interface descriptor */
FAR struct usb_ifdesc_s * dest = (struct usb_ifdesc_s *)buf;
dest->len = USB_SIZEOF_IFDESC; /* Descriptor length */
dest->type = USB_DESC_TYPE_INTERFACE; /* Descriptor type */
dest->ifno = devdesc->ifnobase; /* Interface number */
dest->alt = USBMSC_ALTINTERFACEID; /* Alternate setting */
dest->neps = USBMSC_NENDPOINTS; /* Number of endpoints */
dest->classid = USB_CLASS_MASS_STORAGE; /* Interface class */
dest->subclass = USBMSC_SUBCLASS_SCSI; /* Interface sub-class */
dest->protocol = USBMSC_PROTO_BULKONLY; /* Interface protocol */
dest->iif = devdesc->strbase + USBMSC_INTERFACESTRID; /* iInterface */
COMPILE_TIME_ASSERTION(sizeof(struct usb_ifdesc_s) == USB_SIZEOF_IFDESC);
buf += sizeof(struct usb_ifdesc_s);
length += sizeof(struct usb_ifdesc_s);
}
/* Make the two endpoint configurations */
#ifdef CONFIG_USBDEV_DUALSPEED
/* Check for switches between high and full speed */
/* Bulk IN endpoint descriptor */
hispeed = (speed == USB_SPEED_HIGH);
if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
{
hispeed = !hispeed;
}
{
int len = usbmsc_copy_epdesc(USBMSC_EPBULKIN, (FAR struct usb_epdesc_s *)buf,
devdesc, hispeed);
epdesc = USBMSC_EPBULKINDESC(hispeed);
memcpy(buf, epdesc, USB_SIZEOF_EPDESC);
buf += USB_SIZEOF_EPDESC;
buf += len;
length += len;
}
epdesc = USBMSC_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
/* Bulk OUT endpoint descriptor */
{
int len = usbmsc_copy_epdesc(USBMSC_EPBULKOUT,
(FAR struct usb_epdesc_s *)buf, devdesc,
hispeed);
buf += len;
length += len;
}
return SIZEOF_USBMSC_CFGDESC;
}
@ -423,4 +462,3 @@ FAR const struct usb_qualdesc_s *usbmsc_getqualdesc(void)
return &g_qualdesc;
}
#endif

View File

@ -1,7 +1,7 @@
/********************************************************************************************
* include/nuttx/usb/cdc.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2011, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* References: "Universal Serial Bus Class Definitions for Communication
@ -73,7 +73,7 @@
/* Table 17: Communication Interface Class Control Protocol Codes */
#define CDC_PROTO_NONE 0x00 /* No class specific protocol required */
#define CDC_PROTO_ATM 0x01 /* Common AT commands (also known as Hayes compatible) */
#define CDC_PROTO_ATM 0x01 /* Common AT commands (also known as Hayes compatible) */
/* 0x02-0xfe Reserved (future use) */
#define CDC_PROTO_VENDOR 0xff /* Vendor-specific */
@ -242,12 +242,12 @@
* (Optional)
*/
#define ECM_SET_MCAST_FILTERS 0x40 /* As applications are loaded and unloaded on the host,
* the networking transport will instruct the devices MAC
* driver to change settings of the Networking devices
* the networking transport will instruct the device's MAC
* driver to change settings of the Networking device's
* multicast filters. (Optional)
*/
#define ECM_SET_PM_PAT_FILTER 0x41 /* Some hosts are able to conserve energy and stay quiet
* in a sleeping state while not being used. USB
* in a "sleeping" state while not being used. USB
* Networking devices may provide special pattern filtering
* hardware that enables it to wake up the attached host
* on demand when something is attempting to contact the
@ -588,20 +588,20 @@ struct cdc_funcdesc_s
/* Table 26: Class-Specific Descriptor Header Format */
struct cdc_hdr_funcdesc_s
begin_packed_struct struct cdc_hdr_funcdesc_s
{
uint8_t size; /* bFunctionLength, Size of this descriptor */
uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */
uint8_t subtype; /* bDescriptorSubType, CDC_DSUBTYPE_HDR as defined in Table 25 */
uint8_t cdc[2]; /* bcdCDC, USB Class Definitions for Communication Devices Specification release
* number in binary-coded decimal.
uint8_t cdc[2]; /* bcdCDC, USB Class Definitions for Communication Devices Specification
* release number in binary-coded decimal.
*/
};
} end_packed_struct;
#define SIZEOF_HDR_FUNCDESC 5
/* Table 27: Call Management Functional Descriptor */
struct cdc_callmgmt_funcdesc_s
begin_packed_struct struct cdc_callmgmt_funcdesc_s
{
uint8_t size; /* bFunctionLength, Size of this descriptor */
uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */
@ -610,18 +610,18 @@ struct cdc_callmgmt_funcdesc_s
uint8_t ifno; /* bDataInterface, Interface number of Data Class interface
* optionally used for call management
*/
};
} end_packed_struct;
#define SIZEOF_CALLMGMT_FUNCDESC 5
/* Table 28: Abstract Control Management Functional Descriptor */
struct cdc_acm_funcdesc_s
begin_packed_struct struct cdc_acm_funcdesc_s
{
uint8_t size; /* bFunctionLength, Size of this descriptor */
uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */
uint8_t subtype; /* bDescriptorSubType, CDC_DSUBTYPE_ACM as defined in Table 25 */
uint8_t caps; /* bmCapabilities: Bit encoded */
};
} end_packed_struct;
#define SIZEOF_ACM_FUNCDESC 4
/* Table 29: Direct Line Management Functional Descriptor */
@ -673,7 +673,7 @@ struct cdc_tcmc_funcdesc_s
/* Table 33: Union Interface Functional Descriptor */
struct cdc_union_funcdesc_s
begin_packed_struct struct cdc_union_funcdesc_s
{
uint8_t size; /* bFunctionLength, Size of this descriptor */
uint8_t type; /* bDescriptorType, USB_DESC_TYPE_CSINTERFACE */
@ -685,7 +685,7 @@ struct cdc_union_funcdesc_s
uint8_t slave[1]; /* bSlaveInterfaceN: Interface number of N slave or associated
* interface in the union
*/
};
} end_packed_struct;
#define SIZEOF_UNION_FUNCDESC(n) ((n)+4)
/* Table 34: Country Selection Functional Descriptor */
@ -788,7 +788,7 @@ struct cdc_capi_funcdesc_s
};
#define SIZEOF_CAPI_FUNCDESC 4
/* Table 41: Ethernet Networking Functional Descriptor*/
/* Table 41: Ethernet Networking Functional Descriptor */
struct cdc_ecm_funcdesc_s
{
@ -833,7 +833,7 @@ struct cdc_atm_funcdesc_s
* capable of supporting
*/
};
#define SIZEOF_CALLMGMT_FUNCDESC 12
#define SIZEOF_ATM_FUNCDESC 12
/* Descriptor Data Structures ***************************************************************/
/* Table 50: Line Coding Structure */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/usb/cdcacm.h
*
* Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -47,6 +47,7 @@
/****************************************************************************
* Preprocessor definitions
****************************************************************************/
/* Configuration ************************************************************/
/* CONFIG_CDCACM
* Enable compilation of the USB serial driver
@ -96,6 +97,22 @@
* Size of the serial receive/transmit buffers. Default 256.
*/
/* Informations needed in usbdev_description_s */
#define CDCACM_NUM_EPS (3)
#define CDCACM_EP_INTIN_IDX (0)
#define CDCACM_EP_BULKIN_IDX (1)
#define CDCACM_EP_BULKOUT_IDX (2)
#define CDCACM_NCONFIGS (1) /* Number of configurations supported */
/* Configuration descriptor values */
#define CDCACM_CONFIGID (1) /* The only supported configuration ID */
#define CDCACM_NINTERFACES (2) /* Number of interfaces in the configuration */
/* EP0 max packet size */
#ifndef CONFIG_CDCACM_EP0MAXPACKET
@ -106,8 +123,10 @@
* notification interrupt endpoint.
*/
#ifndef CONFIG_CDCACM_EPINTIN
# define CONFIG_CDCACM_EPINTIN 1
#ifndef CONFIG_CDCACM_COMPOSITE
# ifndef CONFIG_CDCACM_EPINTIN
# define CONFIG_CDCACM_EPINTIN 1
# endif
#endif
#ifndef CONFIG_CDCACM_EPINTIN_FSSIZE
@ -127,8 +146,10 @@
* size will be followed by a NULL packet.
*/
#ifndef CONFIG_CDCACM_EPBULKIN
# define CONFIG_CDCACM_EPBULKIN 2
#ifndef CONFIG_CDCACM_COMPOSITE
# ifndef CONFIG_CDCACM_EPBULKIN
# define CONFIG_CDCACM_EPBULKIN 2
# endif
#endif
#ifndef CONFIG_CDCACM_EPBULKIN_FSSIZE
@ -155,8 +176,10 @@
* maxpacket size.
*/
#ifndef CONFIG_CDCACM_EPBULKOUT
# define CONFIG_CDCACM_EPBULKOUT 3
#ifndef CONFIG_CDCACM_COMPOSITE
# ifndef CONFIG_CDCACM_EPBULKOUT
# define CONFIG_CDCACM_EPBULKOUT 3
# endif
#endif
#ifndef CONFIG_CDCACM_EPBULKOUT_FSSIZE
@ -326,7 +349,9 @@ typedef FAR void (*cdcacm_callback_t)(enum cdcacm_event_e event);
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE)
struct usbdevclass_driver_s;
int board_cdcclassobject(FAR struct usbdevclass_driver_s **classdev);
struct usbdev_description_s;
int board_cdcclassobject(int minor, FAR struct usbdev_description_s *devdesc,
FAR struct usbdevclass_driver_s **classdev);
#endif
/****************************************************************************
@ -370,7 +395,9 @@ void board_cdcuninitialize(FAR struct usbdevclass_driver_s *classdev);
****************************************************************************/
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE)
int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev);
struct usbdev_description_s;
int cdcacm_classobject(int minor, struct usbdev_description_s *devdesc,
FAR struct usbdevclass_driver_s **classdev);
#endif
/****************************************************************************
@ -425,6 +452,26 @@ void cdcacm_uninitialize(FAR struct usbdevclass_driver_s *classdev);
void cdcacm_uninitialize(FAR void *handle);
#endif
/****************************************************************************
* Name: cdcacm_get_composite_devdesc
*
* Description:
* Helper function to fill in some constants into the composite
* configuration struct.
*
* Input Parameters:
* dev - Pointer to the configuration struct we should fill
*
* Returned Value:
* None
*
****************************************************************************/
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE)
struct composite_devdesc_s;
void cdcacm_get_composite_devdesc(struct composite_devdesc_s *dev);
#endif
#undef EXTERN
#if defined(__cplusplus)
}

View File

@ -1,7 +1,7 @@
/************************************************************************************
* include/nuttx/usb/composite.h
*
* Copyright (C) 2008-2011, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2011, 2015, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -41,12 +41,14 @@
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/usb/usbdev.h>
#ifdef CONFIG_USBDEV_COMPOSITE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* CONFIG_USBDEV_COMPOSITE
* Enables USB composite device support
@ -70,6 +72,11 @@
* Interface version number.
*/
#define COMPOSITE_NSTRIDS (5) /* The numer of String-IDs to
* reserve for the composite device */
#define COMPOSITE_NCONFIGS (1) /* The number of configurations
* supported */
/****************************************************************************
* Public Types
****************************************************************************/
@ -113,7 +120,7 @@ extern "C"
*
****************************************************************************/
FAR void *composite_initialize(void);
FAR void *composite_initialize(uint8_t numDevices, struct composite_devdesc_s * pDevices);
/****************************************************************************
* Name: composite_uninitialize
@ -135,30 +142,6 @@ FAR void *composite_initialize(void);
void composite_uninitialize(FAR void *handle);
/****************************************************************************
* Name: composite_initialize
*
* Description:
* Register USB composite device as configured. This function will call
* board-specific implementations in order to obtain the class objects for
* each of the members of the composite (see board_mscclassobject(),
* board_cdcclassobjec(), ...)
*
* Input Parameter:
* None
*
* Returned Value:
* A non-NULL "handle" is returned on success. This handle may be used
* later with composite_uninitialize() in order to removed the composite
* device. This handle is the (untyped) internal representation of the
* the class driver instance.
*
* NULL is returned on any failure.
*
****************************************************************************/
FAR void *composite_initialize(void);
/****************************************************************************
* Name: composite_ep0submit
*

View File

@ -306,7 +306,7 @@ struct usb_devdesc_s
/* Configuration descriptor */
struct usb_cfgdesc_s
begin_packed_struct struct usb_cfgdesc_s
{
uint8_t len; /* Descriptor length */
uint8_t type; /* Descriptor type */
@ -316,7 +316,7 @@ struct usb_cfgdesc_s
uint8_t icfg; /* Configuration */
uint8_t attr; /* Attributes */
uint8_t mxpower; /* Max power (mA/2) */
};
} end_packed_struct;
#define USB_SIZEOF_CFGDESC 9
struct usb_otherspeedconfigdesc_s
@ -343,7 +343,7 @@ struct usb_strdesc_s
/* Interface descriptor */
struct usb_ifdesc_s
begin_packed_struct struct usb_ifdesc_s
{
uint8_t len; /* Descriptor length */
uint8_t type; /* Descriptor type */
@ -354,12 +354,12 @@ struct usb_ifdesc_s
uint8_t subclass; /* Interface sub-class */
uint8_t protocol; /* Interface protocol */
uint8_t iif; /* iInterface */
};
} end_packed_struct;
#define USB_SIZEOF_IFDESC 9
/* Endpoint descriptor */
struct usb_epdesc_s
begin_packed_struct struct usb_epdesc_s
{
uint8_t len; /* Descriptor length */
uint8_t type; /* Descriptor type */
@ -367,7 +367,7 @@ struct usb_epdesc_s
uint8_t attr; /* Endpoint attributes */
uint8_t mxpacketsize[2]; /* Maximum packet size */
uint8_t interval; /* Interval */
};
} end_packed_struct;
#define USB_SIZEOF_EPDESC 7
struct usb_audioepdesc_s
@ -404,7 +404,7 @@ struct usb_qualdesc_s
* interfaces.
*/
struct usb_iaddesc_s
begin_packed_struct struct usb_iaddesc_s
{
uint8_t len; /* Descriptor length */
uint8_t type; /* Descriptor type */
@ -414,7 +414,7 @@ struct usb_iaddesc_s
uint8_t subclass; /* Sub-class code */
uint8_t protocol; /* Protocol code */
uint8_t ifunction; /* Index to string identifying the function */
};
} end_packed_struct;
#define USB_SIZEOF_IADDESC 8
/************************************************************************************