mirror of
https://github.com/apache/nuttx.git
synced 2026-03-27 02:29:15 +08:00
[[This is part 1 or several commits]]
We developed a huge Changeset over a year ago to make USB Composite configuration dynamical and be able to instanciate the CDCACM multiple times inside this device. We use this feature to switch between one in normal and up to three CDCACMs in maintenance boot. The control path starts in “boardctl.c” where the configuration for the device is constructed. There are still a few issues which I’ll ask you to have a look at before this beast can be merged. 1. To be able to construct the data dynamically I have changed some USB-Structs to be packed. Maybe there are additional structs to change (just for completeness – not for current functionality). 2. I’ve added the Macro “COMPILE_TIME_ASSERTION” two times (in usbmsc_desc.c and in cdcacm_desc.c) to stay private. Maybe you’ll find a better place. It’s used to check the size of the structs against the assumptions. 3. I’ve changed the interface for some USB-Functions to receive also the dynamic configuration. Maybe this can be done more elegant. 4. The original NuttX (without the patch) seems to have problems with a Composite device holding a CDCACM and an MSC. The “USB SET CONFIGURATION” request does not to work at all. This makes the test fail under Windows and under Linux. Applying this patch doesn’t change anything – because it only changes the configuration – not the behavior. Maybe you’ll have a look at this problem before applying the patch.
This commit is contained in:
committed by
Gregory Nutt
parent
dc3a7e54a9
commit
dcc9b07715
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* configs/boardctl.c
|
||||
*
|
||||
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -181,8 +181,84 @@ static inline int boardctl_usbdevctrl(FAR struct boardioc_usbdev_ctrl_s *ctrl)
|
||||
|
||||
case BOARDIOC_USBDEV_CONNECT: /* Connect the Composite device */
|
||||
{
|
||||
/* Here we are composing the configuration of the usb composite device.
|
||||
*
|
||||
* The standard is to use one CDC/ACM and one USB mass storage device.
|
||||
*/
|
||||
|
||||
struct composite_devdesc_s dev[2];
|
||||
int ifnobase = 0;
|
||||
int strbase = COMPOSITE_NSTRIDS;
|
||||
|
||||
DEBUGASSERT(ctrl->handle != NULL);
|
||||
*ctrl->handle = composite_initialize();
|
||||
|
||||
/* Configure the CDC/ACM device */
|
||||
|
||||
/* Ask the cdcacm driver to fill in the constants we didn't
|
||||
* know here.
|
||||
*/
|
||||
|
||||
cdcacm_get_composite_devdesc(&dev[0]);
|
||||
|
||||
/* Overwrite and correct some values... */
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev[0].board_classobject = board_cdcclassobject;
|
||||
dev[0].board_uninitialize = board_cdcuninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[0].usb_dev_desc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[0].minor = CONFIG_SYSTEM_COMPOSITE_TTYUSB; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[0].usb_dev_desc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[0].usb_dev_desc.epno[CDCACM_EP_INTIN_IDX] = 3;
|
||||
dev[0].usb_dev_desc.epno[CDCACM_EP_BULKIN_IDX] = 4;
|
||||
dev[0].usb_dev_desc.epno[CDCACM_EP_BULKOUT_IDX] = 5;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[0].usb_dev_desc.ninterfaces;
|
||||
strbase += dev[0].usb_dev_desc.nstrings;
|
||||
|
||||
/* Configure the mass storage device device */
|
||||
/* Ask the usbmsc driver to fill in the constants we didn't
|
||||
* know here.
|
||||
*/
|
||||
|
||||
usbmsc_get_composite_devdesc(&dev[1]);
|
||||
|
||||
/* Overwrite and correct some values... */
|
||||
/* The callback functions for the USBMSC class */
|
||||
|
||||
dev[1].board_classobject = board_mscclassobject;
|
||||
dev[1].board_uninitialize = board_mscuninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[1].usb_dev_desc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[1].minor = CONFIG_SYSTEM_COMPOSITE_DEVMINOR1; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[1].usb_dev_desc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[1].usb_dev_desc.epno[USBMSC_EP_BULKIN_IDX] = 1;
|
||||
dev[1].usb_dev_desc.epno[USBMSC_EP_BULKOUT_IDX] = 2;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[1].usb_dev_desc.ninterfaces;
|
||||
strbase += dev[1].usb_dev_desc.nstrings;
|
||||
|
||||
*ctrl->handle = composite_initialize(2, dev);
|
||||
if (*ctrl->handle == NULL)
|
||||
{
|
||||
ret = -EIO;
|
||||
|
||||
@@ -322,33 +322,10 @@ menuconfig CDCACM_COMPOSITE
|
||||
Configure the CDC serial driver as part of a composite driver
|
||||
(only if USBDEV_COMPOSITE is also defined)
|
||||
|
||||
if CDCACM_COMPOSITE
|
||||
if !CDCACM_COMPOSITE
|
||||
|
||||
config CDCACM_IFNOBASE
|
||||
int "Offset the CDC/ACM interface numbers"
|
||||
default 0
|
||||
---help---
|
||||
If the CDC driver is part of a composite device, then this may need to
|
||||
be defined to offset the CDC/ACM interface numbers so that they are
|
||||
unique and contiguous. When used with the Mass Storage driver, the
|
||||
correct value for this offset is zero.
|
||||
|
||||
config CDCACM_STRBASE
|
||||
int "Offset the CDC/ACM string numbers"
|
||||
default 4
|
||||
---help---
|
||||
If the CDC driver is part of a composite device, then this may need to
|
||||
be defined to offset the CDC/ACM string numbers so that they are
|
||||
unique and contiguous. When used with the Mass Storage driver, the
|
||||
correct value for this offset is four (this value actuallly only needs
|
||||
to be defined if names are provided for the Notification interface,
|
||||
config CDCACM_NOTIFSTR, or the data interface, CDCACM_DATAIFSTR).
|
||||
|
||||
The default of four accounts for strings IDs 0-3 used by the composite
|
||||
descriptors. Any additional CDC/ACM string descripts must then begin
|
||||
with string index four.
|
||||
|
||||
endif
|
||||
# In a composite device the EP0 config comes from the composite device
|
||||
# and the EP-Number is configured dynamically via composite_initialize
|
||||
|
||||
config CDCACM_EP0MAXPACKET
|
||||
int "Endpoint 0 max packet size"
|
||||
@@ -363,6 +340,8 @@ config CDCACM_EPINTIN
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
interrupt IN operation. Default 1.
|
||||
|
||||
endif
|
||||
|
||||
config CDCACM_EPINTIN_FSSIZE
|
||||
int "Interupt IN full speed MAXPACKET size"
|
||||
default 64
|
||||
@@ -377,6 +356,11 @@ config CDCACM_EPINTIN_HSSIZE
|
||||
Max package size for the interrupt IN endpoint if high speed mode.
|
||||
Default 64.
|
||||
|
||||
if !CDCACM_COMPOSITE
|
||||
|
||||
# In a composite device the EP-Number is configured dynamically via
|
||||
# composite_initialize
|
||||
|
||||
config CDCACM_EPBULKOUT
|
||||
int "Bulk OUT endpoint number"
|
||||
default 3
|
||||
@@ -384,6 +368,8 @@ config CDCACM_EPBULKOUT
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
bulk OUT operation. Default: 3
|
||||
|
||||
endif
|
||||
|
||||
config CDCACM_EPBULKOUT_FSSIZE
|
||||
int "Bulk OUT full speed MAXPACKET size"
|
||||
default 64
|
||||
@@ -398,6 +384,11 @@ config CDCACM_EPBULKOUT_HSSIZE
|
||||
Max package size for the bulk OUT endpoint if high speed mode.
|
||||
Default 512.
|
||||
|
||||
if !CDCACM_COMPOSITE
|
||||
|
||||
# In a composite device the EP-Number is configured dynamically via
|
||||
# composite_initialize
|
||||
|
||||
config CDCACM_EPBULKIN
|
||||
int "Bulk IN endpoint number"
|
||||
default 2
|
||||
@@ -405,6 +396,8 @@ config CDCACM_EPBULKIN
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
bulk IN operation. Default: 2
|
||||
|
||||
endif
|
||||
|
||||
config CDCACM_EPBULKIN_FSSIZE
|
||||
int "Bulk IN full speed MAXPACKET size"
|
||||
default 64
|
||||
@@ -468,6 +461,11 @@ config CDCACM_TXBUFSIZE
|
||||
will hold one request of size 768; a buffer size of 193 will hold
|
||||
two requests of size 96 bytes.
|
||||
|
||||
if !CDCACM_COMPOSITE
|
||||
|
||||
# In a composite device the Vendor- and Product-ID is given by the composite
|
||||
# device
|
||||
|
||||
config CDCACM_VENDORID
|
||||
hex "Vendor ID"
|
||||
default 0x0525
|
||||
@@ -493,6 +491,7 @@ config CDCACM_PRODUCTSTR
|
||||
string "Product string"
|
||||
default "CDC/ACM Serial"
|
||||
|
||||
endif # !CDCACM_COMPOSITE
|
||||
endif # CDCACM
|
||||
|
||||
menuconfig USBMSC
|
||||
@@ -530,38 +529,17 @@ config USBMSC_COMPOSITE
|
||||
Configure the mass storage driver as part of a composite driver
|
||||
(only if USBDEV_COMPOSITE is also defined)
|
||||
|
||||
config USBMSC_IFNOBASE
|
||||
int "Offset the mass storage interface number"
|
||||
default 2
|
||||
depends on USBMSC_COMPOSITE
|
||||
---help---
|
||||
If the CDC driver is part of a composite device, then this may need to
|
||||
be defined to offset the mass storage interface number so that it is
|
||||
unique and contiguous. When used with the CDC/ACM driver, the
|
||||
correct value for this offset is two (because of the two CDC/ACM
|
||||
interfaces that will precede it).
|
||||
|
||||
config USBMSC_STRBASE
|
||||
int "Offset the mass storage string numbers"
|
||||
default 4
|
||||
depends on USBMSC_COMPOSITE
|
||||
---help---
|
||||
If the CDC driver is part of a composite device, then this may need to
|
||||
be defined to offset the mass storage string numbers so that they are
|
||||
unique and contiguous. When used with the CDC/ACM driver, the
|
||||
correct value for this offset is four (or perhaps 5 or 6, depending
|
||||
on if CDCACM_NOTIFSTR or CDCACM_DATAIFSTR are defined).
|
||||
|
||||
String IDS 0-3 are used by the composite descriptors. This amount
|
||||
may need to be incremented to account for string IDs used by other
|
||||
members of the composite.
|
||||
|
||||
config USBMSC_EP0MAXPACKET
|
||||
int "Max packet size for endpoint 0"
|
||||
default 64
|
||||
---help---
|
||||
Max packet size for endpoint 0
|
||||
|
||||
if !USBMSC_COMPOSITE
|
||||
|
||||
# In a composite device the EP-Number and STR-Number is configured
|
||||
# dynamically via composite_initialize
|
||||
|
||||
config USBMSC_EPBULKOUT
|
||||
int "Bulk OUT endpoint number"
|
||||
default 2
|
||||
@@ -576,6 +554,8 @@ config USBMSC_EPBULKIN
|
||||
The logical 7-bit address of a hardware endpoints that support
|
||||
bulk OUT and IN operations
|
||||
|
||||
endif
|
||||
|
||||
config USBMSC_NWRREQS
|
||||
int "The number of write requests that can be in flight"
|
||||
default 4
|
||||
@@ -613,6 +593,11 @@ config USBMSC_BULKOUTREQLEN
|
||||
beyond the maximum size of one packet. Default: 512 or 64 bytes
|
||||
(depending upon if dual speed operation is supported or not).
|
||||
|
||||
if !USBMSC_COMPOSITE
|
||||
|
||||
# In a composite device the Vendor- and Product-IDs are handled by the
|
||||
# composite device
|
||||
|
||||
config USBMSC_VENDORID
|
||||
hex "Mass storage Vendor ID"
|
||||
default 0x584e
|
||||
@@ -638,6 +623,8 @@ config USBMSC_PRODUCTSTR
|
||||
string "Mass storage product string"
|
||||
default "Mass Storage"
|
||||
|
||||
endif # !USBMSC_COMPOSITE
|
||||
|
||||
config USBMSC_VERSIONNO
|
||||
hex "USB MSC Version Number"
|
||||
default "0x399"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/usbdev/cdcacm.c
|
||||
*
|
||||
* Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011-2013, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
#include "cdcacm.h"
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
#ifdef CONFIG_CDCACM_COMPOSITE
|
||||
# include <nuttx/usb/composite.h>
|
||||
# include "composite.h"
|
||||
#endif
|
||||
@@ -105,6 +105,8 @@ struct cdcacm_dev_s
|
||||
FAR struct usbdev_req_s *ctrlreq; /* Allocated control request */
|
||||
struct sq_queue_s reqlist; /* List of write request containers */
|
||||
|
||||
struct usbdev_description_s devdesc;
|
||||
|
||||
/* Pre-allocated write request containers. The write requests will
|
||||
* be linked in a free list (reqlist), and used to send requests to
|
||||
* EPBULKIN; Read requests will be queued in the EBULKOUT.
|
||||
@@ -157,10 +159,10 @@ static void cdcacm_freereq(FAR struct usbdev_ep_s *ep,
|
||||
/* Configuration ***********************************************************/
|
||||
|
||||
static void cdcacm_resetconfig(FAR struct cdcacm_dev_s *priv);
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
static int cdcacm_epconfigure(FAR struct usbdev_ep_s *ep,
|
||||
enum cdcacm_epdesc_e epid, uint16_t mxpacket, bool last);
|
||||
#endif
|
||||
enum cdcacm_epdesc_e epid, bool last,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
bool hispeed);
|
||||
static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv,
|
||||
uint8_t config);
|
||||
|
||||
@@ -623,16 +625,15 @@ static void cdcacm_resetconfig(FAR struct cdcacm_dev_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
static int cdcacm_epconfigure(FAR struct usbdev_ep_s *ep,
|
||||
enum cdcacm_epdesc_e epid, uint16_t mxpacket,
|
||||
bool last)
|
||||
enum cdcacm_epdesc_e epid, bool last,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
bool hispeed)
|
||||
{
|
||||
struct usb_epdesc_s epdesc;
|
||||
cdcacm_mkepdesc(epid, mxpacket, &epdesc);
|
||||
cdcacm_copy_epdesc(epid, &epdesc, devdesc, hispeed);
|
||||
return EP_CONFIGURE(ep, &epdesc, last);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_setconfig
|
||||
@@ -690,14 +691,14 @@ static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv, uint8_t config)
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
if (priv->usbdev->speed == USB_SPEED_HIGH)
|
||||
{
|
||||
ret = cdcacm_epconfigure(priv->epintin, CDCACM_EPINTIN,
|
||||
CONFIG_CDCACM_EPINTIN_HSSIZE, false);
|
||||
ret = cdcacm_epconfigure(priv->epintin, CDCACM_EPINTIN, false,
|
||||
&priv->devdesc, true);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = EP_CONFIGURE(priv->epintin,
|
||||
cdcacm_getepdesc(CDCACM_EPINTIN), false);
|
||||
ret = cdcacm_epconfigure(priv->epintin, CDCACM_EPINTIN, false,
|
||||
&priv->devdesc, false);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
@@ -713,14 +714,14 @@ static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv, uint8_t config)
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
if (priv->usbdev->speed == USB_SPEED_HIGH)
|
||||
{
|
||||
ret = cdcacm_epconfigure(priv->epbulkin, CDCACM_EPBULKIN,
|
||||
CONFIG_CDCACM_EPBULKIN_HSSIZE, false);
|
||||
ret = cdcacm_epconfigure(priv->epbulkin, CDCACM_EPBULKIN, false,
|
||||
&priv->devdesc, true);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = EP_CONFIGURE(priv->epbulkin,
|
||||
cdcacm_getepdesc(CDCACM_EPBULKIN), false);
|
||||
ret = cdcacm_epconfigure(priv->epbulkin, CDCACM_EPBULKIN, false,
|
||||
&priv->devdesc, false);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
@@ -736,14 +737,14 @@ static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv, uint8_t config)
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
if (priv->usbdev->speed == USB_SPEED_HIGH)
|
||||
{
|
||||
ret = cdcacm_epconfigure(priv->epbulkout, CDCACM_EPBULKOUT,
|
||||
CONFIG_CDCACM_EPBULKOUT_HSSIZE, true);
|
||||
ret = cdcacm_epconfigure(priv->epbulkout, CDCACM_EPBULKOUT, true,
|
||||
&priv->devdesc, true);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = EP_CONFIGURE(priv->epbulkout,
|
||||
cdcacm_getepdesc(CDCACM_EPBULKOUT), true);
|
||||
ret = cdcacm_epconfigure(priv->epbulkout, CDCACM_EPBULKOUT, true,
|
||||
&priv->devdesc, false);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
@@ -967,7 +968,7 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
* EP0).
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
#ifndef CONFIG_CDCACM_COMPOSITE
|
||||
dev->ep0->priv = priv;
|
||||
#endif
|
||||
|
||||
@@ -992,7 +993,8 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
|
||||
/* Pre-allocate the IN interrupt endpoint */
|
||||
|
||||
priv->epintin = DEV_ALLOCEP(dev, CDCACM_EPINTIN_ADDR, true, USB_EP_ATTR_XFER_INT);
|
||||
priv->epintin = DEV_ALLOCEP(dev, CDCACM_MKEPINTIN(&priv->devdesc),
|
||||
true, USB_EP_ATTR_XFER_INT);
|
||||
if (!priv->epintin)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINALLOCFAIL), 0);
|
||||
@@ -1004,7 +1006,8 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
|
||||
/* Pre-allocate the IN bulk endpoint */
|
||||
|
||||
priv->epbulkin = DEV_ALLOCEP(dev, CDCACM_EPINBULK_ADDR, true, USB_EP_ATTR_XFER_BULK);
|
||||
priv->epbulkin = DEV_ALLOCEP(dev, CDCACM_MKEPBULKIN(&priv->devdesc),
|
||||
true, USB_EP_ATTR_XFER_BULK);
|
||||
if (!priv->epbulkin)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINALLOCFAIL), 0);
|
||||
@@ -1016,7 +1019,8 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
|
||||
/* Pre-allocate the OUT bulk endpoint */
|
||||
|
||||
priv->epbulkout = DEV_ALLOCEP(dev, CDCACM_EPOUTBULK_ADDR, false, USB_EP_ATTR_XFER_BULK);
|
||||
priv->epbulkout = DEV_ALLOCEP(dev, CDCACM_MKEPBULKOUT(&priv->devdesc),
|
||||
false, USB_EP_ATTR_XFER_BULK);
|
||||
if (!priv->epbulkout)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTALLOCFAIL), 0);
|
||||
@@ -1342,7 +1346,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
ret = cdcacm_mkcfgdesc(ctrlreq->buf, dev->speed, ctrl->req);
|
||||
#else
|
||||
ret = cdcacm_mkcfgdesc(ctrlreq->buf);
|
||||
ret = cdcacm_mkcfgdesc(ctrlreq->buf, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -1403,8 +1407,10 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE &&
|
||||
priv->config == CDCACM_CONFIGID)
|
||||
{
|
||||
if ((index == CDCACM_NOTIFID && value == CDCACM_NOTALTIFID) ||
|
||||
(index == CDCACM_DATAIFID && value == CDCACM_DATAALTIFID))
|
||||
if ((index == priv->devdesc.ifnobase &&
|
||||
value == CDCACM_NOTALTIFID) ||
|
||||
(index == (priv->devdesc.ifnobase + 1) &&
|
||||
value == CDCACM_DATAALTIFID))
|
||||
{
|
||||
cdcacm_resetconfig(priv);
|
||||
cdcacm_setconfig(priv, priv->config);
|
||||
@@ -1419,8 +1425,10 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
if (ctrl->type == (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE) &&
|
||||
priv->config == CDCACM_CONFIGIDNONE)
|
||||
{
|
||||
if ((index == CDCACM_NOTIFID && value == CDCACM_NOTALTIFID) ||
|
||||
(index == CDCACM_DATAIFID && value == CDCACM_DATAALTIFID))
|
||||
if ((index == priv->devdesc.ifnobase &&
|
||||
value == CDCACM_NOTALTIFID) ||
|
||||
(index == (priv->devdesc.ifnobase + 1) &&
|
||||
value == CDCACM_DATAALTIFID))
|
||||
{
|
||||
*(FAR uint8_t *) ctrlreq->buf = value;
|
||||
ret = 1;
|
||||
@@ -1454,7 +1462,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
case ACM_GET_LINE_CODING:
|
||||
{
|
||||
if (ctrl->type == (USB_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) &&
|
||||
index == CDCACM_NOTIFID)
|
||||
index == priv->devdesc.ifnobase)
|
||||
{
|
||||
/* Return the current line status from the private data structure */
|
||||
|
||||
@@ -1463,7 +1471,8 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
else
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->type);
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ),
|
||||
ctrl->type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1476,7 +1485,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
{
|
||||
if (ctrl->type == (USB_DIR_OUT | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) &&
|
||||
len == SIZEOF_CDC_LINECODING && /* dataout && len == outlen && */
|
||||
index == CDCACM_NOTIFID)
|
||||
index == priv->devdesc.ifnobase)
|
||||
{
|
||||
/* Save the new line coding in the private data structure. NOTE:
|
||||
* that this is conditional now because not all device controller
|
||||
@@ -1516,7 +1525,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
case ACM_SET_CTRL_LINE_STATE:
|
||||
{
|
||||
if (ctrl->type == (USB_DIR_OUT | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) &&
|
||||
index == CDCACM_NOTIFID)
|
||||
index == priv->devdesc.ifnobase)
|
||||
{
|
||||
/* Save the control line state in the private data structure. Only bits
|
||||
* 0 and 1 have meaning. Respond with a zero length packet.
|
||||
@@ -1546,7 +1555,7 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
case ACM_SEND_BREAK:
|
||||
{
|
||||
if (ctrl->type == (USB_DIR_OUT | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE) &&
|
||||
index == CDCACM_NOTIFID)
|
||||
index == priv->devdesc.ifnobase)
|
||||
{
|
||||
/* If there is a registered callback to handle the SendBreak request,
|
||||
* then callout now. Respond with a zero length packet.
|
||||
@@ -2312,7 +2321,8 @@ static bool cdcuart_txempty(FAR struct uart_dev_s *dev)
|
||||
#ifndef CONFIG_CDCACM_COMPOSITE
|
||||
static
|
||||
#endif
|
||||
int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev)
|
||||
int cdcacm_classobject(int minor, FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
FAR struct cdcacm_alloc_s *alloc;
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
@@ -2340,6 +2350,8 @@ int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev)
|
||||
sq_init(&priv->reqlist);
|
||||
|
||||
priv->minor = minor;
|
||||
memcpy(&priv->devdesc, devdesc,
|
||||
sizeof(struct usbdev_description_s));
|
||||
|
||||
/* Fake line status */
|
||||
|
||||
@@ -2427,11 +2439,31 @@ errout_with_class:
|
||||
int cdcacm_initialize(int minor, FAR void **handle)
|
||||
{
|
||||
FAR struct usbdevclass_driver_s *drvr = NULL;
|
||||
struct usbdev_description_s devdesc;
|
||||
int ret;
|
||||
|
||||
memset(&devdesc, 0, sizeof(struct usbdev_description_s));
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
devdesc.ninterfaces = CDCACM_NINTERFACES; /* Number of interfaces in the configuration */
|
||||
devdesc.ifnobase = 0; /* Offset to Interface-IDs */
|
||||
|
||||
/* Strings */
|
||||
|
||||
devdesc.nstrings = CDCACM_NSTRIDS; /* Number of Strings */
|
||||
devdesc.strbase = 0; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
devdesc.nendpoints = CDCACM_NUM_EPS;
|
||||
devdesc.epno[CDCACM_EP_INTIN_IDX] = 0;
|
||||
devdesc.epno[CDCACM_EP_BULKIN_IDX] = 1;
|
||||
devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 2;
|
||||
|
||||
/* Get an instance of the serial driver class object */
|
||||
|
||||
ret = cdcacm_classobject(minor, &drvr);
|
||||
ret = cdcacm_classobject(minor, &devdesc, &drvr);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Register the USB serial class driver */
|
||||
@@ -2549,3 +2581,60 @@ void cdcacm_uninitialize(FAR void *handle)
|
||||
priv->minor = (uint8_t)-1;
|
||||
#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)
|
||||
void cdcacm_get_composite_devdesc(struct composite_devdesc_s *dev)
|
||||
{
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev->mkconfdesc = cdcacm_mkcfgdesc;
|
||||
dev->mkstrdesc = cdcacm_mkstrdesc;
|
||||
dev->board_classobject = 0;
|
||||
dev->board_uninitialize = 0;
|
||||
|
||||
dev->nconfigs = CDCACM_NCONFIGS; /* Number of configurations supported */
|
||||
dev->configid = CDCACM_CONFIGID; /* The only supported configuration ID */
|
||||
|
||||
/* Let the construction function calculate the size of the config descriptor */
|
||||
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
dev->cfgdescsize = cdcacm_mkcfgdesc(NULL, NULL, USB_SPEED_UNKNOWN, 0);
|
||||
#else
|
||||
dev->cfgdescsize = cdcacm_mkcfgdesc(NULL, NULL);
|
||||
#endif
|
||||
|
||||
dev->minor = 0; /* The minor interface number */
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev->devdesc.ninterfaces = CDCACM_NINTERFACES; /* Number of interfaces in the configuration */
|
||||
dev->devdesc.ifnobase = 0; /* Offset to Interface-IDs */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev->devdesc.nstrings = CDCACM_NSTRIDS; /* Number of Strings */
|
||||
dev->devdesc.strbase = 0; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev->devdesc.nendpoints = CDCACM_NUM_EPS;
|
||||
dev->devdesc.epno[CDCACM_EP_INTIN_IDX] = 0;
|
||||
dev->devdesc.epno[CDCACM_EP_BULKIN_IDX] = 0;
|
||||
dev->devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/usbdev/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
|
||||
@@ -104,16 +104,9 @@
|
||||
* CDCACM_DATAALTIFID No alternate for the data interface
|
||||
*/
|
||||
|
||||
#define CDCACM_NINTERFACES (2) /* Number of interfaces in the configuration */
|
||||
#define CDCACM_NOTIFID (CONFIG_CDCACM_IFNOBASE+0)
|
||||
#define CDCACM_NOTALTIFID (0)
|
||||
#define CDCACM_DATAIFID (CONFIG_CDCACM_IFNOBASE+1)
|
||||
#define CDCACM_DATAALTIFID (0)
|
||||
|
||||
/* Configuration descriptor values */
|
||||
|
||||
#define CDCACM_CONFIGID (1) /* The only supported configuration ID */
|
||||
|
||||
/* Buffer big enough for any of our descriptors (the config descriptor is the
|
||||
* biggest).
|
||||
*/
|
||||
@@ -124,7 +117,6 @@
|
||||
/* Device descriptor values */
|
||||
|
||||
#define CDCACM_VERSIONNO (0x0101) /* Device version number 1.1 (BCD) */
|
||||
#define CDCACM_NCONFIGS (1) /* Number of configurations supported */
|
||||
|
||||
/* String language */
|
||||
|
||||
@@ -165,62 +157,16 @@
|
||||
#define CDCACM_LASTSTRID CDCACM_DATAIFSTRID
|
||||
#define CDCACM_NSTRIDS (CDCACM_LASTSTRID - CDCACM_STRBASE)
|
||||
|
||||
/* Configuration descriptor size */
|
||||
|
||||
#if !defined(CONFIG_CDCACM_COMPOSITE)
|
||||
|
||||
/* Number of individual descriptors in the configuration descriptor:
|
||||
* Configuration descriptor + (2) interface descriptors + (3) endpoint
|
||||
* descriptors + (3) ACM descriptors.
|
||||
*/
|
||||
|
||||
# define CDCACM_CFGGROUP_SIZE (9)
|
||||
|
||||
/* The size of the config descriptor: (9 + 2*9 + 3*7 + 4 + 5 + 5) = 62 */
|
||||
|
||||
# define SIZEOF_CDCACM_CFGDESC \
|
||||
(USB_SIZEOF_CFGDESC + 2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + \
|
||||
SIZEOF_ACM_FUNCDESC + SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
|
||||
|
||||
#elif defined(CONFIG_COMPOSITE_IAD)
|
||||
|
||||
/* Number of individual descriptors in the configuration descriptor:
|
||||
* (1) interface association descriptor + (2) interface descriptors +
|
||||
* (3) endpoint descriptors + (3) ACM descriptors.
|
||||
*/
|
||||
|
||||
# define CDCACM_CFGGROUP_SIZE (9)
|
||||
|
||||
/* The size of the config descriptor: (8 + 2*9 + 3*7 + 4 + 5 + 5) = 61 */
|
||||
|
||||
# define SIZEOF_CDCACM_CFGDESC \
|
||||
(USB_SIZEOF_IADDESC +2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + \
|
||||
SIZEOF_ACM_FUNCDESC + SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
|
||||
|
||||
#else
|
||||
|
||||
/* Number of individual descriptors in the configuration descriptor:
|
||||
* (2) interface descriptors + (3) endpoint descriptors + (3) ACM descriptors.
|
||||
*/
|
||||
|
||||
# define CDCACM_CFGGROUP_SIZE (8)
|
||||
|
||||
/* The size of the config descriptor: (2*9 + 3*7 + 4 + 5 + 5) = 53 */
|
||||
|
||||
# define SIZEOF_CDCACM_CFGDESC \
|
||||
(2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + SIZEOF_ACM_FUNCDESC + \
|
||||
SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
|
||||
#endif
|
||||
|
||||
/* Endpoint configuration ****************************************************/
|
||||
|
||||
#define CDCACM_EPINTIN_ADDR (USB_DIR_IN | CONFIG_CDCACM_EPINTIN)
|
||||
#define CDCACM_MKEPINTIN(desc) (USB_DIR_IN | (desc)->epno[CDCACM_EP_INTIN_IDX])
|
||||
#define CDCACM_EPINTIN_ATTR (USB_EP_ATTR_XFER_INT)
|
||||
|
||||
#define CDCACM_EPOUTBULK_ADDR (CONFIG_CDCACM_EPBULKOUT)
|
||||
#define CDCACM_MKEPBULKIN(desc) (USB_DIR_IN | (desc)->epno[CDCACM_EP_BULKIN_IDX])
|
||||
#define CDCACM_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
|
||||
|
||||
#define CDCACM_EPINBULK_ADDR (USB_DIR_IN | CONFIG_CDCACM_EPBULKIN)
|
||||
#define CDCACM_MKEPBULKOUT(desc) ((desc)->epno[CDCACM_EP_BULKOUT_IDX])
|
||||
#define CDCACM_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK)
|
||||
|
||||
/* Device driver definitions ************************************************/
|
||||
@@ -287,7 +233,7 @@ enum cdcacm_epdesc_e
|
||||
int cdcacm_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_getepdesc
|
||||
* Name: cdcacm_getdevdesc
|
||||
*
|
||||
* Description:
|
||||
* Return a pointer to the raw device descriptor
|
||||
@@ -299,28 +245,18 @@ FAR const struct usb_devdesc_s *cdcacm_getdevdesc(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_getepdesc
|
||||
* Name: cdcacm_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 *cdcacm_getepdesc(enum cdcacm_epdesc_e epid);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_mkepdesc
|
||||
*
|
||||
* Description:
|
||||
* Construct the endpoint descriptor using the correct max packet size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
void cdcacm_mkepdesc(enum cdcacm_epdesc_e epid,
|
||||
uint16_t mxpacket, FAR struct usb_epdesc_s *outdesc);
|
||||
#endif
|
||||
int cdcacm_copy_epdesc(enum cdcacm_epdesc_e epid,
|
||||
FAR struct usb_epdesc_s *epdesc,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
bool hispeed);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_mkcfgdesc
|
||||
@@ -331,9 +267,10 @@ void cdcacm_mkepdesc(enum cdcacm_epdesc_e epid,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type);
|
||||
int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, struct usbdev_description_s *devdesc,
|
||||
uint8_t speed, uint8_t type);
|
||||
#else
|
||||
int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf);
|
||||
int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, struct usbdev_description_s *devdesc);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* include/nuttx/usb/usbmsc.h
|
||||
*
|
||||
* Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2010, 2012, 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* NOTE: This interface was inspired by the Linux gadget interface by
|
||||
@@ -56,6 +56,17 @@
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* Informations about the device needed in usbdev_description_s */
|
||||
|
||||
#define USBMSC_CONFIGID (1) /* The only supported configuration ID */
|
||||
#define USBMSC_NENDPOINTS (2) /* Number of endpoints in the interface */
|
||||
|
||||
#define USBMSC_EP_BULKIN_IDX (0)
|
||||
#define USBMSC_EP_BULKOUT_IDX (1)
|
||||
|
||||
#define USBMSC_NCONFIGS (1) /* Number of configurations supported */
|
||||
#define USBMSC_NINTERFACES (1) /* Number of interfaces in the configuration */
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
@@ -102,10 +113,11 @@ extern "C"
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE)
|
||||
struct usbdevclass_driver_s;
|
||||
int board_mscclassobject(FAR struct usbdevclass_driver_s **classdev);
|
||||
int board_mscclassobject(int minor, FAR struct usbdev_description_s *usb_dev_desc,
|
||||
FAR struct usbdevclass_driver_s **classdev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
/************************************************************************************
|
||||
* Name: board_mscuninitialize
|
||||
*
|
||||
* Description:
|
||||
@@ -120,7 +132,7 @@ int board_mscclassobject(FAR struct usbdevclass_driver_s **classdev);
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE)
|
||||
struct usbdevclass_driver_s;
|
||||
@@ -149,7 +161,7 @@ void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev);
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int usbmsc_configure(unsigned int nluns, void **handle);
|
||||
int usbmsc_configure(unsigned int nluns, FAR void **handle);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: usbmsc_bindlun
|
||||
@@ -222,13 +234,13 @@ int usbmsc_exportluns(FAR void *handle);
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE)
|
||||
struct usbdevclass_driver_s;
|
||||
int usbmsc_classobject(FAR void *handle, FAR struct usbdevclass_driver_s **classdev);
|
||||
int usbmsc_classobject(FAR void *handle, FAR struct usbdev_description_s *usb_dev_desc,
|
||||
FAR struct usbdevclass_driver_s **classdev);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
@@ -250,6 +262,26 @@ int usbmsc_classobject(FAR void *handle, FAR struct usbdevclass_driver_s **class
|
||||
|
||||
void usbmsc_uninitialize(FAR void *handle);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: usbmsc_get_composite_devdesc
|
||||
*
|
||||
* Description:
|
||||
* Helper function to fill in some constants into the composite configuration
|
||||
* structure.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Pointer to the configuration struct we should fill
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE)
|
||||
struct composite_devdesc_s;
|
||||
void usbmsc_get_composite_devdesc(FAR struct composite_devdesc_s *dev);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user