summaryrefslogtreecommitdiff
path: root/usb/device/composite
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-07-04 20:52:54 +0200
committerHarald Welte <laforge@gnumonks.org>2011-07-04 20:52:54 +0200
commit044ad7c3987460ede48ff27afd6bdb0ca05a0432 (patch)
tree924818cdb0d39ca08aec540d18da7bd406eaae8c /usb/device/composite
import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v1501120100901_softpack_1_9_v_1_0_svn_v15011
it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself
Diffstat (limited to 'usb/device/composite')
-rw-r--r--usb/device/composite/AUDDFunctionDriver.c282
-rw-r--r--usb/device/composite/AUDDFunctionDriver.h105
-rw-r--r--usb/device/composite/AUDDFunctionDriverDescriptors.h69
-rw-r--r--usb/device/composite/CDCDFunctionDriver.c337
-rw-r--r--usb/device/composite/CDCDFunctionDriver.h128
-rw-r--r--usb/device/composite/CDCDFunctionDriverDescriptors.h65
-rw-r--r--usb/device/composite/CDCHIDDDriver.c227
-rw-r--r--usb/device/composite/CDCHIDDDriver.h78
-rw-r--r--usb/device/composite/CDCHIDDDriverDescriptors.c592
-rw-r--r--usb/device/composite/CDCHIDDDriverDescriptors.h70
-rw-r--r--usb/device/composite/CDCMSDDDriver.c213
-rw-r--r--usb/device/composite/CDCMSDDDriver.h77
-rw-r--r--usb/device/composite/CDCMSDDDriverDescriptors.c568
-rw-r--r--usb/device/composite/CDCMSDDDriverDescriptors.h71
-rw-r--r--usb/device/composite/COMPOSITEDDriver.c292
-rw-r--r--usb/device/composite/COMPOSITEDDriver.h93
-rw-r--r--usb/device/composite/COMPOSITEDDriverDescriptors.c954
-rw-r--r--usb/device/composite/COMPOSITEDDriverDescriptors.h61
-rw-r--r--usb/device/composite/DUALCDCDDriver.c189
-rw-r--r--usb/device/composite/DUALCDCDDriver.h77
-rw-r--r--usb/device/composite/DUALCDCDDriverDescriptors.c702
-rw-r--r--usb/device/composite/DUALCDCDDriverDescriptors.h72
-rw-r--r--usb/device/composite/HIDDFunctionDriver.c477
-rw-r--r--usb/device/composite/HIDDFunctionDriver.h64
-rw-r--r--usb/device/composite/HIDDFunctionDriverDescriptors.c118
-rw-r--r--usb/device/composite/HIDDFunctionDriverDescriptors.h86
-rw-r--r--usb/device/composite/HIDMSDDDriver.c227
-rw-r--r--usb/device/composite/HIDMSDDDriver.h79
-rw-r--r--usb/device/composite/HIDMSDDDriverDescriptors.c449
-rw-r--r--usb/device/composite/HIDMSDDDriverDescriptors.h66
-rw-r--r--usb/device/composite/MSDDFunctionDriver.c327
-rw-r--r--usb/device/composite/MSDDFunctionDriver.h72
-rw-r--r--usb/device/composite/MSDDFunctionDriverDescriptors.h69
-rw-r--r--usb/device/composite/drv/CompositeCDCSerial.inf57
-rw-r--r--usb/device/composite/drv/drv.dir45
35 files changed, 7458 insertions, 0 deletions
diff --git a/usb/device/composite/AUDDFunctionDriver.c b/usb/device/composite/AUDDFunctionDriver.c
new file mode 100644
index 0000000..a1645aa
--- /dev/null
+++ b/usb/device/composite/AUDDFunctionDriver.c
@@ -0,0 +1,282 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <utility/led.h>
+// USB
+#include <usb/device/core/USBD.h>
+// AUDIO
+#include <usb/common/audio/AUDGenericRequest.h>
+#include <usb/common/audio/AUDFeatureUnitRequest.h>
+
+#include "AUDDFunctionDriver.h"
+#include "AUDDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// USB audio speaker driver instance.
+static AUDDSpeakerChannel auddSpeakerChannels[AUDD_NUMCHANNELS+1];
+/// Intermediate storage variable for the mute status of a channel.
+static unsigned char muted;
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Changes the mute status of the given channel accordingly.
+/// \param channel Number of the channel whose mute status has changed.
+//-----------------------------------------------------------------------------
+static void AUDD_MuteReceived(unsigned char channel)
+{
+ AUDDSpeakerChannel *pChannel = &auddSpeakerChannels[channel];
+ if (muted) {
+
+ if (!pChannel->muted) {
+
+ pChannel->muted = 1;
+ AUDDSpeakerChannel_MuteChanged(pChannel, 1);
+ }
+ }
+ else {
+
+ if (pChannel->muted) {
+
+ pChannel->muted = 0;
+ AUDDSpeakerChannel_MuteChanged(pChannel, 0);
+ }
+ }
+
+ USBD_Write(0, 0, 0, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+/// Sets the current value of a particular Feature control of a channel.
+/// \param channel Number of the channel whose feature will change.
+/// \param control The feature control that will change.
+/// \param length The feature data size.
+//-----------------------------------------------------------------------------
+static void AUDD_SetFeatureCurrentValue(unsigned char channel,
+ unsigned char control,
+ unsigned short length)
+{
+ TRACE_INFO_WP("sFeature ");
+ TRACE_DEBUG("\b(CS%d, CN%d, L%d) ", control, channel, length);
+
+ // Check the the requested control is supported
+ // Mute control on master channel
+ if ((control == AUDFeatureUnitRequest_MUTE)
+ && (channel < (AUDD_NUMCHANNELS+1))
+ && (length == 1)) {
+
+ unsigned int argument = channel; // Avoids compiler warning
+ USBD_Read(0, // Endpoint #0
+ &muted,
+ sizeof(muted),
+ (TransferCallback) AUDD_MuteReceived,
+ (void *) argument);
+ }
+ // Control/channel combination not supported
+ else {
+
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Sends the current value of a particular channel Feature to the USB host.
+/// \param channel Number of the channel whose feature will be sent.
+/// \param control The feature control that will be sent.
+/// \param length The feature data size.
+//-----------------------------------------------------------------------------
+static void AUDD_GetFeatureCurrentValue(unsigned char channel,
+ unsigned char control,
+ unsigned char length)
+{
+ TRACE_INFO_WP("gFeature ");
+ TRACE_DEBUG("\b(CS%d, CN%d, L%d) ", control, channel, length);
+
+ // Check that the requested control is supported
+ // Master channel mute control
+ if ((control == AUDFeatureUnitRequest_MUTE)
+ && (channel < (AUDD_NUMCHANNELS+1))
+ && (length == 1)) {
+
+ muted = auddSpeakerChannels[channel].muted;
+ USBD_Write(0, &muted, sizeof(muted), 0, 0);
+ }
+ else {
+
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes an USB audio speaker function driver
+//-----------------------------------------------------------------------------
+void AUDDFunctionDriver_Initialize()
+{
+ auddSpeakerChannels[0].muted = 0;
+ auddSpeakerChannels[0].number = AUDD_MASTERCHANNEL;
+ auddSpeakerChannels[1].muted = 0;
+ auddSpeakerChannels[1].number = AUDD_LEFTCHANNEL;
+ auddSpeakerChannels[2].muted = 0;
+ auddSpeakerChannels[2].number = AUDD_RIGHTCHANNEL;
+
+ // Initialize the third LED to indicate when the audio interface is active
+ LED_Configure(USBD_LEDOTHER);
+}
+
+//-----------------------------------------------------------------------------
+/// Handles AUDIO-specific USB requests sent by the host
+/// \param request Pointer to a USBGenericRequest instance.
+/// \return 0 if the request is Unsupported, 1 if the request handled.
+//-----------------------------------------------------------------------------
+unsigned char AUDDFunctionDriver_RequestHandler(
+ const USBGenericRequest *request)
+{
+ unsigned char entity;
+ unsigned char interface;
+
+ // Check if the request is supported
+ switch (USBGenericRequest_GetRequest(request)) {
+
+ case AUDGenericRequest_SETCUR:
+ TRACE_INFO_WP(
+ "sCur(0x%04X) ",
+ USBGenericRequest_GetIndex(request));
+
+ // Check the target interface and entity
+ entity = AUDGenericRequest_GetEntity(request);
+ interface = AUDGenericRequest_GetInterface(request);
+ if ((entity == AUDD_Descriptors_FEATUREUNIT)
+ && (interface == AUDD_Descriptors_CONTROL)) {
+
+ AUDD_SetFeatureCurrentValue(
+ AUDFeatureUnitRequest_GetChannel(request),
+ AUDFeatureUnitRequest_GetControl(request),
+ USBGenericRequest_GetLength(request));
+ }
+ else {
+
+ TRACE_WARNING(
+ "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
+ USBGenericRequest_GetIndex(request));
+ USBD_Stall(0);
+ }
+ break;
+
+ case AUDGenericRequest_GETCUR:
+ TRACE_INFO_WP(
+ "gCur(0x%04X) ",
+ USBGenericRequest_GetIndex(request));
+
+ // Check the target interface and entity
+ entity = AUDGenericRequest_GetEntity(request);
+ interface = AUDGenericRequest_GetInterface(request);
+ if ((entity == AUDD_Descriptors_FEATUREUNIT)
+ && (interface == AUDD_Descriptors_CONTROL)) {
+
+ AUDD_GetFeatureCurrentValue(
+ AUDFeatureUnitRequest_GetChannel(request),
+ AUDFeatureUnitRequest_GetControl(request),
+ USBGenericRequest_GetLength(request));
+ }
+ else {
+
+ TRACE_WARNING(
+ "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r",
+ USBGenericRequest_GetIndex(request));
+ USBD_Stall(0);
+ }
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the active setting of an interface is changed by the
+/// host. Changes the status of the third LED accordingly.
+/// \param interface Interface number.
+/// \param setting Newly active setting.
+//-----------------------------------------------------------------------------
+void AUDDFunctionCallbacks_InterfaceSettingChanged(unsigned char interface,
+ unsigned char setting)
+{
+ if ((interface == AUDD_Descriptors_STREAMING) && (setting == 0)) {
+
+ LED_Clear(USBD_LEDOTHER);
+ }
+ else {
+
+ LED_Set(USBD_LEDOTHER);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Reads incoming audio data sent by the USB host into the provided buffer.
+/// When the transfer is complete, an optional callback function is invoked.
+/// \param buffer Pointer to the data storage buffer.
+/// \param length Size of the buffer in bytes.
+/// \param callback Optional callback function.
+/// \param argument Optional argument to the callback function.
+/// \return <USBD_STATUS_SUCCESS> if the transfer is started successfully;
+/// otherwise an error code.
+//-----------------------------------------------------------------------------
+unsigned char AUDDSpeakerDriver_Read(void *buffer,
+ unsigned int length,
+ TransferCallback callback,
+ void *argument)
+{
+ return USBD_Read(AUDD_Descriptors_DATAOUT,
+ buffer,
+ length,
+ callback,
+ argument);
+}
+
+#endif // (AUDIO defined)
+
diff --git a/usb/device/composite/AUDDFunctionDriver.h b/usb/device/composite/AUDDFunctionDriver.h
new file mode 100644
index 0000000..637fc67
--- /dev/null
+++ b/usb/device/composite/AUDDFunctionDriver.h
@@ -0,0 +1,105 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef AUDDFUNCTIONDRIVER_H
+#define AUDDFUNCTIONDRIVER_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+#include <usb/device/core/USBD.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Sample rate in Hz.
+#define AUDD_SAMPLERATE 48000
+/// Number of channels in audio stream.
+#define AUDD_NUMCHANNELS 2
+/// Number of bytes in one sample.
+#define AUDD_BYTESPERSAMPLE 2
+/// Number of bits in one sample.
+#define AUDD_BITSPERSAMPLE (AUDD_BYTESPERSAMPLE * 8)
+/// Number of samples in one USB subframe.
+#define AUDD_BYTESPERSUBFRAME (AUDD_NUMCHANNELS * AUDD_BYTESPERSAMPLE)
+/// Number of samples in one USB frame.
+#define AUDD_SAMPLESPERFRAME (AUDD_SAMPLERATE / 1000 * AUDD_NUMCHANNELS)
+/// Number of bytes in one USB frame.
+#define AUDD_BYTESPERFRAME (AUDD_SAMPLESPERFRAME * AUDD_BYTESPERSAMPLE)
+/// Master channel.
+#define AUDD_MASTERCHANNEL 0
+/// Front left channel.
+#define AUDD_LEFTCHANNEL 1
+/// Front right channel.
+#define AUDD_RIGHTCHANNEL 2
+
+//-----------------------------------------------------------------------------
+// Structs
+//-----------------------------------------------------------------------------
+
+/// AUDIO Speaker channel struct
+typedef struct {
+
+ unsigned char number;
+ unsigned char muted;
+
+} AUDDSpeakerChannel;
+
+//-----------------------------------------------------------------------------
+// Callbacks
+//-----------------------------------------------------------------------------
+extern void AUDDSpeakerChannel_MuteChanged(AUDDSpeakerChannel *channel,
+ unsigned char muted);
+
+extern void AUDDFunctionCallbacks_InterfaceSettingChanged(
+ unsigned char interface,
+ unsigned char setting);
+
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//- Function API For composite device
+extern void AUDDFunctionDriver_Initialize();
+
+extern unsigned char AUDDFunctionDriver_RequestHandler(
+ const USBGenericRequest * request);
+
+//- AUDIO Speaker API
+extern unsigned char AUDDSpeakerDriver_Read(void *buffer,
+ unsigned int length,
+ TransferCallback callback,
+ void *argument);
+
+#endif // #define AUDDFUNCTIONDRIVER_H
+
diff --git a/usb/device/composite/AUDDFunctionDriverDescriptors.h b/usb/device/composite/AUDDFunctionDriverDescriptors.h
new file mode 100644
index 0000000..a5a64f4
--- /dev/null
+++ b/usb/device/composite/AUDDFunctionDriverDescriptors.h
@@ -0,0 +1,69 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef AUDDFUNCTIONDRIVERDESCRIPTORS_H
+#define AUDDFUNCTIONDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <board.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// COMPOSITE option
+#if defined(usb_CDCAUDIO)
+#define AUDD_Descriptors_INTERFACE 2
+#elif defined(usb_HIDAUDIO)
+#define AUDD_Descriptors_INTERFACE 1
+#endif
+
+/// - Endpoint numbers
+/// Data out endpoint number
+#define AUDD_Descriptors_DATAOUT 0x05
+
+/// - Interface IDs
+/// Audio control interface ID
+#define AUDD_Descriptors_CONTROL (AUDD_Descriptors_INTERFACE + 0)
+/// Audio streaming interface ID
+#define AUDD_Descriptors_STREAMING (AUDD_Descriptors_INTERFACE + 1)
+
+/// - Entity IDs
+/// Input terminal ID.
+#define AUDD_Descriptors_INPUTTERMINAL 0
+/// Output terminal ID.
+#define AUDD_Descriptors_OUTPUTTERMINAL 1
+/// Feature unit ID.
+#define AUDD_Descriptors_FEATUREUNIT 2
+
+#endif // #define AUDDFUNCTIONDRIVERDESCRIPTORS_H
diff --git a/usb/device/composite/CDCDFunctionDriver.c b/usb/device/composite/CDCDFunctionDriver.c
new file mode 100644
index 0000000..4e42015
--- /dev/null
+++ b/usb/device/composite/CDCDFunctionDriver.c
@@ -0,0 +1,337 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+// USB
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+// CDC
+#include <usb/common/cdc/CDCGenericRequest.h>
+#include <usb/common/cdc/CDCSetControlLineStateRequest.h>
+
+#include "CDCDFunctionDriver.h"
+#include "CDCDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Types
+//-----------------------------------------------------------------------------
+
+/// CDC Function Driver Struct
+typedef struct {
+ USBDDriver * pUsbdDriver;
+ CDCDSerialPort * pCdcPorts;
+ unsigned char numPorts;
+} CDCFunDriver;
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// CDC Function Driver instance
+static CDCFunDriver cdcFunDriver;
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Callback function which should be invoked after the data of a
+/// SetLineCoding request has been retrieved. Sends a zero-length packet
+/// to the host for acknowledging the request.
+//-----------------------------------------------------------------------------
+static void CDCD_SetLineCodingCallback()
+{
+ USBD_Write(0, 0, 0, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+/// Return the port index that host send this request for.
+//-----------------------------------------------------------------------------
+static char CDCD_GetSerialPort(const USBGenericRequest *request)
+{
+ unsigned char i;
+ for (i = 0; i < cdcFunDriver.numPorts; i ++) {
+ if (request->wIndex == cdcFunDriver.pCdcPorts[i].interfaceNum + 1)
+ return i;
+ }
+ return 0xFF;
+}
+
+//-----------------------------------------------------------------------------
+/// Receives new line coding information from the USB host.
+/// \param request Pointer to a USBGenericRequest instance.
+//-----------------------------------------------------------------------------
+static void CDCD_SetLineCoding(const USBGenericRequest *request)
+{
+ unsigned char serial;
+ serial = CDCD_GetSerialPort(request);
+
+ TRACE_INFO_WP("sLineCoding_%d ", serial);
+
+ USBD_Read(0,
+ (void *) &(cdcFunDriver.pCdcPorts[serial].lineCoding),
+ sizeof(CDCLineCoding),
+ (TransferCallback) CDCD_SetLineCodingCallback,
+ 0);
+}
+
+//-----------------------------------------------------------------------------
+/// Sends the current line coding information to the host through Control
+/// endpoint 0.
+/// \param request Pointer to a USBGenericRequest instance.
+//-----------------------------------------------------------------------------
+static void CDCD_GetLineCoding(const USBGenericRequest *request)
+{
+ unsigned char serial;
+ serial = CDCD_GetSerialPort(request);
+
+ TRACE_INFO_WP("gLineCoding_%d ", serial);
+
+ USBD_Write(0,
+ (void *) &(cdcFunDriver.pCdcPorts[serial].lineCoding),
+ sizeof(CDCLineCoding),
+ 0,
+ 0);
+}
+
+//-----------------------------------------------------------------------------
+/// Changes the state of the serial driver according to the information
+/// sent by the host via a SetControlLineState request, and acknowledges
+/// the request with a zero-length packet.
+/// \param request Pointer to a USBGenericRequest instance.
+/// \param activateCarrier The active carrier state to set.
+/// \param isDTEPresent The DTE status.
+//-----------------------------------------------------------------------------
+static void CDCD_SetControlLineState(const USBGenericRequest *request,
+ unsigned char activateCarrier,
+ unsigned char isDTEPresent)
+{
+ unsigned char serial;
+ serial = CDCD_GetSerialPort(request);
+
+ TRACE_INFO_WP(
+ "sControlLineState_%d(%d, %d) ",
+ serial,
+ activateCarrier,
+ isDTEPresent);
+
+ cdcFunDriver.pCdcPorts[serial].isCarrierActivated = activateCarrier;
+ USBD_Write(0, 0, 0, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes the USB device CDC serial function driver.
+//-----------------------------------------------------------------------------
+void CDCDFunctionDriver_Initialize(USBDDriver * pUsbdDriver,
+ CDCDSerialPort * pCdcPorts,
+ unsigned char numPorts)
+{
+ unsigned char serial;
+
+ TRACE_INFO("CDCDFunctionDriver_Initialize\n\r");
+
+ cdcFunDriver.pUsbdDriver = pUsbdDriver;
+ cdcFunDriver.pCdcPorts = pCdcPorts;
+ cdcFunDriver.numPorts = numPorts;
+
+ for (serial = 0; serial < numPorts; serial ++) {
+
+ CDCDSerialPort * pSerial = &cdcFunDriver.pCdcPorts[serial];
+
+ // Initialize Abstract Control Model attributes
+ CDCLineCoding_Initialize(&(pSerial->lineCoding),
+ 115200,
+ CDCLineCoding_ONESTOPBIT,
+ CDCLineCoding_NOPARITY,
+ 8);
+ pSerial->isCarrierActivated = 0;
+ pSerial->serialState = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Handles CDC/ACM-specific USB requests sent by the host
+/// \param request Pointer to a USBGenericRequest instance.
+/// \return 0 if the request is Unsupported, 1 if the request handled.
+//-----------------------------------------------------------------------------
+unsigned char CDCDFunctionDriver_RequestHandler(
+ const USBGenericRequest *request)
+{
+ switch (USBGenericRequest_GetRequest(request)) {
+
+ case CDCGenericRequest_SETLINECODING:
+
+ CDCD_SetLineCoding(request);
+ break;
+
+ case CDCGenericRequest_GETLINECODING:
+
+ CDCD_GetLineCoding(request);
+ break;
+
+ case CDCGenericRequest_SETCONTROLLINESTATE:
+
+ CDCD_SetControlLineState(request,
+ CDCSetControlLineStateRequest_ActivateCarrier(request),
+ CDCSetControlLineStateRequest_IsDtePresent(request));
+
+ break;
+
+ // Unsupported request
+ default:
+ return 0;
+
+ }
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+/// Receives data from the host through the virtual COM port created by
+/// the CDC function serial driver. This function behaves like <USBD_Read>.
+/// \param Port Port index to receive.
+/// \param Pointer to the data buffer to send.
+/// \param Size of the data buffer in bytes.
+/// \param callback Optional callback function to invoke when the transfer
+/// finishes.
+/// \param argument Optional argument to the callback function.
+/// \return <USBD_STATUS_SUCCESS> if the read operation started normally;
+/// otherwise, the corresponding error code.
+//-----------------------------------------------------------------------------
+unsigned char CDCDSerialDriver_Read(unsigned char port,
+ void *data,
+ unsigned int size,
+ TransferCallback callback,
+ void *argument)
+{
+ unsigned char ep = cdcFunDriver.pCdcPorts[port].bulkOutEndpoint;
+
+ if (port > cdcFunDriver.numPorts)
+ return USBD_STATUS_INVALID_PARAMETER;
+
+ return USBD_Read(ep,
+ data,
+ size,
+ callback,
+ argument);
+}
+
+//-----------------------------------------------------------------------------
+/// Sends a data buffer through the virtual COM port created by the CDC
+/// function serial driver. This function behaves exactly like <USBD_Write>.
+/// \param port Port index to receive.
+/// \param data - Pointer to the data buffer to send.
+/// \param size - Size of the data buffer in bytes.
+/// \param callback - Optional callback function to invoke when the transfer
+/// finishes.
+/// \param argument - Optional argument to the callback function.
+/// \return <USBD_STATUS_SUCCESS> if the write operation started normally;
+/// otherwise, the corresponding error code.
+//-----------------------------------------------------------------------------
+unsigned char CDCDSerialDriver_Write(unsigned char port,
+ void *data,
+ unsigned int size,
+ TransferCallback callback,
+ void *argument)
+{
+ unsigned char ep = cdcFunDriver.pCdcPorts[port].bulkInEndpoint;
+
+ if (port > cdcFunDriver.numPorts)
+ return USBD_STATUS_INVALID_PARAMETER;
+
+ return USBD_Write(ep,
+ data,
+ size,
+ callback,
+ argument);
+}
+
+//------------------------------------------------------------------------------
+/// Returns the current status of the RS-232 line.
+/// \param port The port number that checked.
+//------------------------------------------------------------------------------
+unsigned short CDCDSerialDriver_GetSerialState(unsigned char port)
+{
+ if (port > cdcFunDriver.numPorts)
+ return USBD_STATUS_INVALID_PARAMETER;
+
+ return cdcFunDriver.pCdcPorts[port].serialState;
+}
+
+//------------------------------------------------------------------------------
+/// Sets the current serial state of the device to the given value.
+/// \param port The port number that the port state should be changed.
+/// \param serialState New device state.
+//------------------------------------------------------------------------------
+void CDCDSerialDriver_SetSerialState(unsigned char port,
+ unsigned short serialState)
+{
+ CDCDSerialPort * pPort;
+ unsigned char ep;
+
+ ASSERT((serialState & 0xFF80) == 0,
+ "CDCDSerialDriver_SetSerialState: Bits D7-D15 are reserved!\n\r");
+
+ if (port > cdcFunDriver.numPorts)
+ return;
+
+ // If new state is different from previous one, send a notification to the
+ // host
+ pPort = &cdcFunDriver.pCdcPorts[port];
+ ep = pPort->interruptInEndpoint;
+ if (pPort->serialState != serialState) {
+
+ pPort->serialState = serialState;
+ USBD_Write(ep,
+ &(pPort->serialState),
+ 2,
+ 0,
+ 0);
+
+ // Reset one-time flags
+ pPort->serialState &= ~(CDCD_STATE_OVERRUN
+ | CDCD_STATE_PARITY
+ | CDCD_STATE_FRAMING
+ | CDCD_STATE_RINGSIGNAL
+ | CDCD_STATE_BREAK);
+ }
+}
diff --git a/usb/device/composite/CDCDFunctionDriver.h b/usb/device/composite/CDCDFunctionDriver.h
new file mode 100644
index 0000000..0a9e5d2
--- /dev/null
+++ b/usb/device/composite/CDCDFunctionDriver.h
@@ -0,0 +1,128 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef CDCDFUNCTIONDRIVER_H
+#define CDCDFUNCTIONDRIVER_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+#include <usb/common/cdc/CDCLineCoding.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Indicates the receiver carrier signal is present.
+#define CDCD_STATE_RXDRIVER (1 << 0)
+/// Indicates the transmission carrier signal is present.
+#define CDCD_STATE_TXCARRIER (1 << 1)
+/// Indicates a break has been detected.
+#define CDCD_STATE_BREAK (1 << 2)
+/// Indicates a ring signal has been detected.
+#define CDCD_STATE_RINGSIGNAL (1 << 3)
+/// Indicates a framing error has occured.
+#define CDCD_STATE_FRAMING (1 << 4)
+/// Indicates a parity error has occured.
+#define CDCD_STATE_PARITY (1 << 5)
+/// Indicates a data overrun error has occured.
+#define CDCD_STATE_OVERRUN (1 << 6)
+
+//-----------------------------------------------------------------------------
+// Structs
+//-----------------------------------------------------------------------------
+
+/// CDC Serial port struct
+typedef struct _CDCDSerialPort{
+
+ /// USB interface settings
+ unsigned char interfaceNum;
+ unsigned char interruptInEndpoint;
+ unsigned char bulkInEndpoint;
+ unsigned char bulkOutEndpoint;
+ /// serial port settings
+ CDCLineCoding lineCoding;
+ unsigned char isCarrierActivated;
+ unsigned short serialState;
+
+} CDCDSerialPort;
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+#define CDCDFunctionDriver_ConfigurePort(pPort,ifNum,intIN,bulkIN,bulkOUT) \
+{\
+ (pPort)->interfaceNum=(ifNum);(pPort)->interruptInEndpoint=(intIN); \
+ (pPort)->bulkInEndpoint=(bulkIN);(pPort)->bulkOutEndpoint=(bulkOUT); \
+}
+
+//-----------------------------------------------------------------------------
+// Callbacks
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//- Function API for composite device
+extern void CDCDFunctionDriver_Initialize(USBDDriver * pUsbdDriver,
+ CDCDSerialPort * pCdcPorts,
+ unsigned char numPorts);
+
+extern unsigned char CDCDFunctionDriver_RequestHandler(
+ const USBGenericRequest * request);
+
+//- CDC Serial Port API
+extern unsigned char CDCDSerialDriver_Write(
+ unsigned char port,
+ void *data,
+ unsigned int size,
+ TransferCallback callback,
+ void *argument);
+
+extern unsigned char CDCDSerialDriver_Read(
+ unsigned char port,
+ void *data,
+ unsigned int size,
+ TransferCallback callback,
+ void *argument);
+
+extern unsigned short CDCDSerialDriver_GetSerialState(unsigned char port);
+
+extern void CDCDSerialDriver_SetSerialState(
+ unsigned char port,
+ unsigned short serialState);
+
+
+#endif // #define CDCDFUNCTIONDRIVER_H
+
diff --git a/usb/device/composite/CDCDFunctionDriverDescriptors.h b/usb/device/composite/CDCDFunctionDriverDescriptors.h
new file mode 100644
index 0000000..33490ae
--- /dev/null
+++ b/usb/device/composite/CDCDFunctionDriverDescriptors.h
@@ -0,0 +1,65 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef CDCDFUNCTIONDRIVERDESCRIPTORS_H
+#define CDCDFUNCTIONDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <board.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+#if defined(usb_CDCAUDIO)
+#define CDCD_Descriptors_INTERFACENUM0 0
+#define CDCD_Descriptors_NOTIFICATION0 3
+#define CDCD_Descriptors_DATAIN0 2
+#define CDCD_Descriptors_DATAOUT0 1
+#endif
+
+/// Default CDC interrupt endpoints max packat size (8).
+#define CDCD_Descriptors_INTERRUPT_MAXPACKETSIZE 8
+/// Default CDC bulk endpoints max packat size (128, for HS actually).
+#define CDCD_Descriptors_BULK_MAXPACKETSIZE 128
+
+/// Default CDC interrupt IN endpoint polling rate of Full Speed (16ms).
+#define CDCD_Descriptors_INTERRUPTIN_POLLING_FS 16
+/// Default CDC interrupt IN endpoint polling rate of High Speed (16ms).
+#define CDCD_Descriptors_INTERRUPTIN_POLLING_HS 8
+/// Default interrupt OUT endpoint polling rate of Full Speed (16ms).
+#define CDCD_Descriptors_INTERRUPTOUT_POLLING_FS 16
+/// Default interrupt OUT endpoint polling rate of High Speed (16ms).
+#define CDCD_Descriptors_INTERRUPTOUT_POLLING_HS 8
+
+#endif // #define CDCFUNCTIONDRIVERDESCRIPTORS_H
diff --git a/usb/device/composite/CDCHIDDDriver.c b/usb/device/composite/CDCHIDDDriver.c
new file mode 100644
index 0000000..84c16a6
--- /dev/null
+++ b/usb/device/composite/CDCHIDDDriver.c
@@ -0,0 +1,227 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <utility/led.h>
+
+// USB
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+
+//- HID
+#include <usb/device/hid-keyboard/HIDDKeyboardDriver.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardDriverDescriptors.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardCallbacks.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDGenericRequest.h>
+#include <usb/common/hid/HIDReportRequest.h>
+#include <usb/common/hid/HIDIdleRequest.h>
+#include <usb/common/hid/HIDKeypad.h>
+
+//- MSD
+#if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+#endif
+
+//- CDCHID
+#include "CDCHIDDDriver.h"
+#include "CDCHIDDDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+/// Interface setting spaces (4 byte aligned)
+#define NUM_INTERFACES ((CDCHIDDDriverDescriptors_NUMINTERFACE+3)&0xFC)
+
+//-----------------------------------------------------------------------------
+// Types
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// USBDDriver instance
+static USBDDriver usbdDriver;
+
+/// CDCDSeriaoPort instance
+static CDCDSerialPort cdcdPort;
+
+/// Array for storing the current setting of each interface
+static unsigned char cdchiddDriverInterfaces[NUM_INTERFACES];
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Optional RequestReceived() callback re-implementation
+//-----------------------------------------------------------------------------
+#if !defined(NOAUTOCALLBACK)
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ CDCHIDDDriver_RequestHandler(request);
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+// ConfigurationChanged() callback re-implementation
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the configuration value of a device is changed by the host
+/// \param cfgnum Configuration number.
+//-----------------------------------------------------------------------------
+void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+ // HID
+ HIDDFunctionCallbacks_ConfigurationChanged(cfgnum);
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes the USB device composite device driver.
+//-----------------------------------------------------------------------------
+void CDCHIDDDriver_Initialize()
+{
+ // CDC
+ CDCDFunctionDriver_ConfigurePort(&cdcdPort,
+ CDCD_Descriptors_INTERFACENUM0,
+ CDCD_Descriptors_NOTIFICATION0,
+ CDCD_Descriptors_DATAIN0,
+ CDCD_Descriptors_DATAOUT0);
+ CDCDFunctionDriver_Initialize(&usbdDriver,
+ &cdcdPort,
+ 1);
+
+ // HID
+ HIDDFunctionDriver_Initialize(&usbdDriver,
+ HIDD_Descriptors_INTERFACENUM,
+ HIDD_Descriptors_INTERRUPTIN,
+ HIDD_Descriptors_INTERRUPTOUT);
+
+ // Initialize the standard USB driver
+ USBDDriver_Initialize(&usbdDriver,
+ &cdchiddDriverDescriptors,
+ cdchiddDriverInterfaces);
+
+ // Initialize the USB driver
+ USBD_Init();
+}
+
+//-----------------------------------------------------------------------------
+/// Handles composite-specific USB requests sent by the host, and forwards
+/// standard ones to the USB device driver.
+/// \param request Pointer to a USBGenericRequest instance.
+//-----------------------------------------------------------------------------
+void CDCHIDDDriver_RequestHandler(const USBGenericRequest *request)
+{
+ // Check if this is a class request
+ if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
+
+ unsigned char rc = 0;
+
+ // CDC class request
+ if (rc == 0) {
+
+ rc = CDCDFunctionDriver_RequestHandler(request);
+ }
+
+ // HID class request
+ if (rc == 0) {
+
+ rc = HIDDFunctionDriver_RequestHandler(request);
+ }
+
+ if (!rc) {
+
+ TRACE_WARNING(
+ "CDCHIDDDriver_RequestHandler: Unsupported request (%d)\n\r",
+ USBGenericRequest_GetRequest(request));
+ USBD_Stall(0);
+ }
+
+ }
+ // Check if this is a standard request
+ else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
+
+ unsigned char rc = 0;
+
+ rc = HIDDFunctionDriver_RequestHandler(request);
+
+ // Forward request to the standard handler
+ if (rc == 0) {
+
+ USBDDriver_RequestHandler(&(usbdDriver), request);
+ }
+ }
+ // Unsupported request type
+ else {
+
+ TRACE_WARNING(
+ "CDCHIDDDriver_RequestHandler: Unsupported request type (%d)\n\r",
+ USBGenericRequest_GetType(request));
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Starts a remote wake-up sequence if the host has explicitely enabled it
+/// by sending the appropriate SET_FEATURE request.
+//-----------------------------------------------------------------------------
+void CDCHIDDDriver_RemoteWakeUp(void)
+{
+ // Remote wake-up has been enabled
+ if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver)) {
+
+ USBD_RemoteWakeUp();
+ }
+ // Remote wake-up NOT enabled
+ else {
+
+ TRACE_WARNING("CDCHIDDDriver_RemoteWakeUp: not enabled\n\r");
+ }
+}
+
+
diff --git a/usb/device/composite/CDCHIDDDriver.h b/usb/device/composite/CDCHIDDDriver.h
new file mode 100644
index 0000000..d7ef755
--- /dev/null
+++ b/usb/device/composite/CDCHIDDDriver.h
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Definitions and methods for USB composite device implement.
+///
+/// !Usage
+///
+/// -# Initialize USB function specified driver ( for MSD currently )
+/// - MSDDFunctionDriver_Initialize
+///
+/// -# Initialize USB composite driver and USB driver
+/// - CDCHIDDDriver_Initialize
+///
+/// -# Handle and dispach USB requests
+/// - CDCHIDDDriver_RequestHandler
+///
+/// -# Try starting a remote wake-up sequence
+/// - CDCHIDDDriver_RemoteWakeUp
+//-----------------------------------------------------------------------------
+
+#ifndef CDCHIDDDRIVER_H
+#define CDCHIDDDRIVER_H
+
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+#include <usb/device/core/USBD.h>
+
+#include "CDCDFunctionDriver.h"
+#include "HIDDFunctionDriver.h"
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+// -CDCHID
+extern void CDCHIDDDriver_Initialize();
+
+extern void CDCHIDDDriver_RequestHandler(const USBGenericRequest *request);
+
+extern void CDCHIDDDriver_RemoteWakeUp(void);
+
+#endif //#ifndef CDCHIDDDRIVER_H
+
diff --git a/usb/device/composite/CDCHIDDDriverDescriptors.c b/usb/device/composite/CDCHIDDDriverDescriptors.c
new file mode 100644
index 0000000..e19ba2d
--- /dev/null
+++ b/usb/device/composite/CDCHIDDDriverDescriptors.c
@@ -0,0 +1,592 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+
+//- Composite
+#include "CDCHIDDDriver.h"
+#include "CDCHIDDDriverDescriptors.h"
+
+//- USB Generic
+#include <usb/common/core/USBGenericDescriptor.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/common/core/USBInterfaceAssociationDescriptor.h>
+#include <usb/common/core/USBEndpointDescriptor.h>
+#include <usb/common/core/USBStringDescriptor.h>
+#include <usb/common/core/USBGenericRequest.h>
+
+//- CDC
+#include <usb/common/cdc/CDCGenericDescriptor.h>
+#include <usb/common/cdc/CDCDeviceDescriptor.h>
+#include <usb/common/cdc/CDCCommunicationInterfaceDescriptor.h>
+#include <usb/common/cdc/CDCDataInterfaceDescriptor.h>
+#include <usb/common/cdc/CDCHeaderDescriptor.h>
+#include <usb/common/cdc/CDCCallManagementDescriptor.h>
+#include <usb/common/cdc/CDCAbstractControlManagementDescriptor.h>
+#include <usb/common/cdc/CDCUnionDescriptor.h>
+#include "CDCDFunctionDriverDescriptors.h"
+
+//- HID
+#include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDeviceDescriptor.h>
+#include <usb/common/hid/HIDInterfaceDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDReport.h>
+#include <usb/common/hid/HIDGenericDesktop.h>
+#include <usb/common/hid/HIDLeds.h>
+#include <usb/common/hid/HIDKeypad.h>
+#include "HIDDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Device product ID.
+#define CDCHIDDDriverDescriptors_PRODUCTID 0x6130
+
+/// Device vendor ID (Atmel).
+#define CDCHIDDDriverDescriptors_VENDORID 0x03EB
+
+/// Device release number.
+#define CDCHIDDDriverDescriptors_RELEASE 0x0003
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+/// Returns the minimum between two values.
+#define MIN(a, b) ((a < b) ? a : b)
+
+//-----------------------------------------------------------------------------
+// Internal structures
+//-----------------------------------------------------------------------------
+
+#ifdef __ICCARM__ // IAR
+#pragma pack(1) // IAR
+#define __attribute__(...) // IAR
+#endif // IAR
+
+//-----------------------------------------------------------------------------
+/// Configuration descriptor list for a device implementing a composite driver.
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Standard configuration descriptor.
+ USBConfigurationDescriptor configuration;
+
+ /// --- CDC 0
+ /// IAD 0
+ USBInterfaceAssociationDescriptor cdcIAD0;
+ /// Communication interface descriptor
+ USBInterfaceDescriptor cdcCommunication0;
+ /// CDC header functional descriptor.
+ CDCHeaderDescriptor cdcHeader0;
+ /// CDC call management functional descriptor.
+ CDCCallManagementDescriptor cdcCallManagement0;
+ /// CDC abstract control management functional descriptor.
+ CDCAbstractControlManagementDescriptor cdcAbstractControlManagement0;
+ /// CDC union functional descriptor (with one slave interface).
+ CDCUnionDescriptor cdcUnion0;
+ /// Notification endpoint descriptor.
+ USBEndpointDescriptor cdcNotification0;
+ /// Data interface descriptor.
+ USBInterfaceDescriptor cdcData0;
+ /// Data OUT endpoint descriptor.
+ USBEndpointDescriptor cdcDataOut0;
+ /// Data IN endpoint descriptor.
+ USBEndpointDescriptor cdcDataIn0;
+
+ /// --- HID
+ USBInterfaceDescriptor hidInterface;
+ HIDDescriptor hid;
+ USBEndpointDescriptor hidInterruptIn;
+ USBEndpointDescriptor hidInterruptOut;
+
+} __attribute__ ((packed)) CdcHidDriverConfigurationDescriptors;
+
+#ifdef __ICCARM__ // IAR
+#pragma pack() // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// Standard USB device descriptor for the composite device driver
+static const USBDeviceDescriptor deviceDescriptor = {
+
+ sizeof(USBDeviceDescriptor),
+ USBGenericDescriptor_DEVICE,
+ USBDeviceDescriptor_USB2_00,
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ CDCHIDDDriverDescriptors_VENDORID,
+ CDCHIDDDriverDescriptors_PRODUCTID,
+ CDCHIDDDriverDescriptors_RELEASE,
+ 0, // No string descriptor for manufacturer
+ 1, // Index of product string descriptor is #1
+ 0, // No string descriptor for serial number
+ 1 // Device has 1 possible configuration
+};
+
+#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+
+/// USB device qualifier descriptor.
+static const USBDeviceQualifierDescriptor qualifierDescriptor = {
+
+ sizeof(USBDeviceQualifierDescriptor),
+ USBGenericDescriptor_DEVICEQUALIFIER,
+ USBDeviceDescriptor_USB2_00,
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ 1, // Device has one possible configuration
+ 0 // Reserved
+};
+
+/// USB configuration descriptors for the composite device driver
+static const CdcHidDriverConfigurationDescriptors configurationDescriptorsHS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(CdcHidDriverConfigurationDescriptors),
+ CDCHIDDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // CDC 0
+ // IAD for CDC/ACM port
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM0,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0, // This is interface #0
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM0 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM0, // Number of master interface is #0
+ CDCD_Descriptors_INTERFACENUM0 + 1 // First slave interface is #1
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
+ CDCD_Descriptors_INTERRUPT_MAXPACKETSIZE),
+ CDCD_Descriptors_INTERRUPTOUT_POLLING_HS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0 + 1, // This is interface #1
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+
+ // HID
+ // Interface descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ HIDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0
+ 2, // Two endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_NONE,
+ 0 // No associated string descriptor
+ },
+ // HID descriptor
+ {
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDD_Descriptors_REPORTSIZE
+ },
+ // Interrupt IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDD_Descriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardInputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING_HS
+ },
+ // Interrupt OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ HIDD_Descriptors_INTERRUPTOUT),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardOutputReport),
+ HIDD_Descriptors_INTERRUPTOUT_POLLING_HS
+ }
+};
+
+#endif
+
+/// USB configuration descriptors for the composite device driver
+static const CdcHidDriverConfigurationDescriptors configurationDescriptorsFS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(CdcHidDriverConfigurationDescriptors),
+ CDCHIDDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // CDC 0
+ // IAD for CDC/ACM port
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM0,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0, // This is interface #0
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM0 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM0, // Number of master interface is #0
+ CDCD_Descriptors_INTERFACENUM0 + 1 // First slave interface is #1
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
+ CDCD_Descriptors_INTERRUPTOUT_POLLING_FS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0 + 1, // This is interface #1
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+
+ // HID
+ // Interface descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ HIDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0
+ 2, // Two endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_NONE,
+ 0 // No associated string descriptor
+ },
+ // HID descriptor
+ {
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDD_Descriptors_REPORTSIZE
+ },
+ // Interrupt IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDD_Descriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardInputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING_FS
+ },
+ // Interrupt OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ HIDD_Descriptors_INTERRUPTOUT),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardOutputReport),
+ HIDD_Descriptors_INTERRUPTOUT_POLLING_FS
+ }
+};
+
+/// String descriptor with the supported languages.
+static const unsigned char languageIdDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(1),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_ENGLISH_US
+};
+
+/// Manufacturer name.
+static const unsigned char manufacturerDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(5),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('l')
+};
+
+/// Product name.
+static const unsigned char productDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(14),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('C'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('p'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('s'),
+ USBStringDescriptor_UNICODE('i'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('D'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('o')
+};
+
+/// Product serial number.
+static const unsigned char serialNumberDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(4),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('0'),
+ USBStringDescriptor_UNICODE('1'),
+ USBStringDescriptor_UNICODE('2'),
+ USBStringDescriptor_UNICODE('3')
+};
+
+/// Array of pointers to the four string descriptors.
+static const unsigned char *stringDescriptors[] = {
+
+ languageIdDescriptor,
+ manufacturerDescriptor,
+ productDescriptor,
+ serialNumberDescriptor,
+};
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// List of descriptors required by an USB audio speaker device driver.
+const USBDDriverDescriptors cdchiddDriverDescriptors = {
+
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#else
+ 0, 0, 0, 0, 0, 0,
+#endif
+ stringDescriptors,
+ 4 // Number of string descriptors
+};
diff --git a/usb/device/composite/CDCHIDDDriverDescriptors.h b/usb/device/composite/CDCHIDDDriverDescriptors.h
new file mode 100644
index 0000000..0a34f8a
--- /dev/null
+++ b/usb/device/composite/CDCHIDDDriverDescriptors.h
@@ -0,0 +1,70 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef CDCHIDDDRIVERDESCRIPTORS_H
+#define CDCHIDDDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <board.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Number of interfaces of the device
+#define CDCHIDDDriverDescriptors_NUMINTERFACE 3
+
+/// Number of the CDC interface.
+#define CDCD_Descriptors_INTERFACENUM0 0
+/// Address of the CDC interrupt-in endpoint.
+#define CDCD_Descriptors_NOTIFICATION0 3
+/// Address of the CDC bulk-in endpoint.
+#define CDCD_Descriptors_DATAIN0 2
+/// Address of the CDC bulk-out endpoint.
+#define CDCD_Descriptors_DATAOUT0 1
+
+/// Number of the HID interface.
+#define HIDD_Descriptors_INTERFACENUM 2
+/// Address of the HID interrupt IN endpoint.
+#define HIDD_Descriptors_INTERRUPTIN 4
+/// Address of the HID interrupt OUT endpoint.
+#define HIDD_Descriptors_INTERRUPTOUT 5
+
+
+//-----------------------------------------------------------------------------
+// Exported variables
+//-----------------------------------------------------------------------------
+
+extern const USBDDriverDescriptors cdchiddDriverDescriptors;
+
+#endif //#ifndef CDCHIDDDRIVERDESCRIPTORS_H
diff --git a/usb/device/composite/CDCMSDDDriver.c b/usb/device/composite/CDCMSDDDriver.c
new file mode 100644
index 0000000..9a605a7
--- /dev/null
+++ b/usb/device/composite/CDCMSDDDriver.c
@@ -0,0 +1,213 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <utility/led.h>
+
+// USB
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+
+//- CDCMSD
+#include "CDCMSDDDriver.h"
+#include "CDCMSDDDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+/// Interface setting spaces (4 byte aligned)
+#define NUM_INTERFACES ((CDCMSDDDriverDescriptors_NUMINTERFACE+3)&0xFC)
+
+//-----------------------------------------------------------------------------
+// Types
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// USBDDriver instance
+static USBDDriver usbdDriver;
+
+/// CDCDSeriaoPort instance
+static CDCDSerialPort cdcdPort;
+
+/// Array for storing the current setting of each interface
+static unsigned char cdcmsddDriverInterfaces[NUM_INTERFACES];
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Optional RequestReceived() callback re-implementation
+//-----------------------------------------------------------------------------
+#if !defined(NOAUTOCALLBACK)
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ CDCMSDDDriver_RequestHandler(request);
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+// ConfigurationChanged() callback re-implementation
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the configuration value of a device is changed by the host
+/// \param cfgnum Configuration number.
+//-----------------------------------------------------------------------------
+void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+ // MSD
+ MSDDFunctionCallbacks_ConfigurationChanged(cfgnum);
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes the USB device CDCMSD device driver.
+//-----------------------------------------------------------------------------
+void CDCMSDDDriver_Initialize(MSDLun *pLuns, unsigned char numLuns)
+{
+ // CDC
+ CDCDFunctionDriver_ConfigurePort(&cdcdPort,
+ CDCD_Descriptors_INTERFACENUM0,
+ CDCD_Descriptors_NOTIFICATION0,
+ CDCD_Descriptors_DATAIN0,
+ CDCD_Descriptors_DATAOUT0);
+ CDCDFunctionDriver_Initialize(&usbdDriver,
+ &cdcdPort,
+ 1);
+
+ // MSD
+ MSDDFunctionDriver_Initialize(&usbdDriver,
+ pLuns, numLuns,
+ MSDD_Descriptors_INTERFACENUM,
+ MSDD_Descriptors_BULKIN,
+ MSDD_Descriptors_BULKOUT);
+
+ // Initialize the standard USB driver
+ USBDDriver_Initialize(&usbdDriver,
+ &cdcmsddDriverDescriptors,
+ cdcmsddDriverInterfaces);
+
+ // Initialize the USB driver
+ USBD_Init();
+}
+
+//-----------------------------------------------------------------------------
+/// Handles CDCMSD-specific USB requests sent by the host, and forwards
+/// standard ones to the USB device driver.
+/// \param request Pointer to a USBGenericRequest instance.
+//-----------------------------------------------------------------------------
+void CDCMSDDDriver_RequestHandler(const USBGenericRequest *request)
+{
+ // Check if this is a class request
+ if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
+
+ unsigned char rc = 0;
+
+ // CDC class request
+ if (rc == 0) {
+
+ rc = CDCDFunctionDriver_RequestHandler(request);
+ }
+
+ // MSD class request
+ if (rc == 0) {
+
+ rc = MSDDFunctionDriver_RequestHandler(request);
+ }
+
+ if (!rc) {
+
+ TRACE_WARNING(
+ "CDCMSDDDriver_RequestHandler: Unsupported request (%d)\n\r",
+ USBGenericRequest_GetRequest(request));
+ USBD_Stall(0);
+ }
+
+ }
+ // Check if this is a standard request
+ else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
+
+ unsigned char rc = 0;
+
+ if (rc == 0) {
+
+ rc = MSDDFunctionDriver_RequestHandler(request);
+ }
+
+ // Forward request to the standard handler
+ if (rc == 0) {
+
+ USBDDriver_RequestHandler(&(usbdDriver), request);
+ }
+ }
+ // Unsupported request type
+ else {
+
+ TRACE_WARNING(
+ "CDCMSDDDriver_RequestHandler: Unsupported request type (%d)\n\r",
+ USBGenericRequest_GetType(request));
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Starts a remote wake-up sequence if the host has explicitely enabled it
+/// by sending the appropriate SET_FEATURE request.
+//-----------------------------------------------------------------------------
+void CDCMSDDDriver_RemoteWakeUp(void)
+{
+ // Remote wake-up has been enabled
+ if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver)) {
+
+ USBD_RemoteWakeUp();
+ }
+ // Remote wake-up NOT enabled
+ else {
+
+ TRACE_WARNING("CDCMSDDDriver_RemoteWakeUp: not enabled\n\r");
+ }
+}
+
+
diff --git a/usb/device/composite/CDCMSDDDriver.h b/usb/device/composite/CDCMSDDDriver.h
new file mode 100644
index 0000000..e6a6834
--- /dev/null
+++ b/usb/device/composite/CDCMSDDDriver.h
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Definitions and methods for USB CDCMSD device implement.
+///
+/// !Usage
+///
+/// -# Initialize USB function specified driver ( for MSD currently )
+/// - MSDDFunctionDriver_Initialize
+///
+/// -# Initialize USB CDCMSD driver and USB driver
+/// - CDCMSDDDriver_Initialize
+///
+/// -# Handle and dispach USB requests
+/// - CDCMSDDDriver_RequestHandler
+///
+/// -# Try starting a remote wake-up sequence
+/// - CDCMSDDDriver_RemoteWakeUp
+//-----------------------------------------------------------------------------
+
+#ifndef CDCMSDDDRIVER_H
+#define CDCMSDDDRIVER_H
+
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+
+#include "CDCDFunctionDriver.h"
+#include "MSDDFunctionDriver.h"
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+// -CDCMSD
+extern void CDCMSDDDriver_Initialize(MSDLun *pLuns, unsigned char numLuns);
+
+extern void CDCMSDDDriver_RequestHandler(const USBGenericRequest *request);
+
+extern void CDCMSDDDriver_RemoteWakeUp(void);
+
+#endif //#ifndef CDCMSDDDRIVER_H
+
diff --git a/usb/device/composite/CDCMSDDDriverDescriptors.c b/usb/device/composite/CDCMSDDDriverDescriptors.c
new file mode 100644
index 0000000..27932ac
--- /dev/null
+++ b/usb/device/composite/CDCMSDDDriverDescriptors.c
@@ -0,0 +1,568 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "CDCMSDDDriver.h"
+#include "CDCMSDDDriverDescriptors.h"
+#include <board.h>
+
+//- USB Generic
+#include <usb/common/core/USBGenericDescriptor.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/common/core/USBInterfaceAssociationDescriptor.h>
+#include <usb/common/core/USBEndpointDescriptor.h>
+#include <usb/common/core/USBStringDescriptor.h>
+#include <usb/common/core/USBGenericRequest.h>
+
+//- CDC
+#include <usb/common/cdc/CDCGenericDescriptor.h>
+#include <usb/common/cdc/CDCDeviceDescriptor.h>
+#include <usb/common/cdc/CDCCommunicationInterfaceDescriptor.h>
+#include <usb/common/cdc/CDCDataInterfaceDescriptor.h>
+#include <usb/common/cdc/CDCHeaderDescriptor.h>
+#include <usb/common/cdc/CDCCallManagementDescriptor.h>
+#include <usb/common/cdc/CDCAbstractControlManagementDescriptor.h>
+#include <usb/common/cdc/CDCUnionDescriptor.h>
+#include "CDCDFunctionDriverDescriptors.h"
+
+//- MSD
+#include <usb/common/massstorage/MSDeviceDescriptor.h>
+#include <usb/common/massstorage/MSInterfaceDescriptor.h>
+#include "MSDDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Device product ID.
+#define CDCMSDDDriverDescriptors_PRODUCTID 0x6132
+
+/// Device vendor ID (Atmel).
+#define CDCMSDDDriverDescriptors_VENDORID 0x03EB
+
+/// Device release number.
+#define CDCMSDDDriverDescriptors_RELEASE 0x0003
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+/// Returns the minimum between two values.
+#define MIN(a, b) ((a < b) ? a : b)
+
+//-----------------------------------------------------------------------------
+// Internal structures
+//-----------------------------------------------------------------------------
+
+#ifdef __ICCARM__ // IAR
+#pragma pack(1) // IAR
+#define __attribute__(...) // IAR
+#endif // IAR
+
+//-----------------------------------------------------------------------------
+/// Configuration descriptor list for a device implementing a CDCMSD driver.
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Standard configuration descriptor.
+ USBConfigurationDescriptor configuration;
+
+ /// --- CDC 0
+ /// IAD 0
+ USBInterfaceAssociationDescriptor cdcIAD0;
+ /// Communication interface descriptor
+ USBInterfaceDescriptor cdcCommunication0;
+ /// CDC header functional descriptor.
+ CDCHeaderDescriptor cdcHeader0;
+ /// CDC call management functional descriptor.
+ CDCCallManagementDescriptor cdcCallManagement0;
+ /// CDC abstract control management functional descriptor.
+ CDCAbstractControlManagementDescriptor cdcAbstractControlManagement0;
+ /// CDC union functional descriptor (with one slave interface).
+ CDCUnionDescriptor cdcUnion0;
+ /// Notification endpoint descriptor.
+ USBEndpointDescriptor cdcNotification0;
+ /// Data interface descriptor.
+ USBInterfaceDescriptor cdcData0;
+ /// Data OUT endpoint descriptor.
+ USBEndpointDescriptor cdcDataOut0;
+ /// Data IN endpoint descriptor.
+ USBEndpointDescriptor cdcDataIn0;
+
+ /// --- MSD
+ /// Mass storage interface descriptor.
+ USBInterfaceDescriptor msdInterface;
+ /// Bulk-out endpoint descriptor.
+ USBEndpointDescriptor msdBulkOut;
+ /// Bulk-in endpoint descriptor.
+ USBEndpointDescriptor msdBulkIn;
+
+} __attribute__ ((packed)) CDCMSDDriverConfigurationDescriptors;
+
+#ifdef __ICCARM__ // IAR
+#pragma pack() // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// Standard USB device descriptor for the CDCMSD device driver
+static const USBDeviceDescriptor deviceDescriptor = {
+
+ sizeof(USBDeviceDescriptor),
+ USBGenericDescriptor_DEVICE,
+ USBDeviceDescriptor_USB2_00,
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ CDCMSDDDriverDescriptors_VENDORID,
+ CDCMSDDDriverDescriptors_PRODUCTID,
+ CDCMSDDDriverDescriptors_RELEASE,
+ 0, // No string descriptor for manufacturer
+ 1, // Index of product string descriptor is #1
+ 0, // No string descriptor for serial number
+ 1 // Device has 1 possible configuration
+};
+
+#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+
+/// USB device qualifier descriptor.
+static const USBDeviceQualifierDescriptor qualifierDescriptor = {
+
+ sizeof(USBDeviceQualifierDescriptor),
+ USBGenericDescriptor_DEVICEQUALIFIER,
+ USBDeviceDescriptor_USB2_00,
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ 1, // Device has one possible configuration
+ 0 // Reserved
+};
+
+/// USB configuration descriptors for the CDCMSD device driver
+static const CDCMSDDriverConfigurationDescriptors configurationDescriptorsHS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(CDCMSDDriverConfigurationDescriptors),
+ CDCMSDDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // CDC
+ // IAD for CDC/ACM port
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM0,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0, // This is interface #0
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM0 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM0, // Number of master interface is #0
+ CDCD_Descriptors_INTERFACENUM0 + 1 // First slave interface is #1
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
+ CDCD_Descriptors_INTERRUPT_MAXPACKETSIZE),
+ CDCD_Descriptors_INTERRUPTIN_POLLING_HS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0 + 1, // This is interface #1
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+
+ // Mass Storage interface descriptor.
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ MSDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0.
+ 2, // Interface uses two endpoints.
+ MSInterfaceDescriptor_CLASS,
+ MSInterfaceDescriptor_SCSI,
+ MSInterfaceDescriptor_BULKONLY,
+ 0 // No string descriptor for interface.
+ },
+ // Bulk-OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_MAXBULKSIZE_HS),
+ 0 // No string descriptor for endpoint.
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_MAXBULKSIZE_HS),
+ 0 // No string descriptor for endpoint.
+ }
+
+};
+
+#endif
+
+/// USB configuration descriptors for the CDCMSD device driver
+static const CDCMSDDriverConfigurationDescriptors configurationDescriptorsFS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(CDCMSDDriverConfigurationDescriptors),
+ CDCMSDDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // CDC
+ // IAD for CDC/ACM port
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM0,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0, // This is interface #0
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM0 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM0, // Number of master interface is #0
+ CDCD_Descriptors_INTERFACENUM0 + 1 // First slave interface is #1
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
+ CDCD_Descriptors_INTERRUPT_MAXPACKETSIZE),
+ CDCD_Descriptors_INTERRUPTIN_POLLING_FS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0 + 1, // This is interface #1
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+
+ // Mass Storage interface descriptor.
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ MSDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0.
+ 2, // Interface uses two endpoints.
+ MSInterfaceDescriptor_CLASS,
+ MSInterfaceDescriptor_SCSI,
+ MSInterfaceDescriptor_BULKONLY,
+ 0 // No string descriptor for interface.
+ },
+ // Bulk-OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // No string descriptor for endpoint.
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // No string descriptor for endpoint.
+ }
+
+};
+
+/// String descriptor with the supported languages.
+static const unsigned char languageIdDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(1),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_ENGLISH_US
+};
+
+/// Manufacturer name.
+static const unsigned char manufacturerDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(5),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('l')
+};
+
+/// Product name.
+static const unsigned char productDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(14),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('C'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('p'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('s'),
+ USBStringDescriptor_UNICODE('i'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('D'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('o')
+};
+
+/// Product serial number.
+static const unsigned char serialNumberDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(4),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('0'),
+ USBStringDescriptor_UNICODE('1'),
+ USBStringDescriptor_UNICODE('2'),
+ USBStringDescriptor_UNICODE('3')
+};
+
+/// Array of pointers to the four string descriptors.
+static const unsigned char *stringDescriptors[] = {
+
+ languageIdDescriptor,
+ manufacturerDescriptor,
+ productDescriptor,
+ serialNumberDescriptor,
+};
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// List of descriptors required by an USB audio speaker device driver.
+const USBDDriverDescriptors cdcmsddDriverDescriptors = {
+
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#else
+ 0, 0, 0, 0, 0, 0,
+#endif
+ stringDescriptors,
+ 4 // Number of string descriptors
+};
diff --git a/usb/device/composite/CDCMSDDDriverDescriptors.h b/usb/device/composite/CDCMSDDDriverDescriptors.h
new file mode 100644
index 0000000..5db1a0c
--- /dev/null
+++ b/usb/device/composite/CDCMSDDDriverDescriptors.h
@@ -0,0 +1,71 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef CDCMSDDDRIVERDESCRIPTORS_H
+#define CDCMSDDDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <board.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Number of interfaces of the device
+#define CDCMSDDDriverDescriptors_NUMINTERFACE 3
+
+/// Number of the CDC interface.
+#define CDCD_Descriptors_INTERFACENUM0 0
+/// Address of the CDC interrupt-in endpoint.
+#define CDCD_Descriptors_NOTIFICATION0 3
+/// Address of the CDC bulk-in endpoint.
+#define CDCD_Descriptors_DATAIN0 2
+/// Address of the CDC bulk-out endpoint.
+#define CDCD_Descriptors_DATAOUT0 1
+
+/// Number of the Mass Storage interface.
+#define MSDD_Descriptors_INTERFACENUM 2
+
+/// Address of the Mass Storage bulk-out endpoint.
+#define MSDD_Descriptors_BULKOUT 4
+
+/// Address of the Mass Storage bulk-in endpoint.
+#define MSDD_Descriptors_BULKIN 5
+
+//-----------------------------------------------------------------------------
+// Exported variables
+//-----------------------------------------------------------------------------
+
+extern const USBDDriverDescriptors cdcmsddDriverDescriptors;
+
+#endif //#ifndef CDCMSDDDRIVERDESCRIPTORS_H
diff --git a/usb/device/composite/COMPOSITEDDriver.c b/usb/device/composite/COMPOSITEDDriver.c
new file mode 100644
index 0000000..88d64b6
--- /dev/null
+++ b/usb/device/composite/COMPOSITEDDriver.c
@@ -0,0 +1,292 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <utility/led.h>
+
+// USB
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+
+//- HID
+#if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ #include <usb/device/hid-keyboard/HIDDKeyboardDriver.h>
+ #include <usb/device/hid-keyboard/HIDDKeyboardDriverDescriptors.h>
+ #include <usb/device/hid-keyboard/HIDDKeyboardCallbacks.h>
+ #include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+ #include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+
+ #include <usb/common/hid/HIDGenericDescriptor.h>
+ #include <usb/common/hid/HIDDescriptor.h>
+ #include <usb/common/hid/HIDGenericRequest.h>
+ #include <usb/common/hid/HIDReportRequest.h>
+ #include <usb/common/hid/HIDIdleRequest.h>
+ #include <usb/common/hid/HIDKeypad.h>
+#endif // (HID defined)
+
+//- MSD
+#if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+#endif
+
+//- COMPOSITE
+#include "COMPOSITEDDriver.h"
+#include "COMPOSITEDDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+/// Interface setting spaces (4 byte aligned)
+#define NUM_INTERFACES ((COMPOSITEDDriverDescriptors_NUMINTERFACE+3)&0xFC)
+
+//-----------------------------------------------------------------------------
+// Types
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// USBDDriver instance
+static USBDDriver usbdDriver;
+
+// CDC
+#if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCCDC) || defined(usb_CDCMSD)
+/// CDCDSeriaoPort instance
+static CDCDSerialPort cdcdPort;
+#endif // CDC defined
+
+/// Array for storing the current setting of each interface
+static unsigned char compositedDriverInterfaces[NUM_INTERFACES];
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Optional RequestReceived() callback re-implementation
+//-----------------------------------------------------------------------------
+#if !defined(NOAUTOCALLBACK)
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ COMPOSITEDDriver_RequestHandler(request);
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the active setting of an interface is changed by the
+/// host. Changes the status of the third LED accordingly.
+/// \param interface Interface number.
+/// \param setting Newly active setting.
+//-----------------------------------------------------------------------------
+void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
+ unsigned char setting)
+{
+ // AUDIO
+ #if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+ AUDDFunctionCallbacks_InterfaceSettingChanged(interface, setting);
+ #endif
+}
+
+//-----------------------------------------------------------------------------
+// ConfigurationChanged() callback re-implementation
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the configuration value of a device is changed by the host
+/// \param cfgnum Configuration number.
+//-----------------------------------------------------------------------------
+void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+ // HID
+ #if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ HIDDFunctionCallbacks_ConfigurationChanged(cfgnum);
+ #endif
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes the USB device composite device driver.
+//-----------------------------------------------------------------------------
+void COMPOSITEDDriver_Initialize()
+{
+ // CDC
+ #if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCCDC) || defined(usb_CDCMSD)
+ CDCDFunctionDriver_ConfigurePort(&cdcdPort,
+ CDCD_Descriptors_INTERFACENUM0,
+ CDCD_Descriptors_NOTIFICATION0,
+ CDCD_Descriptors_DATAIN0,
+ CDCD_Descriptors_DATAOUT0);
+ CDCDFunctionDriver_Initialize(&usbdDriver,
+ &cdcdPort,
+ 1);
+ #endif
+
+ // AUDIO
+ #if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+ AUDDFunctionDriver_Initialize();
+ #endif
+
+ // HID
+ #if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ HIDDFunctionDriver_Initialize(&usbdDriver,
+ HIDD_Descriptors_INTERFACENUM,
+ HIDD_Descriptors_INTERRUPTIN,
+ HIDD_Descriptors_INTERRUPTOUT);
+ #endif
+
+ // MSD
+ #if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+ // Function driver initialize is put to main() for additional LUN list
+ #endif
+
+ // Initialize the standard USB driver
+ USBDDriver_Initialize(&usbdDriver,
+ &compositedDriverDescriptors,
+ compositedDriverInterfaces);
+
+ // Initialize the USB driver
+ USBD_Init();
+}
+
+//-----------------------------------------------------------------------------
+/// Handles composite-specific USB requests sent by the host, and forwards
+/// standard ones to the USB device driver.
+/// \param request Pointer to a USBGenericRequest instance.
+//-----------------------------------------------------------------------------
+void COMPOSITEDDriver_RequestHandler(const USBGenericRequest *request)
+{
+ // Check if this is a class request
+ if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
+
+ unsigned char rc = 0;
+
+ // AUDIO class request
+ #if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+ if (rc == 0) {
+
+ rc = AUDDFunctionDriver_RequestHandler(request);
+ }
+ #endif
+
+ // CDC class request
+ #if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCMSD) || defined(usb_CDCCDC)
+ if (rc == 0) {
+
+ rc = CDCDFunctionDriver_RequestHandler(request);
+ }
+ #endif
+
+ // MSD class request
+ #if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+ if (rc == 0) {
+
+ rc = MSDDFunctionDriver_RequestHandler(request);
+ }
+ #endif
+
+ // HID class request
+ #if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ if (rc == 0) {
+
+ rc = HIDDFunctionDriver_RequestHandler(request);
+ }
+ #endif
+
+ if (!rc) {
+
+ TRACE_WARNING(
+ "COMPOSITEDDriver_RequestHandler: Unsupported request (%d)\n\r",
+ USBGenericRequest_GetRequest(request));
+ USBD_Stall(0);
+ }
+
+ }
+ // Check if this is a standard request
+ else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
+
+ unsigned char rc = 0;
+
+ #if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ rc = HIDDFunctionDriver_RequestHandler(request);
+ #endif
+
+ #if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+ if (rc == 0) {
+
+ rc = MSDDFunctionDriver_RequestHandler(request);
+ }
+ #endif
+
+ // Forward request to the standard handler
+ if (rc == 0) {
+
+ USBDDriver_RequestHandler(&(usbdDriver), request);
+ }
+ }
+ // Unsupported request type
+ else {
+
+ TRACE_WARNING(
+ "COMPOSITEDDriver_RequestHandler: Unsupported request type (%d)\n\r",
+ USBGenericRequest_GetType(request));
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Starts a remote wake-up sequence if the host has explicitely enabled it
+/// by sending the appropriate SET_FEATURE request.
+//-----------------------------------------------------------------------------
+void COMPOSITEDDriver_RemoteWakeUp(void)
+{
+ // Remote wake-up has been enabled
+ if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver)) {
+
+ USBD_RemoteWakeUp();
+ }
+ // Remote wake-up NOT enabled
+ else {
+
+ TRACE_WARNING("COMPOSITEDDriver_RemoteWakeUp: not enabled\n\r");
+ }
+}
+
+
diff --git a/usb/device/composite/COMPOSITEDDriver.h b/usb/device/composite/COMPOSITEDDriver.h
new file mode 100644
index 0000000..6106a9f
--- /dev/null
+++ b/usb/device/composite/COMPOSITEDDriver.h
@@ -0,0 +1,93 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Definitions and methods for USB composite device implement.
+///
+/// !Usage
+///
+/// -# Initialize USB function specified driver ( for MSD currently )
+/// - MSDDFunctionDriver_Initialize
+///
+/// -# Initialize USB composite driver and USB driver
+/// - COMPOSITEDDriver_Initialize
+///
+/// -# Handle and dispach USB requests
+/// - COMPOSITEDDriver_RequestHandler
+///
+/// -# Try starting a remote wake-up sequence
+/// - COMPOSITEDDriver_RemoteWakeUp
+//-----------------------------------------------------------------------------
+
+#ifndef COMPOSITEDDRIVER_H
+#define COMPOSITEDDRIVER_H
+
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+#include <usb/device/core/USBD.h>
+
+#if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCCDC) || defined(usb_CDCMSD)
+ #include "CDCDFunctionDriver.h"
+ #include "CDCDFunctionDriverDescriptors.h"
+#endif
+
+#if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+ #include "AUDDFunctionDriver.h"
+#endif
+
+#if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ #include "HIDDFunctionDriver.h"
+ #include "HIDDFunctionDriverDescriptors.h"
+#endif
+
+#if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+ #include "MSDDFunctionDriver.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+// -COMPOSITE
+extern void COMPOSITEDDriver_Initialize();
+
+extern void COMPOSITEDDriver_RequestHandler(const USBGenericRequest *request);
+
+extern void COMPOSITEDDriver_RemoteWakeUp(void);
+
+#endif //#ifndef COMPOSITEDDRIVER_H
+
diff --git a/usb/device/composite/COMPOSITEDDriverDescriptors.c b/usb/device/composite/COMPOSITEDDriverDescriptors.c
new file mode 100644
index 0000000..db195af
--- /dev/null
+++ b/usb/device/composite/COMPOSITEDDriverDescriptors.c
@@ -0,0 +1,954 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "COMPOSITEDDriver.h"
+#include "COMPOSITEDDriverDescriptors.h"
+#include <board.h>
+
+//- USB Generic
+#include <usb/common/core/USBGenericDescriptor.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/common/core/USBInterfaceAssociationDescriptor.h>
+#include <usb/common/core/USBEndpointDescriptor.h>
+#include <usb/common/core/USBStringDescriptor.h>
+#include <usb/common/core/USBGenericRequest.h>
+
+//- CDC
+#if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCCDC) || defined(usb_CDCMSD)
+ #include <usb/common/cdc/CDCGenericDescriptor.h>
+ #include <usb/common/cdc/CDCDeviceDescriptor.h>
+ #include <usb/common/cdc/CDCCommunicationInterfaceDescriptor.h>
+ #include <usb/common/cdc/CDCDataInterfaceDescriptor.h>
+ #include <usb/common/cdc/CDCHeaderDescriptor.h>
+ #include <usb/common/cdc/CDCCallManagementDescriptor.h>
+ #include <usb/common/cdc/CDCAbstractControlManagementDescriptor.h>
+ #include <usb/common/cdc/CDCUnionDescriptor.h>
+ #include "CDCDFunctionDriverDescriptors.h"
+#endif // (CDC defined)
+
+//- HID
+#if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ #include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+ #include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+ #include <usb/common/hid/HIDGenericDescriptor.h>
+ #include <usb/common/hid/HIDDeviceDescriptor.h>
+ #include <usb/common/hid/HIDInterfaceDescriptor.h>
+ #include <usb/common/hid/HIDDescriptor.h>
+ #include <usb/common/hid/HIDReport.h>
+ #include <usb/common/hid/HIDGenericDesktop.h>
+ #include <usb/common/hid/HIDLeds.h>
+ #include <usb/common/hid/HIDKeypad.h>
+ #include "HIDDFunctionDriverDescriptors.h"
+#endif // (HID defined)
+
+//- AUDIO
+#if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+ #include <usb/common/audio/AUDGenericDescriptor.h>
+ #include <usb/common/audio/AUDDeviceDescriptor.h>
+ #include <usb/common/audio/AUDControlInterfaceDescriptor.h>
+ #include <usb/common/audio/AUDStreamingInterfaceDescriptor.h>
+ #include <usb/common/audio/AUDEndpointDescriptor.h>
+ #include <usb/common/audio/AUDDataEndpointDescriptor.h>
+ #include <usb/common/audio/AUDFormatTypeOneDescriptor.h>
+ #include <usb/common/audio/AUDHeaderDescriptor.h>
+ #include <usb/common/audio/AUDFeatureUnitDescriptor.h>
+ #include <usb/common/audio/AUDInputTerminalDescriptor.h>
+ #include <usb/common/audio/AUDOutputTerminalDescriptor.h>
+ #include "AUDDFunctionDriverDescriptors.h"
+#endif // (AUDIO defined)
+
+//- MSD
+#if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+ #include <usb/common/massstorage/MSDeviceDescriptor.h>
+ #include <usb/common/massstorage/MSInterfaceDescriptor.h>
+ #include "MSDDFunctionDriverDescriptors.h"
+#endif // (MSD defined)
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Device product ID.
+#if defined(usb_CDCHID)
+#define COMPOSITEDDriverDescriptors_PRODUCTID 0x6130
+#elif defined(usb_CDCAUDIO)
+#define COMPOSITEDDriverDescriptors_PRODUCTID 0x6131
+#elif defined(usb_CDCMSD)
+#define COMPOSITEDDriverDescriptors_PRODUCTID 0x6132
+#elif defined(usb_CDCCDC)
+#define COMPOSITEDDriverDescriptors_PRODUCTID 0x6133
+#elif defined(usb_HIDAUDIO)
+#define COMPOSITEDDriverDescriptors_PRODUCTID 0x6134
+#elif defined(usb_HIDMSD)
+#define COMPOSITEDDriverDescriptors_PRODUCTID 0x6135
+#else
+#error COMPOSITE Device Classes not defined!
+#endif
+
+/// Device vendor ID (Atmel).
+#define COMPOSITEDDriverDescriptors_VENDORID 0x03EB
+
+/// Device release number.
+#define COMPOSITEDDriverDescriptors_RELEASE 0x0003
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+/// Returns the minimum between two values.
+#define MIN(a, b) ((a < b) ? a : b)
+
+//-----------------------------------------------------------------------------
+// Internal structures
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Audio control header descriptor with one slave interface.
+//-----------------------------------------------------------------------------
+#ifdef __ICCARM__ // IAR
+#pragma pack(1) // IAR
+#define __attribute__(...) // IAR
+#endif // IAR
+
+//- AUDIO
+#if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+typedef struct {
+
+ /// Header descriptor.
+ AUDHeaderDescriptor header;
+ /// Id of the first grouped interface.
+ unsigned char bInterface0;
+
+} __attribute__ ((packed)) AUDHeaderDescriptor1; // GCC
+
+//-----------------------------------------------------------------------------
+/// Feature unit descriptor with 3 channel controls (master, right, left).
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Feature unit descriptor.
+ AUDFeatureUnitDescriptor feature;
+ /// Available controls for each channel.
+ unsigned char bmaControls[3];
+ /// Index of a string descriptor for the feature unit.
+ unsigned char iFeature;
+
+} __attribute__ ((packed)) AUDFeatureUnitDescriptor3; // GCC
+
+//-----------------------------------------------------------------------------
+/// List of descriptors for detailling the audio control interface of a
+/// device using a USB audio speaker driver.
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Header descriptor (with one slave interface).
+ AUDHeaderDescriptor1 header;
+ /// Input terminal descriptor.
+ AUDInputTerminalDescriptor input;
+ /// Output terminal descriptor.
+ AUDOutputTerminalDescriptor output;
+ /// Feature unit descriptor.
+ AUDFeatureUnitDescriptor3 feature;
+
+} __attribute__ ((packed)) AUDDSpeakerDriverAudioControlDescriptors; // GCC
+
+//-----------------------------------------------------------------------------
+/// Format type I descriptor with one discrete sampling frequency.
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Format type I descriptor.
+ AUDFormatTypeOneDescriptor formatType;
+ /// Sampling frequency in Hz.
+ unsigned char tSamFreq[3];
+
+} __attribute__ ((packed)) AUDFormatTypeOneDescriptor1; // GCC
+#endif // (AUDIO defined)
+
+//-----------------------------------------------------------------------------
+/// Configuration descriptor list for a device implementing a composite driver.
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Standard configuration descriptor.
+ USBConfigurationDescriptor configuration;
+
+ #if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCCDC) || defined(usb_CDCMSD)
+ /// --- CDC 0
+ /// IAD 0
+ USBInterfaceAssociationDescriptor cdcIAD0;
+ /// Communication interface descriptor
+ USBInterfaceDescriptor cdcCommunication0;
+ /// CDC header functional descriptor.
+ CDCHeaderDescriptor cdcHeader0;
+ /// CDC call management functional descriptor.
+ CDCCallManagementDescriptor cdcCallManagement0;
+ /// CDC abstract control management functional descriptor.
+ CDCAbstractControlManagementDescriptor cdcAbstractControlManagement0;
+ /// CDC union functional descriptor (with one slave interface).
+ CDCUnionDescriptor cdcUnion0;
+ /// Notification endpoint descriptor.
+ USBEndpointDescriptor cdcNotification0;
+ /// Data interface descriptor.
+ USBInterfaceDescriptor cdcData0;
+ /// Data OUT endpoint descriptor.
+ USBEndpointDescriptor cdcDataOut0;
+ /// Data IN endpoint descriptor.
+ USBEndpointDescriptor cdcDataIn0;
+ #endif // (CDC defined)
+
+ #if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ /// --- HID
+ USBInterfaceDescriptor hidInterface;
+ HIDDescriptor hid;
+ USBEndpointDescriptor hidInterruptIn;
+ USBEndpointDescriptor hidInterruptOut;
+ #endif // (HID defined)
+
+ #if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+ /// --- AUDIO
+ /// IAD 1
+ USBInterfaceAssociationDescriptor audIAD;
+ /// Audio control interface.
+ USBInterfaceDescriptor audInterface;
+ /// Descriptors for the audio control interface.
+ AUDDSpeakerDriverAudioControlDescriptors audControl;
+ /// -- AUDIO out
+ /// Streaming out interface descriptor (with no endpoint, required).
+ USBInterfaceDescriptor audStreamingOutNoIsochronous;
+ /// Streaming out interface descriptor.
+ USBInterfaceDescriptor audStreamingOut;
+ /// Audio class descriptor for the streaming out interface.
+ AUDStreamingInterfaceDescriptor audStreamingOutClass;
+ /// Stream format descriptor.
+ AUDFormatTypeOneDescriptor1 audStreamingOutFormatType;
+ /// Streaming out endpoint descriptor.
+ AUDEndpointDescriptor audStreamingOutEndpoint;
+ /// Audio class descriptor for the streaming out endpoint.
+ AUDDataEndpointDescriptor audStreamingOutDataEndpoint;
+ #endif // (AUDIO defined)
+
+ #if defined(usb_CDCCDC)
+ /// --- CDC 1
+ /// IAD 1
+ USBInterfaceAssociationDescriptor cdcIAD1;
+ /// Communication interface descriptor
+ USBInterfaceDescriptor cdcCommunication1;
+ /// CDC header functional descriptor.
+ CDCHeaderDescriptor cdcHeader1;
+ /// CDC call management functional descriptor.
+ CDCCallManagementDescriptor cdcCallManagement1;
+ /// CDC abstract control management functional descriptor.
+ CDCAbstractControlManagementDescriptor cdcAbstractControlManagement1;
+ /// CDC union functional descriptor (with one slave interface).
+ CDCUnionDescriptor cdcUnion1;
+ /// Notification endpoint descriptor.
+ USBEndpointDescriptor cdcNotification1;
+ /// Data interface descriptor.
+ USBInterfaceDescriptor cdcData1;
+ /// Data OUT endpoint descriptor.
+ USBEndpointDescriptor cdcDataOut1;
+ /// Data IN endpoint descriptor.
+ USBEndpointDescriptor cdcDataIn1;
+ #endif // (Another CDC defined)
+
+ #if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+ /// --- MSD
+ /// Mass storage interface descriptor.
+ USBInterfaceDescriptor msdInterface;
+ /// Bulk-out endpoint descriptor.
+ USBEndpointDescriptor msdBulkOut;
+ /// Bulk-in endpoint descriptor.
+ USBEndpointDescriptor msdBulkIn;
+ #endif // (MSD defined)
+
+} __attribute__ ((packed)) CompositeDriverConfigurationDescriptors;
+
+#ifdef __ICCARM__ // IAR
+#pragma pack() // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// Standard USB device descriptor for the composite device driver
+const USBDeviceDescriptor deviceDescriptor = {
+
+ sizeof(USBDeviceDescriptor),
+ USBGenericDescriptor_DEVICE,
+ USBDeviceDescriptor_USB2_00,
+ #if defined(usb_HIDMSD)
+ 0x00,
+ 0x00,
+ 0x00,
+ #else
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ #endif
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ COMPOSITEDDriverDescriptors_VENDORID,
+ COMPOSITEDDriverDescriptors_PRODUCTID,
+ COMPOSITEDDriverDescriptors_RELEASE,
+ 0, // No string descriptor for manufacturer
+ 1, // Index of product string descriptor is #1
+ 0, // No string descriptor for serial number
+ 1 // Device has 1 possible configuration
+};
+
+#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+
+/// USB device qualifier descriptor.
+const USBDeviceQualifierDescriptor qualifierDescriptor = {
+
+ sizeof(USBDeviceQualifierDescriptor),
+ USBGenericDescriptor_DEVICEQUALIFIER,
+ USBDeviceDescriptor_USB2_00,
+ #if defined(usb_HIDMSD)
+ 0x00,
+ 0x00,
+ 0x00,
+ #else
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ #endif
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ 1, // Device has one possible configuration
+ 0 // Reserved
+};
+
+#endif
+
+/// USB configuration descriptors for the composite device driver
+const CompositeDriverConfigurationDescriptors configurationDescriptors = {
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(CompositeDriverConfigurationDescriptors),
+ COMPOSITEDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ #if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCCDC) || defined(usb_CDCMSD)
+ // CDC
+ // IAD for CDC/ACM port
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM0,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0, // This is interface #0
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM0 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM0, // Number of master interface is #0
+ CDCD_Descriptors_INTERFACENUM0 + 1 // First slave interface is #1
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
+ 10 // Endpoint is polled every 10ms
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0 + 1, // This is interface #1
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ #endif // (CDC defined)
+
+ #if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+ // Interface descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ HIDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0
+ 2, // Two endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_NONE,
+ 0 // No associated string descriptor
+ },
+ // HID descriptor
+ {
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDD_Descriptors_REPORTSIZE
+ },
+ // Interrupt IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDD_Descriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardInputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING
+ },
+ // Interrupt OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ HIDD_Descriptors_INTERRUPTOUT),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardOutputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING
+ },
+ #endif // (HID defined)
+
+ #if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO)
+ // AUDIO
+ // IAD for AUDIO function
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ AUDD_Descriptors_INTERFACE,
+ 2,
+ AUDControlInterfaceDescriptor_CLASS,
+ AUDControlInterfaceDescriptor_SUBCLASS,
+ AUDControlInterfaceDescriptor_PROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Audio control interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ AUDD_Descriptors_CONTROL,
+ 0, // This is alternate setting #0
+ 0, // This interface uses no endpoint
+ AUDControlInterfaceDescriptor_CLASS,
+ AUDControlInterfaceDescriptor_SUBCLASS,
+ AUDControlInterfaceDescriptor_PROTOCOL,
+ 0 // No string descriptor
+ },
+ // Audio control interface descriptors
+ {
+ // Header descriptor
+ {
+ {
+ sizeof(AUDHeaderDescriptor1),
+ AUDGenericDescriptor_INTERFACE,
+ AUDGenericDescriptor_HEADER,
+ AUDHeaderDescriptor_AUD1_00,
+ sizeof(AUDDSpeakerDriverAudioControlDescriptors),
+ 1 // One streaming interface
+ },
+ AUDD_Descriptors_STREAMING
+ },
+ // Input terminal descriptor
+ {
+ sizeof(AUDInputTerminalDescriptor),
+ AUDGenericDescriptor_INTERFACE,
+ AUDGenericDescriptor_INPUTTERMINAL,
+ AUDD_Descriptors_INPUTTERMINAL,
+ AUDInputTerminalDescriptor_USBSTREAMING,
+ AUDD_Descriptors_OUTPUTTERMINAL,
+ AUDD_NUMCHANNELS,
+ AUDInputTerminalDescriptor_LEFTFRONT
+ | AUDInputTerminalDescriptor_RIGHTFRONT,
+ 0, // No string descriptor for channels
+ 0 // No string descriptor for input terminal
+ },
+ // Output terminal descriptor
+ {
+ sizeof(AUDOutputTerminalDescriptor),
+ AUDGenericDescriptor_INTERFACE,
+ AUDGenericDescriptor_OUTPUTTERMINAL,
+ AUDD_Descriptors_OUTPUTTERMINAL,
+ AUDOutputTerminalDescriptor_SPEAKER,
+ AUDD_Descriptors_INPUTTERMINAL,
+ AUDD_Descriptors_FEATUREUNIT,
+ 0 // No string descriptor
+ },
+ // Feature unit descriptor
+ {
+ {
+ sizeof(AUDFeatureUnitDescriptor3),
+ AUDGenericDescriptor_INTERFACE,
+ AUDGenericDescriptor_FEATUREUNIT,
+ AUDD_Descriptors_FEATUREUNIT,
+ AUDD_Descriptors_INPUTTERMINAL,
+ 1, // 1 byte per channel for controls
+ },
+ {
+ AUDFeatureUnitDescriptor_MUTE, // Master channel controls
+ 0, // Right channel controls
+ 0 // Left channel controls
+ },
+ 0 // No string descriptor
+ }
+ },
+ // Audio streaming interface with 0 endpoints
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ AUDD_Descriptors_STREAMING,
+ 0, // This is alternate setting #0
+ 0, // This interface uses no endpoints
+ AUDStreamingInterfaceDescriptor_CLASS,
+ AUDStreamingInterfaceDescriptor_SUBCLASS,
+ AUDStreamingInterfaceDescriptor_PROTOCOL,
+ 0 // No string descriptor
+ },
+ // Audio streaming interface with data endpoint
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ AUDD_Descriptors_STREAMING,
+ 1, // This is alternate setting #1
+ 1, // This interface uses 1 endpoint
+ AUDStreamingInterfaceDescriptor_CLASS,
+ AUDStreamingInterfaceDescriptor_SUBCLASS,
+ AUDStreamingInterfaceDescriptor_PROTOCOL,
+ 0 // No string descriptor
+ },
+ // Audio streaming class-specific descriptor
+ {
+ sizeof(AUDStreamingInterfaceDescriptor),
+ AUDGenericDescriptor_INTERFACE,
+ AUDStreamingInterfaceDescriptor_GENERAL,
+ AUDD_Descriptors_INPUTTERMINAL,
+ 0, // No internal delay because of data path
+ AUDFormatTypeOneDescriptor_PCM
+ },
+ // Format type I descriptor
+ {
+ {
+ sizeof(AUDFormatTypeOneDescriptor1),
+ AUDGenericDescriptor_INTERFACE,
+ AUDStreamingInterfaceDescriptor_FORMATTYPE,
+ AUDFormatTypeOneDescriptor_FORMATTYPEONE,
+ AUDD_NUMCHANNELS,
+ AUDD_BYTESPERSAMPLE,
+ AUDD_BYTESPERSAMPLE*8,
+ 1 // One discrete frequency supported
+ },
+ {
+ AUDD_SAMPLERATE & 0xFF,
+ (AUDD_SAMPLERATE >> 8) & 0xFF,
+ (AUDD_SAMPLERATE >> 16) & 0xFF
+ }
+ },
+ // Audio streaming endpoint standard descriptor
+ {
+ sizeof(AUDEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ AUDD_Descriptors_DATAOUT),
+ USBEndpointDescriptor_ISOCHRONOUS,
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(AUDD_Descriptors_DATAOUT),
+ 1, // Polling interval = 2^(x-1) milliseconds (1 ms)
+ 0, // This is not a synchronization endpoint
+ 0 // No associated synchronization endpoint
+ },
+ // Audio streaming endpoint class-specific descriptor
+ {
+ sizeof(AUDDataEndpointDescriptor),
+ AUDGenericDescriptor_ENDPOINT,
+ AUDDataEndpointDescriptor_SUBTYPE,
+ 0, // No attributes
+ 0, // Endpoint is not synchronized
+ 0 // Endpoint is not synchronized
+ },
+ #endif // (AUDIO defined)
+
+ #if defined(usb_CDCCDC)
+ // CDC 1
+ // IAD for CDC/ACM port 1
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM1,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM1, // This is interface #2
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM1 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM1, // Number of master interface is #2
+ CDCD_Descriptors_INTERFACENUM1+1 // First slave interface is #3
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION1),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION1),
+ USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
+ 10 // Endpoint is polled every 10ms
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM1 + 1, // This is interface #3
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT1),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT1),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN1),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN1),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ #endif // (2 CDCs defined)
+
+ #if defined(usb_CDCMSD) || defined(usb_HIDMSD)
+ // Mass Storage interface descriptor.
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ MSDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0.
+ 2, // Interface uses two endpoints.
+ MSInterfaceDescriptor_CLASS,
+ MSInterfaceDescriptor_SCSI,
+ MSInterfaceDescriptor_BULKONLY,
+ 0 // No string descriptor for interface.
+ },
+ // Bulk-OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // No string descriptor for endpoint.
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // No string descriptor for endpoint.
+ },
+ #endif // (MSD defined)
+
+};
+
+/// String descriptor with the supported languages.
+const unsigned char languageIdDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(1),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_ENGLISH_US
+};
+
+/// Manufacturer name.
+const unsigned char manufacturerDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(5),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('l')
+};
+
+/// Product name.
+const unsigned char productDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(14),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('C'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('p'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('s'),
+ USBStringDescriptor_UNICODE('i'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('D'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('o')
+};
+
+/// Product serial number.
+const unsigned char serialNumberDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(4),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('0'),
+ USBStringDescriptor_UNICODE('1'),
+ USBStringDescriptor_UNICODE('2'),
+ USBStringDescriptor_UNICODE('3')
+};
+
+/// Array of pointers to the four string descriptors.
+const unsigned char *stringDescriptors[] = {
+
+ languageIdDescriptor,
+ manufacturerDescriptor,
+ productDescriptor,
+ serialNumberDescriptor,
+};
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// List of descriptors required by an USB audio speaker device driver.
+const USBDDriverDescriptors compositedDriverDescriptors = {
+
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptors,
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptors,
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptors,
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptors,
+#else
+ 0, 0, 0, 0, 0, 0,
+#endif
+ stringDescriptors,
+ 4 // Number of string descriptors
+};
+
+#if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD)
+/// Report descriptor used by the driver.
+const unsigned char hiddReportDescriptor[] = {
+
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID,
+ HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_KEYBOARD,
+ HIDReport_COLLECTION + 1, HIDReport_COLLECTION_APPLICATION,
+
+ // Input report: modifier keys
+ HIDReport_GLOBAL_REPORTSIZE + 1, 1,
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 8,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDKeypad_PAGEID,
+ HIDReport_LOCAL_USAGEMINIMUM + 1,
+ HIDD_Descriptors_FIRSTMODIFIERKEY,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1,
+ HIDD_Descriptors_LASTMODIFIERKEY,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
+ HIDReport_INPUT + 1, HIDReport_VARIABLE,
+
+ // Input report: standard keys
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 8,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1,
+ HIDD_Descriptors_FIRSTSTANDARDKEY,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1,
+ HIDD_Descriptors_LASTSTANDARDKEY,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDKeypad_PAGEID,
+ HIDReport_LOCAL_USAGEMINIMUM + 1,
+ HIDD_Descriptors_FIRSTSTANDARDKEY,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1,
+ HIDD_Descriptors_LASTSTANDARDKEY,
+ HIDReport_INPUT + 1, 0 /* Data array */,
+
+ // Output report: LEDs
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 1,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDLeds_PAGEID,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
+ HIDReport_LOCAL_USAGEMINIMUM + 1, HIDLeds_NUMLOCK,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1, HIDLeds_SCROLLLOCK,
+ HIDReport_OUTPUT + 1, HIDReport_VARIABLE,
+
+ // Output report: padding
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 1,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 5,
+ HIDReport_OUTPUT + 1, HIDReport_CONSTANT,
+
+ HIDReport_ENDCOLLECTION
+};
+#endif // (HID defined)
+
diff --git a/usb/device/composite/COMPOSITEDDriverDescriptors.h b/usb/device/composite/COMPOSITEDDriverDescriptors.h
new file mode 100644
index 0000000..c82f9bc
--- /dev/null
+++ b/usb/device/composite/COMPOSITEDDriverDescriptors.h
@@ -0,0 +1,61 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef COMPOSITEDDRIVERDESCRIPTORS_H
+#define COMPOSITEDDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <board.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Number of interfaces of the device
+#if defined(usb_CDCAUDIO) || defined(usb_CDCCDC)
+ #define COMPOSITEDDriverDescriptors_NUMINTERFACE 4
+#elif defined(usb_CDCHID) || defined(usb_CDCMSD) || defined(usb_HIDAUDIO)
+ #define COMPOSITEDDriverDescriptors_NUMINTERFACE 3
+#elif defined(usb_HIDMSD)
+ #define COMPOSITEDDriverDescriptors_NUMINTERFACE 2
+#else
+ #error USB Composite class not defined.
+#endif
+
+//-----------------------------------------------------------------------------
+// Exported variables
+//-----------------------------------------------------------------------------
+
+extern const USBDDriverDescriptors compositedDriverDescriptors;
+
+#endif //#ifndef COMPOSITEDDRIVERDESCRIPTORS_H
diff --git a/usb/device/composite/DUALCDCDDriver.c b/usb/device/composite/DUALCDCDDriver.c
new file mode 100644
index 0000000..cced6f3
--- /dev/null
+++ b/usb/device/composite/DUALCDCDDriver.c
@@ -0,0 +1,189 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <utility/led.h>
+
+// USB
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+
+//- DUALCDC
+#include "DUALCDCDDriver.h"
+#include "DUALCDCDDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+/// Interface setting spaces (4 byte aligned)
+#define NUM_INTERFACES ((DUALCDCDDriverDescriptors_NUMINTERFACE+3)&0xFC)
+
+//-----------------------------------------------------------------------------
+// Types
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// USBDDriver instance
+static USBDDriver usbdDriver;
+
+/// CDCDSeriaoPort instance for 2 CDC/CAM serial ports.
+static CDCDSerialPort cdcdPorts[2];
+
+/// Array for storing the current setting of each interface
+static unsigned char compositedDriverInterfaces[NUM_INTERFACES];
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Optional RequestReceived() callback re-implementation
+//-----------------------------------------------------------------------------
+#if !defined(NOAUTOCALLBACK)
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ DUALCDCDDriver_RequestHandler(request);
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+// ConfigurationChanged() callback re-implementation
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes the USB device composite device driver.
+//-----------------------------------------------------------------------------
+void DUALCDCDDriver_Initialize()
+{
+ // CDC
+ CDCDFunctionDriver_ConfigurePort(&cdcdPorts[0],
+ CDCD_Descriptors_INTERFACENUM0,
+ CDCD_Descriptors_NOTIFICATION0,
+ CDCD_Descriptors_DATAIN0,
+ CDCD_Descriptors_DATAOUT0);
+ CDCDFunctionDriver_ConfigurePort(&cdcdPorts[1],
+ CDCD_Descriptors_INTERFACENUM1,
+ CDCD_Descriptors_NOTIFICATION1,
+ CDCD_Descriptors_DATAIN1,
+ CDCD_Descriptors_DATAOUT1);
+ CDCDFunctionDriver_Initialize(&usbdDriver,
+ cdcdPorts,
+ 2);
+
+ // Initialize the standard USB driver
+ USBDDriver_Initialize(&usbdDriver,
+ &dualcdcdDriverDescriptors,
+ compositedDriverInterfaces);
+
+ // Initialize the USB driver
+ USBD_Init();
+}
+
+//-----------------------------------------------------------------------------
+/// Handles composite-specific USB requests sent by the host, and forwards
+/// standard ones to the USB device driver.
+/// \param request Pointer to a USBGenericRequest instance.
+//-----------------------------------------------------------------------------
+void DUALCDCDDriver_RequestHandler(const USBGenericRequest *request)
+{
+ // Check if this is a class request
+ if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
+
+ unsigned char rc = 0;
+
+ if (rc == 0) {
+
+ rc = CDCDFunctionDriver_RequestHandler(request);
+ }
+
+ if (!rc) {
+
+ TRACE_WARNING(
+ "DUALCDCDDriver_RequestHandler: Unsupported request (%d)\n\r",
+ USBGenericRequest_GetRequest(request));
+ USBD_Stall(0);
+ }
+
+ }
+ // Check if this is a standard request
+ else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
+
+ unsigned char rc = 0;
+
+ // Forward request to the standard handler
+ if (rc == 0) {
+
+ USBDDriver_RequestHandler(&(usbdDriver), request);
+ }
+ }
+ // Unsupported request type
+ else {
+
+ TRACE_WARNING(
+ "DUALCDCDDriver_RequestHandler: Unsupported request type (%d)\n\r",
+ USBGenericRequest_GetType(request));
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Starts a remote wake-up sequence if the host has explicitely enabled it
+/// by sending the appropriate SET_FEATURE request.
+//-----------------------------------------------------------------------------
+void DUALCDCDDriver_RemoteWakeUp(void)
+{
+ // Remote wake-up has been enabled
+ if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver)) {
+
+ USBD_RemoteWakeUp();
+ }
+ // Remote wake-up NOT enabled
+ else {
+
+ TRACE_WARNING("DUALCDCDDriver_RemoteWakeUp: not enabled\n\r");
+ }
+}
+
+
diff --git a/usb/device/composite/DUALCDCDDriver.h b/usb/device/composite/DUALCDCDDriver.h
new file mode 100644
index 0000000..8ff2c66
--- /dev/null
+++ b/usb/device/composite/DUALCDCDDriver.h
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Definitions and methods for USB composite device implement.
+///
+/// !Usage
+///
+/// -# Initialize USB function specified driver ( for MSD currently )
+/// - MSDDFunctionDriver_Initialize
+///
+/// -# Initialize USB composite driver and USB driver
+/// - DUALCDCDDriver_Initialize
+///
+/// -# Handle and dispach USB requests
+/// - DUALCDCDDriver_RequestHandler
+///
+/// -# Try starting a remote wake-up sequence
+/// - DUALCDCDDriver_RemoteWakeUp
+//-----------------------------------------------------------------------------
+
+#ifndef DUALCDCDDRIVER_H
+#define DUALCDCDDRIVER_H
+
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+#include <usb/device/core/USBD.h>
+
+#include "CDCDFunctionDriver.h"
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+// -DUALCDC
+extern void DUALCDCDDriver_Initialize();
+
+extern void DUALCDCDDriver_RequestHandler(const USBGenericRequest *request);
+
+extern void DUALCDCDDriver_RemoteWakeUp(void);
+
+#endif //#ifndef DUALCDCDDRIVER_H
+
diff --git a/usb/device/composite/DUALCDCDDriverDescriptors.c b/usb/device/composite/DUALCDCDDriverDescriptors.c
new file mode 100644
index 0000000..f39b29e
--- /dev/null
+++ b/usb/device/composite/DUALCDCDDriverDescriptors.c
@@ -0,0 +1,702 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "DUALCDCDDriver.h"
+#include "DUALCDCDDriverDescriptors.h"
+#include <board.h>
+
+//- USB Generic
+#include <usb/common/core/USBGenericDescriptor.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/common/core/USBInterfaceAssociationDescriptor.h>
+#include <usb/common/core/USBEndpointDescriptor.h>
+#include <usb/common/core/USBStringDescriptor.h>
+#include <usb/common/core/USBGenericRequest.h>
+
+#include <usb/common/cdc/CDCGenericDescriptor.h>
+#include <usb/common/cdc/CDCDeviceDescriptor.h>
+#include <usb/common/cdc/CDCCommunicationInterfaceDescriptor.h>
+#include <usb/common/cdc/CDCDataInterfaceDescriptor.h>
+#include <usb/common/cdc/CDCHeaderDescriptor.h>
+#include <usb/common/cdc/CDCCallManagementDescriptor.h>
+#include <usb/common/cdc/CDCAbstractControlManagementDescriptor.h>
+#include <usb/common/cdc/CDCUnionDescriptor.h>
+#include "CDCDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Device product ID.
+#define DUALCDCDDriverDescriptors_PRODUCTID 0x6133
+
+/// Device vendor ID (Atmel).
+#define DUALCDCDDriverDescriptors_VENDORID 0x03EB
+
+/// Device release number.
+#define DUALCDCDDriverDescriptors_RELEASE 0x0003
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+/// Returns the minimum between two values.
+#define MIN(a, b) ((a < b) ? a : b)
+
+//-----------------------------------------------------------------------------
+// Internal structures
+//-----------------------------------------------------------------------------
+
+#ifdef __ICCARM__ // IAR
+#pragma pack(1) // IAR
+#define __attribute__(...) // IAR
+#endif // IAR
+
+//-----------------------------------------------------------------------------
+/// Configuration descriptor list for a device implementing a composite driver.
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Standard configuration descriptor.
+ USBConfigurationDescriptor configuration;
+
+ /// --- CDC 0
+ /// IAD 0
+ USBInterfaceAssociationDescriptor cdcIAD0;
+ /// Communication interface descriptor
+ USBInterfaceDescriptor cdcCommunication0;
+ /// CDC header functional descriptor.
+ CDCHeaderDescriptor cdcHeader0;
+ /// CDC call management functional descriptor.
+ CDCCallManagementDescriptor cdcCallManagement0;
+ /// CDC abstract control management functional descriptor.
+ CDCAbstractControlManagementDescriptor cdcAbstractControlManagement0;
+ /// CDC union functional descriptor (with one slave interface).
+ CDCUnionDescriptor cdcUnion0;
+ /// Notification endpoint descriptor.
+ USBEndpointDescriptor cdcNotification0;
+ /// Data interface descriptor.
+ USBInterfaceDescriptor cdcData0;
+ /// Data OUT endpoint descriptor.
+ USBEndpointDescriptor cdcDataOut0;
+ /// Data IN endpoint descriptor.
+ USBEndpointDescriptor cdcDataIn0;
+
+ /// --- CDC 1
+ /// IAD 1
+ USBInterfaceAssociationDescriptor cdcIAD1;
+ /// Communication interface descriptor
+ USBInterfaceDescriptor cdcCommunication1;
+ /// CDC header functional descriptor.
+ CDCHeaderDescriptor cdcHeader1;
+ /// CDC call management functional descriptor.
+ CDCCallManagementDescriptor cdcCallManagement1;
+ /// CDC abstract control management functional descriptor.
+ CDCAbstractControlManagementDescriptor cdcAbstractControlManagement1;
+ /// CDC union functional descriptor (with one slave interface).
+ CDCUnionDescriptor cdcUnion1;
+ /// Notification endpoint descriptor.
+ USBEndpointDescriptor cdcNotification1;
+ /// Data interface descriptor.
+ USBInterfaceDescriptor cdcData1;
+ /// Data OUT endpoint descriptor.
+ USBEndpointDescriptor cdcDataOut1;
+ /// Data IN endpoint descriptor.
+ USBEndpointDescriptor cdcDataIn1;
+
+} __attribute__ ((packed)) DualCdcDriverConfigurationDescriptors;
+
+#ifdef __ICCARM__ // IAR
+#pragma pack() // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// Standard USB device descriptor for the composite device driver
+static const USBDeviceDescriptor deviceDescriptor = {
+
+ sizeof(USBDeviceDescriptor),
+ USBGenericDescriptor_DEVICE,
+ USBDeviceDescriptor_USB2_00,
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ DUALCDCDDriverDescriptors_VENDORID,
+ DUALCDCDDriverDescriptors_PRODUCTID,
+ DUALCDCDDriverDescriptors_RELEASE,
+ 0, // No string descriptor for manufacturer
+ 1, // Index of product string descriptor is #1
+ 0, // No string descriptor for serial number
+ 1 // Device has 1 possible configuration
+};
+
+#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+
+/// USB device qualifier descriptor.
+static const USBDeviceQualifierDescriptor qualifierDescriptor = {
+
+ sizeof(USBDeviceQualifierDescriptor),
+ USBGenericDescriptor_DEVICEQUALIFIER,
+ USBDeviceDescriptor_USB2_00,
+ 0xEF,// MI
+ 0x02,//
+ 0x01,//
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ 1, // Device has one possible configuration
+ 0 // Reserved
+};
+
+/// USB configuration descriptors for the composite device driver
+static const DualCdcDriverConfigurationDescriptors configurationDescriptorsHS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(DualCdcDriverConfigurationDescriptors),
+ DUALCDCDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // CDC 0
+ // IAD for CDC/ACM port
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM0,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0, // This is interface #0
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM0 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM0, // Number of master interface is #0
+ CDCD_Descriptors_INTERFACENUM0 + 1 // First slave interface is #1
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
+ CDCD_Descriptors_INTERRUPT_MAXPACKETSIZE),
+ CDCD_Descriptors_INTERRUPTIN_POLLING_HS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0 + 1, // This is interface #1
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+
+ // CDC 1
+ // IAD for CDC/ACM port 1
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM1,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM1, // This is interface #2
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM1 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM1, // Number of master interface is #2
+ CDCD_Descriptors_INTERFACENUM1+1 // First slave interface is #3
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION1),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION1),
+ CDCD_Descriptors_INTERRUPT_MAXPACKETSIZE),
+ CDCD_Descriptors_INTERRUPTIN_POLLING_HS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM1 + 1, // This is interface #3
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT1),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT1),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN1),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN1),
+ CDCD_Descriptors_BULK_MAXPACKETSIZE),
+ 0 // Must be 0 for full-speed bulk endpoints
+ }
+
+};
+
+#endif
+
+/// USB configuration descriptors for the composite device driver
+static const DualCdcDriverConfigurationDescriptors configurationDescriptorsFS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(DualCdcDriverConfigurationDescriptors),
+ DUALCDCDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // CDC 0
+ // IAD for CDC/ACM port
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM0,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0, // This is interface #0
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM0 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM0, // Number of master interface is #0
+ CDCD_Descriptors_INTERFACENUM0 + 1 // First slave interface is #1
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
+ USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
+ CDCD_Descriptors_INTERRUPTIN_POLLING_FS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM0 + 1, // This is interface #1
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+
+ // CDC 1
+ // IAD for CDC/ACM port 1
+ {
+ sizeof(USBInterfaceAssociationDescriptor),
+ USBGenericDescriptor_INTERFACEASSOCIATION,
+ CDCD_Descriptors_INTERFACENUM1,
+ 2,
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Communication class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM1, // This is interface #2
+ 0, // This is alternate setting #0 for this interface
+ 1, // This interface uses 1 endpoint
+ CDCCommunicationInterfaceDescriptor_CLASS,
+ CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+ CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Class-specific header functional descriptor
+ {
+ sizeof(CDCHeaderDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_HEADER,
+ CDCGenericDescriptor_CDC1_10
+ },
+ // Class-specific call management functional descriptor
+ {
+ sizeof(CDCCallManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_CALLMANAGEMENT,
+ CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
+ CDCD_Descriptors_INTERFACENUM1 + 1 // No associated data interface
+ },
+ // Class-specific abstract control management functional descriptor
+ {
+ sizeof(CDCAbstractControlManagementDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
+ CDCAbstractControlManagementDescriptor_LINE
+ },
+ // Class-specific union functional descriptor with one slave interface
+ {
+ sizeof(CDCUnionDescriptor),
+ CDCGenericDescriptor_INTERFACE,
+ CDCGenericDescriptor_UNION,
+ CDCD_Descriptors_INTERFACENUM1, // Number of master interface is #2
+ CDCD_Descriptors_INTERFACENUM1+1 // First slave interface is #3
+ },
+ // Notification endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_NOTIFICATION1),
+ USBEndpointDescriptor_INTERRUPT,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION1),
+ USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
+ CDCD_Descriptors_INTERRUPTIN_POLLING_FS
+ },
+ // Data class interface standard descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ CDCD_Descriptors_INTERFACENUM1 + 1, // This is interface #3
+ 0, // This is alternate setting #0 for this interface
+ 2, // This interface uses 2 endpoints
+ CDCDataInterfaceDescriptor_CLASS,
+ CDCDataInterfaceDescriptor_SUBCLASS,
+ CDCDataInterfaceDescriptor_NOPROTOCOL,
+ 0 // No string descriptor for this interface
+ },
+ // Bulk-OUT endpoint standard descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+ CDCD_Descriptors_DATAOUT1),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT1),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+ CDCD_Descriptors_DATAIN1),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN1),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // Must be 0 for full-speed bulk endpoints
+ }
+
+};
+
+/// String descriptor with the supported languages.
+static const unsigned char languageIdDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(1),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_ENGLISH_US
+};
+
+/// Manufacturer name.
+static const unsigned char manufacturerDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(5),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('l')
+};
+
+/// Product name.
+static const unsigned char productDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(14),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('C'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('p'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('s'),
+ USBStringDescriptor_UNICODE('i'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('D'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('o')
+};
+
+/// Product serial number.
+static const unsigned char serialNumberDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(4),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('0'),
+ USBStringDescriptor_UNICODE('1'),
+ USBStringDescriptor_UNICODE('2'),
+ USBStringDescriptor_UNICODE('3')
+};
+
+/// Array of pointers to the four string descriptors.
+static const unsigned char *stringDescriptors[] = {
+
+ languageIdDescriptor,
+ manufacturerDescriptor,
+ productDescriptor,
+ serialNumberDescriptor,
+};
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// List of descriptors required by an USB audio speaker device driver.
+const USBDDriverDescriptors dualcdcdDriverDescriptors = {
+
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#else
+ 0, 0, 0, 0, 0, 0,
+#endif
+ stringDescriptors,
+ 4 // Number of string descriptors
+};
diff --git a/usb/device/composite/DUALCDCDDriverDescriptors.h b/usb/device/composite/DUALCDCDDriverDescriptors.h
new file mode 100644
index 0000000..13e1f4d
--- /dev/null
+++ b/usb/device/composite/DUALCDCDDriverDescriptors.h
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef DUALCDCDDRIVERDESCRIPTORS_H
+#define DUALCDCDDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <board.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Number of interfaces of the device
+#define DUALCDCDDriverDescriptors_NUMINTERFACE 4
+
+/// Number of the CDC0 interface.
+#define CDCD_Descriptors_INTERFACENUM0 0
+/// Address of the CDC0 interrupt-in endpoint.
+#define CDCD_Descriptors_NOTIFICATION0 3
+/// Address of the CDC0 bulk-in endpoint.
+#define CDCD_Descriptors_DATAIN0 2
+/// Address of the CDC0 bulk-out endpoint.
+#define CDCD_Descriptors_DATAOUT0 1
+
+/// Number of the CDC1 interface.
+#define CDCD_Descriptors_INTERFACENUM1 2
+/// Address of the CDC1 interrupt-in endpoint.
+#define CDCD_Descriptors_NOTIFICATION1 6
+/// Address of the CDC1 bulk-in endpoint.
+#define CDCD_Descriptors_DATAIN1 5
+/// Address of the CDC1 bulk-out endpoint.
+#define CDCD_Descriptors_DATAOUT1 4
+
+
+//-----------------------------------------------------------------------------
+// Exported variables
+//-----------------------------------------------------------------------------
+
+extern const USBDDriverDescriptors dualcdcdDriverDescriptors;
+
+#endif //#ifndef DUALCDCDDRIVERDESCRIPTORS_H
diff --git a/usb/device/composite/HIDDFunctionDriver.c b/usb/device/composite/HIDDFunctionDriver.c
new file mode 100644
index 0000000..03f8a1c
--- /dev/null
+++ b/usb/device/composite/HIDDFunctionDriver.c
@@ -0,0 +1,477 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+// USB
+#include <usb/device/core/USBD.h>
+#include <usb/common/core/USBGetDescriptorRequest.h>
+#include <usb/device/core/USBDDriver.h>
+// HID
+#include <usb/device/hid-keyboard/HIDDKeyboardDriver.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardDriverDescriptors.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardCallbacks.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDGenericRequest.h>
+#include <usb/common/hid/HIDReportRequest.h>
+#include <usb/common/hid/HIDIdleRequest.h>
+#include <usb/common/hid/HIDKeypad.h>
+
+#include "HIDDFunctionDriver.h"
+#include "HIDDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Internal types
+//-----------------------------------------------------------------------------
+
+/// Driver structure for an HID device implementing keyboard functionalities.
+typedef struct {
+
+ /// Pointer to USB device driver instance
+ USBDDriver * pUsbdDriver;
+ /// Interface Number to access this function
+ unsigned char interfaceNum;
+ /// Interrupt IN endpoint address
+ unsigned char interruptInEndpoint;
+ /// Interrupt OUT endpoint address
+ unsigned char interruptOutEndpoint;
+ /// Idle rate (in milliseconds) of the input report
+ unsigned char inputReportIdleRate;
+ /// Input report instance.
+ HIDDKeyboardInputReport inputReport;
+ /// Output report instance.
+ HIDDKeyboardOutputReport outputReport;
+
+} HIDDKeyboardDriver;
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// Static instance of the HID keyboard device driver.
+static HIDDKeyboardDriver hiddKeyboardDriver;
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Returns the descriptor requested by the host.
+/// \param type Descriptor type.
+/// \param length Maximum number of bytes to send.
+/// \return 1 if the request has been handled by this function, otherwise 0.
+//-----------------------------------------------------------------------------
+static unsigned char HIDD_GetDescriptor(unsigned char type,
+ unsigned char length)
+{
+ const USBConfigurationDescriptor *pConfiguration;
+ HIDDescriptor *hidDescriptors[2];
+
+ switch (type) {
+
+ case HIDGenericDescriptor_REPORT:
+ TRACE_INFO_WP("Report ");
+
+ // Adjust length and send report descriptor
+ if (length > HIDD_Descriptors_REPORTSIZE) {
+
+ length = HIDD_Descriptors_REPORTSIZE;
+ }
+ USBD_Write(0, &hiddReportDescriptor, length, 0, 0);
+ break;
+
+ case HIDGenericDescriptor_HID:
+ TRACE_INFO_WP("HID ");
+
+ // Configuration descriptor is different depending on speed
+ if (USBD_IsHighSpeed()) {
+
+ pConfiguration = hiddKeyboardDriver
+ .pUsbdDriver->pDescriptors->pHsConfiguration;
+ }
+ else {
+
+ pConfiguration = hiddKeyboardDriver
+ .pUsbdDriver->pDescriptors->pFsConfiguration;
+ }
+
+ // Parse the device configuration to get the HID descriptor
+ USBConfigurationDescriptor_Parse(pConfiguration,
+ 0,
+ 0,
+ (USBGenericDescriptor **) hidDescriptors);
+
+ // Adjust length and send HID descriptor
+ if (length > sizeof(HIDDescriptor)) {
+
+ length = sizeof(HIDDescriptor);
+ }
+ USBD_Write(0, hidDescriptors[0], length, 0, 0);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+/// Sends the current Idle rate of the input report to the host.
+//-----------------------------------------------------------------------------
+static void HIDD_GetIdle()
+{
+ TRACE_INFO_WP("gIdle ");
+
+ USBD_Write(0, &(hiddKeyboardDriver.inputReportIdleRate), 1, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+/// Retrieves the new idle rate of the input report from the USB host.
+/// \param idleRate New input report idle rate.
+//-----------------------------------------------------------------------------
+static void HIDD_SetIdle(unsigned char idleRate)
+{
+ TRACE_INFO_WP("sIdle(%d) ", idleRate);
+
+ hiddKeyboardDriver.inputReportIdleRate = idleRate;
+ USBD_Write(0, 0, 0, 0, 0);
+}
+
+//-----------------------------------------------------------------------------
+/// Sends the requested report to the host.
+/// \param type Report type.
+/// \param length Maximum number of bytes to send.
+//-----------------------------------------------------------------------------
+static void HIDD_GetReport(unsigned char type,
+ unsigned short length)
+{
+ TRACE_INFO_WP("gReport ");
+
+ // Check report type
+ switch (type) {
+
+ case HIDReportRequest_INPUT:
+ TRACE_INFO_WP("In ");
+
+ // Adjust size and send report
+ if (length > sizeof(HIDDKeyboardInputReport)) {
+
+ length = sizeof(HIDDKeyboardInputReport);
+ }
+ USBD_Write(0, // Endpoint #0
+ &(hiddKeyboardDriver.inputReport),
+ length,
+ 0, // No callback
+ 0);
+ break;
+
+ case HIDReportRequest_OUTPUT:
+ TRACE_INFO_WP("Out ");
+
+ // Adjust size and send report
+ if (length > sizeof(HIDDKeyboardOutputReport)) {
+
+ length = sizeof(HIDDKeyboardOutputReport);
+ }
+ USBD_Write(0, // Endpoint #0
+ &(hiddKeyboardDriver.outputReport),
+ length,
+ 0, // No callback
+ 0);
+ break;
+
+ default:
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Callback invoked when an output report has been received from the host.
+/// Forward the new status of the LEDs to the user program via the
+//-----------------------------------------------------------------------------
+static void HIDD_ReportReceived()
+{
+ TRACE_INFO_WP("oReport ");
+
+ // Trigger callback
+ HIDDKeyboardCallbacks_LedsChanged(
+ HIDDKeyboardOutputReport_GetNumLockStatus(
+ &(hiddKeyboardDriver.outputReport)),
+ HIDDKeyboardOutputReport_GetCapsLockStatus(
+ &(hiddKeyboardDriver.outputReport)),
+ HIDDKeyboardOutputReport_GetScrollLockStatus(
+ &(hiddKeyboardDriver.outputReport)));
+
+ // Restart transfer
+ USBD_Read(hiddKeyboardDriver.interruptOutEndpoint,
+ &(hiddKeyboardDriver.outputReport),
+ sizeof(HIDDKeyboardOutputReport),
+ (TransferCallback) HIDD_ReportReceived,
+ 0); // No argument for callback function
+}
+
+//-----------------------------------------------------------------------------
+/// Retrieves the new value of a report from the host and saves it.
+/// \param type Report type.
+/// \param length Report length.
+//-----------------------------------------------------------------------------
+static void HIDD_SetReport(unsigned char type,
+ unsigned short length)
+{
+ TRACE_INFO_WP("sReport ");
+
+ // Check report type
+ switch (type) {
+
+ case HIDReportRequest_INPUT:
+ // SET_REPORT requests on input reports are ignored
+ USBD_Stall(0);
+ break;
+
+ case HIDReportRequest_OUTPUT:
+ // Check report length
+ if (length != sizeof(HIDDKeyboardOutputReport)) {
+
+ USBD_Stall(0);
+ }
+ else {
+
+ USBD_Read(0, // Endpoint #0
+ &(hiddKeyboardDriver.outputReport),
+ length,
+ (TransferCallback) HIDD_ReportReceived,
+ 0); // No argument to the callback function
+ }
+ break;
+
+ default:
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes an USB HID keyboard function driver.
+/// \param pUsbdDriver Pointer to the USB driver instance.
+/// \param interfaceNum Interface number to access the MSD function
+/// \param interruptInEndpoint Interrupt IN endpoint address
+/// \param interruptOutEndpoint Interrupt OUT endpoint address
+//-----------------------------------------------------------------------------
+void HIDDFunctionDriver_Initialize(USBDDriver * pUsbdDriver,
+ unsigned char interfaceNum,
+ unsigned char interruptInEndpoint,
+ unsigned char interruptOutEndpoint)
+{
+ hiddKeyboardDriver.inputReportIdleRate = 0;
+ HIDDKeyboardInputReport_Initialize(&(hiddKeyboardDriver.inputReport));
+ HIDDKeyboardOutputReport_Initialize(&(hiddKeyboardDriver.outputReport));
+
+ hiddKeyboardDriver.pUsbdDriver = pUsbdDriver;
+ hiddKeyboardDriver.interfaceNum = interfaceNum;
+ hiddKeyboardDriver.interruptInEndpoint = interruptInEndpoint;
+ hiddKeyboardDriver.interruptOutEndpoint = interruptOutEndpoint;
+}
+
+//-----------------------------------------------------------------------------
+/// Handles HID-specific SETUP request sent by the host.
+/// \param request Pointer to a USBGenericRequest instance.
+/// \return 0 if the request is Unsupported, 1 if the request handled.
+//-----------------------------------------------------------------------------
+unsigned char HIDDFunctionDriver_RequestHandler(
+ const USBGenericRequest *request)
+{
+ TRACE_INFO_WP("NewReq ");
+
+ // Check if this is a standard request
+ if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
+
+ // This is a standard request
+ switch (USBGenericRequest_GetRequest(request)) {
+
+ case USBGenericRequest_GETDESCRIPTOR:
+ // Check if this is a HID descriptor, otherwise forward it to
+ // the standard driver
+ if (!HIDD_GetDescriptor(
+ USBGetDescriptorRequest_GetDescriptorType(request),
+ USBGenericRequest_GetLength(request))) {
+
+ USBDDriver_RequestHandler(hiddKeyboardDriver.pUsbdDriver,
+ request);
+ }
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ // Check if this is a class request
+ else if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
+
+ // This is a class-specific request
+ switch (USBGenericRequest_GetRequest(request)) {
+
+ case HIDGenericRequest_GETIDLE:
+ HIDD_GetIdle();
+ break;
+
+ case HIDGenericRequest_SETIDLE:
+ HIDD_SetIdle(HIDIdleRequest_GetIdleRate(request));
+ break;
+
+ case HIDGenericRequest_GETREPORT:
+ HIDD_GetReport(
+ HIDReportRequest_GetReportType(request),
+ USBGenericRequest_GetLength(request));
+ break;
+
+ case HIDGenericRequest_SETREPORT:
+ HIDD_SetReport(
+ HIDReportRequest_GetReportType(request),
+ USBGenericRequest_GetLength(request));
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the configuration of the device is changed by the host.
+/// \param cfgnum Newly configuration number.
+//-----------------------------------------------------------------------------
+void HIDDFunctionCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+ if (cfgnum > 0) {
+
+ // Start receiving output reports
+ USBD_Read(hiddKeyboardDriver.interruptOutEndpoint,
+ &(hiddKeyboardDriver.outputReport),
+ sizeof(HIDDKeyboardOutputReport),
+ (TransferCallback) HIDD_ReportReceived,
+ 0); // No argument for callback function
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Reports a change in which keys are currently pressed or release to the
+/// host.
+/// \param pressedKeys Pointer to an array of key codes indicating keys that
+/// have been pressed since the last call to
+/// <HIDDKeyboardDriver_ChangeKeys>.
+/// \param pressedKeysSize Number of key codes in the pressedKeys array.
+/// \param releasedKeys Pointer to an array of key codes indicates keys that
+/// have been released since the last call to
+/// <HIDDKeyboardDriver_ChangeKeys>.
+/// \param releasedKeysSize Number of key codes in the releasedKeys array.
+/// \return <USBD_STATUS_SUCCESS> if the report has been sent to the host;
+/// otherwise an error code.
+//-----------------------------------------------------------------------------
+unsigned char HIDDKeyboardDriver_ChangeKeys(unsigned char *pressedKeys,
+ unsigned char pressedKeysSize,
+ unsigned char *releasedKeys,
+ unsigned char releasedKeysSize)
+{
+ // Press keys
+ while (pressedKeysSize > 0) {
+
+ // Check if this is a standard or modifier key
+ if (HIDKeypad_IsModifierKey(*pressedKeys)) {
+
+ // Set the corresponding bit in the input report
+ HIDDKeyboardInputReport_PressModifierKey(
+ &(hiddKeyboardDriver.inputReport),
+ *pressedKeys);
+ }
+ else {
+
+ HIDDKeyboardInputReport_PressStandardKey(
+ &(hiddKeyboardDriver.inputReport),
+ *pressedKeys);
+ }
+
+ pressedKeysSize--;
+ pressedKeys++;
+ }
+
+ // Release keys
+ while (releasedKeysSize > 0) {
+
+ // Check if this is a standard or modifier key
+ if (HIDKeypad_IsModifierKey(*releasedKeys)) {
+
+ // Set the corresponding bit in the input report
+ HIDDKeyboardInputReport_ReleaseModifierKey(
+ &(hiddKeyboardDriver.inputReport),
+ *releasedKeys);
+ }
+ else {
+
+ HIDDKeyboardInputReport_ReleaseStandardKey(
+ &(hiddKeyboardDriver.inputReport),
+ *releasedKeys);
+ }
+
+ releasedKeysSize--;
+ releasedKeys++;
+ }
+
+ // Send input report through the interrupt IN endpoint
+ return USBD_Write(hiddKeyboardDriver.interruptInEndpoint,
+ &(hiddKeyboardDriver.inputReport),
+ sizeof(HIDDKeyboardInputReport),
+ 0,
+ 0);
+}
+
+//-----------------------------------------------------------------------------
+/// Starts a remote wake-up sequence if the host has explicitely enabled it
+/// by sending the appropriate SET_FEATURE request.
+//-----------------------------------------------------------------------------
+void HIDDKeyboardDriver_RemoteWakeUp(void)
+{
+ // Remote wake-up has been enabled
+ if (USBDDriver_IsRemoteWakeUpEnabled(hiddKeyboardDriver.pUsbdDriver)) {
+
+ USBD_RemoteWakeUp();
+ }
+}
diff --git a/usb/device/composite/HIDDFunctionDriver.h b/usb/device/composite/HIDDFunctionDriver.h
new file mode 100644
index 0000000..a788d57
--- /dev/null
+++ b/usb/device/composite/HIDDFunctionDriver.h
@@ -0,0 +1,64 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef HIDDFUNCTIONDRIVER_H
+#define HIDDFUNCTIONDRIVER_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/device/core/USBDDriver.h>
+#include <usb/common/core/USBGenericRequest.h>
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//- Function API for composite device
+extern void HIDDFunctionDriver_Initialize(USBDDriver * pUsbdDriver,
+ unsigned char interfaceNum,
+ unsigned char interruptInEndpoint,
+ unsigned char interruptOutEndpoint);
+
+extern unsigned char HIDDFunctionDriver_RequestHandler(
+ const USBGenericRequest *request);
+
+extern void HIDDFunctionCallbacks_ConfigurationChanged(unsigned char cfgnum);
+
+//- HID Keyboard API
+extern unsigned char HIDDKeyboardDriver_ChangeKeys(
+ unsigned char *pressedKeys,
+ unsigned char pressedKeysSize,
+ unsigned char *releasedKeys,
+ unsigned char releasedKeysSize);
+
+extern void HIDDKeyboardDriver_RemoteWakeUp(void);
+
+#endif // #define HIDDFUNCTIONDRIVER_H
diff --git a/usb/device/composite/HIDDFunctionDriverDescriptors.c b/usb/device/composite/HIDDFunctionDriverDescriptors.c
new file mode 100644
index 0000000..747a5fb
--- /dev/null
+++ b/usb/device/composite/HIDDFunctionDriverDescriptors.c
@@ -0,0 +1,118 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+
+//- HID
+#include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDeviceDescriptor.h>
+#include <usb/common/hid/HIDInterfaceDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDReport.h>
+#include <usb/common/hid/HIDGenericDesktop.h>
+#include <usb/common/hid/HIDLeds.h>
+#include <usb/common/hid/HIDKeypad.h>
+#include "HIDDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Internal structures
+//-----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// Report descriptor used by the HID function driver.
+const unsigned char hiddReportDescriptor[] = {
+
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID,
+ HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_KEYBOARD,
+ HIDReport_COLLECTION + 1, HIDReport_COLLECTION_APPLICATION,
+
+ // Input report: modifier keys
+ HIDReport_GLOBAL_REPORTSIZE + 1, 1,
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 8,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDKeypad_PAGEID,
+ HIDReport_LOCAL_USAGEMINIMUM + 1,
+ HIDD_Descriptors_FIRSTMODIFIERKEY,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1,
+ HIDD_Descriptors_LASTMODIFIERKEY,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
+ HIDReport_INPUT + 1, HIDReport_VARIABLE,
+
+ // Input report: standard keys
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 8,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1,
+ HIDD_Descriptors_FIRSTSTANDARDKEY,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1,
+ HIDD_Descriptors_LASTSTANDARDKEY,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDKeypad_PAGEID,
+ HIDReport_LOCAL_USAGEMINIMUM + 1,
+ HIDD_Descriptors_FIRSTSTANDARDKEY,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1,
+ HIDD_Descriptors_LASTSTANDARDKEY,
+ HIDReport_INPUT + 1, 0 /* Data array */,
+
+ // Output report: LEDs
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 1,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDLeds_PAGEID,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
+ HIDReport_LOCAL_USAGEMINIMUM + 1, HIDLeds_NUMLOCK,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1, HIDLeds_SCROLLLOCK,
+ HIDReport_OUTPUT + 1, HIDReport_VARIABLE,
+
+ // Output report: padding
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 1,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 5,
+ HIDReport_OUTPUT + 1, HIDReport_CONSTANT,
+
+ HIDReport_ENDCOLLECTION
+};
diff --git a/usb/device/composite/HIDDFunctionDriverDescriptors.h b/usb/device/composite/HIDDFunctionDriverDescriptors.h
new file mode 100644
index 0000000..7f64321
--- /dev/null
+++ b/usb/device/composite/HIDDFunctionDriverDescriptors.h
@@ -0,0 +1,86 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef HIDDFUNCTIONDRIVERDESCRIPTORS_H
+#define HIDDFUNCTIONDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/device/core/USBDDriverDescriptors.h>
+#include <usb/common/hid/HIDKeypad.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+//- Interface & Endpoints
+/// Interface Number.
+/// Interrupt IN endpoint number.
+/// Interrupt OUT endpoint number.
+/// Interrupt IN endpoint polling rate (in milliseconds).
+/// Interrupt OUT endpoint polling rate (in milliseconds).
+#if defined(usb_HIDAUDIO)
+#define HIDD_Descriptors_INTERFACENUM 0
+#define HIDD_Descriptors_INTERRUPTIN 1
+#define HIDD_Descriptors_INTERRUPTOUT 2
+#define HIDD_Descriptors_INTERRUPTIN_POLLING 10
+#endif
+
+/// Default HID interrupt IN endpoint polling rate (16ms).
+#define HIDD_Descriptors_INTERRUPTIN_POLLING_FS 16
+#define HIDD_Descriptors_INTERRUPTIN_POLLING_HS 8
+/// Default interrupt OUT endpoint polling rate (16ms).
+#define HIDD_Descriptors_INTERRUPTOUT_POLLING_FS 16
+#define HIDD_Descriptors_INTERRUPTOUT_POLLING_HS 8
+
+//- Keypad keys
+/// Key code of the first accepted modifier key.
+#define HIDD_Descriptors_FIRSTMODIFIERKEY HIDKeypad_LEFTCONTROL
+/// Key code of the last accepted modifier key.
+#define HIDD_Descriptors_LASTMODIFIERKEY HIDKeypad_RIGHTGUI
+/// Key code of the first accepted standard key.
+#define HIDD_Descriptors_FIRSTSTANDARDKEY 0
+/// Key code of the last accepted standard key.
+#define HIDD_Descriptors_LASTSTANDARDKEY HIDKeypad_NUMLOCK
+
+//- Report descriptor
+/// Size of the report descriptor in bytes.
+#define HIDD_Descriptors_REPORTSIZE 61
+
+//-----------------------------------------------------------------------------
+// Exported variables
+//-----------------------------------------------------------------------------
+
+/// Report descriptor used by the driver.
+extern const unsigned char hiddReportDescriptor[];
+
+#endif // #define HIDDFUNCTIONDRIVERDESCRIPTORS_H
+
diff --git a/usb/device/composite/HIDMSDDDriver.c b/usb/device/composite/HIDMSDDDriver.c
new file mode 100644
index 0000000..2ef2ea7
--- /dev/null
+++ b/usb/device/composite/HIDMSDDDriver.c
@@ -0,0 +1,227 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+#include <utility/led.h>
+
+// USB
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+
+//- HID
+#include <usb/device/hid-keyboard/HIDDKeyboardDriver.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardDriverDescriptors.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardCallbacks.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDGenericRequest.h>
+#include <usb/common/hid/HIDReportRequest.h>
+#include <usb/common/hid/HIDIdleRequest.h>
+#include <usb/common/hid/HIDKeypad.h>
+
+//- MSD
+
+//- HIDMSD
+#include "HIDMSDDDriver.h"
+#include "HIDMSDDDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+/// Interface setting spaces (4 byte aligned)
+#define NUM_INTERFACES ((HIDMSDDDriverDescriptors_NUMINTERFACE+3)&0xFC)
+
+//-----------------------------------------------------------------------------
+// Types
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// USBDDriver instance
+static USBDDriver usbdDriver;
+
+/// Array for storing the current setting of each interface
+static unsigned char hidmsddDriverInterfaces[NUM_INTERFACES];
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Optional RequestReceived() callback re-implementation
+//-----------------------------------------------------------------------------
+#if !defined(NOAUTOCALLBACK)
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ HIDMSDDDriver_RequestHandler(request);
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+// ConfigurationChanged() callback re-implementation
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the configuration value of a device is changed by the host
+/// \param cfgnum Configuration number.
+//-----------------------------------------------------------------------------
+void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+ // HID
+ HIDDFunctionCallbacks_ConfigurationChanged(cfgnum);
+
+ // MSD
+ MSDDFunctionCallbacks_ConfigurationChanged(cfgnum);
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes the USB device HIDMSD device driver.
+//-----------------------------------------------------------------------------
+void HIDMSDDDriver_Initialize(MSDLun *pLuns, unsigned char numLuns)
+{
+ // HID
+ HIDDFunctionDriver_Initialize(&usbdDriver,
+ HIDD_Descriptors_INTERFACENUM,
+ HIDD_Descriptors_INTERRUPTIN,
+ HIDD_Descriptors_INTERRUPTOUT);
+
+ // MSD
+ MSDDFunctionDriver_Initialize(&usbdDriver,
+ pLuns, numLuns,
+ MSDD_Descriptors_INTERFACENUM,
+ MSDD_Descriptors_BULKIN,
+ MSDD_Descriptors_BULKOUT);
+
+ // Initialize the standard USB driver
+ USBDDriver_Initialize(&usbdDriver,
+ &hidmsddDriverDescriptors,
+ hidmsddDriverInterfaces);
+
+ // Initialize the USB driver
+ USBD_Init();
+}
+
+//-----------------------------------------------------------------------------
+/// Handles HIDMSD-specific USB requests sent by the host, and forwards
+/// standard ones to the USB device driver.
+/// \param request Pointer to a USBGenericRequest instance.
+//-----------------------------------------------------------------------------
+void HIDMSDDDriver_RequestHandler(const USBGenericRequest *request)
+{
+ // Check if this is a class request
+ if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
+
+ unsigned char rc = 0;
+
+ // MSD class request
+ if (rc == 0) {
+
+ rc = MSDDFunctionDriver_RequestHandler(request);
+ }
+
+ // HID class request
+ if (rc == 0) {
+
+ rc = HIDDFunctionDriver_RequestHandler(request);
+ }
+
+ if (!rc) {
+
+ TRACE_WARNING(
+ "HIDMSDDDriver_RequestHandler: Unsupported request (%d)\n\r",
+ USBGenericRequest_GetRequest(request));
+ USBD_Stall(0);
+ }
+
+ }
+ // Check if this is a standard request
+ else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
+
+ unsigned char rc = 0;
+
+ rc = HIDDFunctionDriver_RequestHandler(request);
+
+ if (rc == 0) {
+
+ rc = MSDDFunctionDriver_RequestHandler(request);
+ }
+
+ // Forward request to the standard handler
+ if (rc == 0) {
+
+ USBDDriver_RequestHandler(&(usbdDriver), request);
+ }
+ }
+ // Unsupported request type
+ else {
+
+ TRACE_WARNING(
+ "HIDMSDDDriver_RequestHandler: Unsupported request type (%d)\n\r",
+ USBGenericRequest_GetType(request));
+ USBD_Stall(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Starts a remote wake-up sequence if the host has explicitely enabled it
+/// by sending the appropriate SET_FEATURE request.
+//-----------------------------------------------------------------------------
+void HIDMSDDDriver_RemoteWakeUp(void)
+{
+ // Remote wake-up has been enabled
+ if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver)) {
+
+ USBD_RemoteWakeUp();
+ }
+ // Remote wake-up NOT enabled
+ else {
+
+ TRACE_WARNING("HIDMSDDDriver_RemoteWakeUp: not enabled\n\r");
+ }
+}
+
+
diff --git a/usb/device/composite/HIDMSDDDriver.h b/usb/device/composite/HIDMSDDDriver.h
new file mode 100644
index 0000000..ba37205
--- /dev/null
+++ b/usb/device/composite/HIDMSDDDriver.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Definitions and methods for USB HID + MSD HIDMSD device implement.
+///
+/// !Usage
+///
+/// -# Initialize USB function specified driver ( for MSD currently )
+/// - MSDDFunctionDriver_Initialize
+///
+/// -# Initialize USB HIDMSD driver and USB driver
+/// - HIDMSDDDriver_Initialize
+///
+/// -# Handle and dispach USB requests
+/// - HIDMSDDDriver_RequestHandler
+///
+/// -# Try starting a remote wake-up sequence
+/// - HIDMSDDDriver_RemoteWakeUp
+//-----------------------------------------------------------------------------
+
+#ifndef HIDMSDDDRIVER_H
+#define HIDMSDDDRIVER_H
+
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+#include <usb/device/core/USBD.h>
+
+#include "HIDDFunctionDriver.h"
+#include "MSDDFunctionDriver.h"
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+// -HIDMSD Composite device
+extern void HIDMSDDDriver_Initialize(MSDLun *pLuns,
+ unsigned char numLuns);
+
+extern void HIDMSDDDriver_RequestHandler(const USBGenericRequest *request);
+
+extern void HIDMSDDDriver_RemoteWakeUp(void);
+
+#endif //#ifndef HIDMSDDDRIVER_H
+
diff --git a/usb/device/composite/HIDMSDDDriverDescriptors.c b/usb/device/composite/HIDMSDDDriverDescriptors.c
new file mode 100644
index 0000000..aecfd61
--- /dev/null
+++ b/usb/device/composite/HIDMSDDDriverDescriptors.c
@@ -0,0 +1,449 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "HIDMSDDDriver.h"
+#include "HIDMSDDDriverDescriptors.h"
+#include <board.h>
+
+//- USB Generic
+#include <usb/common/core/USBGenericDescriptor.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/common/core/USBInterfaceAssociationDescriptor.h>
+#include <usb/common/core/USBEndpointDescriptor.h>
+#include <usb/common/core/USBStringDescriptor.h>
+#include <usb/common/core/USBGenericRequest.h>
+
+//- HID
+#include <usb/device/hid-keyboard/HIDDKeyboardInputReport.h>
+#include <usb/device/hid-keyboard/HIDDKeyboardOutputReport.h>
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDeviceDescriptor.h>
+#include <usb/common/hid/HIDInterfaceDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDReport.h>
+#include <usb/common/hid/HIDGenericDesktop.h>
+#include <usb/common/hid/HIDLeds.h>
+#include <usb/common/hid/HIDKeypad.h>
+#include "HIDDFunctionDriverDescriptors.h"
+
+//- MSD
+#include <usb/common/massstorage/MSDeviceDescriptor.h>
+#include <usb/common/massstorage/MSInterfaceDescriptor.h>
+#include "MSDDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Device product ID.
+#define HIDMSDDDriverDescriptors_PRODUCTID 0x6135
+
+/// Device vendor ID (Atmel).
+#define HIDMSDDDriverDescriptors_VENDORID 0x03EB
+
+/// Device release number.
+#define HIDMSDDDriverDescriptors_RELEASE 0x0003
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+/// Returns the minimum between two values.
+#define MIN(a, b) ((a < b) ? a : b)
+
+//-----------------------------------------------------------------------------
+// Internal structures
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Audio control header descriptor with one slave interface.
+//-----------------------------------------------------------------------------
+#ifdef __ICCARM__ // IAR
+#pragma pack(1) // IAR
+#define __attribute__(...) // IAR
+#endif // IAR
+
+//-----------------------------------------------------------------------------
+/// Configuration descriptor list for a device implementing a composite driver.
+//-----------------------------------------------------------------------------
+typedef struct {
+
+ /// Standard configuration descriptor.
+ USBConfigurationDescriptor configuration;
+
+ /// --- HID
+ USBInterfaceDescriptor hidInterface;
+ HIDDescriptor hid;
+ USBEndpointDescriptor hidInterruptIn;
+ USBEndpointDescriptor hidInterruptOut;
+
+ /// --- MSD
+ /// Mass storage interface descriptor.
+ USBInterfaceDescriptor msdInterface;
+ /// Bulk-out endpoint descriptor.
+ USBEndpointDescriptor msdBulkOut;
+ /// Bulk-in endpoint descriptor.
+ USBEndpointDescriptor msdBulkIn;
+
+} __attribute__ ((packed)) HidMsdDriverConfigurationDescriptors;
+
+#ifdef __ICCARM__ // IAR
+#pragma pack() // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+/// Standard USB device descriptor for the composite device driver
+static const USBDeviceDescriptor deviceDescriptor =
+{
+
+ sizeof(USBDeviceDescriptor),
+ USBGenericDescriptor_DEVICE,
+ USBDeviceDescriptor_USB2_00,
+ 0x00,
+ 0x00,
+ 0x00,
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ HIDMSDDDriverDescriptors_VENDORID,
+ HIDMSDDDriverDescriptors_PRODUCTID,
+ HIDMSDDDriverDescriptors_RELEASE,
+ 0, // No string descriptor for manufacturer
+ 1, // Index of product string descriptor is #1
+ 0, // No string descriptor for serial number
+ 1 // Device has 1 possible configuration
+};
+
+#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+
+/// USB device qualifier descriptor.
+static const USBDeviceQualifierDescriptor qualifierDescriptor =
+{
+
+ sizeof(USBDeviceQualifierDescriptor),
+ USBGenericDescriptor_DEVICEQUALIFIER,
+ USBDeviceDescriptor_USB2_00,
+ 0x00,
+ 0x00,
+ 0x00,
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ 1, // Device has one possible configuration
+ 0 // Reserved
+};
+
+/// USB configuration descriptors for the composite device driver
+static const HidMsdDriverConfigurationDescriptors configurationDescriptorsHS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(HidMsdDriverConfigurationDescriptors),
+ HIDMSDDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // Interface descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ HIDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0
+ 2, // Two endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_NONE,
+ 0 // No associated string descriptor
+ },
+ // HID descriptor
+ {
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDD_Descriptors_REPORTSIZE
+ },
+ // Interrupt IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDD_Descriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardInputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING_HS
+ },
+ // Interrupt OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ HIDD_Descriptors_INTERRUPTOUT),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardOutputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING_HS
+ },
+
+ // Mass Storage interface descriptor.
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ MSDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0.
+ 2, // Interface uses two endpoints.
+ MSInterfaceDescriptor_CLASS,
+ MSInterfaceDescriptor_SCSI,
+ MSInterfaceDescriptor_BULKONLY,
+ 0 // No string descriptor for interface.
+ },
+ // Bulk-OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_MAXBULKSIZE_HS),
+ 0 // No string descriptor for endpoint.
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_MAXBULKSIZE_HS),
+ 0 // No string descriptor for endpoint.
+ }
+
+};
+
+#endif
+
+/// USB FS configuration descriptors for the composite device driver
+static const HidMsdDriverConfigurationDescriptors configurationDescriptorsFS =
+{
+
+ // Standard configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(HidMsdDriverConfigurationDescriptors),
+ HIDMSDDDriverDescriptors_NUMINTERFACE,
+ 1, // This is configuration #1
+ 0, // No string descriptor for this configuration
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+
+ // Interface descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ HIDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0
+ 2, // Two endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_NONE,
+ 0 // No associated string descriptor
+ },
+ // HID descriptor
+ {
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDD_Descriptors_REPORTSIZE
+ },
+ // Interrupt IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDD_Descriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardInputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING_FS
+ },
+ // Interrupt OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ HIDD_Descriptors_INTERRUPTOUT),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDKeyboardOutputReport),
+ HIDD_Descriptors_INTERRUPTIN_POLLING_FS
+ },
+
+ // Mass Storage interface descriptor.
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ MSDD_Descriptors_INTERFACENUM,
+ 0, // This is alternate setting #0.
+ 2, // Interface uses two endpoints.
+ MSInterfaceDescriptor_CLASS,
+ MSInterfaceDescriptor_SCSI,
+ MSInterfaceDescriptor_BULKONLY,
+ 0 // No string descriptor for interface.
+ },
+ // Bulk-OUT endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKOUT),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // No string descriptor for endpoint.
+ },
+ // Bulk-IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_BULK,
+ MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(MSDD_Descriptors_BULKIN),
+ USBEndpointDescriptor_MAXBULKSIZE_FS),
+ 0 // No string descriptor for endpoint.
+ }
+
+};
+
+/// String descriptor with the supported languages.
+static const unsigned char languageIdDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(1),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_ENGLISH_US
+};
+
+/// Manufacturer name.
+static const unsigned char manufacturerDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(5),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('l')
+};
+
+/// Product name.
+static const unsigned char productDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(14),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('C'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('p'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('s'),
+ USBStringDescriptor_UNICODE('i'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('D'),
+ USBStringDescriptor_UNICODE('e'),
+ USBStringDescriptor_UNICODE('m'),
+ USBStringDescriptor_UNICODE('o')
+};
+
+/// Product serial number.
+static const unsigned char serialNumberDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(4),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('0'),
+ USBStringDescriptor_UNICODE('1'),
+ USBStringDescriptor_UNICODE('2'),
+ USBStringDescriptor_UNICODE('3')
+};
+
+/// Array of pointers to the four string descriptors.
+static const unsigned char *stringDescriptors[] = {
+
+ languageIdDescriptor,
+ manufacturerDescriptor,
+ productDescriptor,
+ serialNumberDescriptor,
+};
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// List of descriptors required by an USB audio speaker device driver.
+const USBDDriverDescriptors hidmsddDriverDescriptors = {
+
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &deviceDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsHS,
+ &qualifierDescriptor,
+ (const USBConfigurationDescriptor *) &configurationDescriptorsFS,
+#else
+ 0, 0, 0, 0, 0, 0,
+#endif
+ stringDescriptors,
+ 4 // Number of string descriptors
+};
diff --git a/usb/device/composite/HIDMSDDDriverDescriptors.h b/usb/device/composite/HIDMSDDDriverDescriptors.h
new file mode 100644
index 0000000..85739be
--- /dev/null
+++ b/usb/device/composite/HIDMSDDDriverDescriptors.h
@@ -0,0 +1,66 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef HIDMSDDDRIVERDESCRIPTORS_H
+#define HIDMSDDDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <board.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+/// Number of interfaces of the device
+#define HIDMSDDDriverDescriptors_NUMINTERFACE 2
+
+#define HIDD_Descriptors_INTERFACENUM 0
+/// Address of the HID interrupt IN endpoint.
+#define HIDD_Descriptors_INTERRUPTIN 1
+/// Address of the HID interrupt OUT endpoint.
+#define HIDD_Descriptors_INTERRUPTOUT 2
+
+#define MSDD_Descriptors_INTERFACENUM 1
+/// Address of the Mass Storage bulk-out endpoint.
+#define MSDD_Descriptors_BULKOUT 4
+/// Address of the Mass Storage bulk-in endpoint.
+#define MSDD_Descriptors_BULKIN 5
+
+
+//-----------------------------------------------------------------------------
+// Exported variables
+//-----------------------------------------------------------------------------
+
+extern const USBDDriverDescriptors hidmsddDriverDescriptors;
+
+#endif //#ifndef HIDMSDDDRIVERDESCRIPTORS_H
diff --git a/usb/device/composite/MSDDFunctionDriver.c b/usb/device/composite/MSDDFunctionDriver.c
new file mode 100644
index 0000000..840294e
--- /dev/null
+++ b/usb/device/composite/MSDDFunctionDriver.c
@@ -0,0 +1,327 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+
+// GENERAL
+#include <utility/trace.h>
+#include <utility/assert.h>
+// USB
+#include <usb/common/core/USBGenericRequest.h>
+#include <usb/common/core/USBFeatureRequest.h>
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+// MSD
+#include <usb/device/massstorage/SBCMethods.h>
+#include <usb/device/massstorage/MSDDStateMachine.h>
+#include "MSDDFunctionDriverDescriptors.h"
+
+//-----------------------------------------------------------------------------
+// Internal types
+//-----------------------------------------------------------------------------
+
+/// Driver structure for an HID device implementing keyboard functionalities.
+typedef struct {
+
+ /// Pointer to USB device driver instance
+ USBDDriver * pUsbdDriver;
+ /// Pointer to MSD driver instance
+ MSDDriver * pMsdDriver;
+ /// Interface Number of MS Function
+ unsigned char interfaceNum;
+ /// Interrupt IN endpoint address
+ unsigned char bulkInEndpoint;
+ /// Interrupt OUT endpoint address
+ unsigned char bulkOutEndpoint;
+
+} MSDFunctionDriver;
+
+//-----------------------------------------------------------------------------
+// Internal variables
+//-----------------------------------------------------------------------------
+
+/// Mass storage general driver instance.
+static MSDDriver msdDriver;
+
+/// Mass storage function driver instance.
+static MSDFunctionDriver msdFunDriver;
+
+//-----------------------------------------------------------------------------
+// Internal functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Resets the state of the MSD driver
+//-----------------------------------------------------------------------------
+static void MSDD_Reset()
+{
+ TRACE_INFO_WP("MSDReset ");
+
+ msdDriver.state = MSDD_STATE_READ_CBW;
+ msdDriver.waitResetRecovery = 0;
+ msdDriver.commandState.state = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// Initializes a MSD driver
+/// \param luns Pointer to a list of LUNs
+/// \param numLuns Number of LUN in list
+/// \param interfaceNum Interface number to access the MSD function
+/// \param bulkInEndpoint Bulk IN endpoint address
+/// \param bulkOutEndpoint Bulk OUT endpoint address
+//-----------------------------------------------------------------------------
+void MSDDFunctionDriver_Initialize(USBDDriver * pUsbdDriver,
+ MSDLun *luns, unsigned char numLuns,
+ unsigned char interfaceNum,
+ unsigned char bulkInEndpoint,
+ unsigned char bulkOutEndpoint)
+{
+ TRACE_INFO("MSD init\n\r");
+
+ msdFunDriver.pUsbdDriver = pUsbdDriver;
+ msdFunDriver.pMsdDriver = &msdDriver;
+ msdFunDriver.interfaceNum = interfaceNum;
+ msdFunDriver.bulkInEndpoint = bulkInEndpoint;
+ msdFunDriver.bulkOutEndpoint = bulkOutEndpoint;
+
+ // Command state initialization
+ msdDriver.commandState.state = 0;
+ msdDriver.commandState.postprocess = 0;
+ msdDriver.commandState.length = 0;
+ msdDriver.commandState.transfer.semaphore = 0;
+
+ // LUNs
+ msdDriver.luns = luns;
+ msdDriver.maxLun = (unsigned char) (numLuns - 1);
+
+ // Reset BOT driver
+ MSDD_Reset();
+}
+
+//-----------------------------------------------------------------------------
+/// Invoked when a new SETUP request is received from the host. Forwards the
+/// request to the Mass Storage device driver handler function.
+/// \param request Pointer to a USBGenericRequest instance.
+/// \return 0 if the request is Unsupported, 1 if the request handled.
+//-----------------------------------------------------------------------------
+unsigned char MSDDFunctionDriver_RequestHandler(
+ const USBGenericRequest *request)
+{
+ // Handle requests
+ switch (USBGenericRequest_GetRequest(request)) {
+ //---------------------
+ case USBGenericRequest_CLEARFEATURE:
+ //---------------------
+ TRACE_INFO_WP("ClrFeat ");
+
+ switch (USBFeatureRequest_GetFeatureSelector(request)) {
+
+ //---------------------
+ case USBFeatureRequest_ENDPOINTHALT:
+ //---------------------
+ TRACE_INFO_WP("Hlt ");
+
+ // Do not clear the endpoint halt status if the device is waiting
+ // for a reset recovery sequence
+ if (!msdDriver.waitResetRecovery) {
+
+ // Forward the request to the standard handler
+ return 0;
+ }
+ else {
+
+ TRACE_INFO_WP("No ");
+ }
+
+ USBD_Write(0, 0, 0, 0, 0);
+ break;
+
+ //------
+ default:
+ //------
+ // Forward the request to the standard handler
+ return 0;
+ }
+ break;
+
+ //-------------------
+ case MSD_GET_MAX_LUN:
+ //-------------------
+ TRACE_INFO_WP("gMaxLun ");
+
+ // Check request parameters
+ if ((request->wValue == 0)
+ && (request->wIndex == msdFunDriver.interfaceNum)
+ && (request->wLength == 1)) {
+
+ USBD_Write(0, &(msdDriver.maxLun), 1, 0, 0);
+
+ }
+ else {
+
+ TRACE_WARNING(
+ "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
+ request->wValue, request->wIndex, request->wLength);
+ USBD_Stall(0);
+ }
+ break;
+
+ //-----------------------
+ case MSD_BULK_ONLY_RESET:
+ //-----------------------
+ TRACE_INFO_WP("Rst ");
+
+ // Check parameters
+ if ((request->wValue == 0)
+ && (request->wIndex == msdFunDriver.interfaceNum)
+ && (request->wLength == 0)) {
+
+ // Reset the MSD driver
+ MSDD_Reset();
+ USBD_Write(0, 0, 0, 0, 0);
+ }
+ else {
+
+ TRACE_WARNING(
+ "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r",
+ request->wValue, request->wIndex, request->wLength);
+ USBD_Stall(0);
+ }
+ break;
+
+ //------
+ default:
+ //------
+ // Forward request to standard handler
+ return 0;
+ }
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+/// Invoked whenever the configuration of the device is changed by the host.
+/// \param cfgnum Newly configuration number.
+//-----------------------------------------------------------------------------
+void MSDDFunctionCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+ if (cfgnum > 0) {
+
+ MSDD_Reset();
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Reads from host through MSD defined pipe. Act as USBD_Read.
+/// \param data Pointer to the data buffer that contains data read from host.
+/// \param size The number of bytes should be read (buffer size).
+/// \param callback Pointer to the function invoked on end of reading.
+/// \param argument Pointer to additional argument data struct.
+//-----------------------------------------------------------------------------
+char MSDD_Read(void *data,
+ unsigned int size,
+ TransferCallback callback,
+ void *argument)
+
+{
+ return USBD_Read(msdFunDriver.bulkOutEndpoint,
+ data,
+ size,
+ callback,
+ argument);
+}
+
+//-----------------------------------------------------------------------------
+/// Writes to host through MSD defined pipe. Act as USBD_Write.
+/// \param data Pointer to the data that writes to the host.
+/// \param size The number of bytes should be write.
+/// \param callback Pointer to the function invoked on end of writing.
+/// \param argument Pointer to additional argument data struct.
+//-----------------------------------------------------------------------------
+char MSDD_Write(void *data,
+ unsigned int size,
+ TransferCallback callback,
+ void *argument)
+{
+ return USBD_Write(msdFunDriver.bulkInEndpoint,
+ data,
+ size,
+ callback,
+ argument);
+}
+
+//-----------------------------------------------------------------------------
+/// HALT Specified USB pipe.
+/// \param stallCASE Case of the stall condition (Bulk In/Out/Both).
+//-----------------------------------------------------------------------------
+void MSDD_Halt(unsigned int stallCASE)
+{
+ if (stallCASE & MSDD_CASE_STALL_OUT) {
+
+ USBD_Halt(msdFunDriver.bulkOutEndpoint);
+ }
+
+ if (stallCASE & MSDD_CASE_STALL_IN) {
+
+ USBD_Halt(msdFunDriver.bulkInEndpoint);
+ }
+}
+
+//-----------------------------------------------------------------------------
+/// Return halted status
+/// \return stallCASE bitmap, case of the stall condition
+/// (bit: MSDD_CASE_STALL_OUT or MSDD_CASE_STALL_IN)
+//-----------------------------------------------------------------------------
+unsigned int MSDD_IsHalted(void)
+{
+ unsigned int stallCASE = 0;
+ if (USBD_IsHalted(msdFunDriver.bulkOutEndpoint)) {
+
+ stallCASE |= MSDD_CASE_STALL_OUT;
+ }
+ if (USBD_IsHalted(msdFunDriver.bulkInEndpoint)) {
+
+ stallCASE |= MSDD_CASE_STALL_IN;
+ }
+ return stallCASE;
+}
+
+//-----------------------------------------------------------------------------
+/// State machine for the MSD driver
+//-----------------------------------------------------------------------------
+void MSDDriver_StateMachine(void)
+{
+ MSDD_StateMachine(&msdDriver);
+}
diff --git a/usb/device/composite/MSDDFunctionDriver.h b/usb/device/composite/MSDDFunctionDriver.h
new file mode 100644
index 0000000..c96fbfd
--- /dev/null
+++ b/usb/device/composite/MSDDFunctionDriver.h
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//-----------------------------------------------------------------------------
+/// \unit
+/// !Purpose
+///
+/// Mass storage function driver implementation.
+///
+/// !Usage
+/// TODO
+//-----------------------------------------------------------------------------
+
+#ifndef MSDDFUNCTIONDRIVER_H
+#define MSDDFUNCTIONDRIVER_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+#include <usb/device/core/USBDDriver.h>
+#include <usb/device/massstorage/MSD.h>
+#include <usb/device/massstorage/MSDLun.h>
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+
+//- Function API for composite device
+extern void MSDDFunctionDriver_Initialize(USBDDriver * pUsbdDriver,
+ MSDLun *luns, unsigned char numLuns,
+ unsigned char interfaceNum,
+ unsigned char bulkInEndpoint,
+ unsigned char bulkOutEndpoint);
+
+extern unsigned char MSDDFunctionDriver_RequestHandler(
+ const USBGenericRequest *request);
+
+extern void MSDDFunctionCallbacks_ConfigurationChanged(unsigned char cfgnum);
+
+//- MSD APIs
+extern void MSDDriver_StateMachine(void);
+
+#endif // #define MSDDFUNCTIONDRIVER_H
+
diff --git a/usb/device/composite/MSDDFunctionDriverDescriptors.h b/usb/device/composite/MSDDFunctionDriverDescriptors.h
new file mode 100644
index 0000000..6da6214
--- /dev/null
+++ b/usb/device/composite/MSDDFunctionDriverDescriptors.h
@@ -0,0 +1,69 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef MSDDFUNCTIONDRIVERDESCRIPTORS_H
+#define MSDDFUNCTIONDRIVERDESCRIPTORS_H
+
+//-----------------------------------------------------------------------------
+// Headers
+//-----------------------------------------------------------------------------
+
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//-----------------------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// \page "MS interface & endpoint descriptor settings"
+/// This page lists the definition used by the Mass Storage driver.
+///
+/// !Settings
+///
+/// - MSDD_Descriptors_INTERFACENUM
+/// - MSDD_Descriptors_BULKOUT
+/// - MSDD_Descriptors_BULKIN
+
+/// Number of the Mass Storage interface.
+#if defined(usb_CDCMSD)
+#define MSDD_Descriptors_INTERFACENUM 2
+#elif defined(usb_HIDMSD)
+#define MSDD_Descriptors_INTERFACENUM 1
+#endif
+
+/// Address of the Mass Storage bulk-out endpoint.
+#define MSDD_Descriptors_BULKOUT 4
+
+/// Address of the Mass Storage bulk-in endpoint.
+#define MSDD_Descriptors_BULKIN 5
+//-----------------------------------------------------------------------------
+
+
+#endif // #define MSDDFUNCTIONDRIVERDESCRIPTORS_H
+
diff --git a/usb/device/composite/drv/CompositeCDCSerial.inf b/usb/device/composite/drv/CompositeCDCSerial.inf
new file mode 100644
index 0000000..973a14b
--- /dev/null
+++ b/usb/device/composite/drv/CompositeCDCSerial.inf
@@ -0,0 +1,57 @@
+; $Id: 6119.inf,v 1.1.2.1 2006/12/05 08:33:25 danielru Exp $
+
+[Version] ; Version section
+Signature="$Chicago$" ; All Windows versions
+Class=Ports ; This is a serial port driver
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} ; Associated GUID
+Provider=%ATMEL% ; Driver is provided by ATMEL
+DriverVer=09/12/2006,1.1.1.5 ; Driver version 1.1.1.5 published on 23 February 2007
+
+[DestinationDirs] ; DestinationDirs section
+DefaultDestDir=12 ; Default install directory is \drivers or \IOSubSys
+
+[Manufacturer] ; Manufacturer section
+%ATMEL%=AtmelMfg ; Only one manufacturer (ATMEL), models section is named
+ ; AtmelMfg
+
+[AtmelMfg] ; Models section corresponding to ATMEL
+%USBtoSerialConverter%=USBtoSer.Install,USB\VID_03EB&PID_6130&MI_00 ; Identifies a device with ATMEL Vendor ID (03EBh) and
+ ; Product ID equal to 6130h. Corresponding Install section
+ ; is named USBtoSer.Install ( CDCHID )
+%USBtoSerialConverter%=USBtoSer.Install,USB\VID_03EB&PID_6131&MI_00 ; Identifies a device with ATMEL Vendor ID (03EBh) and
+ ; Product ID equal to 6131h. Corresponding Install section
+ ; is named USBtoSer.Install ( CDCAUDIO )
+%USBtoSerialConverter%=USBtoSer.Install,USB\VID_03EB&PID_6132&MI_00 ; Identifies a device with ATMEL Vendor ID (03EBh) and
+ ; Product ID equal to 6132h. Corresponding Install section
+ ; is named USBtoSer.Install ( CDCMSD )
+%USBtoSerialConverter%=USBtoSer.Install,USB\VID_03EB&PID_6133&MI_00 ; Identifies a device with ATMEL Vendor ID (03EBh) and
+ ; Product ID equal to 6133h. Corresponding Install section
+ ; is named USBtoSer.Install ( CDCCDC )
+%USBtoSerialConverter%=USBtoSer.Install,USB\VID_03EB&PID_6133&MI_02 ; Identifies a device with ATMEL Vendor ID (03EBh) and
+ ; Product ID equal to 6133h. Corresponding Install section
+ ; is named USBtoSer.Install ( CDCCDC )
+
+[USBtoSer.Install] ; Install section
+include=mdmcpq.inf
+CopyFiles=FakeModemCopyFileSection
+AddReg=USBtoSer.AddReg ; Registry keys to add are listed in USBtoSer.AddReg
+
+[USBtoSer.AddReg] ; AddReg section
+HKR,,DevLoader,,*ntkern ;
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[USBtoSer.Install.Services] ; Services section
+AddService=usbser,0x00000002,USBtoSer.AddService ; Assign usbser as the PnP driver for the device
+
+[USBtoSer.AddService] ; Service install section
+DisplayName=%USBSer% ; Name of the serial driver
+ServiceType=1 ; Service kernel driver
+StartType=3 ; Driver is started by the PnP manager
+ErrorControl=1 ; Warn about errors
+ServiceBinary=%12%\usbser.sys ; Driver filename
+
+[Strings] ; Strings section
+ATMEL="ATMEL Corp." ; String value for the ATMEL symbol
+USBtoSerialConverter="AT91 USB to Serial Converter" ; String value for the USBtoSerialConverter symbol
+USBSer="USB Composite Serial Driver" ; String value for the USBSer symbol \ No newline at end of file
diff --git a/usb/device/composite/drv/drv.dir b/usb/device/composite/drv/drv.dir
new file mode 100644
index 0000000..1f2d5d6
--- /dev/null
+++ b/usb/device/composite/drv/drv.dir
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+///
+/// !!!Purpose
+///
+/// This directory provides install file for
+/// - CDC HID
+/// - CDC AUDIO
+/// - CDC MSD
+/// - CDC CDC
+///
+/// !!!Contents
+///
+/// CompositeCDCSerial.inf
+///
+//------------------------------------------------------------------------------
personal git repositories of Harald Welte. Your mileage may vary