From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_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 --- usb/device/composite/AUDDFunctionDriver.c | 282 ++++++ usb/device/composite/AUDDFunctionDriver.h | 105 +++ .../composite/AUDDFunctionDriverDescriptors.h | 69 ++ usb/device/composite/CDCDFunctionDriver.c | 337 ++++++++ usb/device/composite/CDCDFunctionDriver.h | 128 +++ .../composite/CDCDFunctionDriverDescriptors.h | 65 ++ usb/device/composite/CDCHIDDDriver.c | 227 +++++ usb/device/composite/CDCHIDDDriver.h | 78 ++ usb/device/composite/CDCHIDDDriverDescriptors.c | 592 +++++++++++++ usb/device/composite/CDCHIDDDriverDescriptors.h | 70 ++ usb/device/composite/CDCMSDDDriver.c | 213 +++++ usb/device/composite/CDCMSDDDriver.h | 77 ++ usb/device/composite/CDCMSDDDriverDescriptors.c | 568 ++++++++++++ usb/device/composite/CDCMSDDDriverDescriptors.h | 71 ++ usb/device/composite/COMPOSITEDDriver.c | 292 +++++++ usb/device/composite/COMPOSITEDDriver.h | 93 ++ usb/device/composite/COMPOSITEDDriverDescriptors.c | 954 +++++++++++++++++++++ usb/device/composite/COMPOSITEDDriverDescriptors.h | 61 ++ usb/device/composite/DUALCDCDDriver.c | 189 ++++ usb/device/composite/DUALCDCDDriver.h | 77 ++ usb/device/composite/DUALCDCDDriverDescriptors.c | 702 +++++++++++++++ usb/device/composite/DUALCDCDDriverDescriptors.h | 72 ++ usb/device/composite/HIDDFunctionDriver.c | 477 +++++++++++ usb/device/composite/HIDDFunctionDriver.h | 64 ++ .../composite/HIDDFunctionDriverDescriptors.c | 118 +++ .../composite/HIDDFunctionDriverDescriptors.h | 86 ++ usb/device/composite/HIDMSDDDriver.c | 227 +++++ usb/device/composite/HIDMSDDDriver.h | 79 ++ usb/device/composite/HIDMSDDDriverDescriptors.c | 449 ++++++++++ usb/device/composite/HIDMSDDDriverDescriptors.h | 66 ++ usb/device/composite/MSDDFunctionDriver.c | 327 +++++++ usb/device/composite/MSDDFunctionDriver.h | 72 ++ .../composite/MSDDFunctionDriverDescriptors.h | 69 ++ usb/device/composite/drv/CompositeCDCSerial.inf | 57 ++ usb/device/composite/drv/drv.dir | 45 + 35 files changed, 7458 insertions(+) create mode 100644 usb/device/composite/AUDDFunctionDriver.c create mode 100644 usb/device/composite/AUDDFunctionDriver.h create mode 100644 usb/device/composite/AUDDFunctionDriverDescriptors.h create mode 100644 usb/device/composite/CDCDFunctionDriver.c create mode 100644 usb/device/composite/CDCDFunctionDriver.h create mode 100644 usb/device/composite/CDCDFunctionDriverDescriptors.h create mode 100644 usb/device/composite/CDCHIDDDriver.c create mode 100644 usb/device/composite/CDCHIDDDriver.h create mode 100644 usb/device/composite/CDCHIDDDriverDescriptors.c create mode 100644 usb/device/composite/CDCHIDDDriverDescriptors.h create mode 100644 usb/device/composite/CDCMSDDDriver.c create mode 100644 usb/device/composite/CDCMSDDDriver.h create mode 100644 usb/device/composite/CDCMSDDDriverDescriptors.c create mode 100644 usb/device/composite/CDCMSDDDriverDescriptors.h create mode 100644 usb/device/composite/COMPOSITEDDriver.c create mode 100644 usb/device/composite/COMPOSITEDDriver.h create mode 100644 usb/device/composite/COMPOSITEDDriverDescriptors.c create mode 100644 usb/device/composite/COMPOSITEDDriverDescriptors.h create mode 100644 usb/device/composite/DUALCDCDDriver.c create mode 100644 usb/device/composite/DUALCDCDDriver.h create mode 100644 usb/device/composite/DUALCDCDDriverDescriptors.c create mode 100644 usb/device/composite/DUALCDCDDriverDescriptors.h create mode 100644 usb/device/composite/HIDDFunctionDriver.c create mode 100644 usb/device/composite/HIDDFunctionDriver.h create mode 100644 usb/device/composite/HIDDFunctionDriverDescriptors.c create mode 100644 usb/device/composite/HIDDFunctionDriverDescriptors.h create mode 100644 usb/device/composite/HIDMSDDDriver.c create mode 100644 usb/device/composite/HIDMSDDDriver.h create mode 100644 usb/device/composite/HIDMSDDDriverDescriptors.c create mode 100644 usb/device/composite/HIDMSDDDriverDescriptors.h create mode 100644 usb/device/composite/MSDDFunctionDriver.c create mode 100644 usb/device/composite/MSDDFunctionDriver.h create mode 100644 usb/device/composite/MSDDFunctionDriverDescriptors.h create mode 100644 usb/device/composite/drv/CompositeCDCSerial.inf create mode 100644 usb/device/composite/drv/drv.dir (limited to 'usb/device/composite') 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 +#include +#include +// USB +#include +// AUDIO +#include +#include + +#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 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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +// USB +#include +#include +// CDC +#include +#include + +#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 . +/// \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 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 . +/// \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 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 +#include +#include + +//----------------------------------------------------------------------------- +// 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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +#include + +// USB +#include +#include + +//- HID +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//- 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 +#include + +#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 + +//- Composite +#include "CDCHIDDDriver.h" +#include "CDCHIDDDriverDescriptors.h" + +//- USB Generic +#include +#include +#include +#include +#include +#include + +//- CDC +#include +#include +#include +#include +#include +#include +#include +#include +#include "CDCDFunctionDriverDescriptors.h" + +//- HID +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +#include + +// USB +#include +#include + +//- 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 + +#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 + +//- USB Generic +#include +#include +#include +#include +#include +#include + +//- CDC +#include +#include +#include +#include +#include +#include +#include +#include +#include "CDCDFunctionDriverDescriptors.h" + +//- MSD +#include +#include +#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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +#include + +// USB +#include +#include + +//- HID +#if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD) + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include +#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 +#include + +#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 + +//- USB Generic +#include +#include +#include +#include +#include +#include + +//- CDC +#if defined(usb_CDCAUDIO) || defined(usb_CDCHID) || defined(usb_CDCCDC) || defined(usb_CDCMSD) + #include + #include + #include + #include + #include + #include + #include + #include + #include "CDCDFunctionDriverDescriptors.h" +#endif // (CDC defined) + +//- HID +#if defined(usb_CDCHID) || defined(usb_HIDAUDIO) || defined(usb_HIDMSD) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include "HIDDFunctionDriverDescriptors.h" +#endif // (HID defined) + +//- AUDIO +#if defined(usb_CDCAUDIO) || defined(usb_HIDAUDIO) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include "AUDDFunctionDriverDescriptors.h" +#endif // (AUDIO defined) + +//- MSD +#if defined(usb_CDCMSD) || defined(usb_HIDMSD) + #include + #include + #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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +#include + +// USB +#include +#include + +//- 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 +#include + +#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 + +//- USB Generic +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +// USB +#include +#include +#include +// HID +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +/// . +/// \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 +/// . +/// \param releasedKeysSize Number of key codes in the releasedKeys array. +/// \return 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 +#include + +//----------------------------------------------------------------------------- +// 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 + +//- HID +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +#include + +// USB +#include +#include + +//- HID +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//- 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 +#include + +#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 + +//- USB Generic +#include +#include +#include +#include +#include +#include + +//- HID +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "HIDDFunctionDriverDescriptors.h" + +//- MSD +#include +#include +#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 +#include + +//----------------------------------------------------------------------------- +// 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 +#include +// USB +#include +#include +#include +#include +// MSD +#include +#include +#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 +#include +#include +#include + +//----------------------------------------------------------------------------- +// 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 + +//----------------------------------------------------------------------------- +// 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 +/// +//------------------------------------------------------------------------------ -- cgit v1.2.3