mirror of
https://github.com/apache/nuttx.git
synced 2026-03-27 10:39:28 +08:00
Squashed commit of the following:
commit69fcf3e849Author: Alan Carvalho de Assis <acassis@gmail.com> Date: Sun Jul 16 08:39:33 2017 -0600 Fix spark/stm32_composite.c: board_composite_connect cannot be static commit28eb253401Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 08:36:01 2017 -0600 Composite: Final review for coding style before merge commite6af1b9994Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 07:41:38 2017 -0600 Composite: Simplify some intiialization of data structures. commit771c367411Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 07:15:08 2017 -0600 Cosmetic changes to alignment. commit5d67ddda4eAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 07:00:48 2017 -0600 USBMSC: Add missing logic to saved device description. commit0729151d29Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 17:11:41 2017 -0600 Trivial, costmetic commit74b916ff84Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 14:50:29 2017 -0600 Composite: Private functions need to be marked static. Move static functions out of 'Public Functions' to 'Private Functions' where they belong. Disable composite configuration 1 in all STM32 F1 configurations. commitcfaa4ece13Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 13:20:34 2017 -0600 Add some comments. commit8143563be6Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 12:33:10 2017 -0600 Spark: Need to condition out MSC logic in composite setup if there is no MSC in the composite. commit69d3a91ef1Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 11:03:33 2017 -0600 Composite: Remove all dependencies on CONFIG_SYSTEM_COMPOSITE_* configuration settings. Nothing in the OS can depend on external application settings. commit55a4388bbdAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 09:59:31 2017 -0600 All composite configurations now also support a dual CDC/ACM configuration. commit428f2147afAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 09:24:32 2017 -0600 Composite: Move board_msc* interfaces from apps/system/composite to the board specific OS logic where they belong. commitf1cc168a5cAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 08:56:33 2017 -0600 Refresh all composite configurations. commit246afcaa10Merge:919877191d02c6672868Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 08:22:26 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit919877191dAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 08:20:02 2017 -0600 Composite setup: Remove useless board_cdc* wrapper. commit82129cf8c6Merge:f2cb8b252a6537e4ea20Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 16:23:57 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitf2cb8b252aAuthor: Alan Carvalho de Assis <acassis@gmail.com> Date: Fri Jul 14 10:19:35 2017 -0600 Composite: Fix for another cloned typo. commit676cfd526aAuthor: Alan Carvalho de Assis <acassis@gmail.com> Date: Fri Jul 14 09:11:37 2017 -0600 Composite: Fix some typos commit1ea0368c18Author: Alan Carvalho de Assis <acassis@gmail.com> Date: Fri Jul 14 09:10:18 2017 -0600 Composite: ./stm3210e-eval/src/stm32_composite.c commite485caced9Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 09:08:17 2017 -0600 Composite: I don't think the original code should have forced minor=0. commit6443c29621Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 07:15:38 2017 -0600 Composite: Flesh out support for all of other configurations that support composite. commit23cbc28b05Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 06:59:45 2017 -0600 Detangle use of board_xyzclassobject() and board_xyzuninitialize() commit1674cb8c8eMerge:6bc881a1925033a6def7Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 13 13:57:40 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit6bc881a192Merge:fe3af4941d85b8d16d8cAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 11 12:24:07 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitfe3af4941dMerge:0f9ad16e181bc0eea143Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 10 11:07:36 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit0f9ad16e18Merge:a4cd90d4efaa2e9c15a5Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 7 20:26:53 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commita4cd90d4efMerge:8a4be7175e31f832d8c5Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 5 11:12:52 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit8a4be7175eMerge:18a32ed2caae1771454aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 30 16:14:04 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit18a32ed2caMerge:aaa81ce4976d8df90b79Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 29 10:18:16 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitaaa81ce497Merge:4eb548226b8cb4636bb1Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 26 11:56:11 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit4eb548226bMerge:2327f5a1b4dc8eec0b61Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 19 17:27:00 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit2327f5a1b4Merge:49cd279fc699bf0b522bAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 16 17:30:03 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit49cd279fc6Merge:bb6a13f30a46f86982eeAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jun 14 09:17:49 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitbb6a13f30aMerge:918480047aac93d4bda9Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 5 17:40:06 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit918480047aMerge:e4d262436c4526cd665eAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jun 3 08:52:31 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commite4d262436cAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 2 07:19:27 2017 -0600 SAMV71-Xult Composite: Now can switch between two different composite configurations dynamically. commit815257743dAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 2 07:11:57 2017 -0600 usbdev composite and SAMV7-Xult: Move board-specific USB composite configuration out of boardctl.c and into board-specific logic where it belongs. Add a configuration option to the boardctl() calls to support multiple composite device configurations dynamically. commitac13619dc5Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 17:03:58 2017 -0600 Cosmetic commit9dd41bdd2fAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 17:02:43 2017 -0600 Composite: More compile-related fixes commitfc1438c95dMerge:049ccbfcbeff2b54a5e0Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:35:41 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit049ccbfcbeAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:35:16 2017 -0600 Composite: Add some structure definitions missed in first application of the patch. commitef33329e3aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:14:46 2017 -0600 Add a warning commit89f77cd91aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:11:27 2017 -0600 Fix some incomplete name changes commit0bb7af549aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 15:09:50 2017 -0600 It is unnecessary to pack a structure that consists only of uint8_t data fields. commitbd9b548914Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 15:05:41 2017 -0600 Remove COMPILE_TIME_ASSERTION commit7e6f481581Author: Frank Benkert <Frank.Benkert@avat.de> Date: Thu Jun 1 14:58:04 2017 -0600 Part II of the same big commit commitdcc9b07715Author: Frank Benkert <Frank.Benkert@avat.de> Date: Thu Jun 1 14:08:22 2017 -0600 [[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
02c6672868
commit
eacb4f0e84
@@ -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
|
||||
@@ -182,7 +182,10 @@ static inline int boardctl_usbdevctrl(FAR struct boardioc_usbdev_ctrl_s *ctrl)
|
||||
case BOARDIOC_USBDEV_CONNECT: /* Connect the Composite device */
|
||||
{
|
||||
DEBUGASSERT(ctrl->handle != NULL);
|
||||
*ctrl->handle = composite_initialize();
|
||||
|
||||
*ctrl->handle =
|
||||
board_composite_connect(ctrl->instance, ctrl->config);
|
||||
|
||||
if (*ctrl->handle == NULL)
|
||||
{
|
||||
ret = -EIO;
|
||||
@@ -190,7 +193,8 @@ static inline int boardctl_usbdevctrl(FAR struct boardioc_usbdev_ctrl_s *ctrl)
|
||||
}
|
||||
break;
|
||||
|
||||
case BOARDIOC_USBDEV_DISCONNECT: /* Disconnect the Composite device */
|
||||
case BOARDIOC_USBDEV_DISCONNECT: /* Disconnect the Composite
|
||||
* device */
|
||||
{
|
||||
DEBUGASSERT(ctrl->handle != NULL && *ctrl->handle != NULL);
|
||||
composite_uninitialize(*ctrl->handle);
|
||||
|
||||
@@ -68,8 +68,4 @@ ifeq ($(CONFIG_USBMSC),y)
|
||||
CSRCS += stm32_usbmsc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBDEV_COMPOSITE),y)
|
||||
CSRCS += stm32_composite.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/configs/Board.mk
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/****************************************************************************
|
||||
* configs/fire-stm32v2/src/stm32_composite.c
|
||||
*
|
||||
* Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Configure and register the STM32 SPI-based MMC/SD block driver.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#include "fire-stm32v2.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
/* Device minor number */
|
||||
|
||||
#ifndef CONFIG_SYSTEM_COMPOSITE_DEVMINOR1
|
||||
# define CONFIG_SYSTEM_COMPOSITE_DEVMINOR1 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_initialize
|
||||
*
|
||||
* Description:
|
||||
* Perform architecture specific initialization of a composite USB device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int board_composite_initialize(int port)
|
||||
{
|
||||
/* If system/composite is built as an NSH command, then SD slot should
|
||||
* already have been initialized in board_app_initialize() (see stm32_appinit.c).
|
||||
* In this case, there is nothing further to be done here.
|
||||
*
|
||||
* NOTE: CONFIG_NSH_BUILTIN_APPS is not a fool-proof indication that NSH
|
||||
* was built.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_NSH_BUILTIN_APPS
|
||||
return sd_mount(CONFIG_SYSTEM_COMPOSITE_DEVMINOR1);
|
||||
#else
|
||||
return OK;
|
||||
#endif /* CONFIG_NSH_BUILTIN_APPS */
|
||||
}
|
||||
@@ -51,11 +51,8 @@ CONFIG_USBDEV=y
|
||||
CONFIG_USBMSC_BULKINREQLEN=256
|
||||
CONFIG_USBMSC_BULKOUTREQLEN=256
|
||||
CONFIG_USBMSC_COMPOSITE=y
|
||||
CONFIG_USBMSC_EPBULKIN=5
|
||||
CONFIG_USBMSC_EPBULKOUT=4
|
||||
CONFIG_USBMSC_NRDREQS=2
|
||||
CONFIG_USBMSC_NWRREQS=2
|
||||
CONFIG_USBMSC_PRODUCTSTR="USBdev Storage"
|
||||
CONFIG_USBMSC_REMOVABLE=y
|
||||
CONFIG_USBMSC_VERSIONNO=0x0399
|
||||
CONFIG_USBMSC=y
|
||||
|
||||
@@ -48,25 +48,290 @@
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/cdcacm.h>
|
||||
#include <nuttx/usb/usbmsc.h>
|
||||
#include <nuttx/usb/composite.h>
|
||||
|
||||
#include "lpc214x_spi.h"
|
||||
|
||||
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifndef CONFIG_SYSTEM_COMPOSITE_DEVMINOR1
|
||||
# define CONFIG_SYSTEM_COMPOSITE_DEVMINOR1 0
|
||||
#endif
|
||||
|
||||
/* PORT and SLOT number depend on the board configuration */
|
||||
|
||||
#define LPC214X_MMCSDSPIPORTNO 1
|
||||
#define LPC214X_MMCSDSLOTNO 0
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *g_mschandle;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscclassobject
|
||||
*
|
||||
* Description:
|
||||
* If the mass storage class driver is part of composite device, then
|
||||
* its instantiation and configuration is a multi-step, board-specific,
|
||||
* process (See comments for usbmsc_configure below). In this case,
|
||||
* board-specific logic must provide board_mscclassobject().
|
||||
*
|
||||
* board_mscclassobject() is called from the composite driver. It must
|
||||
* encapsulate the instantiation and configuration of the mass storage
|
||||
* class and the return the mass storage device's class driver instance
|
||||
* to the composite driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The location to return the mass storage class' device
|
||||
* instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static int board_mscclassobject(int minor,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(g_mschandle == NULL);
|
||||
|
||||
/* Configure the mass storage device */
|
||||
|
||||
uinfo("Configuring with NLUNS=1\n");
|
||||
ret = usbmsc_configure(1, &g_mschandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_configure failed: %d\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uinfo("MSC handle=%p\n", g_mschandle);
|
||||
|
||||
/* Bind the LUN(s) */
|
||||
|
||||
uinfo("Bind LUN=0 to /dev/mmcsd0\n");
|
||||
ret = usbmsc_bindlun(g_mschandle, "/dev/mmcsd0", 0, 0, 0, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_bindlun failed for LUN 1 at /dev/mmcsd0: %d\n",
|
||||
ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the mass storage device's class object */
|
||||
|
||||
ret = usbmsc_classobject(g_mschandle, devdesc, classdev);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_classobject failed: %d\n", -ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This is just an application-
|
||||
* specific wrapper aboutn usbmsc_unitialize() that is called form the
|
||||
* composite device logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The class driver instrance previously give to the composite
|
||||
* driver by board_mscclassobject().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev)
|
||||
{
|
||||
DEBUGASSERT(g_mschandle != NULL);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite0_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 0.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *board_composite0_connect(int port)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
/* 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].classobject = cdcacm_classobject;
|
||||
dev[0].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[0].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[0].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[0].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[0].devdesc.epno[CDCACM_EP_INTIN_IDX] = 1;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 2;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 3;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[0].devdesc.ninterfaces;
|
||||
strbase += dev[0].devdesc.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].classobject = board_mscclassobject;
|
||||
dev[1].uninitialize = board_mscuninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[1].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[1].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[1].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKIN_IDX] = 5;
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKOUT_IDX] = 4;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[1].devdesc.ninterfaces;
|
||||
strbase += dev[1].devdesc.nstrings;
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite1_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 1.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR void *board_composite1_connect(int port)
|
||||
{
|
||||
struct composite_devdesc_s dev[2];
|
||||
int strbase = COMPOSITE_NSTRIDS;
|
||||
int ifnobase = 0;
|
||||
int epno;
|
||||
int i;
|
||||
|
||||
for (i = 0, epno = 1; i < 2; i++)
|
||||
{
|
||||
/* Ask the cdcacm driver to fill in the constants we didn't know here */
|
||||
|
||||
cdcacm_get_composite_devdesc(&dev[i]);
|
||||
|
||||
/* Overwrite and correct some values... */
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev[i].classobject = cdcacm_classobject;
|
||||
dev[i].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
dev[i].minor = i; /* The minor interface number */
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[i].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[i].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[i].devdesc.epno[CDCACM_EP_INTIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = epno++;
|
||||
|
||||
ifnobase += dev[i].devdesc.ninterfaces;
|
||||
strbase += dev[i].devdesc.nstrings;
|
||||
}
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -113,8 +378,7 @@ int board_composite_initialize(int port)
|
||||
syslog(LOG_INFO, "Binding SPI port %d to MMC/SD slot %d\n",
|
||||
LPC214X_MMCSDSPIPORTNO, LPC214X_MMCSDSLOTNO);
|
||||
|
||||
ret = mmcsd_spislotinitialize(CONFIG_SYSTEM_COMPOSITE_DEVMINOR1,
|
||||
LPC214X_MMCSDSLOTNO, spi);
|
||||
ret = mmcsd_spislotinitialize(0, LPC214X_MMCSDSLOTNO, spi);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
@@ -130,3 +394,43 @@ int board_composite_initialize(int port)
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port using
|
||||
* the specified configuration. The interpretation of the configid is
|
||||
* board specific.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
* configid - The USB composite configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *board_composite_connect(int port, int configid)
|
||||
{
|
||||
if (configid == 0)
|
||||
{
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
return board_composite0_connect(port);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
else if (configid == 1)
|
||||
{
|
||||
return board_composite1_connect(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
||||
|
||||
@@ -134,8 +134,6 @@ CONFIG_USART2_RXBUFSIZE=32
|
||||
CONFIG_USART2_TXBUFSIZE=32
|
||||
CONFIG_USBDEV_COMPOSITE=y
|
||||
CONFIG_USBMSC_COMPOSITE=y
|
||||
CONFIG_USBMSC_EPBULKIN=5
|
||||
CONFIG_USBMSC_EPBULKOUT=4
|
||||
CONFIG_USBMSC_NRDREQS=2
|
||||
CONFIG_USBMSC_NWRREQS=2
|
||||
CONFIG_USBMSC_REMOVABLE=y
|
||||
|
||||
@@ -99,11 +99,9 @@ int board_app_initialize(uintptr_t arg)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_COMPOSITE
|
||||
#if !defined(CONFIG_NSH_BUILTIN_APPS) && !defined(CONFIG_SYSTEM_COMPOSITE)
|
||||
#if !defined(CONFIG_NSH_BUILTIN_APPS) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
ret = board_composite_initialize(0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CAN
|
||||
/* Initialize CAN and register the CAN driver. */
|
||||
|
||||
@@ -47,22 +47,26 @@
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/cdcacm.h>
|
||||
#include <nuttx/usb/usbmsc.h>
|
||||
#include <nuttx/usb/composite.h>
|
||||
|
||||
#include "stm32.h"
|
||||
#include "olimexino-stm32.h"
|
||||
|
||||
/* There is nothing to do here if SPI support is not selected. */
|
||||
|
||||
#ifdef CONFIG_STM32_SPI
|
||||
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
/* No SPI? Then no USB MSC device in composite */
|
||||
|
||||
#ifndef CONFIG_SYSTEM_COMPOSITE_DEVMINOR1
|
||||
# define CONFIG_SYSTEM_COMPOSITE_DEVMINOR1 0
|
||||
#ifndef CONFIG_STM32_SPI
|
||||
# undef CONFIG_USBMSC_COMPOSITE
|
||||
#endif
|
||||
|
||||
/* SLOT number(s) could depend on the board configuration */
|
||||
@@ -77,6 +81,282 @@
|
||||
# error "Unrecognized STM32 board"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *g_mschandle;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscclassobject
|
||||
*
|
||||
* Description:
|
||||
* If the mass storage class driver is part of composite device, then
|
||||
* its instantiation and configuration is a multi-step, board-specific,
|
||||
* process (See comments for usbmsc_configure below). In this case,
|
||||
* board-specific logic must provide board_mscclassobject().
|
||||
*
|
||||
* board_mscclassobject() is called from the composite driver. It must
|
||||
* encapsulate the instantiation and configuration of the mass storage
|
||||
* class and the return the mass storage device's class driver instance
|
||||
* to the composite driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The location to return the mass storage class' device
|
||||
* instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static int board_mscclassobject(int minor,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(g_mschandle == NULL);
|
||||
|
||||
/* Configure the mass storage device */
|
||||
|
||||
uinfo("Configuring with NLUNS=1\n");
|
||||
ret = usbmsc_configure(1, &g_mschandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_configure failed: %d\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uinfo("MSC handle=%p\n", g_mschandle);
|
||||
|
||||
/* Bind the LUN(s) */
|
||||
|
||||
uinfo("Bind LUN=0 to /dev/mmcsd0\n");
|
||||
ret = usbmsc_bindlun(g_mschandle, "/dev/mmcsd0", 0, 0, 0, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_bindlun failed for LUN 1 at /dev/mmcsd0: %d\n",
|
||||
ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the mass storage device's class object */
|
||||
|
||||
ret = usbmsc_classobject(g_mschandle, devdesc, classdev);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_classobject failed: %d\n", -ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This is just an application-
|
||||
* specific wrapper aboutn usbmsc_unitialize() that is called form the
|
||||
* composite device logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The class driver instrance previously give to the composite
|
||||
* driver by board_mscclassobject().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev)
|
||||
{
|
||||
DEBUGASSERT(g_mschandle != NULL);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite0_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 0.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *board_composite0_connect(int port)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
/* 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].classobject = cdcacm_classobject;
|
||||
dev[0].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[0].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[0].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[0].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[0].devdesc.epno[CDCACM_EP_INTIN_IDX] = 1;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 2;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 3;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[0].devdesc.ninterfaces;
|
||||
strbase += dev[0].devdesc.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].classobject = board_mscclassobject;
|
||||
dev[1].uninitialize = board_mscuninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[1].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[1].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[1].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKIN_IDX] = 5;
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKOUT_IDX] = 4;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[1].devdesc.ninterfaces;
|
||||
strbase += dev[1].devdesc.nstrings;
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite1_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 1.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR void *board_composite1_connect(int port)
|
||||
{
|
||||
/* REVISIT: This configuration currently fails. stm32_epallocpma() fails
|
||||
* allocate a buffer for the 6th endpoint. Currenlty it supports 7x64 byte
|
||||
* buffers, two required for EP0, leaving only buffers for 5 additional
|
||||
* endpoints.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct composite_devdesc_s dev[2];
|
||||
int strbase = COMPOSITE_NSTRIDS;
|
||||
int ifnobase = 0;
|
||||
int epno;
|
||||
int i;
|
||||
|
||||
for (i = 0, epno = 1; i < 2; i++)
|
||||
{
|
||||
/* Ask the cdcacm driver to fill in the constants we didn't know here */
|
||||
|
||||
cdcacm_get_composite_devdesc(&dev[i]);
|
||||
|
||||
/* Overwrite and correct some values... */
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev[i].classobject = cdcacm_classobject;
|
||||
dev[i].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
dev[i].minor = i; /* The minor interface number */
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[i].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[i].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[i].devdesc.epno[CDCACM_EP_INTIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = epno++;
|
||||
|
||||
ifnobase += dev[i].devdesc.ninterfaces;
|
||||
strbase += dev[i].devdesc.nstrings;
|
||||
}
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -117,17 +397,16 @@ int board_composite_initialize(int port)
|
||||
|
||||
/* Now bind the SPI interface to the MMC/SD driver */
|
||||
|
||||
syslog(LOG_INFO, "Bind SPI to the MMC/SD driver, minor=%d slot=%d\n",
|
||||
CONFIG_SYSTEM_COMPOSITE_DEVMINOR1, OLIMEXINO_STM32_MMCSDSLOTNO);
|
||||
syslog(LOG_INFO, "Bind SPI to the MMC/SD driver, minor=0 slot=%d\n",
|
||||
OLIMEXINO_STM32_MMCSDSLOTNO);
|
||||
|
||||
ret = mmcsd_spislotinitialize(CONFIG_SYSTEM_COMPOSITE_DEVMINOR1,
|
||||
OLIMEXINO_STM32_MMCSDSLOTNO, spi);
|
||||
ret = mmcsd_spislotinitialize(0, OLIMEXINO_STM32_MMCSDSLOTNO, spi);
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to bind SPI port %d to MMC/SD minor=%d slot=%d %d\n",
|
||||
OLIMEXINO_STM32_MMCSDSPIPORTNO, CONFIG_SYSTEM_COMPOSITE_DEVMINOR1,
|
||||
OLIMEXINO_STM32_MMCSDSLOTNO, ret);
|
||||
"ERROR: Failed to bind SPI port %d to MMC/SD minor=0 slot=%d %d\n",
|
||||
OLIMEXINO_STM32_MMCSDSPIPORTNO, OLIMEXINO_STM32_MMCSDSLOTNO,
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -135,4 +414,43 @@ int board_composite_initialize(int port)
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif /* CONFIG_STM32_SPI */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port using
|
||||
* the specified configuration. The interpretation of the configid is
|
||||
* board specific.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
* configid - The USB composite configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *board_composite_connect(int port, int configid)
|
||||
{
|
||||
if (configid == 0)
|
||||
{
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
return board_composite0_connect(port);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
else if (configid == 1)
|
||||
{
|
||||
return board_composite1_connect(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* configs/samv71-xult/src/sam_composite.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2016, 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -40,11 +40,123 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/cdcacm.h>
|
||||
#include <nuttx/usb/usbmsc.h>
|
||||
#include <nuttx/usb/composite.h>
|
||||
|
||||
#include "samv71-xult.h"
|
||||
|
||||
#ifdef CONFIG_USBDEV_COMPOSITE
|
||||
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *g_mschandle;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscclassobject
|
||||
*
|
||||
* Description:
|
||||
* If the mass storage class driver is part of composite device, then
|
||||
* its instantiation and configuration is a multi-step, board-specific,
|
||||
* process (See comments for usbmsc_configure below). In this case,
|
||||
* board-specific logic must provide board_mscclassobject().
|
||||
*
|
||||
* board_mscclassobject() is called from the composite driver. It must
|
||||
* encapsulate the instantiation and configuration of the mass storage
|
||||
* class and the return the mass storage device's class driver instance
|
||||
* to the composite driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The location to return the mass storage class' device
|
||||
* instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static int board_mscclassobject(int minor,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(g_mschandle == NULL);
|
||||
|
||||
/* Configure the mass storage device */
|
||||
|
||||
uinfo("Configuring with NLUNS=1\n");
|
||||
ret = usbmsc_configure(1, &g_mschandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_configure failed: %d\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uinfo("MSC handle=%p\n", g_mschandle);
|
||||
|
||||
/* Bind the LUN(s) */
|
||||
|
||||
uinfo("Bind LUN=0 to /dev/mmcsd0\n");
|
||||
ret = usbmsc_bindlun(g_mschandle, "/dev/mmcsd0", 0, 0, 0, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_bindlun failed for LUN 1 at /dev/mmcsd0: %d\n",
|
||||
ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the mass storage device's class object */
|
||||
|
||||
ret = usbmsc_classobject(g_mschandle, devdesc, classdev);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_classobject failed: %d\n", -ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This is just an application-
|
||||
* specific wrapper aboutn usbmsc_unitialize() that is called form the
|
||||
* composite device logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The class driver instrance previously give to the composite
|
||||
* driver by board_mscclassobject().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev)
|
||||
{
|
||||
DEBUGASSERT(g_mschandle != NULL);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -63,4 +175,176 @@ int board_composite_initialize(int port)
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USBDEV_COMPOSITE */
|
||||
/****************************************************************************
|
||||
* Name: board_composite_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port using
|
||||
* the specified configuration. The interpretation of the configid is
|
||||
* board specific.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
* configid - The USB composite configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *board_composite_connect(int port, int configid)
|
||||
{
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
if (configid == 0)
|
||||
{
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
struct composite_devdesc_s dev[2];
|
||||
int ifnobase = 0;
|
||||
int strbase = COMPOSITE_NSTRIDS;
|
||||
|
||||
/* 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].classobject = cdcacm_classobject;
|
||||
dev[0].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[0].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[0].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[0].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[0].devdesc.epno[CDCACM_EP_INTIN_IDX] = 3;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 4;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 5;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[0].devdesc.ninterfaces;
|
||||
strbase += dev[0].devdesc.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].classobject = board_mscclassobject;
|
||||
dev[1].uninitialize = board_mscuninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[1].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[1].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[1].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKIN_IDX] = 1;
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKOUT_IDX] = 2;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[1].devdesc.ninterfaces;
|
||||
strbase += dev[1].devdesc.nstrings;
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configuration with three CDC/ACMs
|
||||
*
|
||||
* This configuration can be used e.g. on a samv71-xult. The samv71 has
|
||||
* 10 Endpoints (EPs). The EPs 0 up to 7 are DMA aware. The EPs 8 and 9
|
||||
* are not.
|
||||
*
|
||||
* In a composite device we need the EP0 as an control Endpoint. Each
|
||||
* CDC/ACM needs one Interrupt driven and two bulk Endpoints. This is
|
||||
* why we configure the EPs 7, 8 and 9 to be the IRQ-EPs and the
|
||||
* EP-Pairs 1/2, 3/4, 5/6 to be the bulk EPs for each device.
|
||||
*
|
||||
* This means, that
|
||||
*
|
||||
* - the Composite device uses EP0 as the control-Endpoint,
|
||||
* - the CDC/ACM 0 uses EP7, EP1 and EP2,
|
||||
* - the CDC/ACM 1 uses EP8, EP3 and EP4,
|
||||
* - the CDC/ACM 2 uses EP9, EP5 and EP6
|
||||
*
|
||||
* as its EP-Configuration.
|
||||
*/
|
||||
|
||||
else if (configid == 1)
|
||||
{
|
||||
struct composite_devdesc_s dev[3];
|
||||
int strbase = COMPOSITE_NSTRIDS;
|
||||
int ifnobase = 0;
|
||||
int ia;
|
||||
|
||||
for (ia = 0; ia < 3; ia++)
|
||||
{
|
||||
/* Ask the cdcacm driver to fill in the constants we didn't know here */
|
||||
|
||||
cdcacm_get_composite_devdesc(&dev[ia]);
|
||||
|
||||
/* Overwrite and correct some values... */
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev[ia].classobject = cdcacm_classobject;
|
||||
dev[ia].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
dev[ia].minor = ia; /* The minor interface number */
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[ia].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[ia].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[ia].devdesc.epno[CDCACM_EP_INTIN_IDX] = 7 + ia;
|
||||
dev[ia].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 1 + ia * 2;
|
||||
dev[ia].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 2 + ia * 2;
|
||||
|
||||
ifnobase += dev[ia].devdesc.ninterfaces;
|
||||
strbase += dev[ia].devdesc.nstrings;
|
||||
}
|
||||
|
||||
return composite_initialize(3, dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
||||
|
||||
@@ -68,10 +68,6 @@ ifeq ($(CONFIG_USBMSC),y)
|
||||
CSRCS += stm32_usbmsc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USBDEV_COMPOSITE),y)
|
||||
CSRCS += stm32_composite.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CAN),y)
|
||||
CSRCS += stm32_can.c
|
||||
endif
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/****************************************************************************
|
||||
* configs/shenzhou/src/stm32_composite.c
|
||||
*
|
||||
* Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Configure and register the STM32 SPI-based MMC/SD block driver.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "shenzhou.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
/* Device minor number */
|
||||
|
||||
#ifndef CONFIG_SYSTEM_COMPOSITE_DEVMINOR1
|
||||
# define CONFIG_SYSTEM_COMPOSITE_DEVMINOR1 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_initialize
|
||||
*
|
||||
* Description:
|
||||
* Perform architecture specific initialization of a composite USB device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int board_composite_initialize(int port)
|
||||
{
|
||||
/* If system/composite is built as an NSH command, then SD slot should
|
||||
* already have been initialized in board_app_initialize() (see
|
||||
* stm32_appinit.c). In this case, there is nothing further to be done here.
|
||||
*
|
||||
* NOTE: CONFIG_NSH_BUILTIN_APPS is not a fool-proof indication that NSH
|
||||
* was built.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_NSH_BUILTIN_APPS
|
||||
return sd_mount(CONFIG_SYSTEM_COMPOSITE_DEVMINOR1);
|
||||
#else
|
||||
return OK;
|
||||
#endif /* CONFIG_NSH_BUILTIN_APPS */
|
||||
}
|
||||
@@ -98,8 +98,6 @@ CONFIG_STM32_SPI_DMA=y
|
||||
CONFIG_STM32_USART2=y
|
||||
CONFIG_STM32_USB=y
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_SYSTEM_COMPOSITE_DEVPATH1="/dev/mtdblock0"
|
||||
CONFIG_SYSTEM_COMPOSITE_DEVPATH2="/dev/mtdblock1"
|
||||
CONFIG_SYSTEM_COMPOSITE=y
|
||||
CONFIG_TASK_NAME_SIZE=7
|
||||
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=768
|
||||
@@ -110,8 +108,6 @@ CONFIG_USBDEV_COMPOSITE=y
|
||||
CONFIG_USBDEV_TRACE_NRECORDS=32
|
||||
CONFIG_USBDEV_TRACE=y
|
||||
CONFIG_USBMSC_COMPOSITE=y
|
||||
CONFIG_USBMSC_EPBULKIN=5
|
||||
CONFIG_USBMSC_EPBULKOUT=4
|
||||
CONFIG_USBMSC_NRDREQS=2
|
||||
CONFIG_USBMSC_NWRREQS=2
|
||||
CONFIG_USBMSC_SCSI_STACKSIZE=340
|
||||
|
||||
@@ -54,6 +54,11 @@
|
||||
# include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/cdcacm.h>
|
||||
#include <nuttx/usb/usbmsc.h>
|
||||
#include <nuttx/usb/composite.h>
|
||||
|
||||
#ifdef CONFIG_USBMONITOR
|
||||
# include <nuttx/usb/usbmonitor.h>
|
||||
#endif
|
||||
@@ -65,6 +70,8 @@
|
||||
#include "stm32.h"
|
||||
#include "spark.h"
|
||||
|
||||
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@@ -116,6 +123,14 @@
|
||||
# undef HAVE_USBMONITOR
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *g_mschandle;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@@ -280,6 +295,270 @@ static int stm32_composite_initialize(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscclassobject
|
||||
*
|
||||
* Description:
|
||||
* If the mass storage class driver is part of composite device, then
|
||||
* its instantiation and configuration is a multi-step, board-specific,
|
||||
* process (See comments for usbmsc_configure below). In this case,
|
||||
* board-specific logic must provide board_mscclassobject().
|
||||
*
|
||||
* board_mscclassobject() is called from the composite driver. It must
|
||||
* encapsulate the instantiation and configuration of the mass storage
|
||||
* class and the return the mass storage device's class driver instance
|
||||
* to the composite driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The location to return the mass storage class' device
|
||||
* instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static int board_mscclassobject(int minor,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(g_mschandle == NULL);
|
||||
|
||||
/* Configure the mass storage device */
|
||||
|
||||
uinfo("Configuring with NLUNS=1\n");
|
||||
ret = usbmsc_configure(1, &g_mschandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_configure failed: %d\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uinfo("MSC handle=%p\n", g_mschandle);
|
||||
|
||||
/* Bind the LUN(s) */
|
||||
|
||||
uinfo("Bind LUN=0 to /dev/mtdblock0\n");
|
||||
ret = usbmsc_bindlun(g_mschandle, "/dev/mtdblock0", 0, 0, 0, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_bindlun failed for LUN 1 at /dev/mtdblock0: %d\n",
|
||||
ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the mass storage device's class object */
|
||||
|
||||
ret = usbmsc_classobject(g_mschandle, devdesc, classdev);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_classobject failed: %d\n", -ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This is just an application-
|
||||
* specific wrapper aboutn usbmsc_unitialize() that is called form the
|
||||
* composite device logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The class driver instrance previously give to the composite
|
||||
* driver by board_mscclassobject().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev)
|
||||
{
|
||||
DEBUGASSERT(g_mschandle != NULL);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite0_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 0.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *board_composite0_connect(int port)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
/* 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].classobject = cdcacm_classobject;
|
||||
dev[0].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[0].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[0].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[0].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[0].devdesc.epno[CDCACM_EP_INTIN_IDX] = 1;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 2;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 3;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[0].devdesc.ninterfaces;
|
||||
strbase += dev[0].devdesc.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].classobject = board_mscclassobject;
|
||||
dev[1].uninitialize = board_mscuninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[1].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[1].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[1].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKIN_IDX] = 5;
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKOUT_IDX] = 4;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[1].devdesc.ninterfaces;
|
||||
strbase += dev[1].devdesc.nstrings;
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite1_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 1.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR void *board_composite1_connect(int port)
|
||||
{
|
||||
/* REVISIT: This configuration currently fails. stm32_epallocpma() fails
|
||||
* allocate a buffer for the 6th endpoint. Currenlty it supports 7x64 byte
|
||||
* buffers, two required for EP0, leaving only buffers for 5 additional
|
||||
* endpoints.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct composite_devdesc_s dev[2];
|
||||
int strbase = COMPOSITE_NSTRIDS;
|
||||
int ifnobase = 0;
|
||||
int epno;
|
||||
int i;
|
||||
|
||||
for (i = 0, epno = 1; i < 2; i++)
|
||||
{
|
||||
/* Ask the cdcacm driver to fill in the constants we didn't know here */
|
||||
|
||||
cdcacm_get_composite_devdesc(&dev[i]);
|
||||
|
||||
/* Overwrite and correct some values... */
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev[i].classobject = cdcacm_classobject;
|
||||
dev[i].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
dev[i].minor = i; /* The minor interface number */
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[i].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[i].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[i].devdesc.epno[CDCACM_EP_INTIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = epno++;
|
||||
|
||||
ifnobase += dev[i].devdesc.ninterfaces;
|
||||
strbase += dev[i].devdesc.nstrings;
|
||||
}
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -300,3 +579,43 @@ int board_composite_initialize(int port)
|
||||
return stm32_composite_initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port using
|
||||
* the specified configuration. The interpretation of the configid is
|
||||
* board specific.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
* configid - The USB composite configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *board_composite_connect(int port, int configid)
|
||||
{
|
||||
if (configid == 0)
|
||||
{
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
return board_composite0_connect(port);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
else if (configid == 1)
|
||||
{
|
||||
return board_composite1_connect(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
||||
|
||||
@@ -58,11 +58,8 @@ CONFIG_USBDEV_COMPOSITE=y
|
||||
CONFIG_USBMSC_BULKINREQLEN=256
|
||||
CONFIG_USBMSC_BULKOUTREQLEN=256
|
||||
CONFIG_USBMSC_COMPOSITE=y
|
||||
CONFIG_USBMSC_EPBULKIN=5
|
||||
CONFIG_USBMSC_EPBULKOUT=4
|
||||
CONFIG_USBMSC_NRDREQS=2
|
||||
CONFIG_USBMSC_NWRREQS=2
|
||||
CONFIG_USBMSC_PRODUCTSTR="USBdev Storage"
|
||||
CONFIG_USBMSC_REMOVABLE=y
|
||||
CONFIG_USBMSC_VERSIONNO=0x0399
|
||||
CONFIG_USBMSC=y
|
||||
|
||||
@@ -48,22 +48,23 @@
|
||||
#include <nuttx/sdio.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/cdcacm.h>
|
||||
#include <nuttx/usb/usbmsc.h>
|
||||
#include <nuttx/usb/composite.h>
|
||||
|
||||
#include "stm32.h"
|
||||
|
||||
/* There is nothing to do here if SDIO support is not selected. */
|
||||
|
||||
#if defined(CONFIG_STM32_SDIO) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
/* No SDIO? Then no USB MSC device in composite */
|
||||
|
||||
#ifndef CONFIG_SYSTEM_COMPOSITE_DEVMINOR1
|
||||
# define CONFIG_SYSTEM_COMPOSITE_DEVMINOR1 0
|
||||
#ifndef CONFIG_STM32_SDIO
|
||||
# undef CONFIG_USBMSC_COMPOSITE
|
||||
#endif
|
||||
|
||||
/* SLOT number(s) could depend on the board configuration */
|
||||
@@ -76,6 +77,282 @@
|
||||
# error "Unrecognized STM32 board"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *g_mschandle;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscclassobject
|
||||
*
|
||||
* Description:
|
||||
* If the mass storage class driver is part of composite device, then
|
||||
* its instantiation and configuration is a multi-step, board-specific,
|
||||
* process (See comments for usbmsc_configure below). In this case,
|
||||
* board-specific logic must provide board_mscclassobject().
|
||||
*
|
||||
* board_mscclassobject() is called from the composite driver. It must
|
||||
* encapsulate the instantiation and configuration of the mass storage
|
||||
* class and the return the mass storage device's class driver instance
|
||||
* to the composite driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The location to return the mass storage class' device
|
||||
* instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static int board_mscclassobject(int minor,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(g_mschandle == NULL);
|
||||
|
||||
/* Configure the mass storage device */
|
||||
|
||||
uinfo("Configuring with NLUNS=1\n");
|
||||
ret = usbmsc_configure(1, &g_mschandle);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_configure failed: %d\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uinfo("MSC handle=%p\n", g_mschandle);
|
||||
|
||||
/* Bind the LUN(s) */
|
||||
|
||||
uinfo("Bind LUN=0 to /dev/mmcsd0\n");
|
||||
ret = usbmsc_bindlun(g_mschandle, "/dev/mmcsd0", 0, 0, 0, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_bindlun failed for LUN 1 at /dev/mmcsd0: %d\n",
|
||||
ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the mass storage device's class object */
|
||||
|
||||
ret = usbmsc_classobject(g_mschandle, devdesc, classdev);
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbmsc_classobject failed: %d\n", -ret);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This is just an application-
|
||||
* specific wrapper aboutn usbmsc_unitialize() that is called form the
|
||||
* composite device logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The class driver instrance previously give to the composite
|
||||
* driver by board_mscclassobject().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev)
|
||||
{
|
||||
DEBUGASSERT(g_mschandle != NULL);
|
||||
usbmsc_uninitialize(g_mschandle);
|
||||
g_mschandle = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite0_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 0.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
static FAR void *board_composite0_connect(int port)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
/* 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].classobject = cdcacm_classobject;
|
||||
dev[0].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[0].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[0].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[0].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[0].devdesc.epno[CDCACM_EP_INTIN_IDX] = 1;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKIN_IDX] = 2;
|
||||
dev[0].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = 3;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[0].devdesc.ninterfaces;
|
||||
strbase += dev[0].devdesc.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].classobject = board_mscclassobject;
|
||||
dev[1].uninitialize = board_mscuninitialize;
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[1].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
dev[1].minor = 0; /* The minor interface number */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[1].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKIN_IDX] = 5;
|
||||
dev[1].devdesc.epno[USBMSC_EP_BULKOUT_IDX] = 4;
|
||||
|
||||
/* Count up the base numbers */
|
||||
|
||||
ifnobase += dev[1].devdesc.ninterfaces;
|
||||
strbase += dev[1].devdesc.nstrings;
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite1_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port for
|
||||
* configuration 1.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR void *board_composite1_connect(int port)
|
||||
{
|
||||
/* REVISIT: This configuration currently fails. stm32_epallocpma() fails
|
||||
* allocate a buffer for the 6th endpoint. Currenlty it supports 7x64 byte
|
||||
* buffers, two required for EP0, leaving only buffers for 5 additional
|
||||
* endpoints.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct composite_devdesc_s dev[2];
|
||||
int strbase = COMPOSITE_NSTRIDS;
|
||||
int ifnobase = 0;
|
||||
int epno;
|
||||
int i;
|
||||
|
||||
for (i = 0, epno = 1; i < 2; i++)
|
||||
{
|
||||
/* Ask the cdcacm driver to fill in the constants we didn't know here */
|
||||
|
||||
cdcacm_get_composite_devdesc(&dev[i]);
|
||||
|
||||
/* Overwrite and correct some values... */
|
||||
/* The callback functions for the CDC/ACM class */
|
||||
|
||||
dev[i].classobject = cdcacm_classobject;
|
||||
dev[i].uninitialize = cdcacm_uninitialize;
|
||||
|
||||
dev[i].minor = i; /* The minor interface number */
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
dev[i].devdesc.ifnobase = ifnobase; /* Offset to Interface-IDs */
|
||||
|
||||
/* Strings */
|
||||
|
||||
dev[i].devdesc.strbase = strbase; /* Offset to String Numbers */
|
||||
|
||||
/* Endpoints */
|
||||
|
||||
dev[i].devdesc.epno[CDCACM_EP_INTIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKIN_IDX] = epno++;
|
||||
dev[i].devdesc.epno[CDCACM_EP_BULKOUT_IDX] = epno++;
|
||||
|
||||
ifnobase += dev[i].devdesc.ninterfaces;
|
||||
strbase += dev[i].devdesc.nstrings;
|
||||
}
|
||||
|
||||
return composite_initialize(2, dev);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -116,10 +393,9 @@ int board_composite_initialize(int port)
|
||||
|
||||
/* Now bind the SDIO interface to the MMC/SD driver */
|
||||
|
||||
syslog(LOG_INFO, "Bind SDIO to the MMC/SD driver, minor=%d\n",
|
||||
CONFIG_SYSTEM_COMPOSITE_DEVMINOR1);
|
||||
syslog(LOG_INFO, "Bind SDIO to the MMC/SD driver, minor=0\n");
|
||||
|
||||
ret = mmcsd_slotinitialize(CONFIG_SYSTEM_COMPOSITE_DEVMINOR1, sdio);
|
||||
ret = mmcsd_slotinitialize(0, sdio);
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
@@ -142,4 +418,42 @@ int board_composite_initialize(int port)
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STM32_SDIO && CONFIG_USBDEV_COMPOSITE */
|
||||
/****************************************************************************
|
||||
* Name: board_composite_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port using
|
||||
* the specified configuration. The interpretation of the configid is
|
||||
* board specific.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
* configid - The USB composite configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *board_composite_connect(int port, int configid)
|
||||
{
|
||||
if (configid == 0)
|
||||
{
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
return board_composite0_connect(port);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
else if (configid == 1)
|
||||
{
|
||||
return board_composite1_connect(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */
|
||||
|
||||
@@ -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"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,12 @@ 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,
|
||||
FAR 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,
|
||||
FAR struct usbdev_description_s *devdesc);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,17 +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 */
|
||||
|
||||
struct composite_driver_s
|
||||
@@ -123,6 +112,7 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* USB class device *********************************************************/
|
||||
|
||||
static const struct usbdevclass_driverops_s g_driverops =
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -264,8 +257,11 @@ static void composite_freereq(FAR struct usbdev_ep_s *ep,
|
||||
static int composite_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s *)driver)->dev;
|
||||
FAR struct composite_dev_s *priv =
|
||||
((FAR struct composite_driver_s *)driver)->dev;
|
||||
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
usbtrace(TRACE_CLASSBIND, 0);
|
||||
|
||||
@@ -281,7 +277,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 +291,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 +356,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 +374,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 +421,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 +471,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 +490,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 +521,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;
|
||||
@@ -593,10 +593,9 @@ static int composite_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Respond to the setup command if (1) data was returned, and (2) the request was
|
||||
* NOT successfully dispatched to the component class driver. On an error return
|
||||
* value (ret < 0), the USB driver will stall EP0.
|
||||
/* Respond to the setup command if (1) data was returned, and (2) the
|
||||
* request was NOT successfully dispatched to the component class driver.
|
||||
* On an error return value (ret < 0), the USB driver will stall EP0.
|
||||
*/
|
||||
|
||||
if (ret >= 0 && !dispatched)
|
||||
@@ -635,6 +634,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 +664,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 +692,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 +719,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 +741,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 +766,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);
|
||||
}
|
||||
|
||||
@@ -770,8 +784,7 @@ static void composite_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
* 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(), ...)
|
||||
* each of the members of the composite.
|
||||
*
|
||||
* Input Parameter:
|
||||
* None
|
||||
@@ -786,16 +799,22 @@ 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;
|
||||
|
||||
DEBUGASSERT(pdevices != NULL && ndevices <= NUM_DEVICES_TO_HANDLE);
|
||||
|
||||
/* 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 +830,32 @@ 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.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 */
|
||||
|
||||
@@ -840,9 +870,10 @@ FAR void *composite_initialize(void)
|
||||
/* Register the USB composite class driver */
|
||||
|
||||
ret = usbdev_register(&drvr->drvr);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_DEVREGISTER), (uint16_t)-ret);
|
||||
usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_DEVREGISTER),
|
||||
(uint16_t)-ret);
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
@@ -860,8 +891,7 @@ errout_with_alloc:
|
||||
* Un-initialize the USB composite driver. The handle is the USB composite
|
||||
* class' device object as was returned by composite_initialize(). This
|
||||
* function will call board-specific implementations in order to free the
|
||||
* class objects for each of the members of the composite (see
|
||||
* board_mscuninitialize(), board_cdcuninitialize(), ...)
|
||||
* class objects for each of the members of the composite.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle returned by a previous call to composite_initialize().
|
||||
@@ -875,6 +905,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 +913,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.uninitialize(priv->device[i].dev);
|
||||
}
|
||||
|
||||
/* Then unregister and destroy the composite class */
|
||||
|
||||
@@ -894,8 +927,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.uninitialize(priv->device[i].dev);
|
||||
}
|
||||
|
||||
/* Then free the composite driver state structure itself */
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -62,6 +63,7 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
/* Packet sizes */
|
||||
|
||||
@@ -106,136 +108,21 @@
|
||||
#ifdef CONFIG_USBDEV_SELFPOWERED
|
||||
# define COMPOSITE_SELFPOWERED USB_CONFIG_ATTR_SELFPOWER
|
||||
#else
|
||||
# define COMPOSITE_SELFPOWERED (0)
|
||||
# define COMPOSITE_SELFPOWERED (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_REMOTEWAKEUP
|
||||
# define COMPOSITE_REMOTEWAKEUP USB_CONFIG_ATTR_WAKEUP
|
||||
#else
|
||||
# define COMPOSITE_REMOTEWAKEUP (0)
|
||||
# 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 +135,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 +150,33 @@
|
||||
* 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,11 @@ 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
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -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,55 @@ 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->ndevices; 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].compdesc.mkconfdesc(buf,
|
||||
&priv->device[i].compdesc.devdesc,
|
||||
speed, type);
|
||||
total += len;
|
||||
buf += len;
|
||||
#else
|
||||
len = DEV1_MKCFGDESC(buf);
|
||||
total += len;
|
||||
buf += len;
|
||||
total += DEV2_MKCFGDESC(buf);
|
||||
len = priv->device[i].compdesc.mkconfdesc(buf,
|
||||
&priv->device[i].compdesc.devdesc);
|
||||
total += len;
|
||||
buf += len;
|
||||
#endif
|
||||
}
|
||||
|
||||
DEBUGASSERT(total == COMPOSITE_CFGDESCSIZE);
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -246,6 +246,7 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
|
||||
/****************************************************************************
|
||||
* Class Driver Interfaces
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_bind
|
||||
*
|
||||
@@ -267,7 +268,7 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
|
||||
/* Bind the structures */
|
||||
|
||||
priv->usbdev = dev;
|
||||
priv->usbdev = dev;
|
||||
|
||||
/* Save the reference to our private data structure in EP0 so that it
|
||||
* can be recovered in ep0 completion events (Unless we are part of
|
||||
@@ -307,7 +308,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->devdesc),
|
||||
true, USB_EP_ATTR_XFER_BULK);
|
||||
if (!priv->epbulkin)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINALLOCFAIL), 0);
|
||||
@@ -319,7 +321,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->devdesc),
|
||||
false, USB_EP_ATTR_XFER_BULK);
|
||||
if (!priv->epbulkout)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTALLOCFAIL), 0);
|
||||
@@ -334,7 +337,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 +346,7 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
reqcontainer->req->priv = reqcontainer;
|
||||
reqcontainer->req->callback = usbmsc_rdcomplete;
|
||||
}
|
||||
@@ -351,7 +356,8 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
for (i = 0; i < CONFIG_USBMSC_NWRREQS; i++)
|
||||
{
|
||||
reqcontainer = &priv->wrreqs[i];
|
||||
reqcontainer->req = usbmsc_allocreq(priv->epbulkin, CONFIG_USBMSC_BULKINREQLEN);
|
||||
reqcontainer->req = usbmsc_allocreq(priv->epbulkin,
|
||||
CONFIG_USBMSC_BULKINREQLEN);
|
||||
if (reqcontainer->req == NULL)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRALLOCREQ),
|
||||
@@ -359,6 +365,7 @@ static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
reqcontainer->req->priv = reqcontainer;
|
||||
reqcontainer->req->callback = usbmsc_wrcomplete;
|
||||
|
||||
@@ -482,7 +489,9 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
|
||||
flags = enter_critical_section();
|
||||
while (!sq_empty(&priv->wrreqlist))
|
||||
{
|
||||
reqcontainer = (struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist);
|
||||
reqcontainer = (struct usbmsc_req_s *)
|
||||
sq_remfirst(&priv->wrreqlist);
|
||||
|
||||
if (reqcontainer->req != NULL)
|
||||
{
|
||||
usbmsc_freereq(priv->epbulkin, reqcontainer->req);
|
||||
@@ -569,9 +578,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
|
||||
switch (ctrl->value[1])
|
||||
{
|
||||
/* If the mass storage device is used in as part of a composite
|
||||
* device, then the device descriptor is is provided by logic
|
||||
* in the composite device implementation.
|
||||
/* If the mass storage device is used in as part of a
|
||||
* composite device, then the device descriptor is is
|
||||
* provided by logic in the composite device implementation.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
@@ -583,9 +592,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* If the mass storage device is used in as part of a composite device,
|
||||
* then the device qualifier descriptor is provided by logic in the
|
||||
* composite device implementation.
|
||||
/* If the mass storage device is used in as part of a
|
||||
* composite device, then the device qualifier descriptor is
|
||||
* provided by logic in the composite device implementation.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_USBMSC_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
|
||||
@@ -608,7 +617,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
case USB_DESC_TYPE_CONFIG:
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
ret = usbmsc_mkcfgdesc(ctrlreq->buf, dev->speed, ctrl->value[1]);
|
||||
ret = usbmsc_mkcfgdesc(ctrlreq->buf, dev->speed,
|
||||
ctrl->value[1]);
|
||||
#else
|
||||
ret = usbmsc_mkcfgdesc(ctrlreq->buf);
|
||||
#endif
|
||||
@@ -616,9 +626,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* If the mass storage device is used in as part of a composite device,
|
||||
* then the language string descriptor is provided by logic in the
|
||||
* composite device implementation.
|
||||
/* If the mass storage device is used in as part of a
|
||||
* composite device, then the language string descriptor is
|
||||
* provided by logic in the composite device implementation.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
@@ -626,7 +636,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
{
|
||||
/* index == language code. */
|
||||
|
||||
ret = usbmsc_mkstrdesc(ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf);
|
||||
ret = usbmsc_mkstrdesc(ctrl->value[0],
|
||||
(struct usb_strdesc_s *)ctrlreq->buf);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -644,7 +655,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
{
|
||||
if (ctrl->type == 0)
|
||||
{
|
||||
/* Signal the worker thread to instantiate the new configuration */
|
||||
/* Signal the worker thread to instantiate the new
|
||||
* configuration.
|
||||
*/
|
||||
|
||||
priv->theventset |= USBMSC_EVENT_CFGCHANGE;
|
||||
priv->thvalue = value;
|
||||
@@ -659,9 +672,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
break;
|
||||
|
||||
/* If the mass storage device is used in as part of a composite device,
|
||||
* then the overall composite class configuration is managed by logic
|
||||
* in the composite device implementation.
|
||||
/* If the mass storage device is used in as part of a composite
|
||||
* device, then the overall composite class configuration is
|
||||
* managed by logic in the composite device implementation.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
@@ -689,8 +702,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
priv->theventset |= USBMSC_EVENT_IFCHANGE;
|
||||
usbmsc_scsi_signal(priv);
|
||||
|
||||
/* Return here... the response will be provided later by the
|
||||
* worker thread.
|
||||
/* Return here... the response will be provided later by
|
||||
* the worker thread.
|
||||
*/
|
||||
|
||||
return OK;
|
||||
@@ -751,13 +764,15 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Signal to stop the current operation and reinitialize state */
|
||||
/* Signal to stop the current operation and reinitialize
|
||||
* state.
|
||||
*/
|
||||
|
||||
priv->theventset |= USBMSC_EVENT_RESET;
|
||||
usbmsc_scsi_signal(priv);
|
||||
|
||||
/* Return here... the response will be provided later by the
|
||||
* worker thread.
|
||||
/* Return here... the response will be provided later by
|
||||
* the worker thread.
|
||||
*/
|
||||
|
||||
return OK;
|
||||
@@ -891,6 +906,7 @@ static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
/****************************************************************************
|
||||
* Initialization/Un-Initialization
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_lununinitialize
|
||||
****************************************************************************/
|
||||
@@ -912,6 +928,7 @@ static void usbmsc_lununinitialize(struct usbmsc_lun_s *lun)
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Internal Interfaces
|
||||
****************************************************************************/
|
||||
@@ -929,10 +946,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 +967,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 +993,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->devdesc,
|
||||
hispeed);
|
||||
ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINCONFIGFAIL), 0);
|
||||
@@ -991,13 +1006,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->devdesc,
|
||||
hispeed);
|
||||
ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true);
|
||||
if (ret < 0)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTCONFIGFAIL), 0);
|
||||
@@ -1015,10 +1026,12 @@ 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)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDSUBMIT), (uint16_t)-ret);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDSUBMIT),
|
||||
(uint16_t)-ret);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
@@ -1067,7 +1080,8 @@ void usbmsc_resetconfig(FAR struct usbmsc_dev_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void usbmsc_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
|
||||
void usbmsc_wrcomplete(FAR struct usbdev_ep_s *ep,
|
||||
FAR struct usbdev_req_s *req)
|
||||
{
|
||||
FAR struct usbmsc_dev_s *priv;
|
||||
FAR struct usbmsc_req_s *privreq;
|
||||
@@ -1127,7 +1141,8 @@ void usbmsc_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void usbmsc_rdcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
|
||||
void usbmsc_rdcomplete(FAR struct usbdev_ep_s *ep,
|
||||
FAR struct usbdev_req_s *req)
|
||||
{
|
||||
FAR struct usbmsc_dev_s *priv;
|
||||
FAR struct usbmsc_req_s *privreq;
|
||||
@@ -1290,6 +1305,7 @@ static inline void usbmsc_sync_wait(FAR struct usbmsc_dev_s *priv)
|
||||
/****************************************************************************
|
||||
* User Interfaces
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_configure
|
||||
*
|
||||
@@ -1494,10 +1510,10 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath,
|
||||
|
||||
memset(lun, 0, sizeof(struct usbmsc_lun_s));
|
||||
|
||||
/* Allocate an I/O buffer big enough to hold one hardware sector. SCSI commands
|
||||
* are processed one at a time so all LUNs may share a single I/O buffer. The
|
||||
* I/O buffer will be allocated so that is it as large as the largest block
|
||||
* device sector size
|
||||
/* Allocate an I/O buffer big enough to hold one hardware sector. SCSI
|
||||
* commands are processed one at a time so all LUNs may share a single I/O
|
||||
* buffer. The I/O buffer will be allocated so that is it as large as the
|
||||
* largest block device sector size
|
||||
*/
|
||||
|
||||
if (!priv->iobuffer)
|
||||
@@ -1513,8 +1529,9 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath,
|
||||
}
|
||||
else if (priv->iosize < geo.geo_sectorsize)
|
||||
{
|
||||
void *tmp;
|
||||
tmp = (FAR uint8_t *)kmm_realloc(priv->iobuffer, geo.geo_sectorsize);
|
||||
FAR void *tmp;
|
||||
|
||||
tmp = (FAR void *)kmm_realloc(priv->iobuffer, geo.geo_sectorsize);
|
||||
if (!tmp)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER), geo.geo_sectorsize);
|
||||
@@ -1669,7 +1686,8 @@ int usbmsc_exportluns(FAR void *handle)
|
||||
usbmsc_scsi_main, NULL);
|
||||
if (priv->thpid <= 0)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_THREADCREATE), (uint16_t)errno);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_THREADCREATE),
|
||||
(uint16_t)errno);
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
@@ -1720,12 +1738,17 @@ errout_with_lock:
|
||||
|
||||
#ifdef CONFIG_USBMSC_COMPOSITE
|
||||
int usbmsc_classobject(FAR void *handle,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev)
|
||||
{
|
||||
FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(handle && classdev);
|
||||
DEBUGASSERT(handle != NULL && classdev != NULL);
|
||||
|
||||
/* Save the device description */
|
||||
|
||||
memcpy(&alloc->dev.devdesc, devdesc, sizeof(struct usbdev_description_s));
|
||||
|
||||
/* Export the LUNs as with the "standalone" USB mass storage driver, but
|
||||
* don't register the class instance with the USB device infrastructure.
|
||||
@@ -1762,9 +1785,6 @@ void usbmsc_uninitialize(FAR void *handle)
|
||||
FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
|
||||
FAR struct usbmsc_dev_s *priv;
|
||||
irqstate_t flags;
|
||||
#if 0
|
||||
void *value;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
@@ -1860,3 +1880,61 @@ 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)
|
||||
{
|
||||
memset(dev, 0, sizeof(struct composite_devdesc_s));
|
||||
|
||||
/* The callback functions for the CDC/ACM class.
|
||||
*
|
||||
* classobject() and uninitializ() must be provided by board-specific
|
||||
* logic
|
||||
*/
|
||||
|
||||
dev->mkconfdesc = usbmsc_mkcfgdesc;
|
||||
dev->mkstrdesc = usbmsc_mkstrdesc;
|
||||
|
||||
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 */
|
||||
|
||||
/* Board-specific logic must provide the device minor */
|
||||
|
||||
/* Interfaces.
|
||||
*
|
||||
* ifnobase must be provided by board-specific logic
|
||||
*/
|
||||
|
||||
dev->devdesc.ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces in the configuration */
|
||||
|
||||
/* Strings.
|
||||
*
|
||||
* strbase must be provided by board-specific logic
|
||||
*/
|
||||
|
||||
dev->devdesc.nstrings = USBMSC_NSTRIDS; /* Number of Strings */
|
||||
|
||||
/* Endpoints.
|
||||
*
|
||||
* Endpoint numbers must be provided by board-specific logic.
|
||||
*/
|
||||
|
||||
dev->devdesc.nendpoints = USBMSC_NENDPOINTS;
|
||||
}
|
||||
#endif
|
||||
@@ -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.
|
||||
@@ -57,6 +57,7 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
/* If the USB mass storage device is configured as part of a composite device
|
||||
* then both CONFIG_USBDEV_COMPOSITE and CONFIG_USBMSC_COMPOSITE must be
|
||||
@@ -98,14 +99,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 +298,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 +320,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 +331,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 \
|
||||
@@ -377,9 +340,12 @@
|
||||
|
||||
/* Block driver helpers *****************************************************/
|
||||
|
||||
#define USBMSC_DRVR_READ(l,b,s,n) ((l)->inode->u.i_bops->read((l)->inode,b,s,n))
|
||||
#define USBMSC_DRVR_WRITE(l,b,s,n) ((l)->inode->u.i_bops->write((l)->inode,b,s,n))
|
||||
#define USBMSC_DRVR_GEOMETRY(l,g) ((l)->inode->u.i_bops->geometry((l)->inode,g))
|
||||
#define USBMSC_DRVR_READ(l,b,s,n) \
|
||||
((l)->inode->u.i_bops->read((l)->inode,b,s,n))
|
||||
#define USBMSC_DRVR_WRITE(l,b,s,n) \
|
||||
((l)->inode->u.i_bops->write((l)->inode,b,s,n))
|
||||
#define USBMSC_DRVR_GEOMETRY(l,g) \
|
||||
((l)->inode->u.i_bops->geometry((l)->inode,g))
|
||||
|
||||
/* Everpresent MIN/MAX macros ***********************************************/
|
||||
|
||||
@@ -398,13 +364,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 */
|
||||
@@ -419,7 +380,7 @@ struct usbmsc_req_s
|
||||
|
||||
struct usbmsc_lun_s
|
||||
{
|
||||
struct inode *inode; /* Inode structure of open'ed block driver */
|
||||
FAR struct inode *inode; /* Inode structure of open'ed block driver */
|
||||
uint8_t readonly:1; /* Media is read-only */
|
||||
uint8_t locked:1; /* Media removal is prevented */
|
||||
uint16_t sectorsize; /* The size of one sector */
|
||||
@@ -487,6 +448,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.
|
||||
@@ -536,11 +499,11 @@ EXTERN const char g_compserialstr[];
|
||||
|
||||
EXTERN FAR struct usbmsc_dev_s *g_usbmsc_handoff;
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_scsi_lock
|
||||
*
|
||||
* Description:
|
||||
@@ -550,91 +513,95 @@ EXTERN FAR struct usbmsc_dev_s *g_usbmsc_handoff;
|
||||
|
||||
void usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_scsi_unlock
|
||||
*
|
||||
* Description:
|
||||
* Relinquish exclusive access to SCSI state data.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#define usbmsc_scsi_unlock(priv) sem_post(&priv->thlock)
|
||||
|
||||
/************************************************************************************
|
||||
/*****************************************************************************
|
||||
* Name: usbmsc_scsi_signal
|
||||
*
|
||||
* Description:
|
||||
* Signal the SCSI worker thread that SCSI events need service.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
void usbmsc_scsi_signal(FAR struct usbmsc_dev_s *priv);
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_synch_signal
|
||||
*
|
||||
* Description:
|
||||
* ACK controlling tasks request for synchronization.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#define usbmsc_synch_signal(priv) sem_post(&priv->thsynch)
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_mkstrdesc
|
||||
*
|
||||
* Description:
|
||||
* Construct a string descriptor
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
struct usb_strdesc_s;
|
||||
int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_getdevdesc
|
||||
*
|
||||
* Description:
|
||||
* Return a pointer to the raw device descriptor
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
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
|
||||
*
|
||||
* Description:
|
||||
* Construct the configuration descriptor
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#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
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_getqualdesc
|
||||
*
|
||||
* Description:
|
||||
* Return a pointer to the raw qual descriptor
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_USBMSC_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
|
||||
FAR const struct usb_qualdesc_s *usbmsc_getqualdesc(void);
|
||||
@@ -725,4 +692,4 @@ void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #define __DRIVERS_USBDEV_USBMSC_H */
|
||||
#endif /* __DRIVERS_USBDEV_USBMSC_H */
|
||||
|
||||
@@ -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
|
||||
@@ -50,21 +50,10 @@
|
||||
|
||||
#include "usbmsc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Descriptors **************************************************************/
|
||||
/* Device descriptor. If the USB mass storage device is configured as part
|
||||
* of a composite device, then the device descriptor will be provided by the
|
||||
@@ -92,79 +81,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 +107,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 +201,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 +216,89 @@ 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;
|
||||
}
|
||||
};
|
||||
|
||||
return sizeof(struct usb_epdesc_s);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_mkcfgdesc
|
||||
@@ -358,53 +309,104 @@ 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) */
|
||||
|
||||
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 */
|
||||
|
||||
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 +425,3 @@ FAR const struct usb_qualdesc_s *usbmsc_getqualdesc(void)
|
||||
return &g_qualdesc;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -263,6 +263,28 @@ int board_composite_initialize(int port);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_composite_connect
|
||||
*
|
||||
* Description:
|
||||
* Connect the USB composite device on the specified USB device port using
|
||||
* the specified configuration. The interpretation of the configid is
|
||||
* board specific.
|
||||
*
|
||||
* Input Parameters:
|
||||
* port - The USB device port.
|
||||
* configid - The USB composite configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL handle value is returned on success. NULL is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE)
|
||||
FAR void *board_composite_connect(int port, int configid);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_tsc_setup
|
||||
*
|
||||
|
||||
@@ -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 device’s MAC
|
||||
* driver to change settings of the Networking device’s
|
||||
* 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
|
||||
@@ -593,9 +593,8 @@ 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. */
|
||||
};
|
||||
#define SIZEOF_HDR_FUNCDESC 5
|
||||
|
||||
@@ -788,7 +787,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 +832,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 */
|
||||
|
||||
@@ -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
|
||||
@@ -306,51 +329,6 @@ typedef FAR void (*cdcacm_callback_t)(enum cdcacm_event_e event);
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_cdcclassobject
|
||||
*
|
||||
* Description:
|
||||
* If the CDC serial class driver is part of composite device, then
|
||||
* board-specific logic must provide board_cdcclassobject(). In the
|
||||
* simplest case, board_cdcclassobject() is simply a wrapper around
|
||||
* cdcacm_classobject() that provides the correct device minor number.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The location to return the CDC serial class' device
|
||||
* instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE)
|
||||
struct usbdevclass_driver_s;
|
||||
int board_cdcclassobject(FAR struct usbdevclass_driver_s **classdev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_cdcuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB serial class driver. This is just an application-
|
||||
* specific wrapper around cdcadm_unitialize() that is called form the
|
||||
* composite device logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The class driver instance previously give to the composite
|
||||
* driver by board_cdcclassobject().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_CDCACM_COMPOSITE)
|
||||
struct usbdevclass_driver_s;
|
||||
void board_cdcuninitialize(FAR struct usbdevclass_driver_s *classdev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_classobject
|
||||
*
|
||||
@@ -370,7 +348,10 @@ 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;
|
||||
struct usbdevclass_driver_s;
|
||||
int cdcacm_classobject(int minor, FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@@ -409,8 +390,7 @@ int cdcacm_initialize(int minor, FAR void **handle);
|
||||
* CDC/ACM driver is an internal part of a composite device, or a
|
||||
* standalone USB driver:
|
||||
*
|
||||
* classdev - The class object returned by board_cdcclassobject() or
|
||||
* cdcacm_classobject()
|
||||
* classdev - The class object returned by cdcacm_classobject()
|
||||
* handle - The opaque handle representing the class object returned by
|
||||
* a previous call to cdcacm_initialize().
|
||||
*
|
||||
@@ -425,6 +405,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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
****************************************************************************/
|
||||
@@ -97,8 +104,7 @@ extern "C"
|
||||
* 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(), ...)
|
||||
* each of the members of the composite.
|
||||
*
|
||||
* Input Parameter:
|
||||
* None
|
||||
@@ -113,7 +119,8 @@ extern "C"
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *composite_initialize(void);
|
||||
FAR void *composite_initialize(uint8_t ndevices,
|
||||
FAR struct composite_devdesc_s *pdevices);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: composite_uninitialize
|
||||
@@ -122,8 +129,7 @@ FAR void *composite_initialize(void);
|
||||
* Un-initialize the USB composite driver. The handle is the USB composite
|
||||
* class' device object as was returned by composite_initialize(). This
|
||||
* function will call board-specific implementations in order to free the
|
||||
* class objects for each of the members of the composite (see
|
||||
* board_mscuninitialize(), board_cdcuninitialize(), ...)
|
||||
* class objects for each of the members of the composite.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle returned by a previous call to composite_initialize().
|
||||
@@ -135,30 +141,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
|
||||
*
|
||||
|
||||
@@ -196,6 +196,48 @@
|
||||
|
||||
/* USB Controller Structures ********************************************************/
|
||||
|
||||
/* usbdev_description_s - describes the low level bindings of an usb device */
|
||||
|
||||
struct usbdev_description_s
|
||||
{
|
||||
int ninterfaces; /* Number of interfaces in the configuration */
|
||||
int ifnobase; /* Offset to Interface-IDs */
|
||||
|
||||
int nstrings; /* Number of Strings */
|
||||
int strbase; /* Offset to String Numbers */
|
||||
|
||||
int nendpoints; /* Number of Endpoints referenced in the following allay */
|
||||
int epno[5]; /* Array holding the endpoint configuration for this device */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USBDEV_COMPOSITE
|
||||
struct composite_devdesc_s
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
CODE int16_t (*mkconfdesc)(FAR uint8_t *buf,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
uint8_t speed, uint8_t type);
|
||||
#else
|
||||
CODE int16_t (*mkconfdesc)(FAR uint8_t *buf,
|
||||
FAR struct usbdev_description_s *devdesc);
|
||||
#endif
|
||||
|
||||
CODE int (*mkstrdesc)(uint8_t id, FAR struct usb_strdesc_s *strdesc);
|
||||
CODE int (*classobject)(int minor,
|
||||
FAR struct usbdev_description_s *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev);
|
||||
CODE void (*uninitialize)(FAR struct usbdevclass_driver_s *classdev);
|
||||
|
||||
int nconfigs; /* Number of configurations supported */
|
||||
int configid; /* The only supported configuration ID */
|
||||
|
||||
int cfgdescsize; /* The size of the config descriptor */
|
||||
int minor;
|
||||
|
||||
struct usbdev_description_s devdesc;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* struct usbdev_req_s - describes one i/o request */
|
||||
|
||||
struct usbdev_ep_s;
|
||||
|
||||
@@ -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
|
||||
@@ -37,14 +37,14 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_USB_USBMSC_H
|
||||
#define __INCLUDE_NUTTX_USB_USBMSC_H
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
@@ -52,17 +52,28 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* 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
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
@@ -73,61 +84,11 @@ extern "C"
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: board_mscclassobject
|
||||
*
|
||||
* Description:
|
||||
* If the mass storage class driver is part of composite device, then
|
||||
* its instantiation and configuration is a multi-step, board-specific,
|
||||
* process (See comments for usbmsc_configure below). In this case,
|
||||
* board-specific logic must provide board_mscclassobject().
|
||||
*
|
||||
* board_mscclassobject() is called from the composite driver. It must
|
||||
* encapsulate the instantiation and configuration of the mass storage
|
||||
* class and the return the mass storage device's class driver instance
|
||||
* to the composite dirver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The location to return the mass storage class' device
|
||||
* instance.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE)
|
||||
struct usbdevclass_driver_s;
|
||||
int board_mscclassobject(FAR struct usbdevclass_driver_s **classdev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_mscuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This is just an application-
|
||||
* specific wrapper aboutn usbmsc_unitialize() that is called form the composite
|
||||
* device logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* classdev - The class driver instrance previously give to the composite
|
||||
* driver by board_mscclassobject().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBDEV_COMPOSITE) && defined(CONFIG_USBMSC_COMPOSITE)
|
||||
struct usbdevclass_driver_s;
|
||||
void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_configure
|
||||
*
|
||||
* Description:
|
||||
@@ -145,20 +106,21 @@ void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev);
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure. The returned handle value is
|
||||
* an untyped equivalent to the usbmsc_classobject() or board_mscclassobject().
|
||||
* an untyped equivalent to the usbmsc_classobject().
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
int usbmsc_configure(unsigned int nluns, void **handle);
|
||||
int usbmsc_configure(unsigned int nluns, FAR void **handle);
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_bindlun
|
||||
*
|
||||
* Description:
|
||||
* Bind the block driver specified by drvrpath to a USB storage LUN.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle returned by a previous call to usbmsc_configure().
|
||||
* handle - The handle returned by a previous call to
|
||||
* usbmsc_configure().
|
||||
* drvrpath - the full path to the block driver
|
||||
* startsector - A sector offset into the block driver to the start of the
|
||||
* partition on drvrpath (0 if no partitions)
|
||||
@@ -169,12 +131,12 @@ int usbmsc_configure(unsigned int nluns, void **handle);
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath, unsigned int lunno,
|
||||
off_t startsector, size_t nsectors, bool readonly);
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_unbindlun
|
||||
*
|
||||
* Description:
|
||||
@@ -187,16 +149,16 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath, unsigned int lunn
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
int usbmsc_unbindlun(FAR void *handle, unsigned int lunno);
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_exportluns
|
||||
*
|
||||
* Description:
|
||||
* After all of the LUNs have been bound, this function may be called in order to
|
||||
* export those LUNs in the USB storage device.
|
||||
* After all of the LUNs have been bound, this function may be called in
|
||||
* order to export those LUNs in the USB storage device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle returned by a previous call to usbmsc_configure().
|
||||
@@ -204,13 +166,13 @@ int usbmsc_unbindlun(FAR void *handle, unsigned int lunno);
|
||||
* Returned Value:
|
||||
* 0 on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_USBDEV_COMPOSITE) || !defined(CONFIG_USBMSC_COMPOSITE)
|
||||
int usbmsc_exportluns(FAR void *handle);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_classobject
|
||||
*
|
||||
* Description:
|
||||
@@ -222,22 +184,22 @@ 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 *devdesc,
|
||||
FAR struct usbdevclass_driver_s **classdev);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. The handle is the USB MSC
|
||||
* class' device object. This is the same value as returned by usbmsc_classobject
|
||||
* (typed) or by usbmsc_configure (untyped).
|
||||
* class' device object. This is the same value as returned by
|
||||
* usbmsc_classobject (typed) or by usbmsc_configure (untyped).
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle returned by a previous call to usbmsc_configure()
|
||||
@@ -246,10 +208,30 @@ int usbmsc_classobject(FAR void *handle, FAR struct usbdevclass_driver_s **class
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
***********************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -247,6 +247,7 @@ struct boardioc_usbdev_ctrl_s
|
||||
uint8_t usbdev; /* See enum boardioc_usbdev_identifier_e */
|
||||
uint8_t action; /* See enum boardioc_usbdev_action_e */
|
||||
uint8_t instance; /* Identifies the USB device class instance */
|
||||
uint8_t config; /* Configuration used with BOARDIOC_USBDEV_CONNECT */
|
||||
FAR void **handle; /* Connection handle */
|
||||
};
|
||||
#endif /* CONFIG_BOARDCTL_USBDEVCTRL */
|
||||
|
||||
Reference in New Issue
Block a user