diff --git a/sam3s_example/atmel_softpack_libraries/usb/USBFrameworkArchitecture.png b/sam3s_example/atmel_softpack_libraries/usb/USBFrameworkArchitecture.png new file mode 100644 index 00000000..83e77eb6 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/USBFrameworkArchitecture.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/audio/AUDFeatureUnitRequest.c b/sam3s_example/atmel_softpack_libraries/usb/common/audio/AUDFeatureUnitRequest.c new file mode 100644 index 00000000..7911cb8a --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/audio/AUDFeatureUnitRequest.c @@ -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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * This file implements functions for USB AUDIO class feature unit requests. + */ + +/** \addtogroup usb_audio + *@{ + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "AUDRequests.h" + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +/** + * Returns the control selector value indicating the target of a Feature Unit + * request. + * \param request Pointer to a USBGenericRequest instance. + * \sa usb_audio_ctrl_sel USB Audio Control selector values + */ +uint8_t AUDFeatureUnitRequest_GetControl(const USBGenericRequest *request) +{ + return ((USBGenericRequest_GetValue(request) >> 8) & 0xFF); +} + +/** + * Returns the channel number of a Feature unit which should be altered by the + * given request. + * \param request Pointer to a USBGenericRequest instance. + */ +uint8_t AUDFeatureUnitRequest_GetChannel(const USBGenericRequest *request) +{ + return (USBGenericRequest_GetValue(request) & 0xFF); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/audio/AUDGenericRequest.c b/sam3s_example/atmel_softpack_libraries/usb/common/audio/AUDGenericRequest.c new file mode 100644 index 00000000..4a691afd --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/audio/AUDGenericRequest.c @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * This file implements functions for USB AUDIO class requests. + */ + +/** \addtogroup usb_audio + *@{ + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "AUDRequests.h" + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +/** + * Returns the ID of the unit or terminal targetted by an USB audio request. + * \param request Pointer to a USBGenericRequest instance. + */ +uint8_t AUDGenericRequest_GetEntity(const USBGenericRequest *request) +{ + return ((USBGenericRequest_GetIndex(request) >> 8) & 0xFF); +} + +/** + * Returns the ID of the interface targetted by an USB audio request. + * \param request Pointer to a USBGenericRequest instance. + */ +uint8_t AUDGenericRequest_GetInterface(const USBGenericRequest *request) +{ + return (USBGenericRequest_GetIndex(request) & 0xFF); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/cdc/CDCLineCoding.c b/sam3s_example/atmel_softpack_libraries/usb/common/cdc/CDCLineCoding.c new file mode 100644 index 00000000..0f28220d --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/cdc/CDCLineCoding.c @@ -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. + * ---------------------------------------------------------------------------- + */ + +/** \file + Implementation of the CDCLineCoding class. + */ +/** \addtogroup usb_cdc + *@{ + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +/** + * Initializes the bitrate, number of stop bits, parity checking and + * number of data bits of a CDCLineCoding object. + * \param lineCoding Pointer to a CDCLineCoding instance. + * \param bitrate Bitrate of the virtual COM connection. + * \param stopbits Number of stop bits + * (\ref usb_cdc_stop CDC LineCoding StopBits). + * \param parity Parity check type + * (\ref usb_cdc_parity CDC LineCoding ParityChecking). + * \param databits Number of data bits. + */ +void CDCLineCoding_Initialize(CDCLineCoding *lineCoding, + uint32_t bitrate, + uint8_t stopbits, + uint8_t parity, + uint8_t databits) +{ + lineCoding->dwDTERate = bitrate; + lineCoding->bCharFormat = stopbits; + lineCoding->bParityType = parity; + lineCoding->bDataBits = databits; +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/cdc/CDCSetControlLineStateRequest.c b/sam3s_example/atmel_softpack_libraries/usb/common/cdc/CDCSetControlLineStateRequest.c new file mode 100644 index 00000000..f11db275 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/cdc/CDCSetControlLineStateRequest.c @@ -0,0 +1,87 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * Implementation of the CDCSetControlLineStateRequest class. + */ + +/** \addtogroup usb_cdc + *@{ + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +/** + * Notifies if the given request indicates that the DTE signal is present. + * \param request Pointer to a USBGenericRequest instance. + * \return 1 if the DTE signal is present, otherwise 0. + */ +uint8_t CDCSetControlLineStateRequest_IsDtePresent( + const USBGenericRequest *request) +{ + if ((USBGenericRequest_GetValue(request) & 0x0001) != 0) { + + return 1; + } + else { + + return 0; + } +} + +/** + * Notifies if the given request indicates that the device carrier should + * be activated. + * \param request Pointer to a USBGenericRequest instance. + * \return 1 is the device should activate its carrier, 0 otherwise. + */ +uint8_t CDCSetControlLineStateRequest_ActivateCarrier( + const USBGenericRequest *request) +{ + if ((USBGenericRequest_GetValue(request) & 0x0002) != 0) { + + return 1; + } + else { + + return 0; + } +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/core/USBDescriptors.c b/sam3s_example/atmel_softpack_libraries/usb/common/core/USBDescriptors.c new file mode 100644 index 00000000..3811b5bb --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/core/USBDescriptors.c @@ -0,0 +1,310 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * Implements for USB descriptor methods described by the USB specification. + */ + +/** \addtogroup usb_descriptor + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "USBDescriptors.h" + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Returns the length of a descriptor. + * \param descriptor Pointer to a USBGenericDescriptor instance. + * \return Length of descriptor in bytes. + */ +uint32_t USBGenericDescriptor_GetLength( + const USBGenericDescriptor *descriptor) +{ + return descriptor->bLength; +} + +/** + * Returns the type of a descriptor. + * \param descriptor Pointer to a USBGenericDescriptor instance. + * \return Type of descriptor. + */ +uint8_t USBGenericDescriptor_GetType( + const USBGenericDescriptor *descriptor) +{ + return descriptor->bDescriptorType; +} + +/** + * Returns a pointer to the descriptor right after the given one, when + * parsing a Configuration descriptor. + * \param descriptor - Pointer to a USBGenericDescriptor instance. + * \return Pointer to the next descriptor. + */ +USBGenericDescriptor *USBGenericDescriptor_GetNextDescriptor( + const USBGenericDescriptor *descriptor) +{ + return (USBGenericDescriptor *) + (((char *) descriptor) + USBGenericDescriptor_GetLength(descriptor)); +} + +/** Parses the given descriptor list via costomized function. + * \param descriptor Pointer to the start of the whole descriptors list. + * \param totalLength Total size of descriptors in bytes. + * \param parseFunction Function to parse each descriptor scanned. + * Return 0 to continue parsing. + * \param parseArg Argument passed to parse function. + * \return Pointer to USBGenericDescriptor instance for next descriptor. + */ +USBGenericDescriptor *USBGenericDescriptor_Parse( + const USBGenericDescriptor *descriptor, + uint32_t totalLength, + USBDescriptorParseFunction parseFunction, + void *parseArg) +{ + int32_t size = totalLength; + + if (size == 0) + return 0; + + /* Start parsing descriptors */ + while (1) { + + uint32_t parseRC = 0; + + /* Parse current descriptor */ + if (parseFunction) { + + parseRC = parseFunction((void*)descriptor, parseArg); + } + + /* Get next descriptor */ + size -= USBGenericDescriptor_GetLength(descriptor); + descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor); + + if (size) { + if (parseRC != 0) { + + return (USBGenericDescriptor *)descriptor; + } + } + else + break; + } + /* No descriptors remaining */ + return 0; +} + + +/** + * Returns the number of an endpoint given its descriptor. + * \param endpoint Pointer to a USBEndpointDescriptor instance. + * \return Endpoint number. + */ +uint8_t USBEndpointDescriptor_GetNumber( + const USBEndpointDescriptor *endpoint) +{ + return endpoint->bEndpointAddress & 0xF; +} + +/** + * Returns the direction of an endpoint given its descriptor. + * \param endpoint Pointer to a USBEndpointDescriptor instance. + * \return Endpoint direction (see \ref usb_ep_dir). + */ +uint8_t USBEndpointDescriptor_GetDirection( + const USBEndpointDescriptor *endpoint) +{ + if ((endpoint->bEndpointAddress & 0x80) != 0) { + + return USBEndpointDescriptor_IN; + } + else { + + return USBEndpointDescriptor_OUT; + } +} + +/** + * Returns the type of an endpoint given its descriptor. + * \param endpoint Pointer to a USBEndpointDescriptor instance. + * \return Endpoint type (see \ref usb_ep_type). + */ +uint8_t USBEndpointDescriptor_GetType( + const USBEndpointDescriptor *endpoint) +{ + return endpoint->bmAttributes & 0x3; +} + +/** + * Returns the maximum size of a packet (in bytes) on an endpoint given + * its descriptor. + * \param endpoint - Pointer to a USBEndpointDescriptor instance. + * \return Maximum packet size of endpoint. + */ +uint16_t USBEndpointDescriptor_GetMaxPacketSize( + const USBEndpointDescriptor *endpoint) +{ + return endpoint->wMaxPacketSize; +} + +/** + * Returns the polling interval on an endpoint given its descriptor. + * \param endpoint - Pointer to a USBEndpointDescriptor instance. + * \return Polling interval of endpoint. + */ +uint8_t USBEndpointDescriptor_GetInterval( + const USBEndpointDescriptor *endpoint) +{ + return endpoint->bInterval; +} + + + +/** Returns the total length of a configuration, i.e. including the + * descriptors following it. + * \param configuration Pointer to a USBConfigurationDescriptor instance. + * \return Total length (in bytes) of the configuration. + */ +uint32_t USBConfigurationDescriptor_GetTotalLength( + const USBConfigurationDescriptor *configuration) +{ + return configuration->wTotalLength; +} + +/** Returns the number of interfaces in a configuration. + * \param configuration Pointer to a USBConfigurationDescriptor instance. + * \return Number of interfaces in configuration. + */ +unsigned char USBConfigurationDescriptor_GetNumInterfaces( + const USBConfigurationDescriptor *configuration) +{ + return configuration->bNumInterfaces; +} + +/** Indicates if the device is self-powered when in a given configuration. + * \param configuration Pointer to a USBConfigurationDescriptor instance. + * \return 1 if the device is self-powered when in the given configuration; + * otherwise 0. + */ +unsigned char USBConfigurationDescriptor_IsSelfPowered( + const USBConfigurationDescriptor *configuration) +{ + if ((configuration->bmAttributes & (1 << 6)) != 0) { + + return 1; + } + else { + + return 0; + } +} + +/** Parses the given Configuration descriptor (followed by relevant + * interface, endpoint and class-specific descriptors) into three arrays. + * *Each array must have its size equal or greater to the number of + * descriptors it stores plus one*. A null-value is inserted after the last + * descriptor of each type to indicate the array end. + * + * Note that if the pointer to an array is null (0), nothing is stored in + * it. + * \param configuration Pointer to the start of the whole Configuration + * descriptor. + * \param interfaces Pointer to the Interface descriptor array. + * \param endpoints Pointer to the Endpoint descriptor array. + * \param others Pointer to the class-specific descriptor array. + */ +void USBConfigurationDescriptor_Parse( + const USBConfigurationDescriptor *configuration, + USBInterfaceDescriptor **interfaces, + USBEndpointDescriptor **endpoints, + USBGenericDescriptor **others) +{ + /* Get size of configuration to parse */ + int size = USBConfigurationDescriptor_GetTotalLength(configuration); + size -= sizeof(USBConfigurationDescriptor); + + /* Start parsing descriptors */ + USBGenericDescriptor *descriptor = (USBGenericDescriptor *) configuration; + while (size > 0) { + + /* Get next descriptor */ + descriptor = USBGenericDescriptor_GetNextDescriptor(descriptor); + size -= USBGenericDescriptor_GetLength(descriptor); + + /* Store descriptor in correponding array */ + if (USBGenericDescriptor_GetType(descriptor) + == USBGenericDescriptor_INTERFACE) { + + if (interfaces) { + + *interfaces = (USBInterfaceDescriptor *) descriptor; + interfaces++; + } + } + else if (USBGenericDescriptor_GetType(descriptor) + == USBGenericDescriptor_ENDPOINT) { + + if (endpoints) { + + *endpoints = (USBEndpointDescriptor *) descriptor; + endpoints++; + } + } + else if (others) { + + *others = descriptor; + others++; + } + } + + /* Null-terminate arrays */ + if (interfaces) { + + *interfaces = 0; + } + if (endpoints) { + + *endpoints = 0; + } + if (others) { + + *others = 0; + } +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/core/USBRequests.c b/sam3s_example/atmel_softpack_libraries/usb/common/core/USBRequests.c new file mode 100644 index 00000000..b70d68eb --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/core/USBRequests.c @@ -0,0 +1,244 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * Implements for USB requests described by the USB specification. + */ + +/** \addtogroup usb_request + * @{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Returns the type of the given request. + * \param request Pointer to a USBGenericRequest instance. + * \return "USB Request Types" + */ +extern uint8_t USBGenericRequest_GetType(const USBGenericRequest *request) +{ + return ((request->bmRequestType >> 5) & 0x3); +} + +/** + * Returns the request code of the given request. + * \param request Pointer to a USBGenericRequest instance. + * \return Request code. + * \sa "USB Request Codes" + */ +uint8_t USBGenericRequest_GetRequest(const USBGenericRequest *request) +{ + return request->bRequest; +} + +/** + * Returns the wValue field of the given request. + * \param request - Pointer to a USBGenericRequest instance. + * \return Request value. + */ +uint16_t USBGenericRequest_GetValue(const USBGenericRequest *request) +{ + return request->wValue; +} + +/** + * Returns the wIndex field of the given request. + * \param request Pointer to a USBGenericRequest instance. + * \return Request index; + */ +uint16_t USBGenericRequest_GetIndex(const USBGenericRequest *request) +{ + return request->wIndex; +} + +/** + * Returns the expected length of the data phase following a request. + * \param request Pointer to a USBGenericRequest instance. + * \return Length of data phase. + */ +uint16_t USBGenericRequest_GetLength(const USBGenericRequest *request) +{ + return request->wLength; +} + +/** + * Returns the endpoint number targetted by a given request. + * \param request Pointer to a USBGenericRequest instance. + * \return Endpoint number. + */ +uint8_t USBGenericRequest_GetEndpointNumber( + const USBGenericRequest *request) +{ + return USBGenericRequest_GetIndex(request) & 0xF; +} + +/** + * Returns the intended recipient of a given request. + * \param request Pointer to a USBGenericRequest instance. + * \return Request recipient. + * \sa "USB Request Recipients" + */ +uint8_t USBGenericRequest_GetRecipient(const USBGenericRequest *request) +{ + /* Recipient is in bits [0..4] of the bmRequestType field */ + return request->bmRequestType & 0xF; +} + +/** + * Returns the direction of the data transfer following the given request. + * \param request Pointer to a USBGenericRequest instance. + * \return Transfer direction. + * \sa "USB Request Directions" + */ +uint8_t USBGenericRequest_GetDirection(const USBGenericRequest *request) +{ + /* Transfer direction is located in bit D7 of the bmRequestType field */ + if ((request->bmRequestType & 0x80) != 0) { + + return USBGenericRequest_IN; + } + else { + + return USBGenericRequest_OUT; + } +} + + +/** + * Returns the type of the descriptor requested by the host given the + * corresponding GET_DESCRIPTOR request. + * \param request Pointer to a USBGenericDescriptor instance. + * \return Type of the requested descriptor. + */ +uint8_t USBGetDescriptorRequest_GetDescriptorType( + const USBGenericRequest *request) +{ + /* Requested descriptor type is in the high-byte of the wValue field */ + return (USBGenericRequest_GetValue(request) >> 8) & 0xFF; +} + +/** + * Returns the index of the requested descriptor, given the corresponding + * GET_DESCRIPTOR request. + * \param request Pointer to a USBGenericDescriptor instance. + * \return Index of the requested descriptor. + */ +uint8_t USBGetDescriptorRequest_GetDescriptorIndex( + const USBGenericRequest *request) +{ + /* Requested descriptor index if in the low byte of the wValue field */ + return USBGenericRequest_GetValue(request) & 0xFF; +} + + +/** + * Returns the address that the device must take in response to a + * SET_ADDRESS request. + * \param request Pointer to a USBGenericRequest instance. + * \return New device address. + */ +uint8_t USBSetAddressRequest_GetAddress(const USBGenericRequest *request) +{ + return USBGenericRequest_GetValue(request) & 0x7F; +} + + +/** + * Returns the number of the configuration that should be set in response + * to the given SET_CONFIGURATION request. + * \param request Pointer to a USBGenericRequest instance. + * \return Number of the requested configuration. + */ +uint8_t USBSetConfigurationRequest_GetConfiguration( + const USBGenericRequest *request) +{ + return USBGenericRequest_GetValue(request); +} + + +/** + * Indicates which interface is targetted by a GET_INTERFACE or + * SET_INTERFACE request. + * \param request Pointer to a USBGenericRequest instance. + * \return Interface number. + */ +uint8_t USBInterfaceRequest_GetInterface(const USBGenericRequest *request) +{ + return (USBGenericRequest_GetIndex(request) & 0xFF); +} + +/** + * Indicates the new alternate setting that the interface targetted by a + * SET_INTERFACE request should use. + * \param request Pointer to a USBGenericRequest instance. + * \return New active setting for the interface. + */ +uint8_t USBInterfaceRequest_GetAlternateSetting( + const USBGenericRequest *request) +{ + return (USBGenericRequest_GetValue(request) & 0xFF); +} + + +/** + * Returns the feature selector of a given CLEAR_FEATURE or SET_FEATURE + * request. + * \param request Pointer to a USBGenericRequest instance. + * \return Feature selector. + */ +uint8_t USBFeatureRequest_GetFeatureSelector( + const USBGenericRequest *request) +{ + return USBGenericRequest_GetValue(request); +} + +/** + * Indicates the test that the device must undertake following a + * SET_FEATURE request. + * \param request Pointer to a USBGenericRequest instance. + * \return Test selector. + */ +uint8_t USBFeatureRequest_GetTestSelector( + const USBGenericRequest *request) +{ + return (USBGenericRequest_GetIndex(request) >> 8) & 0xFF; +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDIdleRequest.c b/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDIdleRequest.c new file mode 100644 index 00000000..c4e83e13 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDIdleRequest.c @@ -0,0 +1,73 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + Title: HIDIdleRequest implementation + + About: Purpose + Implementation of the HIDIdleRequest methods. +*/ + +/**\addtogroup usb_hid + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "HIDRequests.h" + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Indicates the ID of the report targetted by a SET_IDLE or GET_IDLE + * request. This value should be 0 if report IDs are not used. + * \param request Pointer to a USBGenericRequest instance. + * \return Requested report ID. + */ +uint8_t HIDIdleRequest_GetReportId(const USBGenericRequest *request) +{ + return (USBGenericRequest_GetValue(request) & 0xFF); +} + +/** + * Retrieves the Idle rate (in milliseconds) indicated by a SET_IDLE + * request. + * \param request Pointer to a USBGenericRequest instance. + * \return New idle rate for the report. + */ +uint8_t HIDIdleRequest_GetIdleRate(const USBGenericRequest *request) +{ + return ((USBGenericRequest_GetValue(request) >> 8) & 0xFF); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDKeypad.c b/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDKeypad.c new file mode 100644 index 00000000..898c1a6c --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDKeypad.c @@ -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. + * ---------------------------------------------------------------------------- + */ + +/**\file + Title: HIDKeypad implementation + + About: Purpose + Implementation of HID keypad usage page methods. +*/ + +/**\addtogroup usb_hid + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "HIDUsages.h" + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Indicates if the given key code is associated with a modified key. + * \param key Key code. + * \return 1 if the key code represents a modifier key; otherwise 0. + */ +uint8_t HIDKeypad_IsModifierKey(uint8_t key) +{ + return ((key >= HIDKeypad_LEFTCONTROL) && (key <= HIDKeypad_RIGHTGUI)); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDReportRequest.c b/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDReportRequest.c new file mode 100644 index 00000000..4f1e8e99 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/common/hid/HIDReportRequest.c @@ -0,0 +1,73 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + Title: HIDReportRequest implementation + + About: Purpose + Implementation of the HIDReportRequest methods. +*/ + +/**\addtogroup usb_hid + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "HIDRequests.h" + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Indicates the type of report targetted by a SET_REPORT or GET_REPORT + * request. + * \param request Pointer to a USBGenericRequest instance. + * \return Requested report type (see "HID Report Types"). + */ +uint8_t HIDReportRequest_GetReportType(const USBGenericRequest *request) +{ + return ((USBGenericRequest_GetValue(request) >> 8) & 0xFF); +} + +/** + * Indicates the ID of the report targetted by a SET_REPORT or GET_REPORT + * request. This value should be 0 if report IDs are not used. + * \param request Pointer to a USBGenericRequest instance. + * \return Requested report ID. + */ +uint8_t HIDReportRequest_GetReportId(const USBGenericRequest *request) +{ + return (USBGenericRequest_GetValue(request) & 0xFF); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/USBDCallbackInvocationFlowchart.png b/sam3s_example/atmel_softpack_libraries/usb/device/USBDCallbackInvocationFlowchart.png new file mode 100644 index 00000000..af8028e1 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/USBDCallbackInvocationFlowchart.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/USBDeviceStateDiagram.png b/sam3s_example/atmel_softpack_libraries/usb/device/USBDeviceStateDiagram.png new file mode 100644 index 00000000..eacdd41d Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/USBDeviceStateDiagram.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/AUDDSpeakerDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/AUDDSpeakerDriver.c new file mode 100644 index 00000000..6a778520 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/AUDDSpeakerDriver.c @@ -0,0 +1,234 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_audio_speaker + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include + +#include + +#include + +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Internal types + *----------------------------------------------------------------------------*/ + +/** + * \brief Audio speaker driver struct. + */ +typedef struct _AUDDSpeakerDriver { + /** Speaker & Phone function */ + AUDDSpeakerPhone fun; + /** Stream instance for speaker */ + AUDDStream speaker; + /** Array for storing the current setting of each interface */ + uint8_t bAltInterfaces[AUDDSpeakerDriver_NUMINTERFACES]; +} AUDDSpeakerDriver; + +/*---------------------------------------------------------------------------- + * Internal variables + *----------------------------------------------------------------------------*/ + +/** Global USB audio speaker driver instance. */ +static AUDDSpeakerDriver auddSpeakerDriver; + +/*---------------------------------------------------------------------------- + * Dummy callbacks + *----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Internal functions + *----------------------------------------------------------------------------*/ + +/** + * Callback triggerred after the mute or volume status of the channel has been + * changed. + * \param ec Event code. + * \param channel Channel number. + * \param pArg Pointer to AUDDStream instance. + */ +static void AUDDSpeaker_EventCallback(uint32_t ec, + uint8_t channel, + AUDDStream *pArg) +{ + if (ec == AUDD_EC_MuteChanged) { + if (AUDDSpeakerDriver_MuteChanged) + AUDDSpeakerDriver_MuteChanged(channel, pArg->bmMute); + } + else if (ec == AUDD_EC_VolumeChanged) { + /* Not supported now */ + } +} + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +/** + * Initializes an USB audio speaker device driver, as well as the underlying + * USB controller. + */ +void AUDDSpeakerDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; + AUDDSpeakerPhone *pAudf = &pAudd->fun; + AUDDStream *pAuds = &pAudd->speaker; + USBDDriver *pUsbd = USBD_GetDriver(); + + AUDDSpeakerPhone_InitializeStream( + pAuds, AUDDSpeakerDriver_NUMCHANNELS, 0, + (AUDDStreamEventCallback)AUDDSpeaker_EventCallback, pAuds); + + AUDDSpeakerPhone_Initialize( + pAudf, pUsbd, pAuds, 0); + + /* Initialize the USB driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + pAudd->bAltInterfaces); + USBD_Init(); +} + +/** + * Invoked whenever the active configuration of device is changed by the + * host. + * \param cfgnum Configuration number. + */ +void AUDDSpeakerDriver_ConfigurationChangeHandler(uint8_t cfgnum) +{ + AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; + AUDDSpeakerPhone *pAudf = &pAudd->fun; + const USBDDriverDescriptors *pDescriptors = pAudf->pUsbd->pDescriptors; + USBConfigurationDescriptor *pDesc; + + if (cfgnum > 0) { + + /* Parse endpoints for data & notification */ + if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration) + pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration; + else + pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration; + + AUDDSpeakerPhone_ParseInterfaces(pAudf, + (USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * 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 AUDDSpeakerDriver_InterfaceSettingChangedHandler(uint8_t interface, + uint8_t setting) +{ + AUDDSpeakerDriver *pSpeakerd = &auddSpeakerDriver; + AUDDSpeakerPhone *pAudf = &pSpeakerd->fun; + + if (setting == 0) { + AUDDSpeakerPhone_CloseStream(pAudf, interface); + } + + if (AUDDSpeakerDriver_StreamSettingChanged) + AUDDSpeakerDriver_StreamSettingChanged(setting); +} + +/** + * Handles audio-specific USB requests sent by the host, and forwards + * standard ones to the USB device driver. + * \param request Pointer to a USBGenericRequest instance. + */ +void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request) +{ + AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; + AUDDSpeakerPhone *pAudf = &pAudd->fun; + USBDDriver *pUsbd = pAudf->pUsbd; + + TRACE_INFO_WP("NewReq "); + + /* Handle Audio Class requests */ + if (AUDDSpeakerPhone_RequestHandler(pAudf, request) == USBRC_SUCCESS) { + return; + } + + /* Handle STD requests */ + if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { + + USBDDriver_RequestHandler(pUsbd, request); + } + /* Unsupported request */ + else { + + TRACE_WARNING( + "AUDDSpeakerDriver_RequestHandler: Unsupported request (%d,%x)\n\r", + USBGenericRequest_GetType(request), + USBGenericRequest_GetRequest(request)); + USBD_Stall(0); + } +} + +/** + * Reads incoming audio data sent by the USB host into the provided + * buffer. When the transfer is complete, an optional callback function is + * invoked. + * \param buffer Pointer to the data storage buffer. + * \param length Size of the buffer in bytes. + * \param callback Optional callback function. + * \param argument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the transfer is started successfully; + * otherwise an error code. + */ +uint8_t AUDDSpeakerDriver_Read(void *buffer, + uint32_t length, + TransferCallback callback, + void *argument) +{ + AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; + AUDDSpeakerPhone *pAudf = &pAudd->fun; + return USBD_Read(pAudf->pSpeaker->bEndpointOut, + buffer, length, + callback, argument); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/AUDDSpeakerDriver_Callbacks.c b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/AUDDSpeakerDriver_Callbacks.c new file mode 100644 index 00000000..5f2cec73 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/AUDDSpeakerDriver_Callbacks.c @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Default callbacks implement for Audio Speaker Driver. + */ + +/** \addtogroup usbd_audio_speaker + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 + by working group ISO/IEC JTC1/SC22/WG14. */ +#include + +#include "AUDDSpeakerDriver.h" + +/*------------------------------------------------------------------------------ + * Default WEAK Callbacks + *------------------------------------------------------------------------------*/ + +/** + * Invoked when an audio channel get muted or unmuted. Mutes/unmutes the + * channel at the DAC level. + * \param channel Channel number that changed. + * \param muted Indicates the new mute status of the channel. + */ +WEAK void AUDDSpeakerDriver_MuteChanged(uint8_t channel,uint8_t muted) +{ + /* Do nothing */ +} + +/** + * Invoked when an audio streaming interface setting changed. Actually control + * streaming rate. + * \param newSetting New stream (interface) setting. + */ +WEAK void AUDDSpeakerDriver_StreamSettingChanged(uint8_t newSetting) +{ + /* Do nothing */ +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeaker.png b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeaker.png new file mode 100644 index 00000000..bcae3009 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeaker.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerDescriptors.png b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerDescriptors.png new file mode 100644 index 00000000..251a2d1c Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerDescriptors.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerRecorder.png b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerRecorder.png new file mode 100644 index 00000000..ddbd2349 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerRecorder.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerRecorderDescriptors.png b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerRecorderDescriptors.png new file mode 100644 index 00000000..c5c33240 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speaker/USBAudioSpeakerRecorderDescriptors.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDSpeakerPhoneDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDSpeakerPhoneDriver.c new file mode 100644 index 00000000..e2893fb9 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDSpeakerPhoneDriver.c @@ -0,0 +1,468 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_audio_speakerphone + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include + +#include + +/*------------------------------------------------------------------------------ + * Internal types + *------------------------------------------------------------------------------*/ + +/** + * Structs of USB Audio Stream Function Interface. + */ +typedef struct _AUDDStream { + + /* -- USB Interface settings -- */ + /** Audio Control Interface Number */ + uint8_t bAcInterface; + /** Audio Streaming Interface Number */ + uint8_t bAsInterface; + /** Audio Streaming endpoint address */ + uint8_t bEpNum; + /** Audio Control Unit ID */ + uint8_t bUnitID; + + /* -- Channel settings -- */ + /** Number of channels (including master 0, max 32) */ + uint16_t bNumChannels; + /** Mute Controls bitmap */ + uint16_t bmMuteControls; + /** Volume Controls (Master,L,R..) array */ + uint16_t *pVolumes; +} AUDDStream; + +/** + * \brief Audio SpeakerPhone driver internal state. + */ +typedef struct _AUDDSpeakerPhoneDriver { + + /** Pointer to USBDDriver instance */ + USBDDriver * pUsbd; + /** Intermediate storage variable for the mute status of a stream */ + uint8_t muted; + /** Array for storing the current setting of each interface. */ + uint8_t interfaces[3]; + /** Audio Speaker interface */ + AUDDStream speaker; + /** Audio Microphone interface */ + AUDDStream mic; +} AUDDSpeakerPhoneDriver; + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/** Global USB audio SpeakerPhone driver instance. */ +static AUDDSpeakerPhoneDriver auddSpeakerPhoneDriver; + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/** + * Parse descriptors: Interrupt IN, Bulk EP IN/OUT. + * \param desc Pointer to descriptor. + * \param arg Argument, pointer to AUDDSpeakerPhoneDriver instance. + */ +static uint32_t AUDDSpeakerPhone_Parse(USBGenericDescriptor* desc, + AUDDSpeakerPhoneDriver* arg) +{ + /* Not a valid descriptor */ + if (desc->bLength == 0) { + return USBD_STATUS_INVALID_PARAMETER; + } + /* Parse endpoint descriptor */ + if (desc->bDescriptorType == USBGenericDescriptor_ENDPOINT) { + USBEndpointDescriptor *pEP = (USBEndpointDescriptor*)desc; + if (pEP->bmAttributes == USBEndpointDescriptor_ISOCHRONOUS) { + if (pEP->bEndpointAddress & 0x80) + arg->mic.bEpNum = pEP->bEndpointAddress & 0x7F; + else + arg->speaker.bEpNum = pEP->bEndpointAddress; + } + } + return 0; +} + +/** + * Callback triggered after the new mute status of a channel has been read + * by AUDDSpeakerPhoneDriver_SetFeatureCurrentValue. Changes the mute status + * of the given channel accordingly. + * \param channel Number of the channel whose mute status has changed. + */ +static void AUDDSpeakerPhone_MuteReceived(uint32_t channel) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + AUDDStream *pAuds; + + if ((uint8_t)(channel >> 8) == + AUDDSpeakerPhoneDriverDescriptors_OUTPUTTERMINAL_REC) { + pAuds = &pAudd->mic; + } + else { + pAuds = &pAudd->speaker; + } + + if (pAudd->muted != pAuds->bmMuteControls) { + pAuds->bmMuteControls = pAudd->muted; + AUDDSpeakerPhoneDriver_MuteChanged(0, channel, pAudd->muted); + } + USBD_Write(0, 0, 0, 0, 0); +} + +/** + * Handle the SET_CUR request. + * \param pReq Pointer to USBGenericRequest instance. + */ +static void AUDDSpeakerPhone_SetCUR(const USBGenericRequest* pReq) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + uint8_t bIf = AUDGenericRequest_GetInterface(pReq); + uint8_t bEntity = AUDGenericRequest_GetEntity(pReq); + uint8_t bLength = USBGenericRequest_GetLength(pReq); + uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq); + uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq); + uint8_t bSet = 0; + AUDDStream *pAuds = 0; + + TRACE_INFO_WP("sCUR "); + TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength); + /* Only AC.FeatureUnit accepted */ + if (bCtrl == AUDFeatureUnitRequest_MUTE + && bLength == 1) { + + if (bEntity == pAudd->speaker.bUnitID) + pAuds = &pAudd->speaker; + else if (bEntity == pAudd->mic.bUnitID) + pAuds = &pAudd->mic; + + if (pAuds != 0 + && bIf == pAuds->bAcInterface + && bCh <= pAuds->bNumChannels) { + bSet = 1; + } + } + + if (bSet) { + + uint32_t argument = bCh | (bEntity << 8); + USBD_Read(0, /* Endpoint #0 */ + &pAudd->muted, + sizeof(uint8_t), + (TransferCallback) AUDDSpeakerPhone_MuteReceived, + (void *) argument); + } + else { + + USBD_Stall(0); + } + +} + +/** + * Handle the GET_CUR request. + * \param pReq Pointer to USBGenericRequest instance. + */ +static void AUDDSpeakerPhone_GetCUR(const USBGenericRequest *pReq) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + uint8_t bIf = AUDGenericRequest_GetInterface(pReq); + uint8_t bEntity = AUDGenericRequest_GetEntity(pReq); + uint8_t bLength = USBGenericRequest_GetLength(pReq); + uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq); + uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq); + uint8_t bGet = 0; + AUDDStream *pAuds = 0; + + TRACE_INFO_WP("gCUR "); + TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength); + /* Only AC.FeatureUnit accepted */ + if (bCtrl == AUDFeatureUnitRequest_MUTE + && bLength == 1) { + + if (bEntity == pAudd->speaker.bUnitID) + pAuds = &pAudd->speaker; + else if (bEntity == pAudd->mic.bUnitID) + pAuds = &pAudd->mic; + + if (pAuds != 0 + && bIf == pAuds->bAcInterface + && bCh <= pAuds->bNumChannels) { + bGet = 1; + } + } + + if (bGet) { + + pAudd->muted = pAuds->bmMuteControls; + USBD_Write(0, &pAudd->muted, sizeof(uint8_t), 0, 0); + } + else { + + USBD_Stall(0); + } +} + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes an USB audio SpeakerPhone device driver, as well as the underlying + * USB controller. + */ +void AUDDSpeakerPhoneDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + USBDDriver *pUsbd = USBD_GetDriver(); + + pAudd->pUsbd = pUsbd; + + /* Initialize SpeakerPhone channels */ + pAudd->speaker.bNumChannels = 3; + pAudd->speaker.bmMuteControls = 0; + pAudd->speaker.pVolumes = 0; + + pAudd->mic.bNumChannels = 1; + pAudd->mic.bmMuteControls = 0; + pAudd->mic.pVolumes = 0; + + pAudd->mic.bAcInterface = AUDDSpeakerPhoneDriverDescriptors_CONTROL; + pAudd->mic.bAsInterface = AUDDSpeakerPhoneDriverDescriptors_STREAMINGIN; + pAudd->mic.bEpNum = 5;//AUDDSpeakerPhoneDriverDescriptors_DATAIN; + pAudd->mic.bUnitID = AUDDSpeakerPhoneDriverDescriptors_FEATUREUNIT_REC; + + pAudd->speaker.bAcInterface = AUDDSpeakerPhoneDriverDescriptors_CONTROL; + pAudd->speaker.bAsInterface = AUDDSpeakerPhoneDriverDescriptors_STREAMING; + pAudd->speaker.bEpNum = 4;//AUDDSpeakerPhoneDriverDescriptors_DATAOUT; + pAudd->speaker.bUnitID = AUDDSpeakerPhoneDriverDescriptors_FEATUREUNIT; + + /* Initialize the USB driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + pAudd->interfaces); + USBD_Init(); + +} + +/** + * Invoked whenever the active configuration of device is changed by the + * host. + * \param cfgnum Configuration number. + */ +void AUDDSpeakerPhoneDriver_ConfigurationChangeHandler(uint8_t cfgnum) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + const USBDDriverDescriptors *pDescriptors = pAudd->pUsbd->pDescriptors; + USBConfigurationDescriptor *pDesc; + + if (cfgnum > 0) { + + /* Parse endpoints for data & notification */ + if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration) + pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration; + else + pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration; + + USBGenericDescriptor_Parse((USBGenericDescriptor*)pDesc, pDesc->wTotalLength, + (USBDescriptorParseFunction)AUDDSpeakerPhone_Parse, pAudd); + } +} + +/** + * 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 AUDDSpeakerPhoneDriver_InterfaceSettingChangedHandler(uint8_t interface, + uint8_t setting) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + + if (interface == pAudd->speaker.bAsInterface) { + /* reset ISO OUT ep */ + if (setting == 0 && pAudd->speaker.bEpNum) { + USBD_HAL_ResetEPs(1 << pAudd->speaker.bEpNum, + USBD_STATUS_CANCELED, 1); + } + AUDDSpeakerPhoneDriver_StreamSettingChanged(0, setting); + } + if (interface == pAudd->mic.bAsInterface) { + /* reset ISO IN ep */ + if (setting == 0 && pAudd->mic.bEpNum) { + USBD_HAL_ResetEPs(1 << pAudd->mic.bEpNum, + USBD_STATUS_CANCELED, 1); + } + AUDDSpeakerPhoneDriver_StreamSettingChanged(1, setting); + } +} + + +/** + * Handles audio-specific USB requests sent by the host, and forwards + * standard ones to the USB device driver. + * \param request Pointer to a USBGenericRequest instance. + */ +void AUDDSpeakerPhoneDriver_RequestHandler(const USBGenericRequest *request) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + USBDDriver *pUsbd = pAudd->pUsbd; + + TRACE_INFO_WP("NewReq "); + + /* Check if this is a class request */ + if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) { + + /* Check if the request is supported */ + switch (USBGenericRequest_GetRequest(request)) { + + case AUDGenericRequest_SETCUR: + + AUDDSpeakerPhone_SetCUR(request); + break; + + case AUDGenericRequest_GETCUR: + + AUDDSpeakerPhone_GetCUR(request); + break; + + default: + + TRACE_WARNING( + "AUDDSpeakerPhoneDriver_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) { + + /* Forward request to the standard handler */ + USBDDriver_RequestHandler(pUsbd, request); + } + /* Unsupported request type */ + else { + + TRACE_WARNING( + "AUDDSpeakerPhoneDriver_RequestHandler: Unsupported request type (%d)\n\r", + USBGenericRequest_GetType(request)); + USBD_Stall(0); + } +} + +/** + * Reads incoming audio data sent by the USB host into the provided + * buffer. When the transfer is complete, an optional callback function is + * invoked. + * \param buffer Pointer to the data storage buffer. + * \param length Size of the buffer in bytes. + * \param callback Optional callback function. + * \param argument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the transfer is started successfully; + * otherwise an error code. + */ +uint8_t AUDDSpeakerPhoneDriver_Read(void *buffer, + uint32_t length, + TransferCallback callback, + void *argument) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + return USBD_Read(pAudd->speaker.bEpNum, + buffer, + length, + callback, + argument); +} + +/** + * Initialize Frame List for sending audio data. + * + * \param pListInit Pointer to the allocated list for audio write. + * \param pDmaInit Pointer to the allocated DMA descriptors for autio write + * (if DMA supported). + * \param listSize Circular list size. + * \param delaySize Start transfer after delaySize frames filled in. + * \param callback Optional callback function for transfer. + * \param argument Optional callback argument. + * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code. + */ +uint8_t AUDDSpeakerPhoneDriver_SetupWrite(void * pListInit, + void * pDmaInit, + uint16_t listSize, + uint16_t delaySize, + TransferCallback callback, + void * argument) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + uint8_t error; + + if (pAudd->mic.bEpNum == 0) + return USBRC_STATE_ERR; + + error = USBD_HAL_SetupMblTransfer(pAudd->mic.bEpNum, + pListInit, + listSize, + delaySize); + if (error) return error; + error = USBD_HAL_SetTransferCallback( + pAudd->mic.bEpNum, + callback, argument); + return error; +} + +/** + * Add frame buffer to audio sending list. + * \buffer Pointer to data frame to send. + * \length Frame size in bytes. + * \return USBD_STATUS_SUCCESS if the transfer is started successfully; + * otherwise an error code. + */ +uint8_t AUDDSpeakerPhoneDriver_Write(void* buffer, uint16_t length) +{ + AUDDSpeakerPhoneDriver *pAudd = &auddSpeakerPhoneDriver; + + return USBD_HAL_Write(pAudd->mic.bEpNum, + buffer, length); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDSpeakerPhoneDriver_Callbacks.c b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDSpeakerPhoneDriver_Callbacks.c new file mode 100644 index 00000000..ee061f92 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDSpeakerPhoneDriver_Callbacks.c @@ -0,0 +1,76 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Default callbacks implement for Audio SpeakerPhone Driver. + */ + +/** \addtogroup usbd_audio_speakerphone + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 + by working group ISO/IEC JTC1/SC22/WG14. */ +#include + +#include "AUDDSpeakerPhoneDriver.h" + +/*------------------------------------------------------------------------------ + * Default WEAK Callbacks + *------------------------------------------------------------------------------*/ + +/** + * Invoked when an audio channel get muted or unmuted. Mutes/unmutes the + * channel at the DAC level. + * \param mic Microphone/Speaker stream changed. + * \param channel Channel number that changed. + * \param muted Indicates the new mute status of the channel. + */ +WEAK void AUDDSpeakerPhoneDriver_MuteChanged(uint8_t mic,uint8_t channel,uint8_t muted) +{ + /* Do nothing */ +} + +/** + * Invoked when an audio streaming interface setting changed. Actually control + * streaming rate. + * \param mic Microphone/Speaker stream changed. + * \param newSetting New stream (interface) setting. + */ +WEAK void AUDDSpeakerPhoneDriver_StreamSettingChanged(uint8_t mic,uint8_t newSetting) +{ + /* Do nothing */ +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDStream.c b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDStream.c new file mode 100644 index 00000000..07c76ca8 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/audio-speakerphone/AUDDStream.c @@ -0,0 +1,770 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * USB Audio Device Streaming interface with controls. + * (3 channels supported). + */ + +/** \addtogroup usbd_audio_speakerphone + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include +#include +#include +#include + +#include + +#include + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** Parse data extention for descriptor parsing */ +typedef struct _AUDDParseData { + /** Pointer to AUDDSpeakerPhone instance */ + AUDDSpeakerPhone * pAudf; + /** Pointer to found interface descriptor */ + USBInterfaceDescriptor * pIfDesc; + +} AUDDParseData; + +/** Transfer callback extention */ +typedef struct _AUDDXfrExt { + /** Pointer to AUDDStream instance */ + AUDDStream *pStream; + /** Buffer for USB device to get data from host */ + uint16_t usbBuffer; + /** Additional information: Entity */ + uint8_t bEntity; + /** Additional information: Channel */ + uint8_t bCh; +} AUDDXfrExt; + +/*------------------------------------------------------------------------------ + * Internal Variable + *------------------------------------------------------------------------------*/ + +/** Transfer data extension */ +static AUDDXfrExt auddXfrData; + +/*------------------------------------------------------------------------------ + * Internal Functions + *------------------------------------------------------------------------------*/ + +/** + * Parse descriptors: Interface, ISO IN/OUT, Feature Unit IDs. + * \param desc Pointer to descriptor list. + * \param arg Argument, pointer to AUDDParseData instance. + */ +static uint32_t AUDDSpeakerPhone_Parse(USBGenericDescriptor *pDesc, + AUDDParseData * pArg) +{ + AUDDStream *pSpeaker = pArg->pAudf->pSpeaker; + AUDDStream *pMic = pArg->pAudf->pMicrophone; + USBEndpointDescriptor* pEp = (USBEndpointDescriptor*)pDesc; + uint8_t bSpeakerDone = 0, bMicDone = 0; + + /* Validate descriptor */ + if (pDesc->bLength == 0) + return USBRC_PARAM_ERR; + + /* Log current interface */ + if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) { + USBInterfaceDescriptor* pIf = (USBInterfaceDescriptor*)pDesc; + /* AudioControl interface */ + if (pIf->bInterfaceClass == + AUDControlInterfaceDescriptor_CLASS + && pIf->bInterfaceSubClass == + AUDControlInterfaceDescriptor_SUBCLASS) { + pArg->pIfDesc = pIf; + + if (pSpeaker) pSpeaker->bAcInterface = pIf->bInterfaceNumber; + if (pMic) pMic->bAcInterface = pIf->bInterfaceNumber; + } + /* AudioStreaming interface with endpoint */ + else if (pIf->bInterfaceClass == + AUDStreamingInterfaceDescriptor_CLASS + && pIf->bInterfaceSubClass == + AUDStreamingInterfaceDescriptor_SUBCLASS) { + pArg->pIfDesc = pIf; + } + /* Not Audio interface, force end */ + else if (pArg->pIfDesc){ + return USBRC_PARTIAL_DONE; + } + } + + if (pArg->pIfDesc) { + /* Find Control Interface */ + /* Find Entities */ + /* Find Streaming Interface & Endpoints */ + if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT + && (pEp->bmAttributes & 0x3) == USBEndpointDescriptor_ISOCHRONOUS) { + if (pEp->bEndpointAddress & 0x80 + && pMic) { + pMic->bEndpointIn = pEp->bEndpointAddress & 0x7F; + pMic->bAsInterface = pArg->pIfDesc->bInterfaceNumber; + /* Fixed FU */ + pMic->bFeatureUnitIn = AUDD_ID_MicrophoneFU; + } + else if (pSpeaker) { + pSpeaker->bEndpointOut = pEp->bEndpointAddress; + pSpeaker->bAsInterface = pArg->pIfDesc->bInterfaceNumber; + /* Fixed FU */ + pSpeaker->bFeatureUnitOut = AUDD_ID_SpeakerFU; + } + } + } + + if (pSpeaker) { + if (pSpeaker->bAcInterface != 0xFF + && pSpeaker->bAsInterface != 0xFF + && pSpeaker->bFeatureUnitOut != 0xFF + && pSpeaker->bEndpointOut != 0) { + bSpeakerDone = 1; + } + } + else bSpeakerDone = 1; + + if (pMic) { + if (pMic->bAcInterface != 0xFF + && pMic->bAsInterface != 0xFF + && pMic->bFeatureUnitIn != 0xFF + && pMic->bEndpointIn != 0) { + bMicDone = 1; + } + } + else bMicDone = 1; + + if (bSpeakerDone && bMicDone) + return USBRC_FINISHED; + + return USBRC_SUCCESS; +} + +/** + * Callback triggered after the new mute status of a channel has been read. + * Changes the mute status of the given channel accordingly. + * \param pData Pointer to AUDDXfrExt (transfer extension data). + */ +static void AUDD_MuteReceived(AUDDXfrExt *pData) +{ + AUDDStream_ChangeMute(pData->pStream, + pData->bCh, + (uint8_t)pData->usbBuffer); + USBD_Write(0, 0, 0, 0, 0); +} + +/** + * Callback triggered after the new volume status of a channel has been read. + * Changes the volume status of the given channel accordingly. + * \param pData Pointer to AUDDXfrExt (transfer extension data). + */ +static void AUDD_VolumeReceived(AUDDXfrExt *pData) +{ + AUDDStream_SetVolume(pData->pStream, + pData->bCh, + pData->usbBuffer); + USBD_Write(0, 0, 0, 0, 0); +} + +/** + * Get Target AUDDStream for control + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param bAcInterface Interface number + * \param bEntity Entity ID + * \param bChannel Channel number + * \return Pointer to AUDDStream instance + */ +static AUDDStream *AUDD_GetCtlStream( + AUDDSpeakerPhone *pAudf, + uint8_t bAcInterface, + uint8_t bEntity, + uint8_t bChannel) +{ + AUDDStream *pAuds = 0; + + if (bEntity == pAudf->pSpeaker->bFeatureUnitOut + || bEntity == pAudf->pSpeaker->bFeatureUnitIn) + pAuds = pAudf->pSpeaker; + else if (bEntity == pAudf->pMicrophone->bFeatureUnitIn + || bEntity == pAudf->pMicrophone->bFeatureUnitOut) + pAuds = pAudf->pMicrophone; + + if (pAuds != 0 + && bAcInterface == pAuds->bAcInterface + && bChannel <= pAuds->bNumChannels) { + return pAuds; + } + + return 0; +} + +/** + * Handle the SET_CUR request. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pReq Pointer to USBGenericRequest instance. + */ +static void AUDD_SetCUR( + AUDDSpeakerPhone *pAudf, + const USBGenericRequest* pReq) +{ + uint8_t bIf = AUDGenericRequest_GetInterface(pReq); + uint8_t bEntity = AUDGenericRequest_GetEntity(pReq); + uint8_t bLength = USBGenericRequest_GetLength(pReq); + uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq); + uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq); + uint8_t bSet = 1; + AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh); + TransferCallback fCallback; + + TRACE_INFO_WP("sCUR "); + TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength); + + /* Set Mute to AC, 1 byte */ + if (bCtrl == AUDFeatureUnitRequest_MUTE + && bLength == 1 + && pAuds) { + fCallback = (TransferCallback) AUDD_MuteReceived; + } + else if (bCtrl == AUDFeatureUnitRequest_VOLUME + && bLength == 2 + && pAuds && pAuds->pwVolumes) { + fCallback = (TransferCallback) AUDD_VolumeReceived; + } + else + bSet = 0; + + if (bSet) { + + auddXfrData.pStream = pAuds; + auddXfrData.bEntity = bEntity; + auddXfrData.bCh = bCh; + USBD_Read(0, + &auddXfrData.usbBuffer, + bLength, + fCallback, + (void *) &auddXfrData); + } + else { + + USBD_Stall(0); + } + +} + +/** + * Handle the GET_CUR request. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pReq Pointer to USBGenericRequest instance. + */ +static void AUDD_GetCUR( + AUDDSpeakerPhone *pAudf, + const USBGenericRequest *pReq) +{ + uint8_t bIf = AUDGenericRequest_GetInterface(pReq); + uint8_t bEntity = AUDGenericRequest_GetEntity(pReq); + uint8_t bLength = USBGenericRequest_GetLength(pReq); + uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq); + uint8_t bCtrl = AUDFeatureUnitRequest_GetControl(pReq); + uint8_t bGet = 1; + AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh); + + TRACE_INFO_WP("gCUR "); + TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength); + + /* Get Mute 1 byte */ + if (bCtrl == AUDFeatureUnitRequest_MUTE + && bLength == 1 + && pAuds) { + auddXfrData.usbBuffer = ((pAuds->bmMute & (1< 0); + } + else if (bCtrl == AUDFeatureUnitRequest_VOLUME + && bLength == 2 + && pAuds && pAuds->pwVolumes) { + auddXfrData.usbBuffer = pAuds->pwVolumes[bCh]; + } + else + bGet = 0; + + if (bGet) { + + USBD_Write(0, &auddXfrData.usbBuffer, bLength, 0, 0); + } + else { + + USBD_Stall(0); + } +} + +/*------------------------------------------------------------------------------ + * Exported Functions + *------------------------------------------------------------------------------*/ + +/** + * Initialize AUDDStream instance. + * Note the number of channels excludes the master control, so + * actual volume array size should be (1 + numChannels). + * \param pAuds Pointer to AUDDStream instance. + * \param numChannels Number of channels in the stream (<31). + * \param wChannelVolumes Data array for channel volume values. + * \param fCallback Callback function for stream events. + * \param pArg Pointer to event handler arguments. + */ +void AUDDStream_Initialize(AUDDStream *pAuds, + uint8_t numChannels, + uint16_t wChannelVolumes[], + AUDDStreamEventCallback fCallback, + void* pArg) +{ + pAuds->bAcInterface = 0xFF; + pAuds->bFeatureUnitOut = 0xFF; + pAuds->bFeatureUnitIn = 0xFF; + pAuds->bAsInterface = 0xFF; + pAuds->bEndpointOut = 0; + pAuds->bEndpointIn = 0; + + pAuds->bNumChannels = numChannels; + pAuds->bmMute = 0; + pAuds->pwVolumes = wChannelVolumes; + + pAuds->fCallback = fCallback; + pAuds->pArg = pArg; +} + +/** + * Check if the request is accepted. + * \param pAuds Pointer to AUDDStream instance. + * \param pReq Pointer to a USBGenericRequest instance. + * \return 1 if accepted. + */ +uint32_t AUDDStream_IsRequestAccepted( + AUDDStream *pAuds, + const USBGenericRequest *pReq) +{ + uint8_t bIf = AUDGenericRequest_GetInterface(pReq); + uint8_t bEntity = AUDGenericRequest_GetEntity(pReq); + uint8_t bCh = AUDFeatureUnitRequest_GetChannel(pReq); + /* AudioControl Interface */ + if (bIf == pAuds->bAcInterface) { + if (bCh > pAuds->bNumChannels) + return 0; + if (bEntity != pAuds->bFeatureUnitIn + && bEntity != pAuds->bFeatureUnitOut) + return 0; + } + /* AudioStream Interface not handled */ + else { + return 0; + } + return 1; +} + +/** + * Change Stream Mute status. + * \param pAuds Pointer to AUDDStream instance. + * \param bChannel Channel number. + * \param bmMute 1 to mute, 0 to unmute. + */ +uint32_t AUDDStream_ChangeMute(AUDDStream *pAuds, + uint8_t bChannel, + uint8_t bMute) +{ + uint8_t bmMute = (bMute << bChannel); + + if (pAuds->bNumChannels < bChannel) + return USBRC_PARAM_ERR; + + if (bMute) + pAuds->bmMute |= bmMute; + else + pAuds->bmMute &= ~bmMute; + + if (pAuds->fCallback) + pAuds->fCallback(AUDD_EC_MuteChanged, + bChannel, + pAuds->pArg); + + return USBRC_SUCCESS; +} + +/** + * Set Stream Volume status. + * \param pAuds Pointer to AUDDStream instance. + * \param bChannel Channel number. + * \param wVolume New volume value. + */ +uint32_t AUDDStream_SetVolume(AUDDStream *pAuds, + uint8_t bChannel, + uint16_t wVolume) +{ + if (pAuds->pwVolumes == 0) + return USBRC_PARAM_ERR; + if (bChannel > pAuds->bNumChannels) + return USBRC_PARAM_ERR; + + pAuds->pwVolumes[bChannel] = wVolume; + if (pAuds->fCallback) { + pAuds->fCallback(AUDD_EC_VolumeChanged, + bChannel, + pAuds->pArg); + } + + return USBRC_SUCCESS; +} + +/** + * Receives data from the host through the audio function (as speaker). + * This function behaves like USBD_Read. + * \param pAuds Pointer to AUDDStream instance. + * \param pData Pointer to the data buffer to put received data. + * \param dwSize Size of the data buffer in bytes. + * \param fCallback Optional callback function to invoke when the transfer + * finishes. + * \param pArg Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +uint32_t AUDDStream_Read( + AUDDStream *pAuds, + void * pData,uint32_t dwSize, + TransferCallback fCallback,void * pArg) +{ + if (pAuds->bEndpointOut == 0) + return USBRC_PARAM_ERR; + return USBD_Read(pAuds->bEndpointOut, + pData, dwSize, + fCallback, pArg); +} + +/** + * Initialize Frame List for sending audio data. + * \param pAuds Pointer to AUDDStream instance. + * \param pListInit Pointer to the allocated list for audio write. + * \param pDmaInit Pointer to the allocated DMA descriptors for autio write + * (if DMA supported). + * \param listSize Circular list size. + * \param delaySize Start transfer after delaySize frames filled in. + * \param callback Optional callback function for transfer. + * \param argument Optional callback argument. + * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code. + */ +uint32_t AUDDStream_SetupWrite( + AUDDStream *pAuds, + void * pListInit, + void * pDmaInit, + uint16_t listSize, + uint16_t delaySize, + TransferCallback callback, + void * argument) +{ + uint32_t error; + + if (pAuds->bEndpointIn == 0) + return USBRC_STATE_ERR; + + error = USBD_HAL_SetupMblTransfer(pAuds->bEndpointIn, + pListInit, + listSize, + delaySize); + if (error) return error; + + error = USBD_HAL_SetTransferCallback(pAuds->bEndpointIn, + callback, argument); + return error; +} + + +/** + * Add frame buffer to audio sending list. + * \param pAuds Pointer to AUDDStream instance. + * \param pBuffer Pointer to data frame to send. + * \param wLength Frame size in bytes. + * \return USBD_STATUS_SUCCESS if the transfer is started successfully; + * otherwise an error code. + */ +uint32_t AUDDStream_Write(AUDDStream *pAuds, void* pBuffer, uint16_t wLength) +{ + if (pAuds->bEndpointIn == 0) + return USBRC_STATE_ERR; + + return USBD_HAL_Write(pAuds->bEndpointIn, + pBuffer, wLength); +} + +/** + * Close the stream. All pending transfers are canceled. + * \param pStream Pointer to AUDDStream instance. + */ +uint32_t AUDDStream_Close(AUDDStream *pStream) +{ + uint32_t bmEPs = 0; + + /* Close output stream */ + if (pStream->bEndpointIn) { + bmEPs |= 1 << pStream->bEndpointIn; + } + /* Close input stream */ + if (pStream->bEndpointOut) { + bmEPs |= 1 << pStream->bEndpointOut; + } + USBD_HAL_ResetEPs(bmEPs, USBRC_CANCELED, 1); + + return USBRC_SUCCESS; +} + +/* + * Audio Speakerphone functions + */ + +/** + * Initialize AUDDStream instance. + * Note the number of channels excludes the master control, so + * actual volume array size should be (1 + numChannels). + * \param pAuds Pointer to AUDDStream instance. + * \param numChannels Number of channels in the stream (excluding master,<31). + * \param wChannelVolumes Data array for channel volume values, + * must include master (1 + numChannels). + * \param fCallback Callback function for stream control events. + * \param pArg Pointer to event handler arguments. + */ +void AUDDSpeakerPhone_InitializeStream( + AUDDStream *pAuds, + uint8_t numChannels, + uint16_t wChannelVolumes[], + AUDDStreamEventCallback fCallback, + void* pArg) +{ + pAuds->bAcInterface = 0xFF; + pAuds->bFeatureUnitOut = 0xFF; + pAuds->bFeatureUnitIn = 0xFF; + pAuds->bAsInterface = 0xFF; + pAuds->bEndpointOut = 0; + pAuds->bEndpointIn = 0; + + pAuds->bNumChannels = numChannels; + pAuds->bmMute = 0; + pAuds->pwVolumes = wChannelVolumes; + + pAuds->fCallback = fCallback; + pAuds->pArg = pArg; +} + +/** + * Initialize AUDDSpeakerPhone instance. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pUsbd Pointer to USBDDriver instance. + * \param pSpeaker Pointer to speaker streaming interface. + * \param pMicrophone Pointer to microphone streaming interface. + */ +void AUDDSpeakerPhone_Initialize( + AUDDSpeakerPhone *pAudf, + USBDDriver *pUsbd, + AUDDStream *pSpeaker, + AUDDStream *pMicrophone) +{ + pAudf->pUsbd = pUsbd; + pAudf->pSpeaker = pSpeaker; + pAudf->pMicrophone = pMicrophone; +} + +/** + * Parse USB Audio streaming information for AUDDStream instance. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pDescriptors Pointer to descriptor list. + * \param dwLength Descriptor list size in bytes. + */ +USBGenericDescriptor *AUDDSpeakerPhone_ParseInterfaces( + AUDDSpeakerPhone *pAudf, + USBGenericDescriptor *pDescriptors, + uint32_t dwLength) +{ + AUDDParseData data; + + data.pAudf = pAudf; + data.pIfDesc = 0; + + return USBGenericDescriptor_Parse(pDescriptors, + dwLength, + (USBDescriptorParseFunction)AUDDSpeakerPhone_Parse, + (void*)&data); +} + +/** + * Close the stream. All pending transfers are canceled. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param bInterface Stream interface number + */ +uint32_t AUDDSpeakerPhone_CloseStream( + AUDDSpeakerPhone *pAudf, + uint32_t bInterface) +{ + if (pAudf->pSpeaker->bAsInterface == bInterface) { + USBD_HAL_ResetEPs(1 << pAudf->pSpeaker->bEndpointOut, + USBRC_CANCELED, + 1); + } + else if (pAudf->pMicrophone->bAsInterface == bInterface) { + USBD_HAL_ResetEPs(1 << pAudf->pMicrophone->bEndpointIn, + USBRC_CANCELED, + 1); + } + + return USBRC_SUCCESS; +} + +/** + * Handles audio-specific USB requests sent by the host + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pRequest Pointer to a USBGenericRequest instance. + * \return USBRC_PARAM_ERR if not handled. + */ +uint32_t AUDDSpeakerPhone_RequestHandler( + AUDDSpeakerPhone *pAudf, + const USBGenericRequest* pRequest) +{ + //USBDDriver *pUsbd = pAudf->pUsbd; + + if (USBGenericRequest_GetType(pRequest) != USBGenericRequest_CLASS) + return USBRC_PARAM_ERR; + + TRACE_INFO_WP("Aud "); + switch (USBGenericRequest_GetRequest(pRequest)) { + case AUDGenericRequest_SETCUR: + AUDD_SetCUR(pAudf, pRequest); + break; + case AUDGenericRequest_GETCUR: + AUDD_GetCUR(pAudf, pRequest); + break; + + default: + return USBRC_PARAM_ERR; + } + + return USBRC_SUCCESS; +} + +/** + * Receives data from the host through the audio function (as speaker). + * This function behaves like USBD_Read. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pData Pointer to the data buffer to put received data. + * \param dwSize Size of the data buffer in bytes. + * \param fCallback Optional callback function to invoke when the transfer + * finishes. + * \param pArg Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +uint32_t AUDDSpeakerPhone_Read( + AUDDSpeakerPhone *pAudf, + void * pData,uint32_t dwSize, + TransferCallback fCallback,void * pArg) +{ + if (pAudf->pSpeaker == 0) + return USBRC_PARAM_ERR; + if (pAudf->pSpeaker->bEndpointOut == 0) + return USBRC_PARAM_ERR; + return USBD_Read(pAudf->pSpeaker->bEndpointOut, + pData, dwSize, + fCallback, pArg); +} + +/** + * Initialize Frame List for sending audio data. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pListInit Pointer to the allocated list for audio write. + * \param pDmaInit Pointer to the allocated DMA descriptors for autio write + * (if DMA supported). + * \param listSize Circular list size. + * \param delaySize Start transfer after delaySize frames filled in. + * \param callback Optional callback function for transfer. + * \param argument Optional callback argument. + * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code. + */ +uint32_t AUDDSpeakerPhone_SetupWrite( + AUDDSpeakerPhone *pAudf, + void * pListInit, + void * pDmaInit, + uint16_t listSize, + uint16_t delaySize, + TransferCallback callback, + void * argument) +{ + uint32_t error; + + if (pAudf->pMicrophone == 0) + return USBRC_PARAM_ERR; + if (pAudf->pMicrophone->bEndpointIn == 0) + return USBRC_STATE_ERR; + + error = USBD_HAL_SetupMblTransfer(pAudf->pMicrophone->bEndpointIn, + pListInit, + listSize, + delaySize); + if (error) return error; + + error = USBD_HAL_SetTransferCallback( + pAudf->pMicrophone->bEndpointIn, + callback, argument); + return error; +} + + +/** + * Add frame buffer to audio sending list. + * \param pAudf Pointer to AUDDSpeakerPhone instance. + * \param pBuffer Pointer to data frame to send. + * \param wLength Frame size in bytes. + * \return USBD_STATUS_SUCCESS if the transfer is started successfully; + * otherwise an error code. + */ +uint32_t AUDDSpeakerPhone_Write(AUDDSpeakerPhone *pAudf, void* pBuffer, uint16_t wLength) +{ + if (pAudf->pSpeaker == 0) + return USBRC_PARAM_ERR; + if (pAudf->pSpeaker->bEndpointIn == 0) + return USBRC_STATE_ERR; + + return USBD_HAL_Write(pAudf->pSpeaker->bEndpointIn, + pBuffer, wLength); +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriver.c new file mode 100644 index 00000000..86567a09 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriver.c @@ -0,0 +1,1657 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * CCID driver + * + * \section Usage + * + * Explanation on the usage of the code made available through the header file. + * \addtogroup usbd_ccid + * @{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ +#include "board.h" + + +#include "USBLib_Trace.h" +#include "USBD.h" +#include "USBDDriver.h" +#include "USBRequests.h" +//#include "USBStringDescriptor.h" +#include "cciddriver.h" +#include "cciddriverdescriptors.h" +#include "iso7816_4.h" +#include + +/*------------------------------------------------------------------------------ + * Local definition + *------------------------------------------------------------------------------*/ + +/** Constants: IDs: Device product ID. */ + +#define CCIDDriverDescriptors_PRODUCTID 0x6129 +/** Constants: IDs: Device vendor ID. */ + +#define CCIDDriverDescriptors_VENDORID 0x03EB +/** Constants: IDs: Device release number. */ + +#define CCIDDriverDescriptors_RELEASE 0x0100 + +/** Returns the minimum between two values. */ + +#define MIN(a, b) ((a < b) ? a : b) + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef CCIDDriverConfigurationDescriptors + * \brief List of descriptors that make up the configuration descriptors of a + * device using the CCID driver. + */ + +typedef struct _CCIDDriverConfigurationDescriptors +{ + + /** Configuration descriptor */ + USBConfigurationDescriptor configuration; + /** Interface descriptor */ + USBInterfaceDescriptor interface; + /** CCID descriptor */ + CCIDDescriptor ccid; + /** Bulk OUT endpoint descriptor */ + USBEndpointDescriptor bulkOut; + /** Bulk IN endpoint descriptor */ + USBEndpointDescriptor bulkIn; + /** Interrupt OUT endpoint descriptor */ + USBEndpointDescriptor interruptIn; + +} __attribute__ ((packed)) CCIDDriverConfigurationDescriptors; + +#ifdef __ICCARM__ /* IAR*/ +#pragma pack() /* IAR*/ +#endif /* IAR*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** \brief Driver structure for an CCID device */ + +typedef struct { + + /** Standard USB device driver instance */ + USBDDriver usbdDriver; + /** CCID message */ + S_ccid_bulk_in_header sCcidMessage; + /** CCID command */ + S_ccid_bulk_out_header sCcidCommand; + /** Interrupt message answer */ + unsigned char BufferINT[4]; + /** Buffer data of message */ + unsigned char ProtocolDataStructure[10]; + /** Protocol used */ + unsigned char bProtocol; + /** SlotStatus */ + /** Bit 0 = Slot 0 current state */ + /** Bit 1 = Slot 0 changed status */ + /** Bit 2 = Slot 1 current state */ + /** Bit 3 = Slot 1 changed status */ + /** Bit 4 = Slot 2 current state */ + /** Bit 5 = Slot 2 changed status */ + unsigned char SlotStatus; + +} CCIDDriver; + +/*------------------------------------------------------------------------------ + * Local variables + *------------------------------------------------------------------------------*/ + +/** Static instance of the CCID device driver. */ +static CCIDDriver ccidDriver; + +/** Standard USB device descriptor. */ +static const USBDeviceDescriptor deviceDescriptor = { + + sizeof(USBDeviceDescriptor), + USBGenericDescriptor_DEVICE, + USBDeviceDescriptor_USB2_00, + 0, + 0, + 0, + CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0), + CCIDDriverDescriptors_VENDORID, + CCIDDriverDescriptors_PRODUCTID, + CCIDDriverDescriptors_RELEASE, + 1, /* Index of manufacturer description */ + 2, /* Index of product description */ + 3, /* Index of serial number description */ + 1 /* One possible configuration */ + +}; + + +/** List of configuration descriptors. */ +static const CCIDDriverConfigurationDescriptors configurationDescriptorsFS = { + + /* Standard USB configuration descriptor */ + { + sizeof(USBConfigurationDescriptor), + USBGenericDescriptor_CONFIGURATION, + sizeof(CCIDDriverConfigurationDescriptors), + 1, /* One interface in this configuration */ + 1, /* This is configuration #1 */ + 0, /* No associated string descriptor */ + USBD_BMATTRIBUTES, + USBConfigurationDescriptor_POWER(100) + }, + /* CCID interface descriptor */ + /* Table 4.3-1 Interface Descriptor */ + /* Interface descriptor */ + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + 0, /* Interface 0 */ + 0, /* No alternate settings */ + 3, /* uses bulk-IN, bulk-OUT and interrupt–IN */ + SMART_CARD_DEVICE_CLASS, + 0, /* Subclass code */ + 0, /* bulk transfers optional interrupt-IN */ + 0 /* No associated string descriptor */ + + }, + { + sizeof(CCIDDescriptor), /* bLength: Size of this descriptor in bytes */ + CCID_DECRIPTOR_TYPE, /* bDescriptorType:Functional descriptor type */ + CCID1_10, /* bcdCCID: CCID version */ + 0, /* bMaxSlotIndex: Value 0 indicates that one slot is supported */ + VOLTS_5_0, /* bVoltageSupport */ + PROTOCOL_TO, /* dwProtocols */ + 3580, /* dwDefaultClock */ + 3580, /* dwMaxClock */ + 0, /* bNumClockSupported */ + 9600, /* dwDataRate : 9600 bauds */ + 9600, /* dwMaxDataRate : 9600 bauds */ + 0, /* bNumDataRatesSupported */ + 0xfe, /* dwMaxIFSD */ + 0, /* dwSynchProtocols */ + 0, /* dwMechanical */ + //0x00010042, /* dwFeatures: Short APDU level exchanges */ + CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU, + 0x0000010F, /* dwMaxCCIDMessageLength: For extended APDU level the value shall be between 261 + 10 */ + 0xFF, /* bClassGetResponse: Echoes the class of the APDU */ + 0xFF, /* bClassEnvelope: Echoes the class of the APDU */ + 0, /* wLcdLayout: no LCD */ + 0, /* bPINSupport: No PIN */ + 1 /* bMaxCCIDBusySlot */ + }, + /* Bulk-OUT endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT), + USBEndpointDescriptor_MAXBULKSIZE_FS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Bulk-IN endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_DATA_IN ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN), + USBEndpointDescriptor_MAXBULKSIZE_FS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Notification endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION ), + USBEndpointDescriptor_INTERRUPT, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION), + USBEndpointDescriptor_MAXINTERRUPTSIZE_FS), + 0x10 + } +}; + +#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS) +static const CCIDDriverConfigurationDescriptors configurationDescriptorsHS = { + + /* Standard USB configuration descriptor */ + { + sizeof(USBConfigurationDescriptor), + USBGenericDescriptor_CONFIGURATION, + sizeof(CCIDDriverConfigurationDescriptors), + 1, /* One interface in this configuration */ + 1, /* This is configuration #1 */ + 0, /* No associated string descriptor */ + USBD_BMATTRIBUTES, + USBConfigurationDescriptor_POWER(100) + }, + /* CCID interface descriptor */ + /* Table 4.3-1 Interface Descriptor */ + /* Interface descriptor */ + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + 0, /* Interface 0 */ + 0, /* No alternate settings */ + 3, /* uses bulk-IN, bulk-OUT and interrupt–IN */ + SMART_CARD_DEVICE_CLASS, + 0, /* Subclass code */ + 0, /* bulk transfers optional interrupt-IN */ + 0 /* No associated string descriptor */ + + }, + { + sizeof(CCIDDescriptor), /* bLength: Size of this descriptor in bytes */ + CCID_DECRIPTOR_TYPE, /* bDescriptorType:Functional descriptor type */ + CCID1_10, /* bcdCCID: CCID version */ + 0, /* bMaxSlotIndex: Value 0 indicates that one slot is supported */ + VOLTS_5_0, /* bVoltageSupport */ + PROTOCOL_TO, /* dwProtocols */ + 3580, /* dwDefaultClock */ + 3580, /* dwMaxClock */ + 0, /* bNumClockSupported */ + 9600, /* dwDataRate : 9600 bauds */ + 9600, /* dwMaxDataRate : 9600 bauds */ + 0, /* bNumDataRatesSupported */ + 0xfe, /* dwMaxIFSD */ + 0, /* dwSynchProtocols */ + 0, /* dwMechanical */ + /*0x00010042, /* dwFeatures: Short APDU level exchanges */*/ + CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU, + 0x0000010F, /* dwMaxCCIDMessageLength: For extended APDU level the value shall be between 261 + 10 */ + 0xFF, /* bClassGetResponse: Echoes the class of the APDU */ + 0xFF, /* bClassEnvelope: Echoes the class of the APDU */ + 0, /* wLcdLayout: no LCD */ + 0, /* bPINSupport: No PIN */ + 1 /* bMaxCCIDBusySlot */ + }, + /* Bulk-OUT endpoint descriptor */ + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT), + USBEndpointDescriptor_MAXBULKSIZE_HS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Bulk-IN endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_DATA_IN ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN), + USBEndpointDescriptor_MAXBULKSIZE_HS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Notification endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION ), + USBEndpointDescriptor_INTERRUPT, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION), + USBEndpointDescriptor_MAXINTERRUPTSIZE_HS), + 0x10 + } +}; + +/** Qualifier descriptor */ + +const USBDeviceQualifierDescriptor deviceQualifierDescriptor = { + + sizeof(USBDeviceQualifierDescriptor), /* Size of this descriptor in bytes */ + USBGenericDescriptor_DEVICEQUALIFIER, /* Qualifier Descriptor Type */ + USBDeviceDescriptor_USB2_00, /* USB specification 2.00 */ + 0x00, /* Class is specified in interface */ + 0x00, /* Subclass is specified in interface */ + 0x00, /* Protocol is specified in interface */ + CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0), + 0x01, /* One possible configuration */ + 0x00 /* Reserved for future use, must be zero */ + +}; + +/** OtherSpeed configuration descriptor in Full Speed mode */ + +static const CCIDDriverConfigurationDescriptors sOtherSpeedConfigurationFS = { + + /* Standard USB configuration descriptor */ + + { + sizeof(USBConfigurationDescriptor), + USBGenericDescriptor_OTHERSPEEDCONFIGURATION, + sizeof(CCIDDriverConfigurationDescriptors), + 1, /* One interface in this configuration */ + 1, /* This is configuration #1 */ + 0, /* No associated string descriptor */ + USBD_BMATTRIBUTES, + USBConfigurationDescriptor_POWER(100) + }, + /* CCID interface descriptor */ + /* Table 4.3-1 Interface Descriptor */ + /* Interface descriptor */ + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + 0, /* Interface 0 */ + 0, /* No alternate settings */ + 3, /* uses bulk-IN, bulk-OUT and interrupt–IN */ + SMART_CARD_DEVICE_CLASS, + 0, /* Subclass code */ + 0, /* bulk transfers optional interrupt-IN */ + 0 /* No associated string descriptor */ + }, + { + sizeof(CCIDDescriptor), /* bLength: Size of this descriptor in bytes */ + CCID_DECRIPTOR_TYPE, /* bDescriptorType:Functional descriptor type */ + CCID1_10, /* bcdCCID: CCID version */ + 0, /* bMaxSlotIndex: Value 0 indicates that one slot is supported */ + VOLTS_5_0, /* bVoltageSupport */ + PROTOCOL_TO, /* dwProtocols */ + 3580, /* dwDefaultClock */ + 3580, /* dwMaxClock */ + 0, /* bNumClockSupported */ + 9600, /* dwDataRate : 9600 bauds */ + 9600, /* dwMaxDataRate : 9600 bauds */ + 0, /* bNumDataRatesSupported */ + 0xfe, /* dwMaxIFSD */ + 0, /* dwSynchProtocols */ + 0, /* dwMechanical */ + /*0x00010042, /* dwFeatures: Short APDU level exchanges */*/ + CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU, + 0x0000010F, /* dwMaxCCIDMessageLength: For extended APDU level the value shall be between 261 + 10 */ + 0xFF, /* bClassGetResponse: Echoes the class of the APDU */ + 0xFF, /* bClassEnvelope: Echoes the class of the APDU */ + 0, /* wLcdLayout: no LCD */ + 0, /* bPINSupport: No PIN */ + 1 /* bMaxCCIDBusySlot */ + }, + /* Bulk-OUT endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT), + USBEndpointDescriptor_MAXBULKSIZE_FS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Bulk-IN endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_DATA_IN ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN), + USBEndpointDescriptor_MAXBULKSIZE_FS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Notification endpoint descriptor */ + + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION ), + USBEndpointDescriptor_INTERRUPT, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION), + USBEndpointDescriptor_MAXINTERRUPTSIZE_FS), + 0x10 + } +}; + +/** OtherSpeed configuration descriptor in High Speed mode */ + +static const CCIDDriverConfigurationDescriptors sOtherSpeedConfigurationHS = { + + /* Standard USB configuration descriptor */ + + { + sizeof(USBConfigurationDescriptor), + USBGenericDescriptor_OTHERSPEEDCONFIGURATION, + sizeof(CCIDDriverConfigurationDescriptors), + 1, /* One interface in this configuration */ + 1, /* This is configuration #1 */ + 0, /* No associated string descriptor */ + USBD_BMATTRIBUTES, + USBConfigurationDescriptor_POWER(100) + }, + /* CCID interface descriptor */ + /* Table 4.3-1 Interface Descriptor */ + /* Interface descriptor */ + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + 0, /* Interface 0 */ + 0, /* No alternate settings */ + 3, /* uses bulk-IN, bulk-OUT and interrupt–IN */ + SMART_CARD_DEVICE_CLASS, + 0, /* Subclass code */ + 0, /* bulk transfers optional interrupt-IN */ + 0 /* No associated string descriptor */ + }, + { + sizeof(CCIDDescriptor), /* bLength: Size of this descriptor in bytes */ + CCID_DECRIPTOR_TYPE, /* bDescriptorType:Functional descriptor type */ + CCID1_10, /* bcdCCID: CCID version */ + 0, /* bMaxSlotIndex: Value 0 indicates that one slot is supported */ + VOLTS_5_0, /* bVoltageSupport */ + PROTOCOL_TO, /* dwProtocols */ + 3580, /* dwDefaultClock */ + 3580, /* dwMaxClock */ + 0, /* bNumClockSupported */ + 9600, /* dwDataRate : 9600 bauds */ + 9600, /* dwMaxDataRate : 9600 bauds */ + 0, /* bNumDataRatesSupported */ + 0xfe, /* dwMaxIFSD */ + 0, /* dwSynchProtocols */ + 0, /* dwMechanical */ + /*0x00010042, // dwFeatures: Short APDU level exchanges */ + CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO | CCID_FEATURES_EXC_TPDU, + 0x0000010F, /* dwMaxCCIDMessageLength: For extended APDU level the value shall be between 261 + 10 */ + 0xFF, /* bClassGetResponse: Echoes the class of the APDU */ + 0xFF, /* bClassEnvelope: Echoes the class of the APDU */ + 0, /* wLcdLayout: no LCD */ + 0, /* bPINSupport: No PIN */ + 1 /* bMaxCCIDBusySlot */ + }, + /* Bulk-OUT endpoint descriptor */ + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_OUT, CCID_EPT_DATA_OUT ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT), + USBEndpointDescriptor_MAXBULKSIZE_HS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Bulk-IN endpoint descriptor */ + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_DATA_IN ), + USBEndpointDescriptor_BULK, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN), + USBEndpointDescriptor_MAXBULKSIZE_HS), + 0x00 /* Does not apply to Bulk endpoints */ + + }, + /* Notification endpoint descriptor */ + { + sizeof(USBEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( USBEndpointDescriptor_IN, CCID_EPT_NOTIFICATION ), + USBEndpointDescriptor_INTERRUPT, + MIN(CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION), + USBEndpointDescriptor_MAXINTERRUPTSIZE_HS), + 0x10 + } +}; +#endif + +/** Language ID string descriptor. */ +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(23), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('A'), + USBStringDescriptor_UNICODE('T'), + USBStringDescriptor_UNICODE('M'), + USBStringDescriptor_UNICODE('E'), + USBStringDescriptor_UNICODE('L'), + USBStringDescriptor_UNICODE(' '), + USBStringDescriptor_UNICODE('A'), + USBStringDescriptor_UNICODE('T'), + USBStringDescriptor_UNICODE('9'), + USBStringDescriptor_UNICODE('1'), + USBStringDescriptor_UNICODE(' '), + USBStringDescriptor_UNICODE('C'), + USBStringDescriptor_UNICODE('C'), + USBStringDescriptor_UNICODE('I'), + USBStringDescriptor_UNICODE('D'), + USBStringDescriptor_UNICODE(' '), + USBStringDescriptor_UNICODE('D'), + USBStringDescriptor_UNICODE('R'), + USBStringDescriptor_UNICODE('I'), + USBStringDescriptor_UNICODE('V'), + USBStringDescriptor_UNICODE('E'), + USBStringDescriptor_UNICODE('R'), + USBStringDescriptor_UNICODE(' ') +}; + +/** Product serial number. */ +static const unsigned char serialNumberDescriptor[] = { + + USBStringDescriptor_LENGTH(12), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('0'), + USBStringDescriptor_UNICODE('1'), + USBStringDescriptor_UNICODE('2'), + USBStringDescriptor_UNICODE('3'), + USBStringDescriptor_UNICODE('4'), + USBStringDescriptor_UNICODE('5'), + USBStringDescriptor_UNICODE('6'), + USBStringDescriptor_UNICODE('7'), + USBStringDescriptor_UNICODE('8'), + USBStringDescriptor_UNICODE('9'), + USBStringDescriptor_UNICODE('A'), + USBStringDescriptor_UNICODE('F') +}; + +/** Array of pointers to string descriptors. */ +static const unsigned char *stringDescriptors[] = { + + languageIdDescriptor, + manufacturerDescriptor, + productDescriptor, + serialNumberDescriptor +}; + + +/** List of standard descriptors for the serial driver. */ +const USBDDriverDescriptors ccidDriverDescriptors = { + + &deviceDescriptor, /* FS */ + + (USBConfigurationDescriptor *) &configurationDescriptorsFS, +#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS) + (USBDeviceQualifierDescriptor *) &deviceQualifierDescriptor, /* FS */ + (USBConfigurationDescriptor *) &sOtherSpeedConfigurationFS, + &deviceDescriptor, /* HS */ + (USBConfigurationDescriptor *) &configurationDescriptorsHS, + (USBDeviceQualifierDescriptor *) &deviceQualifierDescriptor, /* HS */ + + (USBConfigurationDescriptor *) &sOtherSpeedConfigurationHS, +#else + 0, /* No qualifier descriptor FS */ + 0, /* No other-speed configuration FS */ + 0, /* No device descriptor HS */ + 0, /* No configuration HS */ + 0, /* No qualifier descriptor HS */ + 0, /* No other-speed configuration HS */ +#endif + stringDescriptors, + 4 /* Four string descriptors in array */ + +}; + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/** + * Response Pipe, Bulk-IN Messages + * Return the Slot Status to the host + * Answer to: + * PC_to_RDR_IccPowerOff + * PC_to_RDR_GetSlotStatus + * PC_to_RDR_IccClock + * PC_to_RDR_T0APDU + * PC_to_RDR_Mechanical + * PC_to_RDR_Abort and Class specific ABORT request + */ + +static void RDRtoPCSlotStatus( void ) +{ + TRACE_DEBUG("RDRtoPCSlotStatus\n\r"); + + /* Header fields settings */ + + ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_SLOTSTATUS; + ccidDriver.sCcidMessage.wLength = 0; + ccidDriver.sCcidMessage.bStatus = ccidDriver.SlotStatus; + ccidDriver.sCcidMessage.bError = 0; + /* 00h Clock running */ + + /* 01h Clock stopped in state L */ + + /* 02h Clock stopped in state H */ + + /* 03h Clock stopped in an unknown state */ + + /* All other values are Reserved for Future Use. */ + + ccidDriver.sCcidMessage.bSpecific = 0; +} + +/** + * Response Pipe, Bulk-IN Messages + * Answer to PC_to_RDR_IccPowerOn + */ +static void RDRtoPCDatablock_ATR( void ) +{ + unsigned char i; + unsigned char Atr[ATR_SIZE_MAX]; + unsigned char length; + + /*TRACE_DEBUG("RDRtoPCDatablock\n\r"); */ + + + ISO7816_Datablock_ATR( Atr, &length ); + + if( length > 5 ) { + ccidDriver.ProtocolDataStructure[1] = Atr[5]&0x0F; /* TD(1) */ + + ccidDriver.bProtocol = Atr[5]&0x0F; /* TD(1) */ + + } + + /* S_ccid_protocol_t0 */ + + /* bmFindexDindex */ + + ccidDriver.ProtocolDataStructure[0] = Atr[2]; /* TA(1) */ + + + /* bmTCCKST0 */ + + /* For T=0 ,B0 – 0b, B7-2 – 000000b */ + + /* B1 – Convention used (b1=0 for direct, b1=1 for inverse) */ + + + /* bGuardTimeT0 */ + + /* Extra Guardtime between two characters. Add 0 to 254 etu to the normal */ + + /* guardtime of 12etu. FFh is the same as 00h. */ + + ccidDriver.ProtocolDataStructure[2] = Atr[4]; /* TC(1) */ + + /* AT91C_BASE_US0->US_TTGR = 0; // TC1 */ + + + /* bWaitingIntegerT0 */ + + /* WI for T=0 used to define WWT */ + + ccidDriver.ProtocolDataStructure[3] = Atr[7]; /* TC(2) */ + + + /* bClockStop */ + + /* ICC Clock Stop Support */ + + /* 00 = Stopping the Clock is not allowed */ + + /* 01 = Stop with Clock signal Low */ + + /* 02 = Stop with Clock signal High */ + + /* 03 = Stop with Clock either High or Low */ + + ccidDriver.ProtocolDataStructure[4] = 0x00; /* 0 to 3 */ + + + /* Header fields settings */ + + ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_DATABLOCK; + ccidDriver.sCcidMessage.wLength = length; /* Size of ATR */ + + ccidDriver.sCcidMessage.bSizeToSend += length; /* Size of ATR */ + + /* bChainParameter: 00 the response APDU begins and ends in this command */ + + ccidDriver.sCcidMessage.bSpecific = 0; + + for( i=0; i (configurationDescriptorsFS.ccid.dwMaxCCIDMessageLength-10) ) { + + ccidDriver.sCcidMessage.bStatus = 1; + ccidDriver.sCcidMessage.bError = 0; + } + /* check bBWI */ + + else if ( 0 != ccidDriver.sCcidCommand.bSpecific_0 ) { + + TRACE_ERROR("Bad bBWI\n\r"); + } + else { + + /* APDU or TPDU */ + + switch(configurationDescriptorsFS.ccid.dwFeatures + & (CCID_FEATURES_EXC_TPDU|CCID_FEATURES_EXC_SAPDU|CCID_FEATURES_EXC_APDU)) { + + case CCID_FEATURES_EXC_TPDU: + if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_TO) { + + /* Send commande APDU */ + + indexMessage = ISO7816_XfrBlockTPDU_T0( ccidDriver.sCcidCommand.APDU , + ccidDriver.sCcidMessage.abData, + ccidDriver.sCcidCommand.wLength ); + } + else { + if (ccidDriver.ProtocolDataStructure[1] == PROTOCOL_T1) { + TRACE_INFO("Not supported T=1\n\r"); + } + else { + TRACE_INFO("Not supported\n\r"); + } + } + break; + + case CCID_FEATURES_EXC_APDU: + TRACE_INFO("Not supported\n\r"); + break; + + default: + break; + } + + } + + ccidDriver.sCcidMessage.wLength = indexMessage; + TRACE_DEBUG("USB: 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n\r", ccidDriver.sCcidMessage.abData[0], + ccidDriver.sCcidMessage.abData[1], + ccidDriver.sCcidMessage.abData[2], + ccidDriver.sCcidMessage.abData[3], + ccidDriver.sCcidMessage.abData[4] ); + RDRtoPCDatablock(); + +} + +/** + * Command Pipe, Bulk-OUT Messages + * return parameters by the command: RDR_to_PC_Parameters + */ +static void PCtoRDRGetParameters( void ) +{ + TRACE_DEBUG("PCtoRDRGetParameters\n\r"); + + /* We support only one slot */ + + + /* bmIccStatus */ + + if( ISO7816_StatusReset() ) { + /* 0: An ICC is present and active (power is on and stable, RST is inactive */ + + ccidDriver.sCcidMessage.bStatus = 0; + } + else { + /* 1: An ICC is present and inactive (not activated or shut down by hardware error) */ + + ccidDriver.sCcidMessage.bStatus = 1; + } + + RDRtoPCParameters(); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command resets the slot parameters to their default values + */ +static void PCtoRDRResetParameters( void ) +{ + TRACE_DEBUG("PCtoRDRResetParameters\n\r"); + + ccidDriver.SlotStatus = ICC_NOT_PRESENT; + ccidDriver.sCcidMessage.bStatus = ccidDriver.SlotStatus; + + RDRtoPCParameters(); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command is used to change the parameters for a given slot. + */ +static void PCtoRDRSetParameters( void ) +{ + TRACE_DEBUG("PCtoRDRSetParameters\n\r"); + + ccidDriver.SlotStatus = ccidDriver.sCcidCommand.bSlot; + ccidDriver.sCcidMessage.bStatus = ccidDriver.SlotStatus; + /* Not all feature supported */ + + + RDRtoPCParameters(); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command allows the CCID manufacturer to define and access extended + * features. + * Information sent via this command is processed by the CCID control logic. + */ +static void PCtoRDREscape( void ) +{ + TRACE_DEBUG("PCtoRDREscape\n\r"); + + /* If needed by the user */ + + ISO7816_Escape(); + + /* stub, return all value send */ + + RDRtoPCEscape( ccidDriver.sCcidCommand.wLength, ccidDriver.sCcidCommand.APDU); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command stops or restarts the clock. + */ +static void PCtoRDRICCClock( void ) +{ + TRACE_DEBUG("PCtoRDRICCClock\n\r"); + + if( 0 == ccidDriver.sCcidCommand.bSpecific_0 ) { + /* restarts the clock */ + + ISO7816_RestartClock(); + } + else { + /* stop clock in the state shown in the bClockStop field */ + + ISO7816_StopClock(); + } + + RDRtoPCSlotStatus( ); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command changes the parameters used to perform the transportation of + * APDU messages by the T=0 protocol. + */ +static void PCtoRDRtoAPDU( void ) +{ + unsigned char bmChanges; + unsigned char bClassGetResponse; + unsigned char bClassEnvelope; + + TRACE_DEBUG("PCtoRDRtoAPDU\n\r"); + + if( configurationDescriptorsFS.ccid.dwFeatures == (CCID_FEATURES_EXC_SAPDU|CCID_FEATURES_EXC_APDU) ) { + + bmChanges = ccidDriver.sCcidCommand.bSpecific_0; + bClassGetResponse = ccidDriver.sCcidCommand.bSpecific_1; + bClassEnvelope = ccidDriver.sCcidCommand.bSpecific_2; + + ISO7816_toAPDU(); + } + + RDRtoPCSlotStatus(); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This is a command message to allow entering the PIN for verification or + * modification. + */ +static void PCtoRDRSecure( void ) +{ + TRACE_DEBUG("PCtoRDRSecure\n\r"); + + TRACE_DEBUG("For user\n\r"); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command is used to manage motorized type CCID functionality. + * The Lock Card function is used to hold the ICC. + * This prevents an ICC from being easily removed from the CCID. + * The Unlock Card function is used to remove the hold initiated by the Lock + * Card function + */ +static void PCtoRDRMechanical( void ) +{ + TRACE_DEBUG("PCtoRDRMechanical\n\r"); + TRACE_DEBUG("Not implemented\n\r"); + + RDRtoPCSlotStatus(); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command is used with the Control pipe Abort request to tell the CCID + * to stop any current transfer at the specified slot and return to a state + * where the slot is ready to accept a new command pipe Bulk-OUT message. + */ +static void PCtoRDRAbort( void ) +{ + TRACE_DEBUG("PCtoRDRAbort\n\r"); + + RDRtoPCSlotStatus(); +} + +/** + * Command Pipe, Bulk-OUT Messages + * This command is used to manually set the data rate and clock frequency of + * a specific slot. + */ +static void PCtoRDRSetDataRateAndClockFrequency( void ) +{ + unsigned int dwClockFrequency; + unsigned int dwDataRate; + + TRACE_DEBUG("PCtoRDRSetDatarateandClockFrequency\n\r"); + + dwClockFrequency = ccidDriver.sCcidCommand.APDU[0] + + (ccidDriver.sCcidCommand.APDU[1]<<8) + + (ccidDriver.sCcidCommand.APDU[2]<<16) + + (ccidDriver.sCcidCommand.APDU[3]<<24); + + dwDataRate = ccidDriver.sCcidCommand.APDU[4] + + (ccidDriver.sCcidCommand.APDU[5]<<8) + + (ccidDriver.sCcidCommand.APDU[6]<<16) + + (ccidDriver.sCcidCommand.APDU[7]<<24); + + ISO7816_SetDataRateandClockFrequency( dwClockFrequency, dwDataRate ); + + RDRtoPCDataRateAndClockFrequency( dwClockFrequency, dwDataRate ); + +} + +/** + * Report the CMD_NOT_SUPPORTED error to the host + */ +static void vCCIDCommandNotSupported( void ) +{ + /* Command not supported */ + + /* vCCIDReportError(CMD_NOT_SUPPORTED); */ + + + TRACE_DEBUG("CMD_NOT_SUPPORTED\n\r"); + + /* Header fields settings */ + + ccidDriver.sCcidMessage.bMessageType = RDR_TO_PC_SLOTSTATUS; + ccidDriver.sCcidMessage.wLength = 0; + ccidDriver.sCcidMessage.bSpecific = 0; + + ccidDriver.sCcidMessage.bStatus |= ICC_CS_FAILED; + + /* Send the response to the host */ + + /*vCCIDSendResponse(); */ + +} + +/** + * Sent CCID response on USB + */ +static void vCCIDSendResponse( void ) +{ + unsigned char bStatus; + + do { + bStatus = USBD_Write( CCID_EPT_DATA_IN, (void*)&ccidDriver.sCcidMessage, + ccidDriver.sCcidMessage.bSizeToSend, 0, 0 ); + } + while (bStatus != USBD_STATUS_SUCCESS); +} + + +/** + * Description: CCID Command dispatcher + */ +static void CCIDCommandDispatcher( void ) +{ + unsigned char MessageToSend = 0; + + /*TRACE_DEBUG("Command: 0x%X 0x%x 0x%X 0x%X 0x%X 0x%X 0x%X\n\r\n\r", */ + + /* (unsigned int)ccidDriver.sCcidCommand.bMessageType, */ + + /* (unsigned int)ccidDriver.sCcidCommand.wLength, */ + + /* (unsigned int)ccidDriver.sCcidCommand.bSlot, */ + + /* (unsigned int)ccidDriver.sCcidCommand.bSeq, */ + + /* (unsigned int)ccidDriver.sCcidCommand.bSpecific_0, */ + + /* (unsigned int)ccidDriver.sCcidCommand.bSpecific_1, */ + + /* (unsigned int)ccidDriver.sCcidCommand.bSpecific_2); */ + + + /* Check the slot number */ + + if ( ccidDriver.sCcidCommand.bSlot > 0 ) { + + TRACE_ERROR("BAD_SLOT_NUMBER\n\r"); + } + + TRACE_DEBUG("typ=0x%X\n\r", ccidDriver.sCcidCommand.bMessageType); + + ccidDriver.sCcidMessage.bStatus = 0; + + ccidDriver.sCcidMessage.bSeq = ccidDriver.sCcidCommand.bSeq; + ccidDriver.sCcidMessage.bSlot = ccidDriver.sCcidCommand.bSlot; + + ccidDriver.sCcidMessage.bSizeToSend = sizeof(S_ccid_bulk_in_header)-(ABDATA_SIZE+1); + + + /* Command dispatcher */ + + switch ( ccidDriver.sCcidCommand.bMessageType ) { + + case PC_TO_RDR_ICCPOWERON: + PCtoRDRIccPowerOn(); + MessageToSend = 1; + break; + + case PC_TO_RDR_ICCPOWEROFF: + PCtoRDRIccPowerOff(); + MessageToSend = 1; + break; + + case PC_TO_RDR_GETSLOTSTATUS: + PCtoRDRGetSlotStatus(); + MessageToSend = 1; + break; + + case PC_TO_RDR_XFRBLOCK: + PCtoRDRXfrBlock(); + MessageToSend = 1; + break; + + case PC_TO_RDR_GETPARAMETERS: + PCtoRDRGetParameters(); + MessageToSend = 1; + break; + + case PC_TO_RDR_RESETPARAMETERS: + PCtoRDRResetParameters(); + MessageToSend = 1; + break; + + case PC_TO_RDR_SETPARAMETERS: + PCtoRDRSetParameters(); + MessageToSend = 1; + break; + + case PC_TO_RDR_ESCAPE: + PCtoRDREscape(); + MessageToSend = 1; + break; + + case PC_TO_RDR_ICCCLOCK: + PCtoRDRICCClock(); + MessageToSend = 1; + break; + + case PC_TO_RDR_T0APDU: + /* Only CCIDs reporting a short or extended APDU level in the dwFeatures */ + + /* field of the CCID class descriptor may take this command into account. */ + + if( (CCID_FEATURES_EXC_SAPDU == (CCID_FEATURES_EXC_SAPDU&configurationDescriptorsFS.ccid.dwFeatures)) + || (CCID_FEATURES_EXC_APDU == (CCID_FEATURES_EXC_APDU &configurationDescriptorsFS.ccid.dwFeatures)) ) { + + /* command supported */ + + PCtoRDRtoAPDU(); + } + else { + /* command not supported */ + + TRACE_DEBUG("PC_TO_RDR_T0APDU\n\r"); + vCCIDCommandNotSupported(); + } + MessageToSend = 1; + break; + + case PC_TO_RDR_SECURE: + PCtoRDRSecure(); + MessageToSend = 1; + break; + + case PC_TO_RDR_MECHANICAL: + PCtoRDRMechanical(); + MessageToSend = 1; + break; + + case PC_TO_RDR_ABORT: + PCtoRDRAbort(); + MessageToSend = 1; + break; + + case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY: + PCtoRDRSetDataRateAndClockFrequency(); + MessageToSend = 1; + break; + + default: + TRACE_DEBUG("default: 0x%X\n\r", ccidDriver.sCcidCommand.bMessageType); + vCCIDCommandNotSupported(); + MessageToSend = 1; + break; + + } + + if( MessageToSend == 1 ) { + vCCIDSendResponse(); + } +} + + +/** + * SETUP request handler for a CCID device + * \param pRequest Pointer to a USBGenericRequest instance + */ +static void CCID_RequestHandler(const USBGenericRequest *pRequest) +{ + TRACE_DEBUG("CCID_RHl\n\r"); + + /* Check if this is a class request */ + + if (USBGenericRequest_GetType(pRequest) == USBGenericRequest_CLASS) { + + /* Check if the request is supported */ + + switch (USBGenericRequest_GetRequest(pRequest)) { + + case CCIDGenericRequest_ABORT: + TRACE_DEBUG("CCIDGenericRequest_ABORT\n\r"); + break; + + case CCIDGenericRequest_GET_CLOCK_FREQUENCIES: + TRACE_DEBUG("Not supported\n\r"); + /* A CCID with bNumClockSupported equal to 00h does not have */ + + /* to support this request */ + + break; + + case CCIDGenericRequest_GET_DATA_RATES: + TRACE_DEBUG("Not supported\n\r"); + /* A CCID with bNumDataRatesSupported equal to 00h does not have */ + + /* to support this request. */ + + break; + + default: + TRACE_WARNING( "CCIDDriver_RequestHandler: Unsupported request (%d)\n\r", + USBGenericRequest_GetRequest(pRequest)); + USBD_Stall(0); + } + } + + else if (USBGenericRequest_GetType(pRequest) == USBGenericRequest_STANDARD) { + + /* Forward request to the standard handler */ + + USBDDriver_RequestHandler(&(ccidDriver.usbdDriver), pRequest); + } + else { + + /* Unsupported request type */ + + TRACE_WARNING( "CCIDDriver_RequestHandler: Unsupported request type (%d)\n\r", + USBGenericRequest_GetType(pRequest)); + USBD_Stall(0); + } +} + + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Optional callback re-implementation + */ +#if !defined(NOAUTOCALLBACK) +/* not static function */ + +void USBDCallbacks_RequestReceived(const USBGenericRequest *request) +{ + CCID_RequestHandler(request); +} +#endif + + +/** + * Handles SmartCart request + */ +void CCID_SmartCardRequest( void ) +{ + unsigned char bStatus; + + do { + + bStatus = CCID_Read( (void*)&ccidDriver.sCcidCommand, + sizeof(S_ccid_bulk_out_header), + (TransferCallback)&CCIDCommandDispatcher, + (void*)0 ); + } + while (bStatus != USBD_STATUS_SUCCESS); + +} + +/** + * Initializes the CCID device driver. + */ +void CCIDDriver_Initialize( void ) +{ + TRACE_DEBUG("CCID_Init\n\r"); + USBDDriver_Initialize(&(ccidDriver.usbdDriver), + &ccidDriverDescriptors, + 0); /* Multiple interface settings not supported */ + + USBD_Init(); +} + +/** + * Reads data from the Data OUT endpoint + * \param pBuffer Buffer to store the received data + * \param dLength data buffer length + * \param fCallback Optional callback function + * \param pArgument Optional parameter for the callback function + * \return USBD_STATUS_LOCKED or USBD_STATUS_SUCCESS + */ +unsigned char CCID_Read(void *pBuffer, + unsigned int dLength, + TransferCallback fCallback, + void *pArgument) +{ + return USBD_Read(CCID_EPT_DATA_OUT, pBuffer, dLength, fCallback, pArgument); +} + +/** + * Sends data through the Data IN endpoint + * \param pBuffer Buffer holding the data to transmit + * \param dLength Length of data buffer + * \param fCallback Optional callback function + * \param pArgument Optional parameter for the callback function + * \return USBD_STATUS_LOCKED or USBD_STATUS_SUCCESS + */ +unsigned char CCID_Write(void *pBuffer, + unsigned int dLength, + TransferCallback fCallback, + void *pArgument) +{ + return USBD_Write(CCID_EPT_DATA_IN, pBuffer, dLength, fCallback, pArgument); +} + +/** + * Sends data through the interrupt endpoint, ICC insertion event + * RDR_to_PC_NotifySlotChange + * \return USBD_STATUS_LOCKED or USBD_STATUS_SUCCESS + */ +unsigned char CCID_Insertion( void ) +{ + TRACE_DEBUG("CCID_Insertion\n\r"); + + /* Build the Interrupt-IN message */ + + ccidDriver.BufferINT[0] = RDR_TO_PC_NOTIFYSLOTCHANGE; + ccidDriver.BufferINT[1] = ICC_INSERTED_EVENT; + ccidDriver.SlotStatus = ICC_INSERTED_EVENT; + + /* Notify the host that a ICC is inserted */ + + return USBD_Write( CCID_EPT_NOTIFICATION, ccidDriver.BufferINT, 2, 0, 0 ); +} + +/** + * Sends data through the interrupt endpoint, ICC removal event + * RDR_to_PC_NotifySlotChange + * \return USBD_STATUS_LOCKED or USBD_STATUS_SUCCESS + */ +unsigned char CCID_Removal( void ) +{ + TRACE_DEBUG("CCID_Removal\n\r"); + + /* Build the Interrupt-IN message */ + + ccidDriver.BufferINT[0] = RDR_TO_PC_NOTIFYSLOTCHANGE; + ccidDriver.BufferINT[1] = ICC_NOT_PRESENT; + ccidDriver.SlotStatus = ICC_NOT_PRESENT; + + /* Notify the host that a ICC is inserted */ + + return USBD_Write( CCID_EPT_NOTIFICATION, ccidDriver.BufferINT, 2, 0, 0 ); +} + +/** + * Interrupt-IN Messages + * This message is sent when any bit in the bHardwareErrorCode field is set. + * If this message is sent when there is no “outstanding” command, the bSeq + * field will be undefined. + * \param bSlot ICC slot number + * \param bSeq Sequence number of the bulk OUT command when the hardware error + * occured + * \param bHardwareErrorCode Hardware error code + * \return USBD_STATUS_LOCKED or USBD_STATUS_SUCCESS + */ +unsigned char RDRtoPCHardwareError( unsigned char bSlot, + unsigned char bSeq, + unsigned char bHardwareErrorCode ) +{ + TRACE_DEBUG("RDRtoPCHardwareError\n\r"); + + /* Build the Interrupt-IN message */ + + ccidDriver.BufferINT[0] = RDR_TO_PC_HARDWAREERROR; + ccidDriver.BufferINT[1] = bSlot; + ccidDriver.BufferINT[2] = bSeq; + ccidDriver.BufferINT[3] = bHardwareErrorCode; + + /* Notify the host that a ICC is inserted */ + + return USBD_Write( CCID_EPT_NOTIFICATION, ccidDriver.BufferINT, 4, 0, 0 ); +} + + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriver.h b/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriver.h new file mode 100644 index 00000000..53455ee6 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriver.h @@ -0,0 +1,420 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/**------------------------------------------------------------------------------ + * \file + * + * \section Purpose + * + * Definition of methods for using a CCID device driver. + * + * \section Usage + * + * -# CCIDDriver_Initialize + * -# CCID_Read + * -# CCID_Write + * -# CCID_SmartCardRequest + * -# CCID_Insertion + * -# CCID_Removal + * -# RDRtoPCHardwareError + */ + +#ifndef CCID_DRIVER_H +#define CCID_DRIVER_H + +/** \addtogroup usbd_ccid + *@{ + */ +/** For reference, the absolute maximum block size */ +/** for a TPDU T=0 block is 260 bytes (5 bytes command; 255 bytes data), or */ +/** for a TPDU T=1 block is 259 bytes, or */ +/** for a short APDU T=1 block is 261 bytes, or */ +/** for an extended APDU T=1 block is 65544 bytes. */ +#define ABDATA_SIZE 260 + +/** define protocol T=0 */ +#define PROTOCOL_TO 0 +/** define protocol T=1 */ +#define PROTOCOL_T1 1 + +/** define for dwFeatures see Table 5.1-1 Smart Card Device Class Descriptors */ +/** No special characteristics */ +#define CCID_FEATURES_NADA 0x00000000 +/** Automatic parameter configuration based on ATR data */ +#define CCID_FEATURES_AUTO_PCONF 0x00000002 +/** Automatic activation of ICC on inserting */ +#define CCID_FEATURES_AUTO_ACTIV 0x00000004 +/** Automatic ICC voltage selection */ +#define CCID_FEATURES_AUTO_VOLT 0x00000008 +/** Automatic ICC clock frequency change according to active parameters provided */ +/** by the Host or self determined */ +#define CCID_FEATURES_AUTO_CLOCK 0x00000010 +/** Automatic baud rate change according to active parameters provided by the */ +/** Host or self determined */ +#define CCID_FEATURES_AUTO_BAUD 0x00000020 +/** Automatic parameters negotiation made by the CCID (use of warm or cold */ +/** resets or PPS according to a manufacturer proprietary algorithm to select */ +/** the communication parameters with the ICC) */ +#define CCID_FEATURES_AUTO_PNEGO 0x00000040 +/** Automatic PPS made by the CCID according to the active parameters */ +#define CCID_FEATURES_AUTO_PPS 0x00000080 +/** CCID can set ICC in clock stop mode */ +#define CCID_FEATURES_ICCSTOP 0x00000100 +/** NAD value other than 00 accepted (T=1 protocol in use) */ +#define CCID_FEATURES_NAD 0x00000200 +/** Automatic IFSD exchange as first exchange (T=1 protocol in use) */ +#define CCID_FEATURES_AUTO_IFSD 0x00000400 +/** TPDU level exchanges with CCID */ +#define CCID_FEATURES_EXC_TPDU 0x00010000 +/** Short APDU level exchange with CCID */ +#define CCID_FEATURES_EXC_SAPDU 0x00020000 +/** Short and Extended APDU level exchange with CCID */ +#define CCID_FEATURES_EXC_APDU 0x00040000 +/** USB Wake up signaling supported on card insertion and removal */ +#define CCID_FEATURES_WAKEUP 0x00100000 + +/*------------------------------------------------------------------------------ + + * Types + + *------------------------------------------------------------------------------*/ + +/** + * \typedef S_ccid_bulk_in_header + * \brief Bulk CCID Message header structure + */ +typedef struct _S_ccid_bulk_in_header +{ + unsigned char bMessageType; + /** Message-specific data length */ + unsigned long wLength; + /** Identifies the slot number for this command */ + unsigned char bSlot; + /** Sequence number for command. */ + unsigned char bSeq; + /** Slot status register */ + unsigned char bStatus; + /** Slot error */ + unsigned char bError; + /** specific register */ + unsigned char bSpecific; + /** Data block sent to the CCID. */ + unsigned char abData[ABDATA_SIZE]; + unsigned char bSizeToSend; +} __attribute__ ((packed)) S_ccid_bulk_in_header; + +/** + * \typedef S_ccid_bulk_out_header + * \brief 6.1 Bulk Transfers + */ +typedef struct _S_ccid_bulk_out_header +{ + unsigned char bMessageType; + /** Message-specific data length */ + unsigned long wLength; + /** Identifies the slot number for this command */ + unsigned char bSlot; + /** Sequence number for command. */ + unsigned char bSeq; + /** specific register */ + unsigned char bSpecific_0; + unsigned char bSpecific_1; + unsigned char bSpecific_2; + /** Application Protocol Data Unit */ + unsigned char APDU[ABDATA_SIZE]; +} __attribute__ ((packed)) S_ccid_bulk_out_header; + + +/** + * \typedef S_ccid_PIN_Verification + * \brief 6.1.11.2 PIN Verification Data Structure + */ +typedef struct _S_ccid_PIN_Verification +{ + /** Number of seconds. */ + unsigned char bTimerOut; + /** Several parameters for the PIN format options */ + unsigned char bmFormatString; + /** Define the length of the PIN to present in the APDU command */ + unsigned char bmPINBlockString; + /** Allows the length PIN insertion in the APDU command */ + unsigned char bmPINLengthFormat; + /** Minimum PIN size in digit and Maximum PIN size in digit */ + unsigned char wPINMaxExtraDigit; + /** The value is a bit wise OR operation. */ + unsigned char bEntryValidationCondition; + /** Number of messages to display for the PIN modify command */ + unsigned char bNumberMessage; + /** Language used to display the messages. */ + unsigned char wLangId; + /** Message index in the Reader message table */ + unsigned char bMsgIndex; + /** T=1 I-block prologue field to use */ + unsigned char bTeoPrologue[3]; + /** APDU to send to the ICC */ + unsigned char abPINApdu[255]; +}__attribute__ ((packed)) S_ccid_PIN_Verification; + + +/** + * \typedef S_ccid_PIN_Modification + * \brief 6.1.11.7 PIN Modification Data Structure + */ +typedef struct _S_ccid_PIN_Modification +{ + /** Number of seconds. If 00h then CCID default value is used. */ + unsigned char bTimeOut; + /** Several parameters for the PIN format options (defined in § 6.1.11.4) */ + unsigned char bmFormatString4; + /** Define the length of the PIN to present in the APDU command */ + unsigned char bmPINBlockString; + /** Allows the length PIN insertion in the APDU command (defined in § 6.1.11.6) */ + unsigned char bmPinLengthFormat; + /** Insertion position offset in byte for the current PIN */ + unsigned char bInsertionOffsetOld; + /** Insertion position offset in byte for the new PIN */ + unsigned char bInsertionOffsetNew; + /** XXYYh */ + /** XX: Minimum PIN size in digit */ + /** YY: Maximum PIN size in digit */ + unsigned char wPINMaxExtraDigit; + /** 00h,01h,02h,03h */ + /** Indicates if a confirmation is requested before acceptance of a new PIN (meaning that the user has to enter this new PIN twice before it is accepted) */ + /** Indicates if the current PIN must be entered and set in the same APDU field of not. */ + unsigned char bConfirmPIN; + /** The value is a bit wise OR operation. */ + /** 01h Max size reached */ + /** 02h Validation key pressed */ + /** 04h Timeout occurred */ + unsigned char bEntryValidationCondition; + /** 00h,01h,02h,03h,or FFh */ + /** Number of messages to display for the PIN modify command. */ + unsigned char bNumberMessage; + /** Language used to display the messages. The 16 bit */ + unsigned char wLangId; + /** Message index in the Reader message table (should be 00h or 01h). */ + unsigned char bMsgIndex1; + /** Message index in the Reader message table (should be 01h or 02h). */ + unsigned char bMsgIndex2; + /** Message index in the Reader message table (should be 02h). */ + unsigned char bMsgIndex3; + /** T=1 I-block prologue field to use. Significant only if protocol in use is T=1. */ + unsigned char bTeoPrologue[3]; + /** Byte array APDU to send to the ICC */ + unsigned char abPINApdu[255]; +}__attribute__ ((packed)) S_ccid_PIN_Modification; + +/** + * \typedef S_ccid_protocol_t0 + * \brief Protocol Data Structure for Protocol T=0 (bProtocolNum=0, dwLength=00000005h) + */ +typedef struct _S_ccid_protocol_t0 +{ + /** B7-4 – FI – Index into the table 7 in ISO/IEC 7816-3:1997 selecting a */ + /** clock rate conversion factor */ + /** B3-0 – DI - Index into the table 8 in ISO/IEC 7816-3:1997 selecting a */ + /** baud rate conversion factor */ + unsigned char bmFindexDindex; + /** For T=0 ,B0 – 0b, B7-2 – 000000b */ + /** B1 – Convention used (b1=0 for direct, b1=1 for inverse) */ + unsigned char bmTCCKST0; /* 0 to 2 */ + + /** Extra Guardtime between two characters. Add 0 to 254 etu to the normal */ + /** guardtime of 12etu. FFh is the same as 00h. */ + unsigned char bGuardTimeT0; /* 0 to FF */ + + /** WI for T=0 used to define WWT */ + unsigned char bWaitingIntegerT0; /* 0 to FF */ + + /** ICC Clock Stop Support */ + /** 00 = Stopping the Clock is not allowed */ + /** 01 = Stop with Clock signal Low */ + /** 02 = Stop with Clock signal High */ + /** 03 = Stop with Clock either High or Low */ + unsigned char bClockStop; /* 0 to 3 */ + +} __attribute__ ((packed)) S_ccid_protocol_t0; + + +/** + * \typedef S_ccid_protocol_t1 + * \brief Protocol Data Structure for Protocol T=1 (bProtocolNum=1, dwLength=00000007h) + */ +typedef struct _S_ccid_protocol_t1 +{ + /** B7-4 – FI – Index into the table 7 in ISO/IEC 7816-3:1997 selecting a */ + /** clock rate conversion factor */ + /** B3-0 – DI - Index into the table 8 in ISO/IEC 7816-3:1997 selecting a */ + /** baud rate conversion factor */ + unsigned char bmFindexDindex; + /** For T=1, B7-2 – 000100b */ + /** B0 – Checksum type (b0=0 for LRC, b0=1 for CRC */ + /** B1 – Convention used (b1=0 for direct, b1=1 for inverse) */ + unsigned char bmTCCKST1; /* 10h, 11h, 12h, 13h */ + + /** Extra Guardtime (0 to 254 etu between two characters). */ + /** If value is FFh, then guardtime is reduced by 1. */ + unsigned char bGuardTimeT1; /* 0 to FF */ + + /** B7-4 = BWI */ + /** B3-0 = CWI */ + unsigned char bmWaitingIntegersT1; /* 0 to 9 */ + + /** ICC Clock Stop Support */ + /** 00 = Stopping the Clock is not allowed */ + /** 01 = Stop with Clock signal Low */ + /** 02 = Stop with Clock signal High */ + /** 03 = Stop with Clock either High or Low */ + unsigned char bClockStop; /* 0 to 3 */ + + /** Size of negotiated IFSC */ + unsigned char bIFSC; /* 0 to FE */ + + /** Nad value used by CCID */ + unsigned char bNadValue; /* 0 to FF */ + +} __attribute__ ((packed)) S_ccid_protocol_t1; + + +/** + * \typedef CCIDDescriptor + * \brief Identifies the length of type of subordinate descriptors of a CCID device + * Table 5.1-1 Smart Card Device Class descriptors + */ +typedef struct _CCIDDescriptor +{ + /** Size of this descriptor, in bytes. */ + unsigned char bLength; + /** Functional Descriptor type */ + unsigned char bDescriptorType; + /** Integrated Circuit(s) Cards Interface Devices (CCID) Specification */ + /** Release Number */ + unsigned short bcdCCID; + /** Index of the highest available slot. An USB-ICC is regarded as a single */ + /** slot CCID. */ + unsigned char bMaxSlotIndex; + /** This value indicates what voltages the CCID can supply to its slots. */ + /** It is a bitwise OR operation performed on the following values: */ + /** - 01h 5.0V */ + /** - 02h 3.0V */ + /** - 04h 1.8V */ + /** Other bits are RFU. */ + unsigned char bVoltageSupport; + /** RRRR –Upper Word- is RFU = 0000h */ + /** PPPP –Lower Word- Encodes the supported protocol types. A ‘1’ in a given */ + /** bit position indicates support for the associated ISO protocol. */ + /** 0001h = Protocol T=0 */ + /** 0002h = Protocol T=1 */ + /** All other bits are reserved and must be set to zero. The field is */ + /** intended to correspond to the PCSC specification definitions. */ + unsigned long dwProtocols; + /** Default ICC clock frequency in KHz. This is an integer value. */ + unsigned long dwDefaultClock; + /** Maximum supported ICC clock frequency in KHz. This is an integer value. */ + unsigned long dwMaximumClock; + /** The number of clock frequencies that are supported by the CCID. If the */ + /** value is 00h, the supported clock frequencies are assumed to be the */ + /** default clock frequency defined by dwDefaultClock and the maximum clock */ + /** frequency defined by dwMaximumClock. */ + unsigned char bNumClockSupported; + /** Default ICC I/O data rate in bps. This is an integer value */ + unsigned long dwDataRate; + /** Maximum supported ICC I/O data rate in bps */ + unsigned long dwMaxDataRate; + /** The number of data rates that are supported by the CCID. */ + unsigned char bNumDataRatesSupported; + /** Indicates the maximum IFSD supported by CCID for protocol T=1. */ + unsigned long dwMaxIFSD; + /** - RRRR-Upper Word- is RFU = 0000h */ + /** - PPPP-Lower Word- encodes the supported protocol types. A ‘1’ in a given */ + /** bit position indicates support for the associated protocol. */ + /** 0001h indicates support for the 2-wire protocol 1 */ + /** 0002h indicates support for the 3-wire protocol 1 */ + /** 0004h indicates support for the I2C protocol 1 */ + /** All other values are outside of this specification, and must be handled */ + /** by vendor-supplied drivers. */ + unsigned long dwSynchProtocols; + /** The value is a bitwise OR operation performed on the following values: */ + /** - 00000000h No special characteristics */ + /** - 00000001h Card accept mechanism 2 */ + /** - 00000002h Card ejection mechanism 2 */ + /** - 00000004h Card capture mechanism 2 */ + /** - 00000008h Card lock/unlock mechanism */ + unsigned long dwMechanical; + /** This value indicates what intelligent features the CCID has. */ + unsigned long dwFeatures; + /** For extended APDU level the value shall be between 261 + 10 (header) and */ + /** 65544 +10, otherwise the minimum value is the wMaxPacketSize of the */ + /** Bulk-OUT endpoint. */ + unsigned long dwMaxCCIDMessageLength; + /** Significant only for CCID that offers an APDU level for exchanges. */ + unsigned char bClassGetResponse; + /** Significant only for CCID that offers an extended APDU level for exchanges. */ + unsigned char bClassEnvelope; + /** Number of lines and characters for the LCD display used to send messages for PIN entry. */ + unsigned short wLcdLayout; + /** This value indicates what PIN support features the CCID has. */ + unsigned char bPINSupport; + /** Maximum number of slots which can be simultaneously busy. */ + unsigned char bMaxCCIDBusySlots; + +} __attribute__ ((packed)) CCIDDescriptor; + +/*------------------------------------------------------------------------------ */ + +/* Exported functions */ + +/*------------------------------------------------------------------------------ */ + + +extern unsigned char RDRtoPCHardwareError( unsigned char bSlot, + unsigned char bSeq, + unsigned char bHardwareErrorCode ); + +#if !defined(NOAUTOCALLBACK) +extern void USBDCallbacks_RequestReceived(const USBGenericRequest *request); +#endif +extern void CCID_SmartCardRequest( void ); +extern void CCIDDriver_Initialize( void ); +extern unsigned char CCID_Read(void *pBuffer, + unsigned int dLength, + TransferCallback fCallback, + void *pArgument); +extern unsigned char CCID_Write(void *pBuffer, + unsigned int dLength, + TransferCallback fCallback, + void *pArgument); +extern unsigned char CCID_Insertion( void ); +extern unsigned char CCID_Removal( void ); + +/**@}*/ + +#endif /*#ifndef CCID_DRIVER_H */ + + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriverdescriptors.h b/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriverdescriptors.h new file mode 100644 index 00000000..db3bf8fd --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/ccid/cciddriverdescriptors.h @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Title: cciddriverdescriptors.h + * + * \section Purpose + * Definitions of the descriptors required by the ccid device driver. + * DWG_Smart-Card_CCID_Rev110.pdf + * + */ + +#ifndef CCID_DRIVER_DESCRIPTORS_H +#define CCID_DRIVER_DESCRIPTORS_H + +/** \addtogroup usbd_ccid + *@{ + */ + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Constants: Endpoints + * CCID_EPT_DATA_OUT endpoint data out bulk 1 + * CCID_EPT_DATA_IN endpoint data in bulk 2 + * CCID_EPT_NOTIFICATION endpoint data interupt 3 + *------------------------------------------------------------------------------*/ +#define CCID_EPT_DATA_OUT 1 +#define CCID_EPT_DATA_IN 2 +#define CCID_EPT_NOTIFICATION 3 + +/*------------------------------------------------------------------------------ + * USB-ICC protocol + *------------------------------------------------------------------------------*/ +/* CCID specification version 1.10 */ + +#define CCID1_10 0x0110 + +#define SMART_CARD_DEVICE_CLASS 0x0B +/* Smart Card Device Class Descriptor Type */ + +#define CCID_DECRIPTOR_TYPE 0x21 + +/* Table 5.3-1 Summary of CCID Class Specific Request */ + +#define CCIDGenericRequest_ABORT 0x01 +#define CCIDGenericRequest_GET_CLOCK_FREQUENCIES 0x02 +#define CCIDGenericRequest_GET_DATA_RATES 0x03 + +/* 6.1 Command Pipe, Bulk-OUT Messages */ + +#define PC_TO_RDR_ICCPOWERON 0x62 +#define PC_TO_RDR_ICCPOWEROFF 0x63 +#define PC_TO_RDR_GETSLOTSTATUS 0x65 +#define PC_TO_RDR_XFRBLOCK 0x6F +#define PC_TO_RDR_GETPARAMETERS 0x6C +#define PC_TO_RDR_RESETPARAMETERS 0x6D +#define PC_TO_RDR_SETPARAMETERS 0x61 +#define PC_TO_RDR_ESCAPE 0x6B +#define PC_TO_RDR_ICCCLOCK 0x6E +#define PC_TO_RDR_T0APDU 0x6A +#define PC_TO_RDR_SECURE 0x69 +#define PC_TO_RDR_MECHANICAL 0x71 +#define PC_TO_RDR_ABORT 0x72 +#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73 + +/* 6.2 Response Pipe, Bulk-IN Messages */ + +#define RDR_TO_PC_DATABLOCK 0x80 +#define RDR_TO_PC_SLOTSTATUS 0x81 +#define RDR_TO_PC_PARAMETERS 0x82 +#define RDR_TO_PC_ESCAPE 0x83 +#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84 + +/* 6.3 Interrupt-IN Messages */ + +#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50 +#define RDR_TO_PC_HARDWAREERROR 0x51 + +/* Table 6.2-2 Slot error register when bmCommandStatus = 1 */ + +#define CMD_ABORTED 0xFF +#define ICC_MUTE 0xFE +#define XFR_PARITY_ERROR 0xFD +#define XFR_OVERRUN 0xFC +#define HW_ERROR 0xFB +#define BAD_ATR_TS 0xF8 +#define BAD_ATR_TCK 0xF7 +#define ICC_PROTOCOL_NOT_SUPPORTED 0xF6 +#define ICC_CLASS_NOT_SUPPORTED 0xF5 +#define PROCEDURE_BYTE_CONFLICT 0xF4 +#define DEACTIVATED_PROTOCOL 0xF3 +#define BUSY_WITH_AUTO_SEQUENCE 0xF2 +#define PIN_TIMEOUT 0xF0 +#define PIN_CANCELLED 0xEF +#define CMD_SLOT_BUSY 0xE0 +/* User defined 0xC0 to 0x81 */ + +/* Reserved for futur use 0x80 */ + +/* not supported incorrect message parameter 0x7F to 0x01 */ + +/* Command not supported 0x00 */ + + +/* CCID rev 1.1, p.27 */ + +#define VOLTS_AUTO 0x00 +#define VOLTS_5_0 0x01 +#define VOLTS_3_0 0x02 +#define VOLTS_1_8 0x03 + +/* 6.3.1 RDR_to_PC_NotifySlotChange */ + +#define ICC_NOT_PRESENT 0x00 +#define ICC_PRESENT 0x01 +#define ICC_CHANGE 0x02 +#define ICC_INSERTED_EVENT ICC_PRESENT+ICC_CHANGE + +/* ICCD: Table 6.1-8 Bitmap for bStatus field */ + +#define ICC_BS_PRESENT_ACTIVATED 0x00 /* USB-ICC is present and activated */ + +#define ICC_BS_PRESENT_NOTACTIVATED 0x01 /* USB-ICC is present but not activated */ + +#define ICC_BS_NOTPRESENT 0x02 /* USB-ICC is virtually not present */ + +#define ICC_BS_RFU 0x03 /* RFU */ + +#define ICC_CS_NO_ERROR (0x00<<6) /* Processed without error */ + +#define ICC_CS_FAILED (0x01<<6) /* Failed, error condition given by bError */ + +#define ICC_CS_TIME_EXT (0x02<<6) /* Time extension is requested */ + +#define ICC_CS_RFU (0x03<<6) /* RFU */ + + +/* + * #define NO_ERROR 0x00 + * #define NO_EXTRA_BYTES 0x00 + * #define CCID_FLAG_INITIAL_VALUE 0x05 + * #define CCID_EVENT_SIZE 0x02 + * #define STATUS_MASK 0x41 + */ +/*------------------------------------------------------------------------------ + * Structures + *------------------------------------------------------------------------------*/ + +/**@}*/ + +#endif /*#ifndef CCID_DRIVER_DESCRIPTORS_H */ + + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerial.c b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerial.c new file mode 100644 index 00000000..1b72d63f --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerial.c @@ -0,0 +1,237 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * Implementation of a single CDC serial port function for USB device. + */ + +/** \addtogroup usbd_cdc + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "CDCDSerial.h" + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/** Serial Port instance list */ +static CDCDSerialPort cdcdSerial; + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/** + * USB CDC Serial Port Event Handler. + * \param event Event code. + * \param param Event parameter. + */ +static uint32_t CDCDSerial_EventHandler(uint32_t event, + uint32_t param) +{ + switch (event) { + case CDCDSerialPortEvent_SETCONTROLLINESTATE: + { + if (CDCDSerial_ControlLineStateChanged) { + CDCDSerial_ControlLineStateChanged( + (param & CDCControlLineState_DTR) > 0, + (param & CDCControlLineState_RTS) > 0); + } + } + break; + case CDCDSerialPortEvent_SETLINECODING: + { + if (CDCDSerial_LineCodingIsToChange) { + event = CDCDSerial_LineCodingIsToChange( + (CDCLineCoding*)param); + if (event != USBRC_SUCCESS) + return event; + } + } + break; + default: + return USBRC_SUCCESS; + } + + return USBRC_SUCCESS; +} + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes the USB Device CDC serial driver & USBD Driver. + * \param pUsbd Pointer to USBDDriver instance. + * \param bInterfaceNb Interface number for the function. + */ +void CDCDSerial_Initialize( + USBDDriver *pUsbd, uint8_t bInterfaceNb) +{ + CDCDSerialPort *pCdcd = &cdcdSerial; + + TRACE_INFO("CDCDSerial_Initialize\n\r"); + + /* Initialize serial port function */ + CDCDSerialPort_Initialize( + pCdcd, pUsbd, + (CDCDSerialPortEventHandler)CDCDSerial_EventHandler, + 0, + bInterfaceNb, 2); +} + +/** + * Invoked whenever the device is changed by the + * host. + * \pDescriptors Pointer to the descriptors for function configure. + * \wLength Length of descriptors in number of bytes. + */ +void CDCDSerial_ConfigureFunction(USBGenericDescriptor *pDescriptors, + uint16_t wLength) +{ + CDCDSerialPort *pCdcd = &cdcdSerial; + CDCDSerialPort_ParseInterfaces(pCdcd, + (USBGenericDescriptor*)pDescriptors, + wLength); +} + +/** + * Handles CDC-specific SETUP requests. Should be called from a + * re-implementation of USBDCallbacks_RequestReceived() method. + * \param request Pointer to a USBGenericRequest instance. + */ +uint32_t CDCDSerial_RequestHandler(const USBGenericRequest *request) +{ + CDCDSerialPort * pCdcd = &cdcdSerial; + + TRACE_INFO_WP("Cdcf "); + return CDCDSerialPort_RequestHandler(pCdcd, request); +} + +/** + * Receives data from the host through the virtual COM port created by + * the CDC device serial driver. This function behaves like USBD_Read. + * \param data Pointer to the data buffer to put received data. + * \param size Size of the data buffer in bytes. + * \param callback Optional callback function to invoke when the transfer + * finishes. + * \param argument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +uint32_t CDCDSerial_Read(void *data, + uint32_t size, + TransferCallback callback, + void *argument) +{ + CDCDSerialPort * pCdcd = &cdcdSerial; + return CDCDSerialPort_Read(pCdcd, data, size, callback, argument); +} + +/** + * Sends a data buffer through the virtual COM port created by the CDC + * device serial driver. This function behaves exactly like USBD_Write. + * \param data Pointer to the data buffer to send. + * \param size Size of the data buffer in bytes. + * \param callback Optional callback function to invoke when the transfer + * finishes. + * \param argument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +uint32_t CDCDSerial_Write(void *data, + uint32_t size, + TransferCallback callback, + void *argument) +{ + CDCDSerialPort * pCdcd = &cdcdSerial; + return CDCDSerialPort_Write(pCdcd, data, size, callback, argument); +} + +/** + * Returns the current control line state of the RS-232 line. + */ +uint8_t CDCDSerial_GetControlLineState(void) +{ + CDCDSerialPort * pCdcd = &cdcdSerial; + return CDCDSerialPort_GetControlLineState(pCdcd); +} + +/** + * Copy current line coding settings to pointered space. + * \param pLineCoding Pointer to CDCLineCoding instance. + */ +void CDCDSerial_GetLineCoding(CDCLineCoding* pLineCoding) +{ + CDCDSerialPort * pCdcd = &cdcdSerial; + CDCDSerialPort_GetLineCoding(pCdcd, pLineCoding); +} + +/** + * Returns the current status of the RS-232 line. + */ +uint16_t CDCDSerial_GetSerialState(void) +{ + CDCDSerialPort * pCdcd = &cdcdSerial; + return CDCDSerialPort_GetSerialState(pCdcd); +} + +/** + * Sets the current serial state of the device to the given value. + * \param serialState New device state. + */ +void CDCDSerial_SetSerialState(uint16_t serialState) +{ + CDCDSerialPort * pCdcd = &cdcdSerial; + CDCDSerialPort_SetSerialState(pCdcd, serialState); +} + +WEAK uint8_t CDCDSerial_LineCodingIsToChange(CDCLineCoding * pLineCoding) +{ + /* Nothing to do */ +} + +WEAK void CDCDSerial_ControlLineStateChanged(uint8_t DTR,uint8_t RTS) +{ + /* Nothing to do */ +} +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialDriver.c new file mode 100644 index 00000000..b96ce856 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialDriver.c @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * Title: CDCDSerialDriver implementation + * + * About: Purpose + * Implementation of the CDCDSerialDriver class methods. + */ + +/** \addtogroup usbd_cdc + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "CDCDSerialDriver.h" + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes the USB Device CDC serial driver & USBD Driver. + * \param pDescriptors Pointer to Descriptors list for CDC Serial Device. + */ +void CDCDSerialDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Initialize the standard driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + 0); /* Multiple settings for interfaces not supported */ + + CDCDSerial_Initialize(pUsbd, CDCDSerialDriver_CC_INTERFACE); + + /* Initialize the USB driver */ + USBD_Init(); +} + +/** + * Invoked whenever the active configuration of device is changed by the + * host. + * \param cfgnum Configuration number. + */ +void CDCDSerialDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBConfigurationDescriptor *pDesc; + if (cfgnum) { + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + CDCDSerial_ConfigureFunction((USBGenericDescriptor *)pDesc, + pDesc->wTotalLength); + } +} + +/** + * Handles CDC-specific SETUP requests. Should be called from a + * re-implementation of USBDCallbacks_RequestReceived() method. + * \param request Pointer to a USBGenericRequest instance. + */ +void CDCDSerialDriver_RequestHandler(const USBGenericRequest *request) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + TRACE_INFO_WP("NewReq "); + if (CDCDSerial_RequestHandler(request)) + USBDDriver_RequestHandler(pUsbd, request); +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialDriver_Callbacks.c b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialDriver_Callbacks.c new file mode 100644 index 00000000..8821d04d --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialDriver_Callbacks.c @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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 + *---------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 + by working group ISO/IEC JTC1/SC22/WG14. */ +#include + +#include "CDCDSerialDriver.h" + +/*--------------------------------------------------------------------------- + * Default callback functions + *---------------------------------------------------------------------------*/ + +/** + * Invoked when the CDC LineCoding is requested to changed + * \param port Port number. + * \param pLineCoding Pointer to new LineCoding settings. + */ +extern WEAK uint8_t CDCDSerialDriver_LineCodingIsToChange( + CDCLineCoding * pLineCoding) +{ + /* Accept any of linecoding settings */ + return USBD_STATUS_SUCCESS; +} + +/** + * Invoked when the CDC ControlLineState is changed + * \param port Port number. + * \param DTR New DTR value. + * \param RTS New RTS value. + */ +extern WEAK void CDCDSerialDriver_ControlLineStateChanged(uint8_t DTR, + uint8_t RTS) +{ + /* Do nothing */ +} + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialPort.c b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialPort.c new file mode 100644 index 00000000..e2b188a1 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCDSerialPort.c @@ -0,0 +1,455 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * Implementation of the CDCDSerialPort class methods. + */ + +/** \addtogroup usbd_cdc + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** Parse data extention for descriptor parsing */ +typedef struct _CDCDParseData { + /** Pointer to CDCDSerialPort instance */ + CDCDSerialPort * pCdcd; + /** Pointer to found interface descriptor */ + USBInterfaceDescriptor * pIfDesc; + +} CDCDParseData; + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/** Line coding values */ +static CDCLineCoding lineCoding; + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/** + * Parse descriptors: Interface, Bulk IN/OUT, Interrupt IN. + * \param desc Pointer to descriptor list. + * \param arg Argument, pointer to AUDDParseData instance. + */ +static uint32_t _Interfaces_Parse(USBGenericDescriptor *pDesc, + CDCDParseData * pArg) +{ + CDCDSerialPort *pCdcd = pArg->pCdcd; + + /* Not a valid descriptor */ + if (pDesc->bLength == 0) + return USBRC_PARAM_ERR; + + /* Find interface descriptor */ + if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) { + USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor*)pDesc; + + /* Obtain interface from descriptor */ + if (pCdcd->bInterfaceNdx == 0xFF) { + /* First interface is communication */ + if (pIf->bInterfaceClass == + CDCCommunicationInterfaceDescriptor_CLASS) { + pCdcd->bInterfaceNdx = pIf->bInterfaceNumber; + pCdcd->bNumInterface = 2; + } + /* Only data interface */ + else if(pIf->bInterfaceClass == CDCDataInterfaceDescriptor_CLASS) { + pCdcd->bInterfaceNdx = pIf->bInterfaceNumber; + pCdcd->bNumInterface = 1; + } + pArg->pIfDesc = pIf; + } + else if (pCdcd->bInterfaceNdx <= pIf->bInterfaceNumber + && pCdcd->bInterfaceNdx + pCdcd->bNumInterface + > pIf->bInterfaceNumber) { + pArg->pIfDesc = pIf; + } + } + + /* Parse valid interfaces */ + if (pArg->pIfDesc == 0) + return 0; + + /* Find endpoint descriptors */ + if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) { + USBEndpointDescriptor *pEp = (USBEndpointDescriptor*)pDesc; + switch(pEp->bmAttributes & 0x3) { + case USBEndpointDescriptor_INTERRUPT: + if (pEp->bEndpointAddress & 0x80) + pCdcd->bIntInPIPE = pEp->bEndpointAddress & 0x7F; + break; + case USBEndpointDescriptor_BULK: + if (pEp->bEndpointAddress & 0x80) + pCdcd->bBulkInPIPE = pEp->bEndpointAddress & 0x7F; + else + pCdcd->bBulkOutPIPE = pEp->bEndpointAddress; + } + } + + if ( pCdcd->bInterfaceNdx != 0xFF + && pCdcd->bBulkInPIPE != 0 + && pCdcd->bBulkOutPIPE != 0) + return USBRC_FINISHED; + + return 0; +} + +/** + * 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. + * \param pCdcd Pointer to CDCDSerialPort instance. + */ +static void _SetLineCodingCallback(CDCDSerialPort * pCdcd) +{ + uint32_t exec = 1; + if (pCdcd->fEventHandler) { + uint32_t rc = pCdcd->fEventHandler( + CDCDSerialPortEvent_SETLINECODING, + (uint32_t)(&lineCoding), + pCdcd->pArg); + if (rc == USBD_STATUS_SUCCESS) { + pCdcd->lineCoding.dwDTERate = lineCoding.dwDTERate; + pCdcd->lineCoding.bCharFormat = lineCoding.bCharFormat; + pCdcd->lineCoding.bParityType = lineCoding.bParityType; + pCdcd->lineCoding.bDataBits = lineCoding.bDataBits; + } + else + exec = 0; + } + if (exec) USBD_Write(0, 0, 0, 0, 0); + else USBD_Stall(0); +} + +/** + * Receives new line coding information from the USB host. + * \param pCdcd Pointer to CDCDSerialPort instance. + */ +static void _SetLineCoding(CDCDSerialPort * pCdcd) +{ + TRACE_INFO_WP("sLineCoding "); + + USBD_Read(0, + (void *) & (lineCoding), + sizeof(CDCLineCoding), + (TransferCallback)_SetLineCodingCallback, + (void*)pCdcd); +} + +/** + * Sends the current line coding information to the host through Control + * endpoint 0. + * \param pCdcd Pointer to CDCDSerialPort instance. + */ +static void _GetLineCoding(CDCDSerialPort * pCdcd) +{ + TRACE_INFO_WP("gLineCoding "); + + USBD_Write(0, + (void *) &(pCdcd->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 pCdcd Pointer to CDCDSerialPort instance. + * \param request Pointer to a USBGenericRequest instance. + */ +static void _SetControlLineState( + CDCDSerialPort * pCdcd, + const USBGenericRequest *request) +{ + uint8_t DTR, RTS; + + DTR = ((request->wValue & CDCControlLineState_DTR) > 0); + RTS = ((request->wValue & CDCControlLineState_RTS) > 0); + TRACE_INFO_WP("sControlLineState(%d, %d) ", DTR, RTS); + + pCdcd->bControlLineState = (uint8_t)request->wValue; + USBD_Write(0, 0, 0, 0, 0); + + if (pCdcd->fEventHandler) + pCdcd->fEventHandler(CDCDSerialPortEvent_SETCONTROLLINESTATE, + (uint32_t)pCdcd->bControlLineState, + pCdcd->pArg); +} + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes the USB Device CDC serial port function. + * \param pCdcd Pointer to CDCDSerialPort instance. + * \param pUsbd Pointer to USBDDriver instance. + * \param fEventHandler Pointer to event handler function. + * \param firstInterface First interface index for the function + * (0xFF to parse from descriptors). + * \param numInterface Number of interfaces for the function. + */ +void CDCDSerialPort_Initialize(CDCDSerialPort * pCdcd, + USBDDriver * pUsbd, + CDCDSerialPortEventHandler fEventHandler, + void * pArg, + uint8_t firstInterface,uint8_t numInterface) +{ + TRACE_INFO("CDCDSerialPort_Initialize\n\r"); + + /* Initialize event handler */ + pCdcd->fEventHandler = fEventHandler; + pCdcd->pArg = pArg; + + /* Initialize USB Device Driver interface */ + pCdcd->pUsbd = pUsbd; + pCdcd->bInterfaceNdx = firstInterface; + pCdcd->bNumInterface = numInterface; + pCdcd->bIntInPIPE = 0; + pCdcd->bBulkInPIPE = 0; + pCdcd->bBulkOutPIPE = 0; + + /* Initialize Abstract Control Model attributes */ + pCdcd->bControlLineState = 0; + pCdcd->wSerialState = 0; + CDCLineCoding_Initialize(&(pCdcd->lineCoding), + 115200, + CDCLineCoding_ONESTOPBIT, + CDCLineCoding_NOPARITY, + 8); +} + +/** + * Parse CDC Serial Port information for CDCDSerialPort instance. + * Accepted interfaces: + * - Communication Interface + Data Interface + * - Data Interface ONLY + * \param pCdcd Pointer to CDCDSerialPort instance. + * \param pDescriptors Pointer to descriptor list. + * \param dwLength Descriptor list size in bytes. + */ +USBGenericDescriptor *CDCDSerialPort_ParseInterfaces( + CDCDSerialPort *pCdcd, + USBGenericDescriptor *pDescriptors, + uint32_t dwLength) +{ + CDCDParseData parseData; + + parseData.pCdcd = pCdcd; + parseData.pIfDesc = 0; + + return USBGenericDescriptor_Parse( + pDescriptors, dwLength, + (USBDescriptorParseFunction)_Interfaces_Parse, + &parseData); +} + + +/** + * Handles CDC-specific SETUP requests. Should be called from a + * re-implementation of USBDCallbacks_RequestReceived() method. + * \param pCdcd Pointer to CDCDSerialPort instance. + * \param request Pointer to a USBGenericRequest instance. + * \return USBRC_SUCCESS if request handled, otherwise error. + */ +uint32_t CDCDSerialPort_RequestHandler( + CDCDSerialPort *pCdcd, + const USBGenericRequest *request) +{ + if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS) + return USBRC_PARAM_ERR; + + TRACE_INFO_WP("Cdcs "); + + /* Validate interface */ + if (request->wIndex >= pCdcd->bInterfaceNdx && + request->wIndex < pCdcd->bInterfaceNdx + pCdcd->bNumInterface) { + } + else { + return USBRC_PARAM_ERR; + } + + /* Handle the request */ + switch (USBGenericRequest_GetRequest(request)) { + + case CDCGenericRequest_SETLINECODING: + + _SetLineCoding(pCdcd); + break; + + case CDCGenericRequest_GETLINECODING: + + _GetLineCoding(pCdcd); + break; + + case CDCGenericRequest_SETCONTROLLINESTATE: + + _SetControlLineState(pCdcd, request); + break; + + default: + + return USBRC_PARAM_ERR; + } + + return USBRC_SUCCESS; +} + +/** + * Receives data from the host through the virtual COM port created by + * the CDC device serial driver. This function behaves like USBD_Read. + * \param pCdcd Pointer to CDCDSerialPort instance. + * \param pData Pointer to the data buffer to put received data. + * \param dwSize Size of the data buffer in bytes. + * \param fCallback Optional callback function to invoke when the transfer + * finishes. + * \param pArg Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +uint32_t CDCDSerialPort_Read(const CDCDSerialPort * pCdcd, + void * pData,uint32_t dwSize, + TransferCallback fCallback,void * pArg) +{ + if (pCdcd->bBulkOutPIPE == 0) + return USBRC_PARAM_ERR; + + return USBD_Read(pCdcd->bBulkOutPIPE, + pData, dwSize, + fCallback, pArg); +} + +/** + * Sends a data buffer through the virtual COM port created by the CDC + * device serial driver. This function behaves exactly like USBD_Write. + * \param pCdcd Pointer to CDCDSerialPort instance. + * \param pData Pointer to the data buffer to send. + * \param dwSize Size of the data buffer in bytes. + * \param fCallback Optional callback function to invoke when the transfer + * finishes. + * \param pArg Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +uint32_t CDCDSerialPort_Write(const CDCDSerialPort * pCdcd, + void * pData, uint32_t dwSize, + TransferCallback fCallback, void * pArg) +{ + if (pCdcd->bBulkInPIPE == 0) + return USBRC_PARAM_ERR; + + return USBD_Write(pCdcd->bBulkInPIPE, + pData, dwSize, + fCallback, pArg); +} + +/** + * Returns the current control line state of the RS-232 line. + * \param pCdcd Pointer to CDCDSerialPort instance. + */ +uint8_t CDCDSerialPort_GetControlLineState(const CDCDSerialPort * pCdcd) +{ + return pCdcd->bControlLineState; +} + +/** + * Copy current line coding settings to pointered space. + * \param pCdcd Pointer to CDCDSerialPort instance. + * \param pLineCoding Pointer to CDCLineCoding instance. + */ +void CDCDSerialPort_GetLineCoding(const CDCDSerialPort * pCdcd, + CDCLineCoding* pLineCoding) +{ + if (pLineCoding) { + pLineCoding->dwDTERate = pCdcd->lineCoding.dwDTERate; + pLineCoding->bCharFormat = pCdcd->lineCoding.bCharFormat; + pLineCoding->bParityType = pCdcd->lineCoding.bParityType; + pLineCoding->bDataBits = pCdcd->lineCoding.bDataBits; + } +} + +/** + * Returns the current status of the RS-232 line. + * \param pCdcd Pointer to CDCDSerialPort instance. + */ +uint16_t CDCDSerialPort_GetSerialState(const CDCDSerialPort * pCdcd) +{ + return pCdcd->wSerialState; +} + +/** + * Sets the current serial state of the device to the given value. + * \param pCdcd Pointer to CDCDSerialPort instance. + * \param wSerialState New device state. + */ +void CDCDSerialPort_SetSerialState(CDCDSerialPort * pCdcd, + uint16_t wSerialState) +{ + if (pCdcd->bIntInPIPE == 0) + return; + + /* If new state is different from previous one, send a notification to the + host */ + if (pCdcd->wSerialState != wSerialState) { + + pCdcd->wSerialState = wSerialState; + USBD_Write(pCdcd->bIntInPIPE, + &(pCdcd->wSerialState), + 2, + 0, + 0); + + /* Reset one-time flags */ + pCdcd->wSerialState &= ~(CDCSerialState_OVERRUN + | CDCSerialState_PARITY + | CDCSerialState_FRAMING + | CDCSerialState_RINGSIGNAL + | CDCSerialState_BREAK); + } +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCarchitecture.png b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCarchitecture.png new file mode 100644 index 00000000..9d0e9243 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/CDCarchitecture.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/USB-SerialConverter.png b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/USB-SerialConverter.png new file mode 100644 index 00000000..bc05c1fc Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/USB-SerialConverter.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/drv/6119.inf b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/drv/6119.inf new file mode 100644 index 00000000..04ced2fa --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/cdc-serial/drv/6119.inf @@ -0,0 +1,45 @@ +; $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_6119 ; Identifies a device with ATMEL Vendor ID (03EBh) and + ; Product ID equal to 6119h. Corresponding Install section + ; is named USBtoSer.Install + +[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 Serial Driver" ; String value for the USBSer symbol \ No newline at end of file diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/AUDDFunction.c b/sam3s_example/atmel_softpack_libraries/usb/device/composite/AUDDFunction.c new file mode 100644 index 00000000..9a3ebea4 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/composite/AUDDFunction.c @@ -0,0 +1,235 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ +/** \file */ + +/** \addtogroup usbd_aud_fun + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include +#include + +#include + +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Internal types + *----------------------------------------------------------------------------*/ + +/** + * \brief Audio speaker driver struct. + */ +typedef struct _AUDDFunction { + /** Speaker & Phone function */ + AUDDSpeakerPhone drv; + /** Stream instance for speaker */ + AUDDStream speaker; + /** Stream instance for microphone */ + AUDDStream mic; +} AUDDFunction; + +/*---------------------------------------------------------------------------- + * Internal variables + *----------------------------------------------------------------------------*/ + +/** Global USB audio function driver instance. */ +static AUDDFunction auddFunction; + +/*---------------------------------------------------------------------------- + * Internal functions + *----------------------------------------------------------------------------*/ + +/** + * Callback triggerred after the mute or volume status of the channel has been + * changed. + * \param ec Event code. + * \param channel Channel number. + * \param pArg Pointer to AUDDStream instance. + */ +static void AUDDFunction_EventCallback(uint32_t ec, + uint8_t channel, + AUDDStream *pArg) +{ + AUDDFunction *pAudf = &auddFunction; + uint8_t mic = ((uint32_t)pArg == (uint32_t)(&pAudf->mic)); + if (ec == AUDD_EC_MuteChanged) { + if (AUDDFunction_MuteChanged) + AUDDFunction_MuteChanged(mic, channel, pArg->bmMute); + } + else if (ec == AUDD_EC_VolumeChanged) { + /* Not supported now */ + } +} + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/** + * Initializes an USB audio speaker device driver, as well as the underlying + * USB controller. + */ +void AUDDFunction_Initialize(USBDDriver *pUsbd, uint8_t bInterface) +{ + AUDDFunction *pAudf = &auddFunction; + AUDDSpeakerPhone *pDrv = &pAudf->drv; + AUDDStream *pSpk = &pAudf->speaker; + AUDDStream *pMic = &pAudf->mic; + + /* 0: Speaker */ + AUDDSpeakerPhone_InitializeStream( + pSpk, AUDDFunction_MaxNumSpeakerChannels, 0, + (AUDDStreamEventCallback)AUDDFunction_EventCallback, + (void*)pSpk); + /* 1: Mic */ + AUDDSpeakerPhone_InitializeStream( + pMic, AUDDFunction_MaxNumMicrophoneChannels, 0, + (AUDDStreamEventCallback)AUDDFunction_EventCallback, + (void*)pMic); + /* Audio Driver initialize */ + AUDDSpeakerPhone_Initialize(pDrv, pUsbd, pSpk, pMic); + +} + +/** + * Configure function with expected descriptors and start functionality. + * Usually invoked when device is configured. + * \pDescriptors Pointer to the descriptors for function configure. + * \wLength Length of descriptors in number of bytes. + */ +void AUDDFunction_Configure(USBGenericDescriptor *pDescriptors, + uint16_t wLength) +{ + AUDDFunction *pAudf = &auddFunction; + AUDDSpeakerPhone *pDrv = &pAudf->drv; + AUDDSpeakerPhone_ParseInterfaces(pDrv, pDescriptors, wLength); +} + +/** + * 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 AUDDFunction_InterfaceSettingChangedHandler(uint8_t interface, + uint8_t setting) +{ + AUDDFunction *pAudf = &auddFunction; + AUDDSpeakerPhone *pDrv = &pAudf->drv; + if (setting == 0) AUDDSpeakerPhone_CloseStream(pDrv, interface); + if (AUDDFunction_StreamSettingChanged) { + uint8_t mic = (interface == pDrv->pMicrophone->bAsInterface); + AUDDFunction_StreamSettingChanged(mic, setting); + } +} + +/** + * Handles AUDIO-specific USB requests sent by the host + * \param request Pointer to a USBGenericRequest instance. + * \return USBRC_SUCCESS if request is handled. + */ +uint32_t AUDDFunction_RequestHandler( + const USBGenericRequest *request) +{ + AUDDFunction *pAudf = &auddFunction; + AUDDSpeakerPhone *pDrv = &pAudf->drv; + return AUDDSpeakerPhone_RequestHandler(pDrv, request); +} + +/** + * 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. + */ +uint8_t AUDDFunction_Read(void *buffer, + uint32_t length, + TransferCallback callback, + void *argument) +{ + AUDDFunction *pAudf = &auddFunction; + AUDDSpeakerPhone *pDrv = &pAudf->drv; + return AUDDSpeakerPhone_Read(pDrv, buffer, length, callback, argument); +} + +/** + * Initialize Frame List for sending audio data. + * + * \param pListInit Pointer to the allocated list for audio write. + * \param pDmaInit Pointer to the allocated DMA descriptors for autio write + * (if DMA supported). + * \param listSize Circular list size. + * \param delaySize Start transfer after delaySize frames filled in. + * \param callback Optional callback function for transfer. + * \param argument Optional callback argument. + * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code. + */ +uint8_t AUDDFunction_SetupWrite(void * pListInit, + void * pDmaInit, + uint16_t listSize, + uint16_t delaySize, + TransferCallback callback, + void * argument) +{ + AUDDFunction *pAudf = &auddFunction; + AUDDSpeakerPhone *pDrv = &pAudf->drv; + return AUDDSpeakerPhone_SetupWrite(pDrv, + pListInit, pDmaInit, listSize, delaySize, + callback, argument); +} + +/** + * Add frame buffer to audio sending list. + * \buffer Pointer to data frame to send. + * \length Frame size in bytes. + * \return USBD_STATUS_SUCCESS if the transfer is started successfully; + * otherwise an error code. + */ +uint8_t AUDDFunction_Write(void* buffer, uint16_t length) +{ + AUDDFunction *pAudf = &auddFunction; + AUDDSpeakerPhone *pDrv = &pAudf->drv; + return AUDDSpeakerPhone_Write(pDrv, buffer, length); +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCAUDDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCAUDDDriver.c new file mode 100644 index 00000000..c146052d --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCAUDDDriver.c @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \addtogroup usbd_composite_cdcaud + *@{ + */ +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include + +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Defines + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal variables + *---------------------------------------------------------------------------*/ + +/** Array for storing the current setting of each interface */ +static uint8_t bAltInterfaces[CDCAUDDDriverDescriptors_MaxNumInterfaces]; + +/*--------------------------------------------------------------------------- + * Internal functions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/** + * Initializes the USB device composite device driver. + */ +void CDCAUDDDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Initialize the standard USB driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + bAltInterfaces); + + /* CDC */ + CDCDSerial_Initialize(pUsbd, CDCAUDDDriverDescriptors_CDC_INTERFACE); + /* Audio */ + AUDDFunction_Initialize(pUsbd, CDCAUDDDriverDescriptors_AUD_INTERFACE); + + /* Initialize the USB driver */ + USBD_Init(); +} + +/** + * Invoked whenever the configuration value of a device is changed by the host + * \param cfgnum Configuration number. + */ +void CDCAUDDDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBConfigurationDescriptor *pDesc; + if (cfgnum > 0) { + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + /* CDC */ + CDCDSerial_ConfigureFunction((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + /* AUD */ + AUDDFunction_Configure((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * 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 CDCAUDDDriver_InterfaceSettingChangedHandler(uint8_t interface, + uint8_t setting) +{ + AUDDFunction_InterfaceSettingChangedHandler(interface, setting); +} + +/** + * 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 CDCAUDDDriver_RequestHandler(const USBGenericRequest *request) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + TRACE_INFO_WP("NewReq "); + + if (CDCDSerial_RequestHandler(request) == USBRC_SUCCESS) + return; + + if (AUDDFunction_RequestHandler(request) == USBRC_SUCCESS) + return; + + USBDDriver_RequestHandler(pUsbd, request); +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCHIDDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCHIDDDriver.c new file mode 100644 index 00000000..45509432 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCHIDDDriver.c @@ -0,0 +1,138 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \addtogroup usbd_composite_cdchid + *@{ + */ +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include + +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Defines + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal variables + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal functions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/** + * Initializes the USB device composite device driver. + */ +void CDCHIDDDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Initialize the standard USB driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + 0); + + /* CDC */ + CDCDSerial_Initialize(pUsbd, CDCHIDDDriverDescriptors_CDC_INTERFACE); + /* HID */ + HIDDKeyboard_Initialize(pUsbd, CDCHIDDDriverDescriptors_HID_INTERFACE); + + /* Initialize the USB driver */ + USBD_Init(); +} + +/** + * Invoked whenever the configuration value of a device is changed by the host + * \param cfgnum Configuration number. + */ +void CDCHIDDDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBConfigurationDescriptor *pDesc; + if (cfgnum > 0) { + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + /* CDC */ + CDCDSerial_ConfigureFunction((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + /* HID */ + HIDDKeyboard_ConfigureFunction((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * 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) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + TRACE_INFO_WP("NewReq "); + + if (CDCDSerial_RequestHandler(request) == USBRC_SUCCESS) + return; + + if (HIDDKeyboard_RequestHandler(request) == USBRC_SUCCESS) + return; + + USBDDriver_RequestHandler(pUsbd, request); +} + +/** + * Starts a remote wake-up sequence if the host has explicitely enabled it + * by sending the appropriate SET_FEATURE request. + */ +void CDCHIDDDriver_RemoteWakeUp(void) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Remote wake-up has been enabled */ + if (USBDDriver_IsRemoteWakeUpEnabled(pUsbd)) { + + USBD_RemoteWakeUp(); + } +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCMSDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCMSDDriver.c new file mode 100644 index 00000000..55fe6fb5 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/composite/CDCMSDDriver.c @@ -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. + * ---------------------------------------------------------------------------- + */ +/** \file */ +/** \addtogroup usbd_composite_cdcmsd + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include + +#include + +#include +#include + +/*--------------------------------------------------------------------------- + * Defines + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal variables + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal functions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/** + * Initializes the USB device CDCMSD device driver. + */ +void CDCMSDDriver_Initialize( + const USBDDriverDescriptors *pDescriptors, + MSDLun *pLuns, unsigned char numLuns) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Initialize the standard USB driver */ + USBDDriver_Initialize(pUsbd, pDescriptors, 0); + + /* CDC */ + CDCDSerial_Initialize(pUsbd, CDCMSDDriverDescriptors_CDC_INTERFACE); + + /* MSD */ + MSDFunction_Initialize(pUsbd, CDCMSDDriverDescriptors_MSD_INTERFACE, + pLuns, numLuns); + + /* Initialize the USB driver */ + USBD_Init(); +} + +/** + * Invoked whenever the configuration value of a device is changed by the host + * \param cfgnum Configuration number. + */ +void CDCMSDDriver_ConfigurationChangedHandler(unsigned char cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBConfigurationDescriptor *pDesc; + if (cfgnum > 0) { + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + /* CDC */ + CDCDSerial_ConfigureFunction((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + /* MSD */ + MSDFunction_Configure((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * 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 CDCMSDDriver_RequestHandler(const USBGenericRequest *request) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + TRACE_INFO_WP("NewReq "); + + if (CDCDSerial_RequestHandler(request) == USBRC_SUCCESS) + return; + + if (MSDFunction_RequestHandler(request) == USBRC_SUCCESS) + return; + + USBDDriver_RequestHandler(pUsbd, request); +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/DUALCDCDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/composite/DUALCDCDDriver.c new file mode 100644 index 00000000..7b441997 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/composite/DUALCDCDDriver.c @@ -0,0 +1,194 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ +/** \file */ +/** \addtogroup usbd_composite_cdccdc + *@{ + */ +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +/* GENERAL */ +#include + +/* USB */ +#include +#include +#include + +/* - DUALCDC */ +#include + +/*--------------------------------------------------------------------------- + * Defines + *---------------------------------------------------------------------------*/ + +/** Number of CDC serial ports */ +#define NUM_PORTS 2 + +/** Interface setting spaces (4 byte aligned) */ +#define NUM_INTERFACES ((DUALCDCDDriverDescriptors_NUMINTERFACE+3)&0xFC) + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/** Dual-CDC-Serial device driver struct */ +typedef struct _DualCdcdSerialDriver { + /** CDC Serial Port List */ + CDCDSerialPort cdcdSerialPort[NUM_PORTS]; +} DualCdcdSerialDriver; + +/*--------------------------------------------------------------------------- + * Internal variables + *---------------------------------------------------------------------------*/ + +/** Dual CDC Serial device driver instance */ +DualCdcdSerialDriver dualcdcdDriver; + +/*--------------------------------------------------------------------------- + * Internal functions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/** + * Initializes the USB device composite device driver. + * \param pDescriptors Pointer to Descriptors list for CDC Serial Device. + */ +void DUALCDCDDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + CDCDSerialPort *pCdcd = &dualcdcdDriver.cdcdSerialPort[0]; + + TRACE_INFO("DUALCDCDDriver_Initialize\n\r"); + + pCdcd = &dualcdcdDriver.cdcdSerialPort[0]; + CDCDSerialPort_Initialize(pCdcd, pUsbd, + 0, + 0, + DUALCDCDDriverDescriptors_INTERFACENUM0, 2); + + pCdcd = &dualcdcdDriver.cdcdSerialPort[1]; + CDCDSerialPort_Initialize(pCdcd, pUsbd, + 0, + 0, + DUALCDCDDriverDescriptors_INTERFACENUM1, 2); + + /* Initialize the standard USB driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + 0); + /* Initialize the USB driver */ + USBD_Init(); +} + +/** + * Invoked whenever the active configuration of device is changed by the + * host. + * \param cfgnum Configuration number. + */ +void DUALCDCDDriver_ConfigurationChangeHandler(uint8_t cfgnum) +{ + CDCDSerialPort *pCdcd = &dualcdcdDriver.cdcdSerialPort[0]; + USBDDriver *pUsbd = pCdcd->pUsbd; + USBConfigurationDescriptor *pDesc; + USBGenericDescriptor *pD; + uint32_t i, len; + + if (cfgnum > 0) { + + /* Parse endpoints for data & notification */ + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + + pD = (USBGenericDescriptor *)pDesc; + len = pDesc->wTotalLength; + + for (i = 0; i < NUM_PORTS; i ++) { + pCdcd = &dualcdcdDriver.cdcdSerialPort[i]; + pD = CDCDSerialPort_ParseInterfaces(pCdcd, pD, len); + len = pDesc->wTotalLength - ((uint32_t)pD - (uint32_t)pDesc); + } + } +} + + +/** + * 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) +{ + CDCDSerialPort *pCdcd = 0; + USBDDriver *pUsbd = 0; + uint32_t rc, i; + + TRACE_INFO_WP("NewReq "); + + for (i = 0; i < NUM_PORTS; i ++) { + pCdcd = &dualcdcdDriver.cdcdSerialPort[i]; + rc = CDCDSerialPort_RequestHandler(pCdcd, request); + if (rc == USBRC_SUCCESS) + break; + } + + /* Not handled by CDC Serial */ + if (rc != USBRC_SUCCESS) { + if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) { + pUsbd = pCdcd->pUsbd; + USBDDriver_RequestHandler(pUsbd, request); + } + else { + TRACE_WARNING( + "DUALCDCDDriver_RequestHandler: Unsupported request (%d,%d)\n\r", + USBGenericRequest_GetType(request), + USBGenericRequest_GetRequest(request)); + USBD_Stall(0); + } + } + +} + +/** + * Return CDCDSerialPort for serial port operations. + * \param port Port number. + */ +CDCDSerialPort *DUALCDCDDriver_GetSerialPort(uint32_t port) +{ + if (port < NUM_PORTS) + return &dualcdcdDriver.cdcdSerialPort[port]; + + return 0; +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/HIDAUDDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/composite/HIDAUDDDriver.c new file mode 100644 index 00000000..95d56258 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/composite/HIDAUDDDriver.c @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \addtogroup usbd_composite_hidaud + *@{ + */ +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include + +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Defines + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal variables + *---------------------------------------------------------------------------*/ + +/** Array for storing the current setting of each interface */ +static uint8_t bAltInterfaces[HIDAUDDDriverDescriptors_NUMINTERFACE]; + +/*--------------------------------------------------------------------------- + * Internal functions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/** + * Initializes the USB device composite device driver. + */ +void HIDAUDDDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Initialize the standard USB driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + bAltInterfaces); + + /* HID */ + HIDDKeyboard_Initialize(pUsbd, HIDAUDDDriverDescriptors_HID_INTERFACE); + /* Audio */ + AUDDFunction_Initialize(pUsbd, HIDAUDDDriverDescriptors_AUD_INTERFACE); + + /* Initialize the USB driver */ + USBD_Init(); +} + +/** + * Invoked whenever the configuration value of a device is changed by the host + * \param cfgnum Configuration number. + */ +void HIDAUDDDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBConfigurationDescriptor *pDesc; + if (cfgnum > 0) { + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + /* CDC */ + HIDDKeyboard_ConfigureFunction((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + /* AUD */ + AUDDFunction_Configure((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * 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 HIDAUDDDriver_InterfaceSettingChangedHandler(uint8_t interface, + uint8_t setting) +{ + AUDDFunction_InterfaceSettingChangedHandler(interface, setting); +} + +/** + * 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 HIDAUDDDriver_RequestHandler(const USBGenericRequest *request) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + TRACE_INFO_WP("NewReq "); + + if (HIDDKeyboard_RequestHandler(request) == USBRC_SUCCESS) + return; + + if (AUDDFunction_RequestHandler(request) == USBRC_SUCCESS) + return; + + USBDDriver_RequestHandler(pUsbd, request); +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/HIDMSDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/composite/HIDMSDDriver.c new file mode 100644 index 00000000..18986220 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/composite/HIDMSDDriver.c @@ -0,0 +1,153 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + */ + +/** \addtogroup usbd_composite_hidmsd + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include + +#include + +#include +#include + +/*--------------------------------------------------------------------------- + * Defines + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal variables + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/** + * Initializes the USB device HIDMSD device driver. + */ +void HIDMSDDriver_Initialize( + const USBDDriverDescriptors *pDescriptors, + MSDLun *pLuns, uint8_t numLuns) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Initialize the standard USB driver */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + 0); + + /* HID */ + HIDDKeyboard_Initialize(pUsbd, HIDMSDDriverDescriptors_HID_INTERFACE); + + /* MSD */ + MSDFunction_Initialize(pUsbd, HIDMSDDriverDescriptors_MSD_INTERFACE, + pLuns, numLuns); + + /* Initialize the USB driver */ + USBD_Init(); +} + +/** + * Invoked whenever the configuration value of a device is changed by the host + * \param cfgnum Configuration number. + */ +void HIDMSDDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBConfigurationDescriptor *pDesc; + if (cfgnum > 0) { + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + /* HID */ + HIDDKeyboard_ConfigureFunction((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + /* MSD */ + MSDFunction_Configure((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * 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 HIDMSDDriver_RequestHandler(const USBGenericRequest *request) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + TRACE_INFO_WP("NewReq "); + + if (HIDDKeyboard_RequestHandler(request) == USBRC_SUCCESS) + return; + + if (MSDFunction_RequestHandler(request) == USBRC_SUCCESS) + return; + + USBDDriver_RequestHandler(pUsbd, request); +} + +/** + * Starts a remote wake-up sequence if the host has explicitely enabled it + * by sending the appropriate SET_FEATURE request. + */ +void HIDMSDDriver_RemoteWakeUp(void) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + /* Remote wake-up has been enabled */ + if (USBDDriver_IsRemoteWakeUpEnabled(pUsbd)) { + + USBD_RemoteWakeUp(); + } + /* Remote wake-up NOT enabled */ + else { + + TRACE_WARNING("HIDMSDDDriver_RemoteWakeUp: not enabled\n\r"); + } +} +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcAudioArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcAudioArch.png new file mode 100644 index 00000000..72bc9792 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcAudioArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcCdcArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcCdcArch.png new file mode 100644 index 00000000..97485dde Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcCdcArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcHidArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcHidArch.png new file mode 100644 index 00000000..782312a6 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcHidArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcMsdArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcMsdArch.png new file mode 100644 index 00000000..c51556ee Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeCdcMsdArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeComposition.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeComposition.png new file mode 100644 index 00000000..430c13b2 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeComposition.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeHidAudioArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeHidAudioArch.png new file mode 100644 index 00000000..014776eb Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeHidAudioArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeHidMsdArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeHidMsdArch.png new file mode 100644 index 00000000..0d0e791d Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeHidMsdArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeMultiIF.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeMultiIF.png new file mode 100644 index 00000000..7ad09c76 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeMultiIF.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeRequestHandler.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeRequestHandler.png new file mode 100644 index 00000000..1aa24b7f Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeRequestHandler.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeSWArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeSWArch.png new file mode 100644 index 00000000..608824ab Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeSWArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeSingleIF.png b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeSingleIF.png new file mode 100644 index 00000000..61d47012 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/composite/UsbCompositeSingleIF.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/composite/drv/CompositeCDCSerial.inf b/sam3s_example/atmel_softpack_libraries/usb/device/composite/drv/CompositeCDCSerial.inf new file mode 100644 index 00000000..6716dc0b --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/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/sam3s_example/atmel_softpack_libraries/usb/device/core/USBD.c b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBD.c new file mode 100644 index 00000000..b0d155fe --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBD.c @@ -0,0 +1,380 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * \section Purpose + * + * Implementation of USB device functions on a UDP controller. + * + * See \ref usbd_api "USBD API Methods". + */ + +/** \addtogroup usbd_interface + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ +#include "board.h" +#include "USBD.h" +#include "USBD_HAL.h" + +//#include + +/*--------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Internal variables + *---------------------------------------------------------------------------*/ + +/** Device current state. */ +static uint8_t deviceState; +/** Indicates the previous device state */ +static uint8_t previousDeviceState; + +/*--------------------------------------------------------------------------- + * Internal Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * USBD: Event handlers + *---------------------------------------------------------------------------*/ + +/** + * Handle the USB suspend event, should be invoked whenever + * HW reports a suspend signal. + */ +void USBD_SuspendHandler(void) +{ + /* Don't do anything if the device is already suspended */ + if (deviceState != USBD_STATE_SUSPENDED) { + + /* Switch to the Suspended state */ + previousDeviceState = deviceState; + deviceState = USBD_STATE_SUSPENDED; + + /* Suspend HW interface */ + USBD_HAL_Suspend(); + + /* Invoke the User Suspended callback (Suspend System?) */ + if (USBDCallbacks_Suspended) + USBDCallbacks_Suspended(); + } +} + +/** + * Handle the USB resume event, should be invoked whenever + * HW reports a resume signal. + */ +void USBD_ResumeHandler(void) +{ + /* Don't do anything if the device was not suspended */ + if (deviceState == USBD_STATE_SUSPENDED) { + /* Active the device */ + USBD_HAL_Activate(); + deviceState = previousDeviceState; + if (deviceState >= USBD_STATE_DEFAULT) { + /* Invoke the Resume callback */ + if (USBDCallbacks_Resumed) + USBDCallbacks_Resumed(); + } + } +} + +/** + * Handle the USB reset event, should be invoked whenever + * HW found USB reset signal on bus, which usually is called + * "end of bus reset" status. + */ +void USBD_ResetHandler() +{ + /* The device enters the Default state */ + deviceState = USBD_STATE_DEFAULT; + /* Active the USB HW */ + USBD_HAL_Activate(); + /* Only EP0 enabled */ + USBD_HAL_ResetEPs(0xFFFFFFFF, USBD_STATUS_RESET, 0); + USBD_ConfigureEndpoint(0); + /* Invoke the Reset callback */ + if (USBDCallbacks_Reset) + USBDCallbacks_Reset(); +} + +/** + * Handle the USB setup package received, should be invoked + * when an endpoint got a setup package as request. + * \param bEndpoint Endpoint number. + * \param pRequest Pointer to content of request. + */ +void USBD_RequestHandler(uint8_t bEndpoint, + const USBGenericRequest* pRequest) +{ + if (bEndpoint != 0) { + TRACE_WARNING("EP%d request not supported, default EP only", + bEndpoint); + } + else if (USBDCallbacks_RequestReceived) { + USBDCallbacks_RequestReceived(pRequest); + } +} + +/*--------------------------------------------------------------------------- + * USBD: Library interface + *---------------------------------------------------------------------------*/ + +/** + * Configures an endpoint according to its Endpoint Descriptor. + * \param pDescriptor Pointer to an Endpoint descriptor. + */ +void USBD_ConfigureEndpoint(const USBEndpointDescriptor *pDescriptor) +{ + USBD_HAL_ConfigureEP(pDescriptor); +} + +/** + * Sends data through a USB endpoint. Sets up the transfer descriptor, + * writes one or two data payloads (depending on the number of FIFO bank + * for the endpoint) and then starts the actual transfer. The operation is + * complete when all the data has been sent. + * + * *If the size of the buffer is greater than the size of the endpoint + * (or twice the size if the endpoint has two FIFO banks), then the buffer + * must be kept allocated until the transfer is finished*. This means that + * it is not possible to declare it on the stack (i.e. as a local variable + * of a function which returns after starting a transfer). + * + * \param bEndpoint Endpoint number. + * \param pData Pointer to a buffer with the data to send. + * \param dLength Size of the data buffer. + * \param fCallback Optional callback function to invoke when the transfer is + * complete. + * \param pArgument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the transfer has been started; + * otherwise, the corresponding error status code. + */ +uint8_t USBD_Write( uint8_t bEndpoint, + const void *pData, + uint32_t dLength, + TransferCallback fCallback, + void *pArgument ) +{ + USBD_HAL_SetTransferCallback(bEndpoint, fCallback, pArgument); + return USBD_HAL_Write(bEndpoint, pData, dLength); +} +/** + * Reads incoming data on an USB endpoint This methods sets the transfer + * descriptor and activate the endpoint interrupt. The actual transfer is + * then carried out by the endpoint interrupt handler. The Read operation + * finishes either when the buffer is full, or a short packet (inferior to + * endpoint maximum size) is received. + * + * *The buffer must be kept allocated until the transfer is finished*. + * \param bEndpoint Endpoint number. + * \param pData Pointer to a data buffer. + * \param dLength Size of the data buffer in bytes. + * \param fCallback Optional end-of-transfer callback function. + * \param pArgument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started; + * otherwise, the corresponding error code. + */ +uint8_t USBD_Read(uint8_t bEndpoint, + void *pData, + uint32_t dLength, + TransferCallback fCallback, + void *pArgument) +{ + USBD_HAL_SetTransferCallback(bEndpoint, fCallback, pArgument); + return USBD_HAL_Read(bEndpoint, pData, dLength); +} +/** + * Sets the HALT feature on the given endpoint (if not already in this state). + * \param bEndpoint Endpoint number. + */ +void USBD_Halt(uint8_t bEndpoint) +{ + USBD_HAL_Halt(bEndpoint, 1); +} + +/** + * Clears the Halt feature on the given endpoint. + * \param bEndpoint Index of endpoint + */ +void USBD_Unhalt(uint8_t bEndpoint) +{ + USBD_HAL_Halt(bEndpoint, 0); +} + +/** + * Returns the current Halt status of an endpoint. + * \param bEndpoint Index of endpoint + * \return 1 if the endpoint is currently halted; otherwise 0 + */ +uint8_t USBD_IsHalted(uint8_t bEndpoint) +{ + return USBD_HAL_Halt(bEndpoint, 0xFF); +} + +/** + * Indicates if the device is running in high or full-speed. Always returns 0 + * since UDP does not support high-speed mode. + */ +uint8_t USBD_IsHighSpeed(void) +{ + return USBD_HAL_IsHighSpeed(); +} + +/** + * Causes the given endpoint to acknowledge the next packet it receives + * with a STALL handshake. + * \param bEndpoint Endpoint number. + * \return USBD_STATUS_SUCCESS or USBD_STATUS_LOCKED. + */ +uint8_t USBD_Stall(uint8_t bEndpoint) + +{ + return USBD_HAL_Stall(bEndpoint); +} + +/** + * Sets the device address to the given value. + * \param address New device address. + */ +void USBD_SetAddress(uint8_t address) +{ + TRACE_INFO_WP("SetAddr(%d) ", address); + + USBD_HAL_SetAddress(address); + if (address == 0) deviceState = USBD_STATE_DEFAULT; + else deviceState = USBD_STATE_ADDRESS; +} + +/** + * Sets the current device configuration. + * \param cfgnum - Configuration number to set. + */ +void USBD_SetConfiguration(uint8_t cfgnum) +{ + TRACE_INFO_WP("SetCfg(%d) ", cfgnum); + + USBD_HAL_SetConfiguration(cfgnum); + + if (cfgnum != 0) { + deviceState = USBD_STATE_CONFIGURED; + } + else { + deviceState = USBD_STATE_ADDRESS; + /* Reset all endpoints */ + USBD_HAL_ResetEPs(0xFFFFFFFF, USBD_STATUS_RESET, 0); + } +} + +/*--------------------------------------------------------------------------- + * USBD: Library API + *---------------------------------------------------------------------------*/ + +/** + * Starts a remote wake-up procedure. + */ +void USBD_RemoteWakeUp(void) +{ + /* Device is NOT suspended */ + if (deviceState != USBD_STATE_SUSPENDED) { + + TRACE_INFO("USBD_RemoteWakeUp: Device is not suspended\n\r"); + return; + } + USBD_HAL_Activate(); + USBD_HAL_RemoteWakeUp(); +} + +/** + * Connects the pull-up on the D+ line of the USB. + */ +void USBD_Connect(void) +{ + USBD_HAL_Connect(); +} + +/** + * Disconnects the pull-up from the D+ line of the USB. + */ +void USBD_Disconnect(void) +{ + USBD_HAL_Disconnect(); + + /* Device returns to the Powered state */ + + if (deviceState > USBD_STATE_POWERED) { + + deviceState = USBD_STATE_POWERED; + } + + if (previousDeviceState > USBD_STATE_POWERED) { + + previousDeviceState = USBD_STATE_POWERED; + } +} + +/** + * Initializes the USB driver. + */ +void USBD_Init(void) +{ + TRACE_INFO_WP("USBD_Init\n\r"); + + /* HW Layer Initialize */ + USBD_HAL_Init(); + + /* Device is in the Attached state */ + deviceState = USBD_STATE_SUSPENDED; + previousDeviceState = USBD_STATE_POWERED; + + /* Upper Layer Initialize */ + if (USBDCallbacks_Initialized) + USBDCallbacks_Initialized(); +} + +/** + * Returns the current state of the USB device. + * \return Device current state. + */ +uint8_t USBD_GetState(void) +{ + return deviceState; +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDCallbacks.c b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDCallbacks.c new file mode 100644 index 00000000..04aa5955 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDCallbacks.c @@ -0,0 +1,89 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Definitions of callbacks used by the USBD API to notify the user + * application of incoming events. These functions are declared as 'weak', + * so they can be re-implemented elsewhere in the application in a + * transparent way. + * + * \addtogroup usbd_interface + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "USBD.h" +#include "USBDDriver.h" + +/*------------------------------------------------------------------------------ + * Exported function + *------------------------------------------------------------------------------*/ + +/** + * Invoked after the USB driver has been initialized. By default, do nothing. + */ +WEAK void USBDCallbacks_Initialized(void) +{ + /* Does nothing */ +} + +/** + * Invoked when the USB driver is reset. Does nothing by default. + */ +WEAK void USBDCallbacks_Reset(void) +{ + /* Does nothing*/ +} + +/** + * Invoked when the USB device gets suspended. By default, do nothing. + */ +WEAK void USBDCallbacks_Suspended(void) {} + +/** + * Invoked when the USB device leaves the Suspended state. By default, + * Do nothing. + */ +WEAK void USBDCallbacks_Resumed(void) {} + +/** + * USBDCallbacks_RequestReceived - Invoked when a new SETUP request is + * received. Does nothing by default. + * \param request Pointer to the request to handle. + */ +WEAK void USBDCallbacks_RequestReceived(const USBGenericRequest *request) +{ + /* Does basic enumeration */ + USBDDriver_RequestHandler(USBD_GetDriver(), request); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDDriver.c new file mode 100644 index 00000000..689ae1f3 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDDriver.c @@ -0,0 +1,699 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_interface + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include "USBDDriver.h" +#include "USBD.h" +#include "USBD_HAL.h" + +#include + +/*------------------------------------------------------------------------------ + * Local variables + *------------------------------------------------------------------------------*/ + +/** Default device driver instance, for all class drivers in USB Lib. */ +static USBDDriver usbdDriver; + +/*------------------------------------------------------------------------------ + * Local functions + *------------------------------------------------------------------------------*/ + +/** + * Send a NULL packet + */ +static void TerminateCtrlInWithNull(void *pArg, + uint8_t status, + uint32_t transferred, + uint32_t remaining) +{ + USBD_Write(0, /* Endpoint #0 */ + 0, /* No data buffer */ + 0, /* No data buffer */ + (TransferCallback) 0, + (void *) 0); +} + +/** + * Configures the device by setting it into the Configured state and + * initializing all endpoints. + * \param pDriver Pointer to a USBDDriver instance. + * \param cfgnum Configuration number to set. + */ +static void SetConfiguration(USBDDriver *pDriver, uint8_t cfgnum) +{ + USBEndpointDescriptor *pEndpoints[17]; + const USBConfigurationDescriptor *pConfiguration; + + /* Use different descriptor depending on device speed */ + + if (USBD_IsHighSpeed()) { + + pConfiguration = pDriver->pDescriptors->pHsConfiguration; + } + else { + + pConfiguration = pDriver->pDescriptors->pFsConfiguration; + } + + /* Set & save the desired configuration */ + USBD_SetConfiguration(cfgnum); + + pDriver->cfgnum = cfgnum; + pDriver->isRemoteWakeUpEnabled = + ((pConfiguration->bmAttributes & 0x20) > 0); + + /* If the configuration is not 0, configure endpoints */ + if (cfgnum != 0) { + + /* Parse configuration to get endpoint descriptors */ + USBConfigurationDescriptor_Parse(pConfiguration, 0, pEndpoints, 0); + + /* Configure endpoints */ + int i = 0; + while (pEndpoints[i] != 0) { + + USBD_ConfigureEndpoint(pEndpoints[i]); + i++; + } + } + /* Should be done before send the ZLP */ + USBDDriverCallbacks_ConfigurationChanged(cfgnum); + + /* Acknowledge the request */ + USBD_Write(0, /* Endpoint #0 */ + 0, /* No data buffer */ + 0, /* No data buffer */ + (TransferCallback) 0, + (void *) 0); +} + +/** + * Sends the current configuration number to the host. + * \param pDriver Pointer to a USBDDriver instance. + */ +static void GetConfiguration(const USBDDriver *pDriver) +{ + USBD_Write(0, &(pDriver->cfgnum), 1, 0, 0); +} + +/** + * Sends the current status of the device to the host. + * \param pDriver Pointer to a USBDDriver instance. + */ +static void GetDeviceStatus(const USBDDriver *pDriver) +{ + static unsigned short data; + const USBConfigurationDescriptor *pConfiguration; + + data = 0; + /* Use different configuration depending on device speed */ + + if (USBD_IsHighSpeed()) { + + pConfiguration = pDriver->pDescriptors->pHsConfiguration; + } + else { + + pConfiguration = pDriver->pDescriptors->pFsConfiguration; + } + + /* Check current configuration for power mode (if device is configured) */ + + if (pDriver->cfgnum != 0) { + + if (USBConfigurationDescriptor_IsSelfPowered(pConfiguration)) { + + data |= 1; + } + } + + /* Check if remote wake-up is enabled */ + + if (pDriver->isRemoteWakeUpEnabled) { + + data |= 2; + } + + /* Send the device status */ + + USBD_Write(0, &data, 2, 0, 0); +} + +/** + * Sends the current status of an endpoints to the USB host. + * \param bEndpoint Endpoint number. + */ +static void GetEndpointStatus(uint8_t bEndpoint) +{ + static unsigned short data; + + data = 0; + + switch (USBD_HAL_Halt(bEndpoint, 0xFF)) { + + case USBD_STATUS_INVALID_PARAMETER: /* the endpoint not exists */ + USBD_Stall(0); + break; + + case 1: + data = 1; + case 0: + /* Send the endpoint status */ + USBD_Write(0, &data, 2, 0, 0); + break; + } +} + +/** + * Sends the requested USB descriptor to the host if available, or STALLs the + * request. + * \param pDriver Pointer to a USBDDriver instance. + * \param type Type of the requested descriptor + * \param index Index of the requested descriptor. + * \param length Maximum number of bytes to return. + */ +static void GetDescriptor( + const USBDDriver *pDriver, + uint8_t type, + uint8_t indexRDesc, + uint32_t length) +{ + const USBDeviceDescriptor *pDevice; + const USBConfigurationDescriptor *pConfiguration; + const USBDeviceQualifierDescriptor *pQualifier; + const USBConfigurationDescriptor *pOtherSpeed; + const USBGenericDescriptor **pStrings = + (const USBGenericDescriptor **) pDriver->pDescriptors->pStrings; + const USBGenericDescriptor *pString; + uint8_t numStrings = pDriver->pDescriptors->numStrings; + uint8_t terminateWithNull = 0; + + /* Use different set of descriptors depending on device speed */ + + if (USBD_IsHighSpeed()) { + + TRACE_DEBUG("HS "); + pDevice = pDriver->pDescriptors->pHsDevice; + pConfiguration = pDriver->pDescriptors->pHsConfiguration; + pQualifier = pDriver->pDescriptors->pHsQualifier; + pOtherSpeed = pDriver->pDescriptors->pHsOtherSpeed; + } + else { + + TRACE_DEBUG("FS "); + pDevice = pDriver->pDescriptors->pFsDevice; + pConfiguration = pDriver->pDescriptors->pFsConfiguration; + pQualifier = pDriver->pDescriptors->pFsQualifier; + pOtherSpeed = pDriver->pDescriptors->pFsOtherSpeed; + } + + /* Check the descriptor type */ + + switch (type) { + + case USBGenericDescriptor_DEVICE: + TRACE_INFO_WP("Dev "); + + /* Adjust length and send descriptor */ + + if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice)) { + + length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pDevice); + } + USBD_Write(0, pDevice, length, 0, 0); + break; + + case USBGenericDescriptor_CONFIGURATION: + TRACE_INFO_WP("Cfg "); + + /* Adjust length and send descriptor */ + + if (length > USBConfigurationDescriptor_GetTotalLength(pConfiguration)) { + + length = USBConfigurationDescriptor_GetTotalLength(pConfiguration); + terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); + } + USBD_Write(0, + pConfiguration, + length, + terminateWithNull ? TerminateCtrlInWithNull : 0, + 0); + break; + + case USBGenericDescriptor_DEVICEQUALIFIER: + TRACE_INFO_WP("Qua "); + + /* Check if descriptor exists */ + + if (!pQualifier) { + + USBD_Stall(0); + } + else { + + /* Adjust length and send descriptor */ + + if (length > USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier)) { + + length = USBGenericDescriptor_GetLength((USBGenericDescriptor *) pQualifier); + } + USBD_Write(0, pQualifier, length, 0, 0); + } + break; + + case USBGenericDescriptor_OTHERSPEEDCONFIGURATION: + TRACE_INFO_WP("OSC "); + + /* Check if descriptor exists */ + + if (!pOtherSpeed) { + + USBD_Stall(0); + } + else { + + /* Adjust length and send descriptor */ + + if (length > USBConfigurationDescriptor_GetTotalLength(pOtherSpeed)) { + + length = USBConfigurationDescriptor_GetTotalLength(pOtherSpeed); + terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); + } + USBD_Write(0, + pOtherSpeed, + length, + terminateWithNull ? TerminateCtrlInWithNull : 0, + 0); + } + break; + + case USBGenericDescriptor_STRING: + TRACE_INFO_WP("Str%d ", indexRDesc); + + /* Check if descriptor exists */ + + if (indexRDesc >= numStrings) { + + USBD_Stall(0); + } + else { + + pString = pStrings[indexRDesc]; + + /* Adjust length and send descriptor */ + + if (length > USBGenericDescriptor_GetLength(pString)) { + + length = USBGenericDescriptor_GetLength(pString); + terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0); + } + USBD_Write(0, + pString, + length, + terminateWithNull ? TerminateCtrlInWithNull : 0, + 0); + } + break; + + default: + TRACE_WARNING( + "USBDDriver_GetDescriptor: Unknown descriptor type (%d)\n\r", + type); + USBD_Stall(0); + } +} + +/** + * Sets the active setting of the given interface if the configuration supports + * it; otherwise, the control pipe is STALLed. If the setting of an interface + * changes. + * \parma pDriver Pointer to a USBDDriver instance. + * \parma infnum Interface number. + * \parma setting New active setting for the interface. + */ +static void SetInterface( + USBDDriver *pDriver, + uint8_t infnum, + uint8_t setting) +{ + /* Make sure alternate settings are supported */ + + if (!pDriver->pInterfaces) { + + USBD_Stall(0); + } + else { + + /* Change the current setting of the interface and trigger the callback */ + /* if necessary */ + if (pDriver->pInterfaces[infnum] != setting) { + + pDriver->pInterfaces[infnum] = setting; + USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting); + } + + /* Acknowledge the request */ + + USBD_Write(0, 0, 0, 0, 0); + } +} + +/** + * Sends the currently active setting of the given interface to the USB + * host. If alternate settings are not supported, this function STALLs the + * control pipe. + * \param pDriver Pointer to a USBDDriver instance. + * \param infnum Interface number. + */ +static void GetInterface( + const USBDDriver *pDriver, + uint8_t infnum) +{ + /* Make sure alternate settings are supported, or STALL the control pipe */ + + if (!pDriver->pInterfaces) { + + USBD_Stall(0); + } + else { + + /* Sends the current interface setting to the host */ + + USBD_Write(0, &(pDriver->pInterfaces[infnum]), 1, 0, 0); + } +} +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Return USBDDriver instance pointer for global usage. + */ +USBDDriver *USBD_GetDriver(void) +{ + return &usbdDriver; +} + +/** + * Initializes a USBDDriver instance with a list of descriptors. If + * interfaces can have multiple alternate settings, an array to store the + * current setting for each interface must be provided. + * \param pDriver Pointer to a USBDDriver instance. + * \param pDescriptors Pointer to a USBDDriverDescriptors instance. + * \param pInterfaces Pointer to an array for storing the current alternate + * setting of each interface (optional). + */ +void USBDDriver_Initialize( + USBDDriver *pDriver, + const USBDDriverDescriptors *pDescriptors, + uint8_t *pInterfaces) +{ + + pDriver->cfgnum = 0; + pDriver->isRemoteWakeUpEnabled = 0; + + pDriver->pDescriptors = pDescriptors; + pDriver->pInterfaces = pInterfaces; + + /* Initialize interfaces array if not null */ + + if (pInterfaces != 0) { + + memset(pInterfaces, sizeof(pInterfaces), 0); + } +} + +/** + * Returns configuration descriptor list. + * \param pDriver Pointer to a USBDDriver instance. + * \param cfgNum Reserved. + */ +USBConfigurationDescriptor *USBDDriver_GetCfgDescriptors( + USBDDriver *pDriver, uint8_t cfgNum) +{ + USBDDriverDescriptors *pDescList = (USBDDriverDescriptors *)pDriver->pDescriptors; + USBConfigurationDescriptor *pCfg; + + if (USBD_HAL_IsHighSpeed() && pDescList->pHsConfiguration) + pCfg = (USBConfigurationDescriptor *)pDescList->pHsConfiguration; + else + pCfg = (USBConfigurationDescriptor *)pDescList->pFsConfiguration; + + return pCfg; +} + +/** + * Handles the given request if it is standard, otherwise STALLs it. + * \param pDriver Pointer to a USBDDriver instance. + * \param pRequest Pointer to a USBGenericRequest instance. + */ +void USBDDriver_RequestHandler( + USBDDriver *pDriver, + const USBGenericRequest *pRequest) +{ + uint8_t cfgnum; + uint8_t infnum; + uint8_t eptnum; + uint8_t setting; + uint8_t type; + uint8_t indexDesc; + uint32_t length; + uint32_t address; + + TRACE_INFO_WP("Std "); + + /* Check request code */ + switch (USBGenericRequest_GetRequest(pRequest)) { + + case USBGenericRequest_GETDESCRIPTOR: + TRACE_INFO_WP("gDesc "); + + /* Send the requested descriptor */ + type = USBGetDescriptorRequest_GetDescriptorType(pRequest); + indexDesc = USBGetDescriptorRequest_GetDescriptorIndex(pRequest); + length = USBGenericRequest_GetLength(pRequest); + GetDescriptor(pDriver, type, indexDesc, length); + break; + + case USBGenericRequest_SETADDRESS: + TRACE_INFO_WP("sAddr "); + + /* Sends a zero-length packet and then set the device address */ + address = USBSetAddressRequest_GetAddress(pRequest); + USBD_Write(0, 0, 0, (TransferCallback) USBD_SetAddress, (void *) address); + break; + + case USBGenericRequest_SETCONFIGURATION: + TRACE_INFO_WP("sCfg "); + + /* Set the requested configuration */ + cfgnum = USBSetConfigurationRequest_GetConfiguration(pRequest); + SetConfiguration(pDriver, cfgnum); + break; + + case USBGenericRequest_GETCONFIGURATION: + TRACE_INFO_WP("gCfg "); + + /* Send the current configuration number */ + GetConfiguration(pDriver); + break; + + case USBGenericRequest_GETSTATUS: + TRACE_INFO_WP("gSta "); + + /* Check who is the recipient */ + switch (USBGenericRequest_GetRecipient(pRequest)) { + + case USBGenericRequest_DEVICE: + TRACE_INFO_WP("Dev "); + + /* Send the device status */ + GetDeviceStatus(pDriver); + break; + + case USBGenericRequest_ENDPOINT: + TRACE_INFO_WP("Ept "); + + /* Send the endpoint status */ + eptnum = USBGenericRequest_GetEndpointNumber(pRequest); + GetEndpointStatus(eptnum); + break; + + default: + TRACE_WARNING( + "USBDDriver_RequestHandler: Unknown recipient (%d)\n\r", + USBGenericRequest_GetRecipient(pRequest)); + USBD_Stall(0); + } + break; + + case USBGenericRequest_CLEARFEATURE: + TRACE_INFO_WP("cFeat "); + + /* Check which is the requested feature */ + switch (USBFeatureRequest_GetFeatureSelector(pRequest)) { + + case USBFeatureRequest_ENDPOINTHALT: + TRACE_INFO_WP("Hlt "); + + /* Unhalt endpoint and send a zero-length packet */ + USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest)); + USBD_Write(0, 0, 0, 0, 0); + break; + + case USBFeatureRequest_DEVICEREMOTEWAKEUP: + TRACE_INFO_WP("RmWU "); + + /* Disable remote wake-up and send a zero-length packet */ + pDriver->isRemoteWakeUpEnabled = 0; + USBD_Write(0, 0, 0, 0, 0); + break; + + default: + TRACE_WARNING( + "USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r", + USBFeatureRequest_GetFeatureSelector(pRequest)); + USBD_Stall(0); + } + break; + + case USBGenericRequest_SETFEATURE: + TRACE_INFO_WP("sFeat "); + + /* Check which is the selected feature */ + switch (USBFeatureRequest_GetFeatureSelector(pRequest)) { + + case USBFeatureRequest_DEVICEREMOTEWAKEUP: + TRACE_INFO_WP("RmWU "); + + /* Enable remote wake-up and send a ZLP */ + pDriver->isRemoteWakeUpEnabled = 1; + USBD_Write(0, 0, 0, 0, 0); + break; + + case USBFeatureRequest_ENDPOINTHALT: + TRACE_INFO_WP("Halt "); + /* Halt endpoint */ + USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest)); + USBD_Write(0, 0, 0, 0, 0); + break; + case USBFeatureRequest_OTG_B_HNP_ENABLE: + TRACE_INFO_WP("OTG_B_HNP_ENABLE "); + pDriver->otg_features_supported |= + 1<otg_features_supported |= + 1<otg_features_supported |= + 1<isRemoteWakeUpEnabled; +} + +/** + * Return OTG features supported + * \param pDriver Pointer to an USBDDriver instance. + * \return the OTG features + */ +uint8_t USBDDriver_returnOTGFeatures(const USBDDriver *pDriver) +{ + return pDriver->otg_features_supported; +} + +/** + * Clear OTG features supported + * \param pDriver Pointer to an USBDDriver instance. + * \return none + */ +void USBDDriver_clearOTGFeatures(USBDDriver *pDriver) +{ + pDriver->otg_features_supported = 0; +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDDriverCallbacks.c b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDDriverCallbacks.c new file mode 100644 index 00000000..da8958c2 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/core/USBDDriverCallbacks.c @@ -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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * \section Purpose + * + * Definition of several callbacks which are triggered by the USB software + * driver after receiving specific requests. + * + * \section Usage + * + * -# Re-implement the USBDDriverCallbacks_ConfigurationChanged + * callback to know when the hosts changes the active configuration of + * the device. + * -# Re-implement the USBDDriverCallbacks_InterfaceSettingChanged + * callback to get notified whenever the active setting of an interface + * is changed by the host. + * + * \addtogroup usbd_interface + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ +#include "board.h" +#include "USBDDriver.h" +/*------------------------------------------------------------------------------ + * Global functions + *------------------------------------------------------------------------------*/ + +/** + * Indicates that the current configuration of the device has changed. + * \param cfgnum New device configuration index. + */ +WEAK void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum) +{ + TRACE_INFO_WP("cfgChanged%d ", cfgnum); +} + +/** + * Notifies of a change in the currently active setting of an interface. + * \param interface Number of the interface whose setting has changed. + * \param setting New interface setting. + */ +WEAK void USBDDriverCallbacks_InterfaceSettingChanged( + uint8_t interface, + uint8_t setting) +{ + TRACE_INFO_WP("ifSettingChanged%d.%d ", interface, setting); +} +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDClassArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDClassArch.png new file mode 100644 index 00000000..6d095807 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDClassArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboard.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboard.c new file mode 100644 index 00000000..76a40a86 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboard.c @@ -0,0 +1,374 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_hid_key + *@{ + * Implement HID Keyboard Function For USB Device. + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Internal types + *------------------------------------------------------------------------------*/ + +/** + * Extended struct for an HID Keyboard Input report, for transfer driver to + * send reports. + */ +typedef struct _KBDInputReport { + /** Callback when report done */ + HIDDReportEventCallback fCallback; + /** Callback arguments */ + void* pArg; + + /** Report size (ID + DATA) */ + uint16_t wMaxSize; + /** Transfered size */ + uint16_t wTransferred; + /** Report idle rate */ + uint8_t bIdleRate; + /** Delay count for Idle */ + uint8_t bDelay; + /** Report ID */ + uint8_t bID; + /** Input Report Data Block */ + HIDDKeyboardInputReport sReport; +} KBDInputReport; + +/** + * Extended struct for an HID Keyboard Output report, for transfer driver to + * polling reports. + */ +typedef struct _KBDOutputReport { + /** Callback when report done */ + HIDDReportEventCallback fCallback; + /** Callback arguments */ + void* pArg; + + /** Report size (ID + DATA) */ + uint16_t wMaxSize; + /** Transfered size */ + uint16_t wTransferred; + /** Report idle rate */ + uint8_t bIdleRate; + /** Delay count for Idle */ + uint8_t bDelay; + /** Report ID */ + uint8_t bID; + /** Output Report Data Block */ + HIDDKeyboardOutputReport sReport; +} KBDOutputReport; + +/** + * Driver structure for an HID device implementing keyboard functionalities. + */ +typedef struct _HIDDKeyboard { + + /** USB HID Functionn */ + HIDDFunction hidDrv; + /** Input report list */ + HIDDReport *inputReports[1]; + /** Output report list */ + HIDDReport *outputReports[1]; +} HIDDKeyboard; + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/** HIDD Keyboard Input Report Instance */ +static KBDInputReport inputReport; + +/** HIDD Keyboard Output Report Instance */ +static KBDOutputReport outputReport; + +/** Static instance of the HIDD keyboard device driver. */ +static HIDDKeyboard hiddKeyboard; + +/** Report descriptor used by the driver. */ +const uint8_t hiddKeyboardReportDescriptor[] = { + + 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, + HIDDKeyboardDescriptors_FIRSTMODIFIERKEY, + HIDReport_LOCAL_USAGEMAXIMUM + 1, + HIDDKeyboardDescriptors_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, + HIDDKeyboardDescriptors_FIRSTSTANDARDKEY, + HIDReport_GLOBAL_LOGICALMAXIMUM + 1, + HIDDKeyboardDescriptors_LASTSTANDARDKEY, + HIDReport_GLOBAL_USAGEPAGE + 1, HIDKeypad_PAGEID, + HIDReport_LOCAL_USAGEMINIMUM + 1, + HIDDKeyboardDescriptors_FIRSTSTANDARDKEY, + HIDReport_LOCAL_USAGEMAXIMUM + 1, + HIDDKeyboardDescriptors_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 +}; + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/** + * 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 + * HIDDKeyboardCallbacks_LedsChanged callback. + */ +static void HIDDKeyboard_ReportReceived(void) +{ + HIDDKeyboardOutputReport *pOut = &outputReport.sReport; + + /* Trigger callback */ + if (HIDDKeyboardCallbacks_LedsChanged) { + HIDDKeyboardCallbacks_LedsChanged( + pOut->numLockStatus, + pOut->capsLockStatus, + pOut->scrollLockStatus); + } +} + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes the HID keyboard device driver SW. + * (Init USBDDriver .., Init function driver .., Init USBD ...) + * \param pUsbd Pointer to USBDDriver instance. + * \param bInterfaceNb Interface number for the function. + */ +void HIDDKeyboard_Initialize(USBDDriver* pUsbd, uint8_t bInterfaceNb) +{ + HIDDKeyboard *pKbd = &hiddKeyboard; + HIDDFunction *pHidd = &pKbd->hidDrv; + + /* One input report */ + pKbd->inputReports[0] = (HIDDReport*)&inputReport; + HIDDFunction_InitializeReport(pKbd->inputReports[0], + sizeof(HIDDKeyboardInputReport), + 0, + 0, 0); + /* One output report */ + pKbd->outputReports[0] = (HIDDReport*)&outputReport; + HIDDFunction_InitializeReport( + pKbd->outputReports[0], + sizeof(HIDDKeyboardOutputReport), + 0, + (HIDDReportEventCallback)HIDDKeyboard_ReportReceived, 0); + + /* Function initialize */ + HIDDFunction_Initialize(pHidd, + pUsbd, bInterfaceNb, + hiddKeyboardReportDescriptor, + pKbd->inputReports, 1, + pKbd->outputReports, 1); +} + +/** + * Configure function with expected descriptors and start functionality. + * Usually invoked when device is configured. + * \pDescriptors Pointer to the descriptors for function configure. + * \wLength Length of descriptors in number of bytes. + */ +void HIDDKeyboard_ConfigureFunction(USBGenericDescriptor *pDescriptors, + uint16_t wLength) +{ + HIDDKeyboard *pKbd = &hiddKeyboard; + HIDDFunction *pHidd = &pKbd->hidDrv; + USBGenericDescriptor * pDesc = pDescriptors; + + pDesc = HIDDFunction_ParseInterface(pHidd, + pDescriptors, + wLength); + + /* Start receiving output reports */ + HIDDFunction_StartPollingOutputs(pHidd); +} + +/** + * Handles HID-specific SETUP request sent by the host. + * \param request Pointer to a USBGenericRequest instance. + * \return USBRC_SUCCESS if request is handled. + */ +uint32_t HIDDKeyboard_RequestHandler(const USBGenericRequest *request) +{ + HIDDKeyboard *pKbd = &hiddKeyboard; + HIDDFunction *pHidd = &pKbd->hidDrv; + + TRACE_INFO_WP("Kbd "); + + /* Process HID requests */ + return HIDDFunction_RequestHandler(pHidd, request); +} + +/** + * Reports a change in which keys are currently pressed or release to the + * host. + * + * \param pressedKeys Pointer to an array of key codes indicating keys that have + * been pressed since the last call to + * HIDDKeyboardDriver_ChangeKeys(). + * \param pressedKeysSize Number of key codes in the pressedKeys array. + * \param releasedKeys Pointer to an array of key codes indicates keys that have + * been released since the last call to + * HIDDKeyboardDriver_ChangeKeys(). + * \param releasedKeysSize Number of key codes in the releasedKeys array. + * \return USBD_STATUS_SUCCESS if the report has been sent to the host; + * otherwise an error code. + */ +uint32_t HIDDKeyboard_ChangeKeys(uint8_t *pressedKeys, + uint8_t pressedKeysSize, + uint8_t *releasedKeys, + uint8_t releasedKeysSize) +{ + HIDDKeyboard *pKbd = &hiddKeyboard; + HIDDFunction *pHidd = &pKbd->hidDrv; + HIDDKeyboardInputReport *pReport = + (HIDDKeyboardInputReport *)pKbd->inputReports[0]->bData; + + /* 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( + pReport, + *pressedKeys); + } + else { + + HIDDKeyboardInputReport_PressStandardKey( + pReport, + *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( + pReport, + *releasedKeys); + } + else { + + HIDDKeyboardInputReport_ReleaseStandardKey( + pReport, + *releasedKeys); + } + + releasedKeysSize--; + releasedKeys++; + } + + /* Send input report through the interrupt IN endpoint */ + return USBD_Write(pHidd->bPipeIN, + pReport, + 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 HIDDKeyboard_RemoteWakeUp(void) +{ + HIDDKeyboard *pKbd = &hiddKeyboard; + HIDDFunction *pHidd = &pKbd->hidDrv; + USBDDriver *pUsbd = pHidd->pUsbd; + + /* Remote wake-up has been enabled */ + if (USBDDriver_IsRemoteWakeUpEnabled(pUsbd)) { + + USBD_RemoteWakeUp(); + } +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardCallbacks_LedsChanged.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardCallbacks_LedsChanged.c new file mode 100644 index 00000000..3aaed0ad --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardCallbacks_LedsChanged.c @@ -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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_hid_key + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "HIDDKeyboardDriver.h" +#include + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * For HID Keyboard Function. + * Indicates that the status of one or more LEDs has been changed by the + * host. + * \param numLockStatus Indicates the current status of the num. lock key. + * \param capsLockStatus Indicates the current status of the caps lock key. + * \param scrollLockStatus Indicates the current status of the scroll lock key. + */ +WEAK void HIDDKeyboardCallbacks_LedsChanged( + uint8_t numLockStatus, + uint8_t capsLockStatus, + uint8_t scrollLockStatus) +{ + TRACE_INFO( + "LEDs status: %d, %d, %d\n\r", + numLockStatus, + capsLockStatus, + scrollLockStatus); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardDriver.c new file mode 100644 index 00000000..a9aba272 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardDriver.c @@ -0,0 +1,123 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_hid_key + *@{ + * Implement a USB device that only have HID Keyboard Function. + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Internal types + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes the HID keyboard device driver. + */ +void HIDDKeyboardDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBDDriver_Initialize(pUsbd, pDescriptors, 0); + HIDDKeyboard_Initialize(pUsbd, 0); + USBD_Init(); +} + +/** + * Handles configureation changed event. + * \param cfgnum New configuration number + */ +void HIDDKeyboardDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + const USBDDriverDescriptors * pDescriptors = pUsbd->pDescriptors; + USBConfigurationDescriptor *pDesc; + + if (cfgnum > 0) { + if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration) + pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration; + else + pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration; + HIDDKeyboard_ConfigureFunction((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * Handles HID-specific SETUP request sent by the host. + * \param request Pointer to a USBGenericRequest instance. + */ +void HIDDKeyboardDriver_RequestHandler(const USBGenericRequest *request) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + + TRACE_INFO_WP("NewReq "); + + /* Process HID requests */ + if (USBRC_SUCCESS == HIDDKeyboard_RequestHandler(request)) { + return; + } + /* Process STD requests */ + else { + USBDDriver_RequestHandler(pUsbd, request); + } +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardInputReport.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardInputReport.c new file mode 100644 index 00000000..99c04fca --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardInputReport.c @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Implementation of the HIDDKeyboardInputReport class. + */ + +/** \addtogroup usbd_hid_key + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes a keyboard input report instance. + * \param report Pointer to a HIDDKeyboardInputReport instance. + */ +void HIDDKeyboardInputReport_Initialize(HIDDKeyboardInputReport *report) +{ + uint32_t i; + + report->bmModifierKeys = 0; + for (i = 0; i < HIDDKeyboardInputReport_MAXKEYPRESSES; i++) { + + report->pressedKeys[i] = 0; + } +} + +/** + * Reports a standard key as being pressed. + * \param report Pointer to a HIDDKeyboardInputReport instance. + * \param key Key code of the standard key. + */ +void HIDDKeyboardInputReport_PressStandardKey(HIDDKeyboardInputReport *report, + uint8_t key) +{ + /* Find first available slot */ + uint32_t i = 0; + uint8_t found = 0; + while ((i < HIDDKeyboardInputReport_MAXKEYPRESSES) && !found) { + + /* Free slot: no key referenced (code = 0) or ErrorRollOver */ + if ((report->pressedKeys[i] == 0) + || (report->pressedKeys[i] == HIDKeypad_ERRORROLLOVER)) { + + found = 1; + report->pressedKeys[i] = key; + } + + i++; + } + + /* Report ErrorRollOver in all fields if too many keys are pressed */ + if (!found) { + + for (i=0; i < HIDDKeyboardInputReport_MAXKEYPRESSES; i++) { + + report->pressedKeys[i] = HIDKeypad_ERRORROLLOVER; + } + } +} + +/** + * Reports a standard key as not being pressed anymore. + * \param report Pointer to a HIDDKeyboardInputReport instance. + * \param key Key code of the standard key + */ +void HIDDKeyboardInputReport_ReleaseStandardKey(HIDDKeyboardInputReport *report, + uint8_t key) +{ + /* Look for key in array */ + uint32_t i = 0; + uint8_t found = 0; + while ((i < HIDDKeyboardInputReport_MAXKEYPRESSES) && !found) { + + if (report->pressedKeys[i] == key) { + + found = 1; + report->pressedKeys[i] = 0; + } + + i++; + } +} + +/** + * Reports a modifier key as being currently pressed. + * \param report Pointer to a HIDDKeyboardInputReport instance. + * \param key Key code of the modifier key. + */ +void HIDDKeyboardInputReport_PressModifierKey(HIDDKeyboardInputReport *report, + uint8_t key) +{ + /* Set corresponding bit */ + uint8_t bit = key - HIDDKeyboardDescriptors_FIRSTMODIFIERKEY; + report->bmModifierKeys |= 1 << bit; +} + +/** + * Reports a modifier key as not being pressed anymore. + * \param report Pointer to a HIDDKeyboardInputReport instance. + * \param key Key code of the modifier key. + */ +void HIDDKeyboardInputReport_ReleaseModifierKey(HIDDKeyboardInputReport *report, + uint8_t key) +{ + /* Clear corresponding bit */ + uint8_t bit = key - HIDDKeyboardDescriptors_FIRSTMODIFIERKEY; + report->bmModifierKeys &= ~(1 << bit); +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardOutputReport.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardOutputReport.c new file mode 100644 index 00000000..adcd1037 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-keyboard/HIDDKeyboardOutputReport.c @@ -0,0 +1,96 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Implementation of the HIDDKeyboardOutputReport class. + */ + +/** \addtogroup usbd_hid_key + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes a keyboard output report. + * \param report Pointer to a HIDDKeyboardOutputReport instance. + */ +void HIDDKeyboardOutputReport_Initialize(HIDDKeyboardOutputReport *report) +{ + report->numLockStatus = 0; + report->capsLockStatus = 0; + report->scrollLockStatus = 0; + report->padding = 0; +} + +/** + * Indicates the current status of the num. lock LED according to the + * given report. + * \param report Pointer to a HIDDKeyboardOutputReport instance. + * \return 1 if the num. lock LED is light on; otherwise 0. + */ +unsigned char HIDDKeyboardOutputReport_GetNumLockStatus( + const HIDDKeyboardOutputReport *report) +{ + return report->numLockStatus; +} + +/** + * Indicates the current status of the caps lock LED according to the + * given report. + * \param report Pointer to a HIDDKeyboardOutputReport instance. + * \return 1 if the caps lock LED is light on; otherwise 0. + */ +unsigned char HIDDKeyboardOutputReport_GetCapsLockStatus( + const HIDDKeyboardOutputReport *report) +{ + return report->capsLockStatus; +} + +/** + * Indicates the current status of the scroll lock LED according to the + * given report. + * \param report Pointer to a HIDDKeyboardOutputReport instance. + * \return 1 if the scroll lock LED is light on; otherwise 0. + */ +unsigned char HIDDKeyboardOutputReport_GetScrollLockStatus( + const HIDDKeyboardOutputReport *report) +{ + return report->scrollLockStatus; +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-mouse/HIDDMouseDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-mouse/HIDDMouseDriver.c new file mode 100644 index 00000000..f42a8fa0 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-mouse/HIDDMouseDriver.c @@ -0,0 +1,277 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_hid_mouse + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include + +#include +#include +#include + +#include + +/*------------------------------------------------------------------------------ + * Internal Defines + *------------------------------------------------------------------------------*/ + +/** Tag bit (Always 1) */ +#define HIDDMouse_TAG (1 << 3) +/** Xsign bit */ +#define HIDDMouse_Xsign (1 << 4) +/** Ysign bit */ +#define HIDDMouse_Ysign (1 << 5) + +/*------------------------------------------------------------------------------ + * Internal types + *------------------------------------------------------------------------------*/ + +/** + * Struct for an HID Mouse report. + */ +typedef struct _HIDDMouseReport { + /** Callback when report done */ + HIDDReportEventCallback fCallback; + /** Callback arguments */ + void* pArg; + + /** Report size (ID + DATA) */ + uint16_t wMaxSize; + /** Transfered size */ + uint16_t wTransferred; + /** Report idle rate */ + uint8_t bIdleRate; + /** Delay count for Idle */ + uint8_t bDelay; + /** Report ID */ + uint8_t bID; + /** Report data block */ + HIDDMouseInputReport report; +} HIDDMouseReport; + +/** + * Driver structure for an HID device implementing keyboard functionalities. + */ +typedef struct _HIDDMouseDriver { + + /** Mouse function instance */ + HIDDFunction hidDrv; + /** Mouse input report */ + HIDDReport *inputReports[1]; +} HIDDMouseDriver; + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/** Static instance of the HID mouse device driver. */ +static HIDDMouseDriver hiddMouseDriver; +/** Input report */ +static HIDDMouseReport hiddInputReport; + +/** Report descriptor used by the driver. */ +static const uint8_t hiddReportDescriptor[] = { + + /* Global Usage Page */ + HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID, + /* Collection: Application */ + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_MOUSE, + HIDReport_COLLECTION + 1, HIDReport_COLLECTION_APPLICATION, + /* Physical collection: Pointer */ + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_POINTER, + HIDReport_COLLECTION + 1, HIDReport_COLLECTION_PHYSICAL, + + /* Input report: buttons */ + HIDReport_GLOBAL_USAGEPAGE + 1, HIDButton_PAGEID, + + HIDReport_GLOBAL_REPORTCOUNT + 1, 3, + HIDReport_GLOBAL_REPORTSIZE + 1, 1, + HIDReport_LOCAL_USAGEMINIMUM + 1, 1, + HIDReport_LOCAL_USAGEMAXIMUM + 1, 3, + HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0, + HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1, + HIDReport_INPUT + 1, HIDReport_VARIABLE, /* 3 button bits */ + + /* Input report: padding */ + HIDReport_GLOBAL_REPORTCOUNT + 1, 1, + HIDReport_GLOBAL_REPORTSIZE + 1, 5, + HIDReport_INPUT + 1, HIDReport_CONSTANT, /* 5 bit padding */ + + /* Input report: pointer */ + HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID, + HIDReport_GLOBAL_REPORTSIZE + 1, 8, + HIDReport_GLOBAL_REPORTCOUNT + 1, 2, + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_X, + HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_Y, + HIDReport_GLOBAL_LOGICALMINIMUM + 1, (uint8_t) -127, + HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 127, + HIDReport_INPUT + 1, HIDReport_VARIABLE | HIDReport_RELATIVE, + + HIDReport_ENDCOLLECTION, + HIDReport_ENDCOLLECTION +}; + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes the HID Mouse %device driver. + * \param pDescriptors Pointer to descriptor list for the HID Mouse. + */ +void HIDDMouseDriver_Initialize(const USBDDriverDescriptors *pDescriptors) +{ + HIDDMouseDriver* pMouse = &hiddMouseDriver; + HIDDFunction* pHidd = &pMouse->hidDrv; + USBDDriver* pUsbd = USBD_GetDriver(); + + /* One input report */ + pMouse->inputReports[0] = (HIDDReport*)&hiddInputReport; + HIDDFunction_InitializeReport(pMouse->inputReports[0], + HIDDMouseDriver_REPORTDESCRIPTORSIZE, + 0, + 0, 0); + + /* Initialize USBD Driver instance */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + 0); /* Multiple interface settings not supported */ + /* Function initialize */ + HIDDFunction_Initialize(pHidd, + pUsbd, 0, + hiddReportDescriptor, + (HIDDReport**)(&pMouse->inputReports), 1, + 0, 0); + USBD_Init(); +} + +/** + * Handles configureation changed event. + * \param cfgnum New configuration number + */ +void HIDDMouseDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + HIDDMouseDriver * pMouse = &hiddMouseDriver; + HIDDFunction * pHidd = &pMouse->hidDrv; + USBDDriver * pUsbd = pHidd->pUsbd; + USBConfigurationDescriptor *pDesc; + + if (cfgnum > 0) { + + /* Parse endpoints for reports */ + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + HIDDFunction_ParseInterface(pHidd, + (USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * Handles HID-specific SETUP request sent by the host. + * \param request Pointer to a USBGenericRequest instance + */ +void HIDDMouseDriver_RequestHandler(const USBGenericRequest *request) +{ + HIDDMouseDriver * pMouse = &hiddMouseDriver; + HIDDFunction * pHidd = &pMouse->hidDrv; + USBDDriver * pUsbd = pHidd->pUsbd; + + TRACE_INFO("NewReq "); + + /* Process HID requests */ + if (USBRC_SUCCESS == HIDDFunction_RequestHandler(pHidd, + request)) { + return; + } + /* Process STD requests */ + else { + + USBDDriver_RequestHandler(pUsbd, request); + } + +} + +/** + * Update the Mouse button status and location changes via input report + * to host + * \param bmButtons Bit map of the button status + * \param deltaX Movment on X direction + * \param deltaY Movment on Y direction + */ +uint8_t HIDDMouseDriver_ChangePoints(uint8_t bmButtons, + int8_t deltaX, + int8_t deltaY) +{ + HIDDMouseDriver * pMouse = &hiddMouseDriver; + HIDDFunction * pHidd = &pMouse->hidDrv; + HIDDMouseInputReport * pReport = &hiddInputReport.report; + + pReport->bmButtons = (bmButtons & 0x07) | HIDDMouse_TAG; + pReport->bX = deltaX; + pReport->bY = deltaY; + + /* Send input report through the interrupt IN endpoint */ + return USBD_Write(pHidd->bPipeIN, + (void*)pReport, + sizeof(HIDDMouseInputReport), + 0, + 0); +} + +/** + * Starts a remote wake-up sequence if the host has explicitely enabled it + * by sending the appropriate SET_FEATURE request. + */ +void HIDDMouseDriver_RemoteWakeUp(void) +{ + HIDDMouseDriver * pMouse = &hiddMouseDriver; + HIDDFunction * pHidd = &pMouse->hidDrv; + USBDDriver * pUsbd = pHidd->pUsbd; + + /* Remote wake-up has been enabled */ + if (USBDDriver_IsRemoteWakeUpEnabled(pUsbd)) { + + USBD_RemoteWakeUp(); + } +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-transfer/HIDDFunction.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-transfer/HIDDFunction.c new file mode 100644 index 00000000..10ddd961 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-transfer/HIDDFunction.c @@ -0,0 +1,695 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Implementation of the HIDDFunction class methods. + */ +/** \addtogroup usbd_hid + * @{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include +#include + +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Macros + *------------------------------------------------------------------------------*/ + +/** + * Get byte pointer + */ +#define _PU8(v) ((uint8_t*)&(v)) + +/** + * Get word from un-aligned value + */ +#define _Word(a) (_PU8(a)[0] + (_PU8(a)[1] << 8)) + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** Parse data extention for descriptor parsing */ +typedef struct _HIDDParseData { + HIDDFunction * pHidd; + USBInterfaceDescriptor * pIfDesc; +} HIDDParseData; + +/** Parse data extension for HID descriptor */ + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/** + * Returns the descriptor requested by the host. + * \param pHidd Pointer to HIDDFunction instance + * \param bType Descriptor type. + * \param wLength Maximum number of bytes to send. + * \return USBRC_SUCCESS if the request has been handled by this function, + * otherwise USBRC_PARAM_ERR. + */ +static uint32_t HIDDFunction_GetDescriptor(HIDDFunction *pHidd, + uint8_t bType, + uint32_t wLength) +{ + HIDDescriptor1 *pHidDescriptor = (HIDDescriptor1 *)pHidd->pHidDescriptor; + uint16_t wDescriptorLength; + + TRACE_INFO_WP("gDesc{%x) ", bType); + + switch (bType) { + + case HIDGenericDescriptor_REPORT: + + /* Adjust length and send report descriptor */ + /* + wDescriptorLength = pHidDescriptor->bDescriptorLength0[0] + + pHidDescriptor->bDescriptorLength0[1]; + */ + wDescriptorLength = _Word(pHidDescriptor->wDescriptorLength0); + if (wLength > wDescriptorLength) + wLength = wDescriptorLength; + + TRACE_INFO_WP("Report(%d) ", wLength); + + USBD_Write(0, pHidd->pReportDescriptor, wLength, 0, 0); + break; + + case HIDGenericDescriptor_HID: + + /* Adjust length and send HID descriptor */ + if (wLength > sizeof(HIDDescriptor1)) + wLength = sizeof(HIDDescriptor1); + + TRACE_INFO_WP("HID(%d) ", wLength); + + USBD_Write(0, pHidDescriptor, wLength, 0, 0); + break; + + default: + return USBRC_PARAM_ERR; + } + + return USBRC_SUCCESS; +} + +/** + * Return expected report header pointer. + * \param pHidd Pointer to HIDDFunction instance + * \param bType Report type. + * \param bID Report ID. + */ +static HIDDReport* HIDDFunction_FindReport(const HIDDFunction *pHidd, + uint8_t bType, + uint8_t bID) +{ + HIDDReport** pReportList; + int32_t listSize, i; + switch(bType) { + case HIDReportRequest_INPUT: + pReportList = pHidd->pInputList; + listSize = pHidd->bInputListSize; + break; + case HIDReportRequest_OUTPUT: + pReportList = pHidd->pOutputList; + listSize = pHidd->bOutputListSize; + break; + /* No other reports supported */ + default: + TRACE_INFO("Report %x.%x not support\n\r", bType, bID); + return 0; + } + /* No list */ + if (pReportList == 0) + return 0; + /* Find report in the list */ + for (i = 0; i < listSize; i ++) { + if (bID == pReportList[i]->bID) + return pReportList[i]; + } + /* Not found */ + return 0; +} + +/** + * Sends the current Idle rate of the input report to the host. + * \param pHidd Pointer to HIDDFunction instance + * \param bID Report ID + */ +static void HIDDFunction_GetIdle(HIDDFunction *pHidd, + uint8_t bID) +{ + HIDDReport *pReport = HIDDFunction_FindReport(pHidd, + HIDReportRequest_INPUT, + bID); + TRACE_INFO_WP("gIdle(%x) ", bID); + if (pReport == 0) { + USBD_Stall(0); + return; + } + USBD_Write(0, &pReport->bIdleRate, 1, 0, 0); +} + +/** + * Retrieves the new idle rate of the input report from the USB host. + * \param pHidd Pointer to HIDDFunction instance + * \param bType Report type + * \param bID Report ID + * \param bIdleRate Report idle rate. + */ +static void HIDDFunction_SetIdle(HIDDFunction *pHidd, + uint8_t bID, + uint8_t bIdleRate) +{ + HIDDReport *pReport = HIDDFunction_FindReport(pHidd, + HIDReportRequest_INPUT, + bID); + TRACE_INFO_WP("sIdle(%x<%x) ", bID, bIdleRate); + if (pReport == 0) { + USBD_Stall(0); + return; + } + USBD_Write(0, 0, 0, 0, 0); +} + +/** + * Callback function when GetReport request data sent to host + * \param pReport Pointer to report information. + * \param status Result status + * \param transferred Number of bytes transferred + * \param remaining Number of bytes that are not transferred yet + */ +static void _GetReportCallback(HIDDReport *pReport, + uint8_t status, + uint32_t transferred, + uint32_t remaining) +{ + pReport->wTransferred = transferred; + if (pReport->fCallback) + pReport->fCallback(HIDD_EC_GETREPORT, pReport->pArg); + + USBD_Read(0, 0, 0, 0, 0); +} + +/** + * Sends the requested report to the host. + * \param pHidd Pointer to HIDDFunction instance + * \param bType Report type. + * \param bID Report ID. + * \param wLength Maximum number of bytes to send. + */ +static void HIDDFunction_GetReport(HIDDFunction *pHidd, + uint8_t bType, + uint8_t bID, + uint8_t wLength) +{ + HIDDReport *pReport = HIDDFunction_FindReport(pHidd, + bType, + bID); + TRACE_INFO_WP("gReport(%x.%x) ", bType, bID); + if (pReport == 0) { + USBD_Stall(0); + return; + } + if (wLength >= pReport->wMaxSize) { + wLength = pReport->wMaxSize; + } + USBD_Write(0, pReport->bData, wLength, + (TransferCallback)_GetReportCallback, pReport); +} + +/** + * Callback function when GetReport request data sent to host + * \param pReport Pointer to report information. + * \param status Result status + * \param transferred Number of bytes transferred + * \param remaining Number of bytes that are not transferred yet + */ +static void _SetReportCallback(HIDDReport *pReport, + uint8_t status, + uint32_t transferred, + uint32_t remaining) +{ + pReport->wTransferred = transferred; + if (pReport->fCallback) { + pReport->fCallback(HIDD_EC_SETREPORT, pReport->pArg); + } +} + +/** + * Reads the requested report from the host. + * \param pHidd Pointer to HIDDFunction instance + * \param bType Report type. + * \param bID Report ID. + * \param wLength Maximum number of bytes to read. + */ +static void HIDDFunction_SetReport(HIDDFunction *pHidd, + uint8_t bType, + uint8_t bID, + uint8_t wLength) +{ + HIDDReport *pReport = HIDDFunction_FindReport(pHidd, + bType, + bID); + TRACE_INFO_WP("sReport(%x.%x) ", bType, bID); + + if (pReport == 0) { + USBD_Stall(0); + return; + } + + if (wLength >= pReport->wMaxSize) { + wLength = pReport->wMaxSize; + } + USBD_Read(0, pReport->bData, wLength, + (TransferCallback)_SetReportCallback, pReport); +} + +/** + * Parse descriptors: Interface, Interrupt IN/OUT. + * \param desc Pointer to descriptor list. + * \param arg Argument, pointer to HIDDParseData instance. + */ +static uint32_t HIDDFunction_Parse(USBGenericDescriptor * pDesc, + HIDDParseData * pArg) +{ + /* Find HID Interface */ + if (pArg->pIfDesc == 0) { + if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) { + USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor*)pDesc; + /* Right interface for HID: + HID Class + at least 1 endpoint */ + if (pIf->bInterfaceClass == HIDInterfaceDescriptor_CLASS + && pIf->bNumEndpoints >= 1) { + /* Obtain new interface setting */ + if (pArg->pHidd->bInterface == 0xFF) { + pArg->pHidd->bInterface = pIf->bInterfaceNumber; + pArg->pIfDesc = pIf; + } + /* Find specific interface setting */ + else if (pArg->pHidd->bInterface == pIf->bInterfaceNumber) { + pArg->pIfDesc = pIf; + } + } + } + } + /* Interface end */ + else { + /* Start another interface ? */ + if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) { + /* Terminate the parse */ + return USBRC_PARTIAL_DONE; + } + /* Parse HID descriptor */ + else if (pDesc->bDescriptorType == HIDGenericDescriptor_HID) { + pArg->pHidd->pHidDescriptor = (HIDDescriptor*)pDesc; + } + /* Parse endpoints */ + else if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT) { + USBEndpointDescriptor *pEp = (USBEndpointDescriptor*)pDesc; + if (pEp->bEndpointAddress & 0x80) + pArg->pHidd->bPipeIN = pEp->bEndpointAddress & 0x7F; + else + pArg->pHidd->bPipeOUT = pEp->bEndpointAddress; + } + + /* Check if all data is OK */ + if (pArg->pHidd->bInterface != 0xFF + && pArg->pHidd->bPipeIN != 0xFF + && pArg->pHidd->bPipeOUT != 0xFF) + return USBRC_FINISHED; + } + return 0; +} + +/** + * Callback function when interrupt OUT data received from host + * \param pHidd Pointer to HIDDFunction instance + * \param status Result status + * \param transferred Number of bytes transferred + * \param remaining Number of bytes that are not transferred yet + */ +static void HIDDFunction_ReportReceived(HIDDFunction *pHidd, + uint8_t status, + uint32_t transferred, + uint32_t remaining) +{ + HIDDReport *pOut = pHidd->pOutputList[pHidd->bCurrOutput]; + if (status != USBRC_SUCCESS) { + + TRACE_ERROR("HIDDFun::ReadReport: %x\n\r", status); + return; + } + + /* Transfered information */ + pOut->wTransferred = transferred; + + /* Data Change callback */ + if (pOut->fCallback) + pOut->fCallback(HIDD_EC_REPORTCHANGED, pOut->pArg); + + /* Proceed to next output report */ + pHidd->bCurrOutput ++; + if (pHidd->bCurrOutput >= pHidd->bOutputListSize) + pHidd->bCurrOutput = 0; + + /* Start reading a report */ + USBD_Read(pHidd->bPipeOUT, + pHidd->pOutputList[pHidd->bCurrOutput]->bData, + pHidd->pOutputList[pHidd->bCurrOutput]->wMaxSize, + (TransferCallback)HIDDFunction_ReportReceived, + (void*)pHidd); +} + +/** + * Callback function when interrupt IN data sent to host + * \param pHidd Pointer to HIDDFunction instance + * \param status Result status + * \param transferred Number of bytes transferred + * \param remaining Number of bytes that are not transferred yet + */ +static void HIDDFunction_ReportSent(HIDDFunction *pHidd, + uint8_t status, + uint32_t transferred, + uint32_t remaining) +{ + HIDDReport *pIn = pHidd->pInputList[pHidd->bCurrInput]; + if (status != USBRC_SUCCESS) { + + TRACE_ERROR("HIDDFun::WriteReport: %x\n\r", status); + return; + } + + /* Transfered information */ + pIn->wTransferred = transferred; + + /* Report Sent Callback */ + if (pIn->fCallback) + pIn->fCallback(HIDD_EC_REPORTSENT, pIn->pArg); + + /* Proceed to next output report */ + pHidd->bCurrInput ++; + if (pHidd->bCurrInput >= pHidd->bInputListSize) + pHidd->bCurrInput = 0; + + /* Start writing a report */ + USBD_Write(pHidd->bPipeIN, + pHidd->pInputList[pHidd->bCurrInput]->bData, + pHidd->pInputList[pHidd->bCurrInput]->wMaxSize, + (TransferCallback)HIDDFunction_ReportReceived, + (void*)pHidd); +} + + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initialize the USB Device HID function, for general HID device support. + * \param pHidd Pointer to HIDDFunction instance. + * \param pUsbd Pointer to USBDDriver instance. + * \param bInterfaceNb Interface number, + * can be 0xFF to obtain from descriptors. + * \param pReportDescriptor Pointer to report descriptor. + * \param pInputList Pointer to an HID input report list + * \param bInputListSize HID input report list size + * \param pOutputList Pointer to an HID output report list + * \param bOutputListSize HID output report list size + */ +void HIDDFunction_Initialize(HIDDFunction * pHidd, + USBDDriver * pUsbd, uint8_t bInterfaceNb, + const uint8_t * pReportDescriptor, + HIDDReport* pInputList[], uint8_t bInputListSize, + HIDDReport* pOutputList[], uint8_t bOutputListSize) +{ + TRACE_INFO("HIDDFunction_Initialize\n\r"); + + pHidd->pUsbd = pUsbd; + pHidd->pReportDescriptor = (uint8_t *)pReportDescriptor; + pHidd->pHidDescriptor = 0; + + pHidd->bInterface = bInterfaceNb; + pHidd->bPipeIN = 0xFF; + pHidd->bPipeOUT = 0xFF; + pHidd->bProtocol = HIDProtocol_REPORT; /* Non-boot protocol */ + + pHidd->pInputList = pInputList; + pHidd->pOutputList = pOutputList; + pHidd->bInputListSize = bInputListSize; + pHidd->bOutputListSize = bOutputListSize; + pHidd->bCurrInput = 0; + pHidd->bCurrOutput = 0; + +} + +/** + * Parse the USB HID Function Interface. + * Only first interface and its endpoints parsed. + * \param pHidd Pointer to HIDDFunction instance. + * \param pDescriptors Pointer to descriptor list. + * \param dwLength Descriptor list block length in bytes. + * \return Pointer to next descriptor. 0 means no other descriptor. + */ +USBGenericDescriptor *HIDDFunction_ParseInterface(HIDDFunction * pHidd, + USBGenericDescriptor * pDescriptors, + uint32_t dwLength) +{ + HIDDParseData data; + pHidd->bPipeIN = 0xFF; + pHidd->bPipeOUT = 0xFF; + data.pHidd = pHidd; + data.pIfDesc = 0; + return USBGenericDescriptor_Parse(pDescriptors, + dwLength, + (USBDescriptorParseFunction)HIDDFunction_Parse, + (void*)&data); +} + +/** + * Start polling interrupt OUT pipe + * (output report, host to device) if there is. + * \param pHidd Pointer to HIDDFunction instance. + */ +uint32_t HIDDFunction_StartPollingOutputs(HIDDFunction * pHidd) +{ + /* No report, do nothing */ + if (pHidd->bOutputListSize == 0 + || pHidd->pOutputList == 0) + return USBRC_PARAM_ERR; + + /* Start reading a report */ + return USBD_Read(pHidd->bPipeOUT, + pHidd->pOutputList[pHidd->bCurrOutput]->bData, + pHidd->pOutputList[pHidd->bCurrOutput]->wMaxSize, + (TransferCallback)HIDDFunction_ReportReceived, + (void*)pHidd); +} + +/** + * Start sending reports via interrupt IN pipe + * (input report, device to host) if there is. + * \param pHidd Pointer to HIDDFunction instance. + */ +uint32_t HIDDFunction_StartSendingInputs(HIDDFunction * pHidd) +{ + /* No report, do nothing */ + if (pHidd->bInputListSize == 0 + || pHidd->pInputList == 0) + return USBRC_PARAM_ERR; + /* Start sending a report */ + return USBD_Write(pHidd->bPipeIN, + pHidd->pInputList[pHidd->bCurrInput]->bData, + pHidd->pInputList[pHidd->bCurrInput]->wMaxSize, + (TransferCallback)HIDDFunction_ReportSent, + (void*)pHidd); +} + +/** + * Handles HID-specific SETUP request sent by the host. + * \param pHidd Pointer to HIDDFunction instance. + * \param request Pointer to a USBGenericRequest instance + */ +uint32_t HIDDFunction_RequestHandler(HIDDFunction *pHidd, + const USBGenericRequest *request) +{ + uint32_t reqCode = (request->bmRequestType << 8) + | (request->bRequest); + + switch (reqCode) { + /* Get_Descriptor */ + case USBGenericRequest_GETDESCRIPTOR|(0x81<<8): + return HIDDFunction_GetDescriptor( + pHidd, + USBGetDescriptorRequest_GetDescriptorType(request), + USBGenericRequest_GetLength(request)); + /* Clear_Feature (EP) */ + case USBGenericRequest_CLEARFEATURE|(0x02<<8): + if (USBFeatureRequest_GetFeatureSelector(request) + == USBFeatureRequest_ENDPOINTHALT) { + uint8_t ep = USBGenericRequest_GetEndpointNumber(request); + if (USBD_IsHalted(ep)) { + /* Unhalt EP */ + USBD_Unhalt(ep); + /* Restart Polling OUT */ + if (ep == pHidd->bPipeOUT) { + HIDDFunction_StartPollingOutputs(pHidd); + } + /* and send a zero-length packet */ + USBD_Write(0, 0, 0, 0, 0); + } + break; /* Handled success */ + } + return USBRC_PARAM_ERR; + /* Set_Descriptor */ + case USBGenericRequest_SETDESCRIPTOR|(0x01<<8): + /* Optional, not implemented */ + USBD_Stall(0); + break; + /* Get_Idle */ + case (0xa1<<8)|HIDGenericRequest_GETIDLE: + HIDDFunction_GetIdle(pHidd, + HIDReportRequest_GetReportId(request)); + break; + /* Set_Idle */ + case (0x21<<8)|HIDGenericRequest_SETIDLE: + HIDDFunction_SetIdle(pHidd, + HIDReportRequest_GetReportId(request), + HIDIdleRequest_GetIdleRate(request)); + break; + /* Get_Report */ + case (0xa1<<8)|HIDGenericRequest_GETREPORT: + HIDDFunction_GetReport(pHidd, + HIDReportRequest_GetReportType(request), + HIDReportRequest_GetReportId(request), + USBGenericRequest_GetLength(request)); + break; + /* Set_Report */ + case (0x21<<8)|HIDGenericRequest_SETREPORT: + HIDDFunction_SetReport(pHidd, + HIDReportRequest_GetReportType(request), + HIDReportRequest_GetReportId(request), + USBGenericRequest_GetLength(request)); + break; + /* Get_Protocol */ + case (0xa1<<8)|HIDGenericRequest_SETPROTOCOL: + pHidd->bProtocol = request->wValue; + USBD_Write(0, 0, 0, 0, 0); + break; + /* Set_Protocol */ + case (0x21<<8)|HIDGenericRequest_GETPROTOCOL: + USBD_Write(0, &pHidd->bProtocol, 1, 0, 0); + break; + + default: + return USBRC_PARAM_ERR; + } + return USBRC_SUCCESS; +} + +/** + * Read raw data through USB interrupt OUT EP. + * \param pHidd Pointer to HIDDFunction instance. + * \param pData Pointer to the data buffer. + * \param dwLength The data length. + * \param fCallback Callback function invoked when transferring done. + * \param pArg Pointer to additional arguments. + */ +uint32_t HIDDFunction_Read(const HIDDFunction *pHidd, + void* pData, + uint32_t dwLength, + TransferCallback fCallback, + void* pArg) +{ + return USBD_Read(pHidd->bPipeIN, + pData, dwLength, + fCallback, pArg); +} + +/** + * Write raw data through USB interrupt IN EP. + * \param pHidd Pointer to HIDDFunction instance. + * \param pData Pointer to the data sent. + * \param dwLength The data length. + * \param fCallback Callback function invoked when transferring done. + * \param pArg Pointer to additional arguments. + */ +uint32_t HIDDFunction_Write(const HIDDFunction *pHidd, + void* pData, + uint32_t dwLength, + TransferCallback fCallback, + void* pArg) +{ + return USBD_Write(pHidd->bPipeIN, + pData, dwLength, + fCallback, pArg); +} + +/** + * Initialize a report. + * \param pReport Pointer to HIDDReport instance. + * \param wSize Size of the report data. + * \param bID Report ID. + * \param fCallback Callback function for report events. + * \param pArg Pointer to event handler arguments. + */ +void HIDDFunction_InitializeReport(HIDDReport* pReport, + uint16_t wSize, + uint8_t bID, + HIDDReportEventCallback fCallback, + void* pArg) +{ + pReport->wMaxSize = wSize; + pReport->wTransferred = 0; + pReport->bIdleRate = 0; + pReport->bDelay = 0; + pReport->bID = bID; + + pReport->fCallback = fCallback; + pReport->pArg = pArg; +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/hid-transfer/HIDDTransferDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/hid-transfer/HIDDTransferDriver.c new file mode 100644 index 00000000..0466f401 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/hid-transfer/HIDDTransferDriver.c @@ -0,0 +1,481 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_hid_tran + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include "HIDDTransferDriver.h" +#include + +#include +#include +#include + +#include + +#include + +/*------------------------------------------------------------------------------ + * Internal types + *------------------------------------------------------------------------------*/ + +/** + * Report struct for HID transfer. + */ +typedef struct _HIDDTransferReport { + /** Callback when report done */ + HIDDReportEventCallback fCallback; + /** Callback arguments */ + void* pArg; + + /** Report size (ID + DATA) */ + uint16_t wMaxSize; + /** Transfered size */ + uint16_t wTransferred; + /** Report idle rate */ + uint8_t bIdleRate; + /** Delay count for Idle */ + uint8_t bDelay; + /** Report ID */ + uint8_t bID; + /** Report data address */ + uint8_t bData[HIDDTransferDriver_REPORTSIZE]; +} HIDDTransferReport; + +/** + * Driver structure for an HID device implementing simple transfer + * functionalities. + */ +typedef struct _HIDDTransferDriver { + + /** Standard HID function interface. */ + HIDDFunction hidFunction; + + /** HID Input report list */ + HIDDReport *inputReports[1]; + /** HID Output report list */ + HIDDReport *outputReports[1]; + + /* OUT Report - block input for SET_REPORT */ + /**< Output report block size */ + uint16_t iReportLen; + /**< Output report data buffer */ + uint8_t iReportBuf[HIDDTransferDriver_REPORTSIZE]; + +} HIDDTransferDriver; + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/** Input report buffers */ +static HIDDTransferReport inputReport; + +/** Output report buffers */ +static HIDDTransferReport outputReport; + +/** Static instance of the HID Transfer device driver. */ +static HIDDTransferDriver hiddTransferDriver; + +/** Report descriptor used by the driver. */ +static const uint8_t hiddTransferReportDescriptor[] = { + + /* Global Usage Page */ + HIDReport_GLOBAL_USAGEPAGE + 2, 0xFF, 0xFF, /* Vendor-defined */ + + /* Collection: Application */ + HIDReport_LOCAL_USAGE + 1, 0xFF, /* Vendor-defined */ + HIDReport_COLLECTION + 1, HIDReport_COLLECTION_APPLICATION, + + /* Input report: Vendor-defined */ + HIDReport_LOCAL_USAGE + 1, 0xFF, /* Vendor-defined usage */ + HIDReport_GLOBAL_REPORTCOUNT + 1, HIDDTransferDriver_REPORTSIZE, + HIDReport_GLOBAL_REPORTSIZE + 1, 8, + HIDReport_GLOBAL_LOGICALMINIMUM + 1, (uint8_t) -128, + HIDReport_GLOBAL_LOGICALMAXIMUM + 1, (uint8_t) 127, + HIDReport_INPUT + 1, 0, /* No Modifiers */ + + /* Output report: vendor-defined */ + HIDReport_LOCAL_USAGE + 1, 0xFF, /* Vendor-defined usage */ + HIDReport_GLOBAL_REPORTCOUNT + 1, HIDDTransferDriver_REPORTSIZE, + HIDReport_GLOBAL_REPORTSIZE + 1, 8, + HIDReport_GLOBAL_LOGICALMINIMUM + 1, (uint8_t) -128, + HIDReport_GLOBAL_LOGICALMAXIMUM + 1, (uint8_t) 127, + HIDReport_OUTPUT + 1, 0, /* No Modifiers */ + HIDReport_ENDCOLLECTION +}; + +/*------------------------------------------------------------------------------ + * 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 uint8_t HIDDTransferDriver_GetDescriptor(uint8_t type, + uint8_t length) +{ + HIDDTransferDriver *pDrv = &hiddTransferDriver; + HIDDFunction *pHidd = &pDrv->hidFunction; + + const USBConfigurationDescriptor *pConfiguration; + HIDDescriptor *hidDescriptors[2]; + + switch (type) { + + case HIDGenericDescriptor_REPORT: + TRACE_INFO("Report "); + + /* Adjust length and send report descriptor */ + if (length > HIDDTransferDriver_REPORTDESCRIPTORSIZE) { + + length = HIDDTransferDriver_REPORTDESCRIPTORSIZE; + } + USBD_Write(0, &hiddTransferReportDescriptor, length, 0, 0); + break; + + case HIDGenericDescriptor_HID: + TRACE_INFO("HID "); + + /* Configuration descriptor is different depending on configuration */ + if (USBD_IsHighSpeed()) { + + pConfiguration = + pHidd->pUsbd->pDescriptors->pHsConfiguration; + } + else { + + pConfiguration = + pHidd->pUsbd->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; +} + +/** + * Callback function when SetReport request data received from host + * \param pArg Pointer to additional argument struct + * \param status Result status + * \param transferred Number of bytes transferred + * \param remaining Number of bytes that are not transferred yet + */ +static void HIDDTransferDriver_ReportReceived(void *pArg, + uint8_t status, + uint32_t transferred, + uint32_t remaining) +{ + HIDDTransferDriver *pDrv = &hiddTransferDriver; + pDrv->iReportLen = transferred; + USBD_Write(0, 0, 0, 0, 0); +} + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * Initializes the HID Transfer %device driver. + * \param pDescriptors Pointer to USBDDriverDescriptors instance. + */ +void HIDDTransferDriver_Initialize(const USBDDriverDescriptors * pDescriptors) +{ + HIDDTransferDriver * pDrv = &hiddTransferDriver; + USBDDriver *pUsbd = USBD_GetDriver(); + + /* One input report */ + pDrv->inputReports[0] = (HIDDReport*)&inputReport; + HIDDFunction_InitializeReport((HIDDReport *)pDrv->inputReports[0], + HIDDTransferDriver_REPORTSIZE, + 0, + 0, 0); + /* One output report */ + pDrv->outputReports[0] = (HIDDReport*)&outputReport; + HIDDFunction_InitializeReport((HIDDReport *)pDrv->outputReports[0], + HIDDTransferDriver_REPORTSIZE, + 0, + 0, 0); + + /* Initialize USBD Driver instance */ + USBDDriver_Initialize(pUsbd, + pDescriptors, + 0); /* Multiple interface settings not supported */ + /* Function instance initialize */ + HIDDFunction_Initialize(&pDrv->hidFunction, + pUsbd, 0, + hiddTransferReportDescriptor, + (HIDDReport **)(&pDrv->inputReports), 1, + (HIDDReport **)(&pDrv->outputReports), 1); + /* Initialize USBD */ + USBD_Init(); +} + +/** + * Handles configureation changed event. + * \param cfgnum New configuration number + */ +void HIDDTransferDriver_ConfigurationChangedHandler(uint8_t cfgnum) +{ + const USBDDriverDescriptors * pDescriptors = USBD_GetDriver()->pDescriptors; + HIDDTransferDriver * pDrv = &hiddTransferDriver; + HIDDFunction * pHidd = &pDrv->hidFunction; + + USBConfigurationDescriptor *pDesc; + + if (cfgnum > 0) { + + /* Parse endpoints for reports */ + if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration) + pDesc = (USBConfigurationDescriptor*)pDescriptors->pHsConfiguration; + else + pDesc = (USBConfigurationDescriptor*)pDescriptors->pFsConfiguration; + HIDDFunction_ParseInterface(pHidd, + (USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + + /* Start polling for Output Reports */ + HIDDFunction_StartPollingOutputs(pHidd); + } +} + +/** + * Handles HID-specific SETUP request sent by the host. + * \param request Pointer to a USBGenericRequest instance + */ +void HIDDTransferDriver_RequestHandler(const USBGenericRequest *request) +{ + HIDDTransferDriver *pDrv = &hiddTransferDriver; + HIDDFunction *pHidd = &pDrv->hidFunction; + + TRACE_INFO("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 (!HIDDTransferDriver_GetDescriptor( + USBGetDescriptorRequest_GetDescriptorType(request), + USBGenericRequest_GetLength(request))) { + + USBDDriver_RequestHandler(pHidd->pUsbd, + request); + } + return; /* Handled, no need to do others */ + + case USBGenericRequest_CLEARFEATURE: + + /* Check which is the requested feature */ + switch (USBFeatureRequest_GetFeatureSelector(request)) { + case USBFeatureRequest_ENDPOINTHALT: + { uint8_t ep = + USBGenericRequest_GetEndpointNumber(request); + if (USBD_IsHalted(ep)) { + /* Unhalt endpoint restart OUT EP + */ + USBD_Unhalt(ep); + if (ep == pHidd->bPipeOUT) { + HIDDFunction_StartPollingOutputs(pHidd); + } + } + /* and send a zero-length packet */ + USBD_Write(0, 0, 0, 0, 0); + return; /* Handled, no need to do others */ + } + } + break; + + } + } + /* We use different buffer for SetReport */ + else if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) { + + switch (USBGenericRequest_GetRequest(request)) { + + case HIDGenericRequest_SETREPORT: + { + uint16_t length = USBGenericRequest_GetLength(request); + uint8_t type = HIDReportRequest_GetReportType(request); + if (type == HIDReportRequest_OUTPUT) { + if (length > HIDDTransferDriver_REPORTSIZE) + length = HIDDTransferDriver_REPORTSIZE; + USBD_Read(0, + pDrv->iReportBuf, + length, + HIDDTransferDriver_ReportReceived, + 0); /* No argument to the callback function */ + } + else { + + USBD_Stall(0); + } + } + return; /* Handled, no need do others */ + } + } + + + /* Process HID requests */ + if (USBRC_SUCCESS == HIDDFunction_RequestHandler(pHidd, + request)) { + return; + } + else + USBDDriver_RequestHandler(pHidd->pUsbd, request); +} + +/** + * Try to read request buffer of SetReport. + * Set pData to 0 to get current data length only. + * \param pData Pointer to data buffer + * \param dwLength Data buffer length + * \return Number of bytes read + */ +uint16_t HIDDTransferDriver_ReadReport(void *pData, + uint32_t dwLength) +{ + HIDDTransferDriver *pDrv = &hiddTransferDriver; + + if (pData == 0) { + + return pDrv->iReportLen; + } + + if (dwLength > HIDDTransferDriver_REPORTSIZE) { + + dwLength = HIDDTransferDriver_REPORTSIZE; + } + if (dwLength > pDrv->iReportLen) { + + dwLength = pDrv->iReportLen; + } + pDrv->iReportLen = 0; + memcpy(pData, pDrv->iReportBuf, dwLength); + + return dwLength; +} + +/** + * Try to read request buffer of interrupt OUT EP. + * Set pData to 0 to get current data length only. + * \param pData Pointer to data buffer + * \param dLength Data buffer length + * \return Number of bytes read + */ +uint16_t HIDDTransferDriver_Read(void *pData, + uint32_t dLength) +{ + HIDDTransferDriver *pDrv = &hiddTransferDriver; + if (pData == 0) { + + return pDrv->outputReports[0]->wTransferred; + } + + if (dLength > HIDDTransferDriver_REPORTSIZE) { + + dLength = HIDDTransferDriver_REPORTSIZE; + } + if (dLength > pDrv->outputReports[0]->wTransferred) { + + dLength = pDrv->outputReports[0]->wTransferred; + } + pDrv->outputReports[0]->wTransferred = 0; + memcpy(pData, pDrv->outputReports[0]->bData, dLength); + + return dLength; +} + +/** + * Write data through USB interrupt IN EP. + * \param pData Pointer to the data sent. + * \param dLength The data length. + * \param fCallback Callback function invoked when transferring done. + * \param pArg Pointer to additional arguments. + */ +uint8_t HIDDTransferDriver_Write(const void *pData, + uint32_t dLength, + TransferCallback fCallback, + void *pArg) +{ + HIDDTransferDriver *pDrv = &hiddTransferDriver; + if (dLength != HIDDTransferDriver_REPORTSIZE) { + + dLength = HIDDTransferDriver_REPORTSIZE; + } + return USBD_Write(pDrv->hidFunction.bPipeIN, + pData, dLength, + fCallback, pArg); +} + +/** + * Starts a remote wake-up sequence if the host has explicitely enabled it + * by sending the appropriate SET_FEATURE request. + */ +void HIDDTransferDriver_RemoteWakeUp(void) +{ + HIDDTransferDriver *pDrv = &hiddTransferDriver; + + /* Remote wake-up has been enabled */ + if (USBDDriver_IsRemoteWakeUpEnabled(pDrv->hidFunction.pUsbd)) { + + USBD_RemoteWakeUp(); + } +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDAppArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDAppArch.png new file mode 100644 index 00000000..eec0f159 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDAppArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDStateMachine.c b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDStateMachine.c new file mode 100644 index 00000000..97774821 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDStateMachine.c @@ -0,0 +1,637 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_msd + *@{ + */ + +/*----------------------------------------------------------------------------- + * Includes + *-----------------------------------------------------------------------------*/ + +#include "SBCMethods.h" +#include "MSDDStateMachine.h" + +/*----------------------------------------------------------------------------- + * Internal functions + *-----------------------------------------------------------------------------*/ +/** + * Returns the expected transfer length and direction (IN, OUT or don't care) + * from the host point-of-view. + * \param cbw Pointer to the CBW to examinate + * \param pLength Expected length of command + * \param pType Expected direction of command + */ +static void MSDD_GetCommandInformation(MSCbw *cbw, + unsigned int *length, + unsigned char *type) +{ + /* Expected host transfer direction and length */ + (*length) = cbw->dCBWDataTransferLength; + + if (*length == 0) { + + (*type) = MSDD_NO_TRANSFER; + } + else if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) != 0) { + + (*type) = MSDD_DEVICE_TO_HOST; + } + else { + + (*type) = MSDD_HOST_TO_DEVICE; + } +} + +/** + * Pre-processes a command by checking the differences between the host and + * device expectations in term of transfer type and length. + * Once one of the thirteen cases is identified, the actions to do during the + * post-processing phase are stored in the dCase variable of the command + * state. + * \param pMsdDriver Pointer to a MSDDriver instance + * \return 1 if the command is supported, false otherwise + */ +static unsigned char MSDD_PreProcessCommand(MSDDriver *pMsdDriver) +{ + unsigned int hostLength = 0; + unsigned int deviceLength = 0; + unsigned char hostType; + unsigned char deviceType; + unsigned char isCommandSupported; + MSDCommandState *commandState = &(pMsdDriver->commandState); + MSCsw *csw = &(commandState->csw); + MSCbw *cbw = &(commandState->cbw); + MSDLun *lun = &(pMsdDriver->luns[(unsigned char) cbw->bCBWLUN]); + + /* Get information about the command */ + /* Host-side */ + MSDD_GetCommandInformation(cbw, &hostLength, &hostType); + + /* Device-side */ + isCommandSupported = SBC_GetCommandInformation(cbw->pCommand, + &deviceLength, + &deviceType, + lun); + + /* Initialize data residue and result status */ + csw->dCSWDataResidue = 0; + csw->bCSWStatus = MSD_CSW_COMMAND_PASSED; + + /* Check if the command is supported */ + if (isCommandSupported) { + + /* Identify the command case */ + if(hostType == MSDD_NO_TRANSFER) { + + /* Case 1 (Hn = Dn) */ + if(deviceType == MSDD_NO_TRANSFER) { + + /*TRACE_WARNING("Case 1\n\r"); */ + commandState->postprocess = 0; + commandState->length = 0; + } + else if(deviceType == MSDD_DEVICE_TO_HOST) { + + /* Case 2 (Hn < Di) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 2\n\r"); + commandState->postprocess = MSDD_CASE_PHASE_ERROR; + commandState->length = 0; + } + else { /*if(deviceType == MSDD_HOST_TO_DEVICE) { */ + + /* Case 3 (Hn < Do) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 3\n\r"); + commandState->postprocess = MSDD_CASE_PHASE_ERROR; + commandState->length = 0; + } + } + + /* Case 4 (Hi > Dn) */ + else if(hostType == MSDD_DEVICE_TO_HOST) { + + if(deviceType == MSDD_NO_TRANSFER) { + + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 4\n\r"); + commandState->postprocess = MSDD_CASE_STALL_IN; + commandState->length = 0; + csw->dCSWDataResidue = hostLength; + } + else if(deviceType == MSDD_DEVICE_TO_HOST) { + + if(hostLength > deviceLength) { + + /* Case 5 (Hi > Di) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 5\n\r"); + commandState->postprocess = MSDD_CASE_STALL_IN; + commandState->length = deviceLength; + csw->dCSWDataResidue = hostLength - deviceLength; + } + else if(hostLength == deviceLength) { + + /* Case 6 (Hi = Di) */ + commandState->postprocess = 0; + commandState->length = deviceLength; + } + else { /*if(hostLength < deviceLength) { */ + + /* Case 7 (Hi < Di) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 7\n\r"); + commandState->postprocess = MSDD_CASE_PHASE_ERROR; + commandState->length = hostLength; + } + } + else { /*if(deviceType == MSDD_HOST_TO_DEVICE) { */ + + /* Case 8 (Hi <> Do) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 8\n\r"); + commandState->postprocess = + MSDD_CASE_STALL_IN | MSDD_CASE_PHASE_ERROR; + commandState->length = 0; + } + } + else if(hostType == MSDD_HOST_TO_DEVICE) { + + if(deviceType == MSDD_NO_TRANSFER) { + + /* Case 9 (Ho > Dn) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 9\n\r"); + commandState->postprocess = MSDD_CASE_STALL_OUT; + commandState->length = 0; + csw->dCSWDataResidue = hostLength; + } + else if(deviceType == MSDD_DEVICE_TO_HOST) { + + /* Case 10 (Ho <> Di) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 10\n\r"); + commandState->postprocess = + MSDD_CASE_STALL_OUT | MSDD_CASE_PHASE_ERROR; + commandState->length = 0; + } + else { /*if(deviceType == MSDD_HOST_TO_DEVICE) { */ + + if(hostLength > deviceLength) { + + /* Case 11 (Ho > Do) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 11\n\r"); + commandState->postprocess = MSDD_CASE_STALL_OUT; +/* commandState->length = deviceLength; */ +/* csw->dCSWDataResidue = hostLength - deviceLength; */ + commandState->length = 0; + csw->dCSWDataResidue = deviceLength; + } + else if(hostLength == deviceLength) { + + /* Case 12 (Ho = Do) */ + /*TRACE_WARNING( */ + /* "MSDD_PreProcessCommand: Case 12\n\r"); */ + commandState->postprocess = 0; + commandState->length = deviceLength; + } + else { /*if(hostLength < deviceLength) { */ + + /* Case 13 (Ho < Do) */ + TRACE_WARNING( + "MSDD_PreProcessCommand: Case 13\n\r"); + commandState->postprocess = MSDD_CASE_PHASE_ERROR; + commandState->length = hostLength; + } + } + } + } + + return isCommandSupported; +} + +/** + * Post-processes a command given the case identified during the + * pre-processing step. + * Depending on the case, one of the following actions can be done: + * - Bulk IN endpoint is stalled + * - Bulk OUT endpoint is stalled + * - CSW status set to phase error + * \param pMsdDriver Pointer to a MSDDriver instance + * \return If the device is halted + */ +static unsigned char MSDD_PostProcessCommand(MSDDriver *pMsdDriver) +{ + MSDCommandState *commandState = &(pMsdDriver->commandState); + MSCsw *csw = &(commandState->csw); + unsigned char haltStatus = 0; + + /* STALL Bulk IN endpoint ? */ + if ((commandState->postprocess & MSDD_CASE_STALL_IN) != 0) { + + TRACE_INFO_WP("StallIn "); + //MSDD_Halt(MSDD_CASE_STALL_IN); + USBD_Halt(commandState->pipeIN); + haltStatus = 1; + } + + /* STALL Bulk OUT endpoint ? */ + if ((commandState->postprocess & MSDD_CASE_STALL_OUT) != 0) { + + TRACE_INFO_WP("StallOut "); + //MSDD_Halt(MSDD_CASE_STALL_OUT); + USBD_Halt(commandState->pipeOUT); + haltStatus = 1; + } + + /* Set CSW status code to phase error ? */ + if ((commandState->postprocess & MSDD_CASE_PHASE_ERROR) != 0) { + + TRACE_INFO_WP("PhaseErr "); + csw->bCSWStatus = MSD_CSW_PHASE_ERROR; + } + + return haltStatus; +} + +/** + * Processes the latest command received by the %device. + * \param pMsdDriver Pointer to a MSDDriver instance + * \return 1 if the command has been completed, false otherwise. + */ +static unsigned char MSDD_ProcessCommand(MSDDriver * pMsdDriver) +{ + unsigned char status; + MSDCommandState *commandState = &(pMsdDriver->commandState); + MSCbw *cbw = &(commandState->cbw); + MSCsw *csw = &(commandState->csw); + MSDLun *lun = &(pMsdDriver->luns[(unsigned char) cbw->bCBWLUN]); + unsigned char isCommandComplete = 0; + + /* Check if LUN is valid */ + if (cbw->bCBWLUN > pMsdDriver->maxLun) { + + TRACE_WARNING( + "MSDD_ProcessCommand: LUN %d not exist\n\r", cbw->bCBWLUN); + status = MSDD_STATUS_ERROR; + } + else { + + /* Process command */ + if (pMsdDriver->maxLun > 0) { + + TRACE_INFO_WP("LUN%d ", cbw->bCBWLUN); + } + + status = SBC_ProcessCommand(lun, commandState); + } + + /* Check command result code */ + if (status == MSDD_STATUS_PARAMETER) { + + TRACE_WARNING( + "MSDD_ProcessCommand: Unknown cmd 0x%02X\n\r", + cbw->pCommand[0]); + + /* Update sense data */ + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_ILLEGAL_REQUEST, + SBC_ASC_INVALID_FIELD_IN_CDB, + 0); + + /* Result codes */ + csw->bCSWStatus = MSD_CSW_COMMAND_FAILED; + isCommandComplete = 1; + + /* stall the request, IN or OUT */ + if (((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0) + && (cbw->dCBWDataTransferLength > 0)) { + + /* Stall the OUT endpoint : host to device */ + /* MSDD_Halt(MSDD_CASE_STALL_OUT); */ + commandState->postprocess = MSDD_CASE_STALL_OUT; + TRACE_INFO_WP("StaOUT "); + } + else { + + /* Stall the IN endpoint : device to host */ + /* MSDD_Halt(MSDD_CASE_STALL_IN); */ + commandState->postprocess = MSDD_CASE_STALL_IN; + TRACE_INFO_WP("StaIN "); + } + } + else if (status == MSDD_STATUS_ERROR) { + + TRACE_WARNING("MSD_ProcessCommand: Cmd %x fail\n\r", + ((SBCCommand*)commandState->cbw.pCommand)->bOperationCode); + + /* Update sense data */ + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_MEDIUM_ERROR, + SBC_ASC_INVALID_FIELD_IN_CDB, + 0); + + /* Result codes */ + csw->bCSWStatus = MSD_CSW_COMMAND_FAILED; + isCommandComplete = 1; + } + else if (status == MSDD_STATUS_RW) { + + csw->bCSWStatus = MSD_CSW_COMMAND_FAILED; + isCommandComplete = 1; + } + else { + + /* Update sense data */ + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_NO_SENSE, + 0, + 0); + + /* Is command complete ? */ + if (status == MSDD_STATUS_SUCCESS) { + + isCommandComplete = 1; + } + } + + /* Check if command has been completed */ + if (isCommandComplete) { + + TRACE_INFO_WP("Cplt "); + + /* Adjust data residue */ + if (commandState->length != 0) { + + csw->dCSWDataResidue += commandState->length; + + /* STALL the endpoint waiting for data */ + if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0) { + + /* Stall the OUT endpoint : host to device */ + /* MSDD_Halt(MSDD_CASE_STALL_OUT); */ + commandState->postprocess = MSDD_CASE_STALL_OUT; + TRACE_INFO_WP("StaOUT "); + } + else { + + /* Stall the IN endpoint : device to host */ + /* MSDD_Halt(MSDD_CASE_STALL_IN); */ + commandState->postprocess = MSDD_CASE_STALL_IN; + TRACE_INFO_WP("StaIN "); + } + } + + /* Reset command state */ + commandState->state = 0; + } + + return isCommandComplete; +} + +/** + * State machine for the MSD %device driver + * \param pMsdDriver Pointer to a MSDDriver instance + */ +void MSDD_StateMachine(MSDDriver * pMsdDriver) +{ + MSDCommandState *commandState = &(pMsdDriver->commandState); + MSCbw *cbw = &(commandState->cbw); + MSCsw *csw = &(commandState->csw); + MSDTransfer *transfer = &(commandState->transfer); + unsigned char status; + + /* Identify current driver state */ + switch (pMsdDriver->state) { + /*---------------------- */ + case MSDD_STATE_READ_CBW: + /*---------------------- */ + /* Start the CBW read operation */ + transfer->semaphore = 0; + #if 1 + status = USBD_Read(commandState->pipeOUT, + cbw, + MSD_CBW_SIZE, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Read(cbw, + MSD_CBW_SIZE, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + + /* Check operation result code */ + if (status == USBD_STATUS_SUCCESS) { + + /* If the command was successful, wait for transfer */ + pMsdDriver->state = MSDD_STATE_WAIT_CBW; + } + break; + + /*---------------------- */ + case MSDD_STATE_WAIT_CBW: + /*---------------------- */ + /* Check transfer semaphore */ + if (transfer->semaphore > 0) { + + /* Take semaphore and terminate transfer */ + transfer->semaphore--; + + /* Check if transfer was successful */ + if (transfer->status == USBD_STATUS_SUCCESS) { + + TRACE_INFO_WP("------------------------------\n\r"); + + /* Process received command */ + pMsdDriver->state = MSDD_STATE_PROCESS_CBW; + } + else if (transfer->status == USBD_STATUS_RESET) { + + TRACE_INFO("MSDD_StateMachine: EP resetted\n\r"); + pMsdDriver->state = MSDD_STATE_READ_CBW; + } + else { + + TRACE_WARNING( + "MSDD_StateMachine: Failed to read CBW\n\r"); + pMsdDriver->state = MSDD_STATE_READ_CBW; + } + } + break; + + /*------------------------- */ + case MSDD_STATE_PROCESS_CBW: + /*------------------------- */ + /* Check if this is a new command */ + if (commandState->state == 0) { + + /* Copy the CBW tag */ + csw->dCSWTag = cbw->dCBWTag; + + /* Check that the CBW is 31 bytes long */ + if ((transfer->transferred != MSD_CBW_SIZE) || + (transfer->remaining != 0)) { + + TRACE_WARNING( + "MSDD_StateMachine: Invalid CBW (len %d)\n\r", + (int)transfer->transferred); + + /* Wait for a reset recovery */ + pMsdDriver->waitResetRecovery = 1; + + /* Halt the Bulk-IN and Bulk-OUT pipes */ + //MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN); + USBD_Halt(commandState->pipeIN); + USBD_Halt(commandState->pipeOUT); + + csw->bCSWStatus = MSD_CSW_COMMAND_FAILED; + pMsdDriver->state = MSDD_STATE_READ_CBW; + + } + /* Check the CBW Signature */ + else if (cbw->dCBWSignature != MSD_CBW_SIGNATURE) { + + TRACE_WARNING( + "MSD_BOTStateMachine: Invalid CBW (Bad signature)\n\r"); + + /* Wait for a reset recovery */ + pMsdDriver->waitResetRecovery = 1; + + /* Halt the Bulk-IN and Bulk-OUT pipes */ + //MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN); + USBD_Halt(commandState->pipeIN); + USBD_Halt(commandState->pipeOUT); + + csw->bCSWStatus = MSD_CSW_COMMAND_FAILED; + pMsdDriver->state = MSDD_STATE_READ_CBW; + } + else { + + /* Pre-process command */ + MSDD_PreProcessCommand(pMsdDriver); + } + } + + /* Process command */ + if (csw->bCSWStatus == MSDD_STATUS_SUCCESS) { + + if (MSDD_ProcessCommand(pMsdDriver)) { + + /* Post-process command if it is finished */ + if (MSDD_PostProcessCommand(pMsdDriver)) { + + TRACE_INFO_WP("WaitHALT "); + pMsdDriver->state = MSDD_STATE_WAIT_HALT; + } + else { + + pMsdDriver->state = MSDD_STATE_SEND_CSW; + } + } + TRACE_INFO_WP("\n\r"); + } + + break; + + /*---------------------- */ + case MSDD_STATE_SEND_CSW: + /*---------------------- */ + /* Set signature */ + csw->dCSWSignature = MSD_CSW_SIGNATURE; + + /* Start the CSW write operation */ + #if 1 + status = USBD_Write(commandState->pipeIN, + csw, + MSD_CSW_SIZE, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Write(csw, + MSD_CSW_SIZE, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + + /* Check operation result code */ + if (status == USBD_STATUS_SUCCESS) { + + TRACE_INFO_WP("SendCSW "); + + /* Wait for end of transfer */ + pMsdDriver->state = MSDD_STATE_WAIT_CSW; + } + break; + + /*---------------------- */ + case MSDD_STATE_WAIT_CSW: + /*---------------------- */ + /* Check transfer semaphore */ + if (transfer->semaphore > 0) { + + /* Take semaphore and terminate transfer */ + transfer->semaphore--; + + /* Check if transfer was successful */ + if (transfer->status == USBD_STATUS_RESET) { + + TRACE_INFO("MSDD_StateMachine: EP resetted\n\r"); + } + else if (transfer->status == USBD_STATUS_ABORTED) { + + TRACE_WARNING( + "MSDD_StateMachine: Failed to send CSW\n\r"); + } + else { + + TRACE_INFO_WP("ok"); + } + + /* Read new CBW */ + pMsdDriver->state = MSDD_STATE_READ_CBW; + } + break; + + /*---------------------- */ + case MSDD_STATE_WAIT_HALT: + /*---------------------- */ + //if (MSDD_IsHalted() == 0) { + if (!USBD_IsHalted(commandState->pipeIN)) { + + pMsdDriver->state = MSDD_STATE_SEND_CSW; + } + break; + } +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriver.c b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriver.c new file mode 100644 index 00000000..660e30bb --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriver.c @@ -0,0 +1,113 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_msd + *@{ + * Implement a single interface device with single MS function in. + */ + +/*------------------------------------------------------------------------------ + * Includes + *------------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------- + * Internal variables + *-----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Internal functions + *-----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Exported functions + *-----------------------------------------------------------------------------*/ + +/** + * Initializes the MSD driver and the associated USB driver. + * \param pDescriptors Pointer to Descriptors list for MSD Device. + * \param pLuns Pointer to a list of LUNs + * \param numLuns Number of LUN in list + * \see MSDLun + */ +void MSDDriver_Initialize( + const USBDDriverDescriptors *pDescriptors, + MSDLun *pLuns, unsigned char numLuns) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBDDriver_Initialize(pUsbd, pDescriptors, 0); + MSDFunction_Initialize(pUsbd, 0, pLuns, numLuns); + USBD_Init(); +} + +/** + * Invoked when the configuration of the device changes. Resets the mass + * storage driver. + * \param pMsdDriver Pointer to MSDDriver instance. + * \param cfgnum New configuration number. + */ +void MSDDriver_ConfigurationChangeHandler( + uint8_t cfgnum) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + USBConfigurationDescriptor *pDesc; + if (cfgnum) { + pDesc = USBDDriver_GetCfgDescriptors(pUsbd, cfgnum); + MSDFunction_Configure((USBGenericDescriptor*)pDesc, + pDesc->wTotalLength); + } +} + +/** + * Handler for incoming SETUP requests on default Control endpoint 0. + * + * Standard requests are forwarded to the USBDDriver_RequestHandler + * method. + * \param pMsdDriver Pointer to MSDDriver instance. + * \param request Pointer to a USBGenericRequest instance + */ +void MSDDriver_RequestHandler( + const USBGenericRequest *request) +{ + USBDDriver *pUsbd = USBD_GetDriver(); + TRACE_INFO_WP("NewReq "); + if (MSDFunction_RequestHandler(request)) { + USBDDriver_RequestHandler(pUsbd, request); + } +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverArch.png new file mode 100644 index 00000000..4063440b Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverClasses.png b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverClasses.png new file mode 100644 index 00000000..3fd68d14 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverClasses.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverStates.png b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverStates.png new file mode 100644 index 00000000..a0c55c80 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDDriverStates.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDFunction.c b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDFunction.c new file mode 100644 index 00000000..c4531f41 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDFunction.c @@ -0,0 +1,311 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_msd + *@{ + * Implements Massstorage Function for USB device. + */ + +/*------------------------------------------------------------------------------ + * Includes + *------------------------------------------------------------------------------*/ + +#include + +#include +#include +#include +#include +#include + +/*----------------------------------------------------------------------------- + * Internal Types + *-----------------------------------------------------------------------------*/ + +/** Parse data extension */ +typedef struct _MSDParseData { + /** Pointer to driver instance */ + MSDDriver *pMsdd; + /** Pointer to currently processed interface descriptor */ + USBInterfaceDescriptor *pIf; +} MSDParseData; + + +/*----------------------------------------------------------------------------- + * Internal variables + *-----------------------------------------------------------------------------*/ + +/** MSD Driver instance for device function */ +static MSDDriver msdFunction; + +/*----------------------------------------------------------------------------- + * Internal functions + *-----------------------------------------------------------------------------*/ + +/** + * Parse descriptors: Bulk EP IN/OUT. + * \param desc Pointer to current processed descriptor. + * \param arg Pointer to data extention struct for parsing. + */ +static uint8_t MSDFunction_Parse(USBGenericDescriptor* desc, MSDParseData* arg) +{ + MSDDriver *pMsdd = arg->pMsdd; + USBInterfaceDescriptor *pIf; + + /* Not a valid descriptor */ + if (desc->bLength == 0) { + return USBD_STATUS_INVALID_PARAMETER; + } + /* Find interface descriptor */ + if (desc->bDescriptorType == USBGenericDescriptor_INTERFACE) { + pIf = (USBInterfaceDescriptor*)desc; + if (pIf->bInterfaceClass == MSInterfaceDescriptor_CLASS) { + /* First found IF */ + if (pMsdd->interfaceNb == 0xFF) { + pMsdd->interfaceNb = pIf->bInterfaceNumber; + arg->pIf = pIf; + } + /* Specific IF */ + else if (pMsdd->interfaceNb == pIf->bInterfaceNumber) { + arg->pIf = pIf; + } + + } + } + /* Start parse endpoints */ + if (arg->pIf) { + if (desc->bDescriptorType == USBGenericDescriptor_ENDPOINT) { + USBEndpointDescriptor *pEP = (USBEndpointDescriptor*)desc; + if (pEP->bmAttributes == USBEndpointDescriptor_BULK) { + if (pEP->bEndpointAddress & 0x80) + pMsdd->commandState.pipeIN = pEP->bEndpointAddress & 0x7F; + else + pMsdd->commandState.pipeOUT = pEP->bEndpointAddress; + } + } + + /* Finish when found all pipes */ + if (pMsdd->commandState.pipeIN != 0 + && pMsdd->commandState.pipeOUT != 0) { + return USBRC_FINISHED; + } + } + return 0; +} + +/** + * Resets the state of the MSD driver + */ +static void MSDFunction_Reset(void) +{ + MSDDriver *pMsdd = &msdFunction; + + TRACE_INFO_WP("MSDReset "); + + pMsdd->state = MSDD_STATE_READ_CBW; + pMsdd->waitResetRecovery = 0; + pMsdd->commandState.state = 0; +} + +/*----------------------------------------------------------------------------- + * Exported functions + *-----------------------------------------------------------------------------*/ + +/** + * Initializes the MSD driver and the associated USB driver. + * \param pUsbd Pointer to USBDDriver instance. + * \param bInterfaceNb Interface number for the function. + * \param pLuns Pointer to a list of LUNs + * \param numLuns Number of LUN in list + * \see MSDLun + */ +void MSDFunction_Initialize( + USBDDriver *pUsbd, uint8_t bInterfaceNb, + MSDLun *pLuns, uint8_t numLuns) +{ + MSDDriver *pMsdDriver = &msdFunction; + + TRACE_INFO("MSDFun init\n\r"); + + /* Driver instance */ + pMsdDriver->pUsbd = pUsbd; + pMsdDriver->interfaceNb = bInterfaceNb; + + /* Command state initialization */ + pMsdDriver->commandState.state = 0; + pMsdDriver->commandState.postprocess = 0; + pMsdDriver->commandState.length = 0; + pMsdDriver->commandState.transfer.semaphore = 0; + + /* LUNs */ + pMsdDriver->luns = pLuns; + pMsdDriver->maxLun = (uint8_t) (numLuns - 1); + + /* Reset BOT driver */ + MSDFunction_Reset(); +} + +/** + * Invoked when the configuration of the device changes. + * Pass endpoints and resets the mass storage function. + * \pDescriptors Pointer to the descriptors for function configure. + * \wLength Length of descriptors in number of bytes. + */ +void MSDFunction_Configure(USBGenericDescriptor *pDescriptors, + uint16_t wLength) +{ + MSDDriver *pMsdDriver = &msdFunction; + MSDParseData parseData; + + TRACE_INFO_WP("MSDFunCfg "); + + pMsdDriver->state = MSDD_STATE_READ_CBW; + pMsdDriver->waitResetRecovery = 0; + pMsdDriver->commandState.state = 0; + + parseData.pIf = 0; + parseData.pMsdd = pMsdDriver; + USBGenericDescriptor_Parse((USBGenericDescriptor*)pDescriptors, wLength, + (USBDescriptorParseFunction)MSDFunction_Parse, &parseData); + + MSDFunction_Reset(); +} + +/** + * Handler for incoming SETUP requests on default Control endpoint 0. + * + * Standard requests are forwarded to the USBDDriver_RequestHandler + * method. + * \param pMsdDriver Pointer to MSDDriver instance. + * \param request Pointer to a USBGenericRequest instance + */ +uint32_t MSDFunction_RequestHandler( + const USBGenericRequest *request) +{ + MSDDriver *pMsdDriver = &msdFunction; + uint32_t reqCode = (USBGenericRequest_GetType(request) << 8) + | (USBGenericRequest_GetRequest(request)); + + TRACE_INFO_WP("Msdf "); + + /* Handle requests */ + switch (reqCode) { + /*--------------------- */ + 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 (!pMsdDriver->waitResetRecovery) { + + /* Forward the request to the standard handler */ + USBDDriver_RequestHandler(USBD_GetDriver(), request); + } + else { + + TRACE_INFO_WP("No "); + } + + USBD_Write(0, 0, 0, 0, 0); + + return USBRC_SUCCESS; /* Handled */ + + } + break; + + /*------------------- */ + case (USBGenericRequest_CLASS<<8)|MSD_GET_MAX_LUN: + /*------------------- */ + TRACE_INFO_WP("gMaxLun "); + + /* Check request parameters */ + if ((request->wValue == 0) + && (request->wIndex == pMsdDriver->interfaceNb) + && (request->wLength == 1)) { + + USBD_Write(0, &(pMsdDriver->maxLun), 1, 0, 0); + + } + else { + + TRACE_WARNING( + "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r", + request->wValue, request->wIndex, request->wLength); + USBD_Stall(0); + } + return USBRC_SUCCESS; /* Handled */ + + /*----------------------- */ + case (USBGenericRequest_CLASS<<8)|MSD_BULK_ONLY_RESET: + /*----------------------- */ + TRACE_INFO_WP("Rst "); + + /* Check parameters */ + if ((request->wValue == 0) + && (request->wIndex == pMsdDriver->interfaceNb) + && (request->wLength == 0)) { + + /* Reset the MSD driver */ + MSDFunction_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); + } + return USBRC_SUCCESS; /* Handled */ + } + + return USBRC_PARAM_ERR; +} + +/** + * State machine for the MSD driver + */ +void MSDFunction_StateMachine(void) +{ + if (USBD_GetState() < USBD_STATE_CONFIGURED){} + else MSDD_StateMachine(&msdFunction); + +} + +/**@}*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDIOFifo.c b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDIOFifo.c new file mode 100644 index 00000000..be742e4c --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDIOFifo.c @@ -0,0 +1,75 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "MSDIOFifo.h" + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * \brief Initializes a MSDIOFifo instance. + * \param pFifo Pointer to the MSDIOFifo instance to initialize + * \param pBuffer Pointer to a buffer used for read/write operation and + * which must be blockSize bytes aligned. + * \param bufferSize Total size of the buffer in bytes + */ +void MSDIOFifo_Init(MSDIOFifo *pFifo, + void * pBuffer, unsigned short bufferSize) +{ + pFifo->pBuffer = pBuffer; + pFifo->bufferSize = bufferSize; + + pFifo->inputNdx = 0; + pFifo->outputNdx = 0; + pFifo->inputTotal = 0; + pFifo->outputTotal = 0; + + pFifo->inputState = MSDIO_IDLE; + pFifo->outputState = MSDIO_IDLE; + + pFifo->fullCnt = 0; + pFifo->nullCnt = 0; +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDLun.c b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDLun.c new file mode 100644 index 00000000..66a4d335 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDLun.c @@ -0,0 +1,389 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + + +#include "MSDLun.h" +#include +#include + +/*------------------------------------------------------------------------------ + * Constants + *------------------------------------------------------------------------------*/ + +/** Default LUN block size in bytes */ +#define DEFAULT_LUN_BLOCK_SIZE 512 + +/*------------------------------------------------------------------------------ + * Internal variables + *------------------------------------------------------------------------------*/ + +/** Inquiry data to return to the host for the Lun. */ +static SBCInquiryData inquiryData = { + + SBC_DIRECT_ACCESS_BLOCK_DEVICE, /* Direct-access block device */ + SBC_PERIPHERAL_DEVICE_CONNECTED,/* Peripheral device is connected */ + 0x00, /* Reserved bits */ + 0x01, /* Media is removable */ + SBC_SPC_VERSION_4, /* SPC-4 supported */ + 0x2, /* Response data format, must be 0x2 */ + 0, /* Hierarchical addressing not supported */ + 0, /* ACA not supported */ + 0x0, /* Obsolete bits */ + sizeof(SBCInquiryData) - 5, /* Additional length */ + 0, /* No embedded SCC */ + 0, /* No access control coordinator */ + SBC_TPGS_NONE, /* No target port support group */ + 0, /* Third-party copy not supported */ + 0x0, /* Reserved bits */ + 0, /* Protection information not supported */ + 0x0, /* Obsolete bit */ + 0, /* No embedded enclosure service component */ + 0x0, /* ??? */ + 0, /* Device is not multi-port */ + 0x0, /* Obsolete bits */ + 0x0, /* Unused feature */ + 0x0, /* Unused features */ + 0, /* Task management model not supported */ + 0x0, /* ??? */ + {'A','T','M','E','L',' ',' ',' '}, + {'M','a','s','s',' ', + 'S','t','o','r','a','g','e',' ', + 'M','S','D'}, + {'0','.','0','1'}, + {'M','a','s','s',' ', + 'S','t','o','r','a','g','e',' ', + 'E','x','a','m','p','l','e'}, + 0x00, /* Unused features */ + 0x00, /* Reserved bits */ + {SBC_VERSION_DESCRIPTOR_SBC_3}, /* SBC-3 compliant device */ + {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0} /* Reserved */ +}; + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +/** + * \brief Initializes a LUN instance. Must be invoked at least once even no + * Media is linked. + * \param lun Pointer to the MSDLun instance to initialize + * \param media Media on which the LUN is constructed, set to 0 to + * disconnect the Media or initialize an ejected LUN. + * \param ioBuffer Pointer to a buffer used for read/write operation and + * which must be blockSize bytes long. + * \param ioBufferSize Size of the allocated IO buffer. + * \param baseAddress Base address of the LUN in number of media blocks + * \param size Total size of the LUN in number of media blocks + * \param blockSize One block of the LUN in number of media blocks + * \param protected The LUN area is forced to readonly even the media + * is writable + * \param dataMonitor Pointer to a Monitor Function to analyze the flow of + * this LUN. + */ +void LUN_Init(MSDLun *lun, + Media *media, + uint8_t *ioBuffer, + uint32_t ioBufferSize, + uint32_t baseAddress, + uint32_t size, + uint16_t blockSize, + uint8_t protected, + void (*dataMonitor)(uint8_t flowDirection, + uint32_t dataLength, + uint32_t fifoNullCount, + uint32_t fifoFullCount)) +{ + uint32_t logicalBlockAddress; + TRACE_INFO("LUN init\n\r"); + + /* Initialize inquiry data */ + + lun->inquiryData = &inquiryData; + + /* Initialize request sense data */ + + lun->requestSenseData.bResponseCode = SBC_SENSE_DATA_FIXED_CURRENT; + lun->requestSenseData.isValid = 1; + lun->requestSenseData.bObsolete1 = 0; + lun->requestSenseData.bSenseKey = SBC_SENSE_KEY_NO_SENSE; + lun->requestSenseData.bReserved1 = 0; + lun->requestSenseData.isILI = 0; + lun->requestSenseData.isEOM = 0; + lun->requestSenseData.isFilemark = 0; + lun->requestSenseData.pInformation[0] = 0; + lun->requestSenseData.pInformation[1] = 0; + lun->requestSenseData.pInformation[2] = 0; + lun->requestSenseData.pInformation[3] = 0; + lun->requestSenseData.bAdditionalSenseLength + = sizeof(SBCRequestSenseData) - 8; + lun->requestSenseData.bAdditionalSenseCode = 0; + lun->requestSenseData.bAdditionalSenseCodeQualifier = 0; + lun->requestSenseData.bFieldReplaceableUnitCode = 0; + lun->requestSenseData.bSenseKeySpecific = 0; + lun->requestSenseData.pSenseKeySpecific[0] = 0; + lun->requestSenseData.pSenseKeySpecific[0] = 0; + lun->requestSenseData.isSKSV = 0; + + STORE_DWORDB(0, lun->readCapacityData.pLogicalBlockAddress); + STORE_DWORDB(0, lun->readCapacityData.pLogicalBlockLength); + + /* Initialize LUN */ + + lun->media = media; + if (media == 0) { + lun->status = LUN_NOT_PRESENT; + return; + } + + lun->baseAddress = baseAddress; + + /* Customized block size */ + + if (blockSize) { + lun->blockSize = blockSize; + } + else { + if (media->blockSize < DEFAULT_LUN_BLOCK_SIZE) + lun->blockSize = DEFAULT_LUN_BLOCK_SIZE / media->blockSize; + else + lun->blockSize = 1; + } + + if (size) { + lun->size = size; + } + else { + lun->size = media->size; + /*if (blockSize) */ + + /* lun->size = media->size / blockSize; */ + + /*else { */ + + /* if (media->blockSize < DEFAULT_LUN_BLOCK_SIZE) */ + + /* lun->size = media->size / lun->blockSize; */ + + /* else */ + + /* lun->size = media->size; */ + + /*} */ + + } + + TRACE_INFO("LUN: blkSize %d, size %d\n\r", (int)lun->blockSize, (int)lun->size); + if (protected) lun->protected = 1; + else lun->protected = media->protected; + + lun->ioFifo.pBuffer = ioBuffer; + lun->ioFifo.bufferSize = ioBufferSize; + + lun->dataMonitor = dataMonitor; + + /* Initialize read capacity data */ + + logicalBlockAddress = lun->size / lun->blockSize - 1; + STORE_DWORDB(logicalBlockAddress, + lun->readCapacityData.pLogicalBlockAddress); + STORE_DWORDB(lun->blockSize * media->blockSize, + lun->readCapacityData.pLogicalBlockLength); + + /* Indicate media change */ + + lun->status = LUN_CHANGED; +} + +/** + * \brief Eject the media from a LUN + * \param lun Pointer to the MSDLun instance to initialize + * \return Operation result code + */ +uint32_t LUN_Eject(MSDLun *lun) +{ + if (lun->media) { + + /* Avoid any LUN R/W in progress */ + if (lun->media->state == MED_STATE_BUSY) { + + return USBD_STATUS_LOCKED; + } + + /* Remove the link of the media */ + lun->media = 0; + } + /* LUN is removed */ + lun->status = LUN_NOT_PRESENT; + + return USBD_STATUS_SUCCESS; +} + +/** + * \brief Writes data on the a LUN starting at the specified block address. + * \param lun Pointer to a MSDLun instance + * \param blockAddress First block address to write + * \param data Pointer to the data to write + * \param length Number of blocks to write + * \param callback Optional callback to invoke when the write finishes + * \param argument Optional callback argument. + * \return Operation result code + */ +uint32_t LUN_Write(MSDLun *lun, + uint32_t blockAddress, + void *data, + uint32_t length, + TransferCallback callback, + void *argument) +{ + uint32_t medBlk, medLen; + uint8_t status; + + TRACE_INFO_WP("LUNWrite(%u) ", blockAddress); + + /* Check that the data is not too big */ + if ((length + blockAddress) * lun->blockSize > lun->size) { + + TRACE_WARNING("LUN_Write: Data too big\n\r"); + status = USBD_STATUS_ABORTED; + } + else if (lun->media == 0 || lun->status != LUN_READY) { + + TRACE_WARNING("LUN_Write: Media not ready\n\r"); + status = USBD_STATUS_ABORTED; + } + else if (lun->protected) { + TRACE_WARNING("LUN_Write: LUN is readonly\n\r"); + status = USBD_STATUS_ABORTED; + } + else { + + /* Compute write start address */ + medBlk = lun->baseAddress + blockAddress * lun->blockSize; + medLen = length * lun->blockSize; + + /* Start write operation */ + status = MED_Write(lun->media, + medBlk, + data, + medLen, + (MediaCallback) callback, + argument); + + /* Check operation result code */ + if (status == MED_STATUS_SUCCESS) { + + status = USBD_STATUS_SUCCESS; + } + else { + + TRACE_WARNING("LUN_Write: Cannot write media\n\r"); + status = USBD_STATUS_ABORTED; + } + } + + return status; +} + +/** + * \brief Reads data from a LUN, starting at the specified block address. + * \param lun Pointer to a MSDLun instance + * \param blockAddress First block address to read + * \param data Pointer to a data buffer in which to store the data + * \param length Number of blocks to read + * \param callback Optional callback to invoke when the read finishes + * \param argument Optional callback argument. + * \return Operation result code + */ +uint32_t LUN_Read(MSDLun *lun, + uint32_t blockAddress, + void *data, + uint32_t length, + TransferCallback callback, + void *argument) +{ + uint32_t medBlk, medLen; + uint8_t status; + + /* Check that the data is not too big */ + if ((length + blockAddress) * lun->blockSize > lun->size) { + + TRACE_WARNING("LUN_Read: Area: (%d + %d)*%d > %d\n\r", + (int)length, (int)blockAddress, (int)lun->blockSize, (int)lun->size); + status = USBD_STATUS_ABORTED; + } + else if (lun->media == 0 || lun->status != LUN_READY) { + + TRACE_WARNING("LUN_Read: Media not present\n\r"); + status = USBD_STATUS_ABORTED; + } + else { + + TRACE_INFO_WP("LUNRead(%u) ", blockAddress); + + /* Compute read start address */ + medBlk = lun->baseAddress + (blockAddress * lun->blockSize); + medLen = length * lun->blockSize; + + /* Start write operation */ + status = MED_Read(lun->media, + medBlk, + data, + medLen, + (MediaCallback) callback, + argument); + + /* Check result code */ + if (status == MED_STATUS_SUCCESS) { + + status = USBD_STATUS_SUCCESS; + } + else { + + TRACE_WARNING("LUN_Read: Cannot read media\n\r"); + status = USBD_STATUS_ABORTED; + } + } + + return status; +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDMediaArch.png b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDMediaArch.png new file mode 100644 index 00000000..b641e97c Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/MSDMediaArch.png differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/SBCMethods.c b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/SBCMethods.c new file mode 100644 index 00000000..3b2d6ab6 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/device/massstorage/SBCMethods.c @@ -0,0 +1,1855 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "SBCMethods.h" +#include "MSDDStateMachine.h" +#include + +#include "MSDIOFifo.h" + +/*------------------------------------------------------------------------------ + * Global variables + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Macros + *------------------------------------------------------------------------------*/ + +#ifdef MSDIO_READ10_CHUNK_SIZE +/** READ10 - Read data from specific LUN to FIFO */ +#define SBC_READ_CHUNK(pLun, lba, pFifo, pCb, pArg) \ + LUN_Read((pLun), (lba), \ + &(pFifo)->pBuffer[(pFifo)->inputNdx], \ + ((pFifo)->chunkSize/(pFifo)->blockSize), \ + (TransferCallback)(pCb), (void*)pArg) +/** READ10 - Transfer data from FIFO to USB */ +#define SBC_TX_CHUNK(ep, pFifo, pCb, pArg) \ + USBD_Write( (ep), \ + &(pFifo)->pBuffer[(pFifo)->outputNdx], \ + (pFifo)->chunkSize, \ + (TransferCallback)(pCb), (void*)(pArg)) +#endif + +#ifdef MSDIO_WRITE10_CHUNK_SIZE +/** WRITE10 - Read data from USB to FIFO */ +#define SBC_RX_CHUNK(ep, pFifo,pCb,pArg) \ + USBD_Read( (ep), \ + &(pFifo)->pBuffer[(pFifo)->inputNdx], \ + (pFifo)->chunkSize, \ + (TransferCallback)(pCb), (void*)(pArg)) +/** WRITE10 - Write data from FIFO to LUN */ +#define SBC_WRITE_CHUNK(pLun, lba, pFifo, pCb, pArg) \ + LUN_Write((pLun), (lba), \ + &(pFifo)->pBuffer[(pFifo)->outputNdx], \ + ((pFifo)->chunkSize/(pFifo)->blockSize), \ + (TransferCallback)(pCb), (void*)(pArg)) +#endif + + +/** + * \brief Header for the mode pages data + * \see SBCModeParameterHeader6 + */ +static const SBCModeParameterHeader6 modeParameterHeader6 = { + + sizeof(SBCModeParameterHeader6) - 1, /*! Length is 0x03 */ + + SBC_MEDIUM_TYPE_DIRECT_ACCESS_BLOCK_DEVICE, /*! Direct-access block device */ + + 0, /*! Reserved bits */ + + 0, /*! DPO/FUA not supported */ + + 0, /*! Reserved bits */ + + 0, /*! not write-protected */ + + 0 /*! No block descriptor */ + +}; + +/*------------------------------------------------------------------------------ + * Internal functions + *------------------------------------------------------------------------------*/ + +/** + * \brief Check if the LUN is ready. + * \param lun Pointer to the LUN affected by the command + * \return 1 if the LUN is ready to be written + * \see MSDLun + */ +static unsigned char SBCLunIsReady(MSDLun *lun) +{ + unsigned char lunIsReady = 0; + + if (lun->media == 0 || lun->status < LUN_CHANGED) { + TRACE_INFO("SBCLunIsReady: Not Present!\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_NOT_READY, + SBC_ASC_MEDIUM_NOT_PRESENT, + 0); + + } + else if (lun->status < LUN_READY) { + TRACE_INFO("SBCLunIsReady: Changing!\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_UNIT_ATTENTION, + SBC_ASC_NOT_READY_TO_READY_CHANGE, + 0); + lun->status = LUN_READY; + } + else { + + lunIsReady = 1; + } + + return lunIsReady; +} + +/** + * \brief Check if the LUN can write. + * \param lun Pointer to the LUN affected by the command + * \return 1 if the LUN is ready to be written + * \see MSDLun + */ +static unsigned char SBCLunCanBeWritten(MSDLun *lun) +{ + unsigned char canBeWritten = 0; + + if (!SBCLunIsReady(lun)) { + + TRACE_WARNING("SBCLunCanBeWritten: Not Ready!\n\r"); + } + else if (lun->protected) { + + TRACE_WARNING("SBCLunCanBeWritten: Protected!\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_DATA_PROTECT, + SBC_ASC_WRITE_PROTECTED, + 0); + } + else { + + canBeWritten = 1; + } + + return canBeWritten; +} + +/** + * \brief Performs a WRITE (10) command on the specified LUN. + * + * The data to write is first received from the USB host and then + * actually written on the media. + * This function operates asynchronously and must be called multiple + * times to complete. A result code of MSDDriver_STATUS_INCOMPLETE + * indicates that at least another call of the method is necessary. + * \param lun Pointer to the LUN affected by the command + * \param commandState Current state of the command + * \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER) + * \see MSDLun + * \see MSDCommandState + */ +static unsigned char SBC_Write10(MSDLun *lun, + MSDCommandState *commandState) +{ + unsigned char status; + unsigned char result = MSDD_STATUS_INCOMPLETE; + SBCRead10 *command = (SBCRead10 *) commandState->cbw.pCommand; + MSDTransfer *transfer = &(commandState->transfer); + MSDTransfer *disktransfer = &(commandState->disktransfer); + MSDIOFifo *fifo = &lun->ioFifo; + + /* Init command state */ + if (commandState->state == 0) { + + commandState->state = SBC_STATE_WRITE; + + /* The command should not be proceeded if READONLY */ + if (!SBCLunCanBeWritten(lun)) { + + return MSDD_STATUS_RW; + } + else { + + + /* Initialize FIFO */ + fifo->dataTotal = commandState->length; + fifo->blockSize = lun->blockSize * lun->media->blockSize; + #ifdef MSDIO_WRITE10_CHUNK_SIZE + if ( fifo->dataTotal >= 64 * 1024 + && fifo->blockSize < MSDIO_WRITE10_CHUNK_SIZE) + fifo->chunkSize = MSDIO_WRITE10_CHUNK_SIZE; + else + fifo->chunkSize = fifo->blockSize; + #endif + fifo->fullCnt = 0; + fifo->nullCnt = 0; + + /* Initialize FIFO output (Disk) */ + fifo->outputNdx = 0; + fifo->outputTotal = 0; + fifo->outputState = MSDIO_IDLE; + transfer->semaphore = 0; + + /* Initialize FIFO input (USB) */ + fifo->inputNdx = 0; + fifo->inputTotal = 0; + fifo->inputState = MSDIO_START; + disktransfer->semaphore = 0; + } + + } + + if (commandState->length == 0) { + + /* Perform the callback! */ + if (lun->dataMonitor) { + + lun->dataMonitor(0, fifo->dataTotal, fifo->nullCnt, fifo->fullCnt); + } + return MSDD_STATUS_SUCCESS; + } + + /* USB receive task */ + switch(fifo->inputState) { + + /*------------------ */ + case MSDIO_IDLE: + /*------------------ */ + + if (fifo->inputTotal < fifo->dataTotal && + fifo->inputTotal - fifo->outputTotal < fifo->bufferSize) { + + fifo->inputState = MSDIO_START; + } + break; + + /*------------------ */ + case MSDIO_START: + /*------------------ */ + + /* Should not start if there is any disk error */ + if (fifo->outputState == MSDIO_ERROR) { + + TRACE_INFO_WP("udErr "); + fifo->inputState = MSDIO_ERROR; + break; + } + + /* Read one block of data sent by the host */ + if (lun->media->mappedWR) { + + /* Directly read to memory */ + #if 1 + status = USBD_Read(commandState->pipeOUT, + (void*) + ((lun->media->baseAddress + + (lun->baseAddress + + DWORDB(command->pLogicalBlockAddress) + * lun->blockSize + ) + ) * lun->media->blockSize + ), + fifo->dataTotal, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Read((void*) + ((lun->media->baseAddress + + (lun->baseAddress + + DWORDB(command->pLogicalBlockAddress) + * lun->blockSize + ) + ) * lun->media->blockSize + ), + fifo->dataTotal, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + } + else { + #ifdef MSDIO_WRITE10_CHUNK_SIZE + status = SBC_RX_CHUNK(commandState->pipeOUT, + fifo, MSDDriver_Callback, transfer); + #else + /* Read block to buffer */ + #if 1 + status = USBD_Read(commandState->pipeOUT, + (void*)&fifo->pBuffer[fifo->inputNdx], + fifo->blockSize, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Read((void*)&fifo->pBuffer[fifo->inputNdx], + fifo->blockSize, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + #endif + } + + /* Check operation result code */ + + if (status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_Write10: Failed to start receiving\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_HARDWARE_ERROR, + 0, + 0); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("uRx "); + + /* Prepare next device state */ + + fifo->inputState = MSDIO_WAIT; + } + break; /* MSDIO_START */ + + + /*------------------ */ + + case MSDIO_WAIT: + /*------------------ */ + + TRACE_INFO_WP("uWait "); + + /* Check semaphore */ + + if (transfer->semaphore > 0) { + + transfer->semaphore--; + fifo->inputState = MSDIO_NEXT; + } + break; + + /*------------------ */ + + case MSDIO_NEXT: + /*------------------ */ + + /* Check the result code of the read operation */ + + if (transfer->status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_Write10: Failed to received\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_HARDWARE_ERROR, + 0, + 0); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("uNxt "); + + /* Mapped read, all data done */ + + if (lun->media->mappedWR) { + + fifo->inputTotal = fifo->dataTotal; + fifo->inputState = MSDIO_IDLE; + } + else { + + /* Update input index */ + + #ifdef MSDIO_WRITE10_CHUNK_SIZE + MSDIOFifo_IncNdx(fifo->inputNdx, + fifo->chunkSize, + fifo->bufferSize); + fifo->inputTotal += fifo->chunkSize; + #else + MSDIOFifo_IncNdx(fifo->inputNdx, + fifo->blockSize, + fifo->bufferSize); + fifo->inputTotal += fifo->blockSize; + #endif + + /* Start Next block */ + + /* - All Data done? */ + + if (fifo->inputTotal >= fifo->dataTotal) { + + fifo->inputState = MSDIO_IDLE; + } + /* - Buffer full? */ + + else if (fifo->inputNdx == fifo->outputNdx) { + fifo->inputState = MSDIO_IDLE; + fifo->fullCnt ++; + + TRACE_DEBUG_WP("ufFull%d ", fifo->inputNdx); + } + /* - More data to transfer? */ + + else if (fifo->inputTotal < fifo->dataTotal) { + fifo->inputState = MSDIO_START; + + TRACE_INFO_WP("uStart "); + } + /* never executed ! */ + + /*else { */ + + /* fifo->inputState = MSDIO_IDLE; */ + + /* TRACE_INFO_WP("uDone "); */ + + /*} */ + + } + + } + break; /* MSDIO_NEXT */ + + + /*------------------ */ + + case MSDIO_ERROR: + /*------------------ */ + + + TRACE_WARNING_WP("uErr "); + commandState->length -= fifo->inputTotal; + return MSDD_STATUS_RW; + + } + + /* Disk write task */ + + switch(fifo->outputState) { + + /*------------------ */ + + case MSDIO_IDLE: + /*------------------ */ + + if (fifo->outputTotal < fifo->inputTotal) { + + fifo->outputState = MSDIO_START; + } + break; + + /*------------------ */ + + case MSDIO_START: + /*------------------ */ + + + /* Write the block to the media */ + + if (lun->media->mappedWR) { + + MSDDriver_Callback(disktransfer, MED_STATUS_SUCCESS, 0, 0); + status = LUN_STATUS_SUCCESS; + } + else { + #ifdef MSDIO_WRITE10_CHUNK_SIZE + status = SBC_WRITE_CHUNK(lun, DWORDB(command->pLogicalBlockAddress), + fifo, MSDDriver_Callback, disktransfer); + #else + status = LUN_Write(lun, + DWORDB(command->pLogicalBlockAddress), + &fifo->pBuffer[fifo->outputNdx], + 1, + (TransferCallback) MSDDriver_Callback, + (void *) disktransfer); + #endif + } + + /* Check operation result code */ + + if (status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_Write10: Failed to start write - "); + + if (!SBCLunCanBeWritten(lun)) { + + TRACE_WARNING("?\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_NOT_READY, + 0, + 0); + } + + fifo->outputState = MSDIO_ERROR; + } + else { + + /* Prepare next state */ + + fifo->outputState = MSDIO_WAIT; + } + break; /* MSDIO_START */ + + + /*------------------ */ + + case MSDIO_WAIT: + /*------------------ */ + + TRACE_INFO_WP("dWait "); + + /* Check semaphore value */ + + if (disktransfer->semaphore > 0) { + + /* Take semaphore and move to next state */ + + disktransfer->semaphore--; + fifo->outputState = MSDIO_NEXT; + } + break; + + /*------------------ */ + + case MSDIO_NEXT: + /*------------------ */ + + /* Check operation result code */ + + if (transfer->status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_Write10: Failed to write\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_RECOVERED_ERROR, + SBC_ASC_TOO_MUCH_WRITE_DATA, + 0); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("dNxt "); + + /* Update transfer length and block address */ + + + /* Mapped memory, done */ + + if (lun->media->mappedWR) { + + commandState->length = 0; + fifo->outputState = MSDIO_IDLE; + } + else { + + /* Update output index */ + + #ifdef MSDIO_WRITE10_CHUNK_SIZE + STORE_DWORDB(DWORDB(command->pLogicalBlockAddress) + + fifo->chunkSize/fifo->blockSize, + command->pLogicalBlockAddress); + MSDIOFifo_IncNdx(fifo->outputNdx, + fifo->chunkSize, + fifo->bufferSize); + fifo->outputTotal += fifo->chunkSize; + #else + STORE_DWORDB(DWORDB(command->pLogicalBlockAddress) + 1, + command->pLogicalBlockAddress); + MSDIOFifo_IncNdx(fifo->outputNdx, + fifo->blockSize, + fifo->bufferSize); + fifo->outputTotal += fifo->blockSize; + #endif + + /* Start Next block */ + + /* - All data done? */ + + if (fifo->outputTotal >= fifo->dataTotal) { + + fifo->outputState = MSDIO_IDLE; + commandState->length = 0; + TRACE_INFO_WP("dDone "); + } + /* - Send next? */ + + else if (fifo->outputTotal < fifo->inputTotal) { + + fifo->outputState = MSDIO_START; + TRACE_INFO_WP("dStart "); + } + /* - Buffer Null? */ + + else { + fifo->outputState = MSDIO_IDLE; + fifo->nullCnt ++; + + TRACE_DEBUG_WP("dfNull%d ", fifo->outputNdx); + } + } + } + break; /* MSDIO_NEXT */ + + + /*------------------ */ + + case MSDIO_ERROR: + /*------------------ */ + + break; + } + + return result; +} + +/** + * \brief Performs a READ (10) command on specified LUN. + * + * The data is first read from the media and then sent to the USB host. + * This function operates asynchronously and must be called multiple + * times to complete. A result code of MSDDriver_STATUS_INCOMPLETE + * indicates that at least another call of the method is necessary. + * \param lun Pointer to the LUN affected by the command + * \param commandState Current state of the command + * \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER) + * \see MSDLun + * \see MSDCommandState + */ +static unsigned char SBC_Read10(MSDLun *lun, + MSDCommandState *commandState) +{ + unsigned char status; + unsigned char result = MSDD_STATUS_INCOMPLETE; + SBCRead10 *command = (SBCRead10 *) commandState->cbw.pCommand; + MSDTransfer *transfer = &(commandState->transfer); + MSDTransfer *disktransfer = &(commandState->disktransfer); + MSDIOFifo *fifo = &lun->ioFifo; + + /* Init command state */ + + if (commandState->state == 0) { + + commandState->state = SBC_STATE_READ; + + if (!SBCLunIsReady(lun)) { + + return MSDD_STATUS_RW; + } + else { + + /* Initialize FIFO */ + + fifo->dataTotal = commandState->length; + fifo->blockSize = lun->blockSize * lun->media->blockSize; + #ifdef MSDIO_READ10_CHUNK_SIZE + if ( fifo->dataTotal >= 64*1024 + && fifo->blockSize < MSDIO_READ10_CHUNK_SIZE) + fifo->chunkSize = MSDIO_READ10_CHUNK_SIZE; + else + fifo->chunkSize = fifo->blockSize; + #endif + fifo->fullCnt = 0; + fifo->nullCnt = 0; + + #ifdef MSDIO_FIFO_OFFSET + /* Enable offset if total size >= 2*bufferSize */ + + if (fifo->dataTotal / fifo->bufferSize >= 2) + fifo->bufferOffset = MSDIO_FIFO_OFFSET; + else + fifo->bufferOffset = 0; + #endif + + /* Initialize FIFO output (USB) */ + + fifo->outputNdx = 0; + fifo->outputTotal = 0; + fifo->outputState = MSDIO_IDLE; + transfer->semaphore = 0; + + /* Initialize FIFO input (Disk) */ + + fifo->inputNdx = 0; + fifo->inputTotal = 0; + fifo->inputState = MSDIO_START; + disktransfer->semaphore = 0; + } + } + + /* Check length */ + + if (commandState->length == 0) { + + /* Perform the callback! */ + + if (lun->dataMonitor) { + + lun->dataMonitor(1, fifo->dataTotal, fifo->nullCnt, fifo->fullCnt); + } + return MSDD_STATUS_SUCCESS; + } + + /* Disk reading task */ + + switch(fifo->inputState) { + + /*------------------ */ + + case MSDIO_IDLE: + /*------------------ */ + + if (fifo->inputTotal < fifo->dataTotal && + fifo->inputTotal - fifo->outputTotal < fifo->bufferSize) { + + fifo->inputState = MSDIO_START; + } + break; + + /*------------------ */ + + case MSDIO_START: + /*------------------ */ + + /* Read one block of data from the media */ + + if (lun->media->mappedRD) { + + /* Directly write, no read needed */ + + MSDDriver_Callback(disktransfer, MED_STATUS_SUCCESS, 0, 0); + status = LUN_STATUS_SUCCESS; + } + else { + #ifdef MSDIO_READ10_CHUNK_SIZE + status = SBC_READ_CHUNK(lun, DWORDB(command->pLogicalBlockAddress), + fifo, MSDDriver_Callback, disktransfer); + #else + status = LUN_Read(lun, + DWORDB(command->pLogicalBlockAddress), + &fifo->pBuffer[fifo->inputNdx], + 1, + (TransferCallback) MSDDriver_Callback, + (void *)disktransfer); + #endif + } + + /* Check operation result code */ + + if (status != LUN_STATUS_SUCCESS) { + + TRACE_WARNING("RBC_Read10: Failed to start reading\n\r"); + + if (SBCLunIsReady(lun)) { + + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_NOT_READY, + SBC_ASC_LOGICAL_UNIT_NOT_READY, + 0); + } + + fifo->inputState = MSDIO_ERROR; + } + else { + + TRACE_INFO_WP("dRd "); + + /* Move to next command state */ + + fifo->inputState = MSDIO_WAIT; + } + break; /* MSDIO_START */ + + + /*------------------ */ + + case MSDIO_WAIT: + /*------------------ */ + + /* Check semaphore value */ + + if (disktransfer->semaphore > 0) { + + TRACE_INFO_WP("dOk "); + + /* Take semaphore and move to next state */ + + disktransfer->semaphore--; + fifo->inputState = MSDIO_NEXT; + } + break; + + /*------------------ */ + + case MSDIO_NEXT: + /*------------------ */ + + /* Check the operation result code */ + + if (disktransfer->status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_Read10: Failed to read media\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_RECOVERED_ERROR, + SBC_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, + 0); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("dNxt "); + + if (lun->media->mappedRD) { + + /* All data is ready */ + + fifo->inputState = MSDIO_IDLE; + fifo->inputTotal = fifo->dataTotal; + } + else { + + /* Update block address */ + + #ifdef MSDIO_READ10_CHUNK_SIZE + STORE_DWORDB(DWORDB(command->pLogicalBlockAddress) + + fifo->chunkSize/fifo->blockSize, + command->pLogicalBlockAddress); + + /* Update input index */ + + MSDIOFifo_IncNdx(fifo->inputNdx, + fifo->chunkSize, + fifo->bufferSize); + fifo->inputTotal += fifo->chunkSize; + #else + /* Update block address */ + + STORE_DWORDB(DWORDB(command->pLogicalBlockAddress) + 1, + command->pLogicalBlockAddress); + + /* Update input index */ + + MSDIOFifo_IncNdx(fifo->inputNdx, + fifo->blockSize, + fifo->bufferSize); + fifo->inputTotal += fifo->blockSize; + #endif + + /* Start Next block */ + + /* - All Data done? */ + + if (fifo->inputTotal >= fifo->dataTotal) { + + TRACE_INFO_WP("dDone "); + fifo->inputState = MSDIO_IDLE; + } + /* - Buffer full? */ + + else if (fifo->inputNdx == fifo->outputNdx) { + + TRACE_INFO_WP("dfFull%d ", (int)fifo->inputNdx); + fifo->inputState = MSDIO_IDLE; + fifo->fullCnt ++; + } + /* - More data to transfer? */ + + else if (fifo->inputTotal < fifo->dataTotal) { + + TRACE_DEBUG_WP("dStart "); + fifo->inputState = MSDIO_START; + } + } + + } + + break; + + /*------------------ */ + + case MSDIO_ERROR: + /*------------------ */ + + break; + } + + /* USB sending task */ + + switch(fifo->outputState) { + + /*------------------ */ + + case MSDIO_IDLE: + /*------------------ */ + + if (fifo->outputTotal < fifo->inputTotal) { + + #ifdef MSDIO_FIFO_OFFSET + /* Offset buffer the input data */ + + if (fifo->bufferOffset) { + if (fifo->inputTotal < fifo->bufferOffset) { + break; + } + fifo->bufferOffset = 0; + } + #endif + fifo->outputState = MSDIO_START; + } + break; + + /*------------------ */ + + case MSDIO_START: + /*------------------ */ + + /* Should not start if there is any disk error */ + + if (fifo->outputState == MSDIO_ERROR) { + + fifo->inputState = MSDIO_ERROR; + break; + } + + /* Send the block to the host */ + if (lun->media->mappedRD) { + #if 1 + status = USBD_Write(commandState->pipeIN, + (void*) + ((lun->media->baseAddress + + (lun->baseAddress + + DWORDB(command->pLogicalBlockAddress) + * lun->blockSize + ) + ) * lun->media->blockSize + ), + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Write((void*) + ((lun->media->baseAddress + + (lun->baseAddress + + DWORDB(command->pLogicalBlockAddress) + * lun->blockSize + ) + ) * lun->media->blockSize + ), + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + } + else { + #ifdef MSDIO_READ10_CHUNK_SIZE + status = SBC_TX_CHUNK(commandState->pipeIN, + fifo, MSDDriver_Callback, transfer); + #else + #if 1 + status = USBD_Write(commandState->pipeIN, + &fifo->pBuffer[fifo->outputNdx], + fifo->blockSize, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Write(&fifo->pBuffer[fifo->outputNdx], + fifo->blockSize, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + #endif + } + /* Check operation result code */ + + if (status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_Read10: Failed to start to send\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_HARDWARE_ERROR, + 0, + 0); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("uTx "); + + /* Move to next command state */ + + fifo->outputState = MSDIO_WAIT; + } + break; /* MSDIO_START */ + + + /*------------------ */ + + case MSDIO_WAIT: + /*------------------ */ + + /* Check semaphore value */ + + if (transfer->semaphore > 0) { + + TRACE_INFO_WP("uOk "); + + /* Take semaphore and move to next state */ + + transfer->semaphore--; + fifo->outputState = MSDIO_NEXT; + } + break; + + /*------------------ */ + + case MSDIO_NEXT: + /*------------------ */ + + /* Check operation result code */ + + if (transfer->status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_Read10: Failed to send data\n\r"); + SBC_UpdateSenseData(&(lun->requestSenseData), + SBC_SENSE_KEY_HARDWARE_ERROR, + 0, + 0); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("uNxt "); + + if (lun->media->mappedRD) { + + commandState->length = 0; + } + else { + + /* Update output index */ + + #ifdef MSDIO_READ10_CHUNK_SIZE + MSDIOFifo_IncNdx(fifo->outputNdx, + fifo->chunkSize, + fifo->bufferSize); + fifo->outputTotal += fifo->chunkSize; + #else + MSDIOFifo_IncNdx(fifo->outputNdx, + fifo->blockSize, + fifo->bufferSize); + fifo->outputTotal += fifo->blockSize; + #endif + + /* Start Next block */ + + /* - All data done? */ + + if (fifo->outputTotal >= fifo->dataTotal) { + + fifo->outputState = MSDIO_IDLE; + commandState->length = 0; + TRACE_INFO_WP("uDone "); + } + /* - Buffer Null? */ + + else if (fifo->inputNdx == fifo->outputNdx) { + + TRACE_INFO_WP("ufNull%d ", (int)fifo->outputNdx); + fifo->outputState = MSDIO_IDLE; + fifo->nullCnt ++; + } + /* - Send next? */ + + else if (fifo->outputTotal < fifo->inputTotal) { + + TRACE_DEBUG_WP("uStart "); + fifo->outputState = MSDIO_START; + } + } + + } + break; + + /*------------------ */ + + case MSDIO_ERROR: + /*------------------ */ + + break; + } + + return result; +} + +/** + * \brief Performs a READ CAPACITY (10) command. + * + * This function operates asynchronously and must be called multiple + * times to complete. A result code of MSDD_STATUS_INCOMPLETE + * indicates that at least another call of the method is necessary. + * \param lun Pointer to the LUN affected by the command + * \param commandState Current state of the command + * \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER) + * \see MSDLun + * \see MSDCommandState + */ +static unsigned char SBC_ReadCapacity10(MSDLun *lun, + MSDCommandState *commandState) +{ + unsigned char result = MSDD_STATUS_INCOMPLETE; + unsigned char status; + MSDTransfer *transfer = &(commandState->transfer); + + if (!SBCLunIsReady(lun)) { + + TRACE_INFO("SBC_ReadCapacity10: Not Ready!\n\r"); + return MSDD_STATUS_RW; + } + + /* Initialize command state if needed */ + if (commandState->state == 0) { + + commandState->state = SBC_STATE_WRITE; + } + + /* Identify current command state */ + switch (commandState->state) { + /*------------------- */ + case SBC_STATE_WRITE: + /*------------------- */ + + /* Start the write operation */ + #if 1 + status = USBD_Write(commandState->pipeIN, + &(lun->readCapacityData), + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Write(&(lun->readCapacityData), + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + + /* Check operation result code */ + if (status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_ReadCapacity: Cannot start sending data\n\r"); + result = MSDD_STATUS_ERROR; + } + else { + + /* Proceed to next command state */ + TRACE_INFO_WP("Sending "); + commandState->state = SBC_STATE_WAIT_WRITE; + } + break; + + /*------------------------ */ + case SBC_STATE_WAIT_WRITE: + /*------------------------ */ + + /* Check semaphore value */ + if (transfer->semaphore > 0) { + + /* Take semaphore and terminate command */ + transfer->semaphore--; + + if (transfer->status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING("RBC_ReadCapacity: Cannot send data\n\r"); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("Sent "); + result = MSDD_STATUS_SUCCESS; + } + commandState->length -= transfer->transferred; + } + break; + } + + return result; +} + +/** + * \brief Handles an INQUIRY command. + * + * This function operates asynchronously and must be called multiple + * times to complete. A result code of MSDDriver_STATUS_INCOMPLETE + * indicates that at least another call of the method is necessary. + * \param lun Pointer to the LUN affected by the command + * \param commandState Current state of the command + * \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER) + * \see MSDLun + * \see MSDCommandState + */ +static unsigned char SBC_Inquiry(MSDLun *lun, + MSDCommandState *commandState) +{ + unsigned char result = MSDD_STATUS_INCOMPLETE; + unsigned char status; + MSDTransfer *transfer = &(commandState->transfer); + + /* Check if required length is 0 */ + if (commandState->length == 0) { + + /* Nothing to do */ + result = MSDD_STATUS_SUCCESS; + } + /* Initialize command state if needed */ + else if (commandState->state == 0) { + + commandState->state = SBC_STATE_WRITE; + + /* Change additional length field of inquiry data */ + lun->inquiryData->bAdditionalLength + = (unsigned char) (commandState->length - 5); + } + + /* Identify current command state */ + + switch (commandState->state) { + /*------------------- */ + case SBC_STATE_WRITE: + /*------------------- */ + + /* Start write operation */ + #if 1 + status = USBD_Write(commandState->pipeIN, + (void *) lun->inquiryData, + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Write((void *) lun->inquiryData, + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + + /* Check operation result code */ + if (status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "SPC_Inquiry: Cannot start sending data\n\r"); + result = MSDD_STATUS_ERROR; + } + else { + + /* Proceed to next state */ + TRACE_INFO_WP("Sending "); + commandState->state = SBC_STATE_WAIT_WRITE; + } + break; + + /*------------------------ */ + case SBC_STATE_WAIT_WRITE: + /*------------------------ */ + + /* Check the semaphore value */ + if (transfer->semaphore > 0) { + + /* Take semaphore and terminate command */ + transfer->semaphore--; + + if (transfer->status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "SPC_Inquiry: Data transfer failed\n\r"); + result = MSDD_STATUS_ERROR; + } + else { + + TRACE_INFO_WP("Sent "); + result = MSDD_STATUS_SUCCESS; + } + + /* Update length field */ + commandState->length -= transfer->transferred; + } + break; + } + + return result; +} + +/** + * \brief Performs a REQUEST SENSE command. + * + * This function operates asynchronously and must be called multiple + * times to complete. A result code of MSDDriver_STATUS_INCOMPLETE + * indicates that at least another call of the method is necessary. + * \param lun Pointer to the LUN affected by the command + * \param commandState Current state of the command + * \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER) + * \see MSDLun + * \see MSDCommandState + */ +static unsigned char SBC_RequestSense(MSDLun *lun, + MSDCommandState *commandState) +{ + unsigned char result = MSDD_STATUS_INCOMPLETE; + unsigned char status; + MSDTransfer *transfer = &(commandState->transfer); + + /* Check if requested length is zero */ + if (commandState->length == 0) { + + /* Nothing to do */ + + result = MSDD_STATUS_SUCCESS; + } + /* Initialize command state if needed */ + else if (commandState->state == 0) { + + commandState->state = SBC_STATE_WRITE; + } + + /* Identify current command state */ + switch (commandState->state) { + /*------------------- */ + case SBC_STATE_WRITE: + /*------------------- */ + + /* Start transfer */ + #if 1 + status = USBD_Write(commandState->pipeIN, + &(lun->requestSenseData), + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Write(&(lun->requestSenseData), + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + + /* Check result code */ + if (status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "RBC_RequestSense: Cannot start sending data\n\r"); + result = MSDD_STATUS_ERROR; + } + else { + + /* Change state */ + commandState->state = SBC_STATE_WAIT_WRITE; + } + break; + + /*------------------------ */ + case SBC_STATE_WAIT_WRITE: + /*------------------------ */ + + /* Check the transfer semaphore */ + if (transfer->semaphore > 0) { + + /* Take semaphore and finish command */ + transfer->semaphore--; + + if (transfer->status != USBD_STATUS_SUCCESS) { + + result = MSDD_STATUS_ERROR; + } + else { + + result = MSDD_STATUS_SUCCESS; + } + + /* Update length */ + commandState->length -= transfer->transferred; + } + break; + } + + return result; +} + +/** + * \brief Performs a MODE SENSE (6) command. + * + * This function operates asynchronously and must be called multiple + * times to complete. A result code of MSDDriver_STATUS_INCOMPLETE + * indicates that at least another call of the method is necessary. + * \param lun Pointer to the LUN affected by the command + * \param commandState Current state of the command + * \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER) + * \see MSDLun + * \see MSDCommandState + */ +static unsigned char SBC_ModeSense6(MSDLun *lun, MSDCommandState *commandState) +{ + unsigned char result = MSDD_STATUS_INCOMPLETE; + unsigned char status; + MSDTransfer *transfer = &(commandState->transfer); + + if (!SBCLunIsReady(lun)) { + + TRACE_INFO("SBC_ModeSense6: Not Ready!\n\r"); + return MSDD_STATUS_RW; + } + + /* Check if mode page is supported */ + if (((SBCCommand *) commandState->cbw.pCommand)->modeSense6.bPageCode + != SBC_PAGE_RETURN_ALL) { + + return MSDD_STATUS_PARAMETER; + } + + /* Initialize command state if needed */ + if (commandState->state == 0) { + + commandState->state = SBC_STATE_WRITE; + } + + /* Check current command state */ + switch (commandState->state) { + /*------------------- */ + case SBC_STATE_WRITE: + /*------------------- */ + + /* Start transfer */ + #if 1 + status = USBD_Write(commandState->pipeIN, + (void *) &modeParameterHeader6, + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #else + status = MSDD_Write((void *) &modeParameterHeader6, + commandState->length, + (TransferCallback) MSDDriver_Callback, + (void *) transfer); + #endif + + /* Check operation result code */ + if (status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "SPC_ModeSense6: Cannot start data transfer\n\r"); + result = MSDD_STATUS_ERROR; + } + else { + + /* Proceed to next state */ + commandState->state = SBC_STATE_WAIT_WRITE; + } + break; + + /*------------------------ */ + case SBC_STATE_WAIT_WRITE: + /*------------------------ */ + + TRACE_INFO_WP("Wait "); + + /* Check semaphore value */ + if (transfer->semaphore > 0) { + + /* Take semaphore and terminate command */ + transfer->semaphore--; + + if (transfer->status != USBD_STATUS_SUCCESS) { + + TRACE_WARNING( + "SPC_ModeSense6: Data transfer failed\n\r"); + result = MSDD_STATUS_ERROR; + } + else { + + result = MSDD_STATUS_SUCCESS; + } + + /* Update length field */ + commandState->length -= transfer->transferred; + + } + break; + } + + return result; +} + +/** + * \brief Performs a TEST UNIT READY COMMAND command. + * \param lun Pointer to the LUN affected by the command + * \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER) + * \see MSDLun + */ +static unsigned char SBC_TestUnitReady(MSDLun *lun) +{ + unsigned char result = MSDD_STATUS_RW; + unsigned char senseKey = SBC_SENSE_KEY_NO_SENSE, + addSenseCode = 0, + addSenseCodeQual = 0; + + /* Check current media state */ + + if (lun->status < LUN_CHANGED) { + + TRACE_INFO_WP("Ejc "); + senseKey = SBC_SENSE_KEY_NOT_READY; + addSenseCode = SBC_ASC_MEDIUM_NOT_PRESENT; + } + else if (lun->status == LUN_CHANGED) { + + TRACE_INFO_WP("Chg "); + senseKey = SBC_SENSE_KEY_UNIT_ATTENTION; + addSenseCode = SBC_ASC_NOT_READY_TO_READY_CHANGE; + lun->status = LUN_READY; + } + else { + + switch(lun->media->state) { + /*------------------- */ + + case MED_STATE_READY: + /*------------------- */ + + /* Nothing to do */ + + TRACE_INFO_WP("Rdy "); + result = MSDD_STATUS_SUCCESS; + break; + + /*------------------ */ + + case MED_STATE_BUSY: + /*------------------ */ + + TRACE_INFO_WP("Bsy "); + senseKey = SBC_SENSE_KEY_NOT_READY; + break; + + /*------ */ + + default: + /*------ */ + + TRACE_INFO_WP("? "); + senseKey = SBC_SENSE_KEY_NOT_READY; + addSenseCode = SBC_ASC_MEDIUM_NOT_PRESENT; + break; + } + } + SBC_UpdateSenseData(&(lun->requestSenseData), + senseKey, + addSenseCode, + addSenseCodeQual); + + return result; +} + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ +/** + * \brief Updates the sense data of a LUN with the given key and codes + * \param requestSenseData Pointer to the sense data to update + * \param senseKey Sense key + * \param additionalSenseCode Additional sense code + * \param additionalSenseCodeQualifier Additional sense code qualifier + */ +void SBC_UpdateSenseData(SBCRequestSenseData *requestSenseData, + unsigned char senseKey, + unsigned char additionalSenseCode, + unsigned char additionalSenseCodeQualifier) +{ + requestSenseData->bSenseKey = senseKey; + requestSenseData->bAdditionalSenseCode = additionalSenseCode; + requestSenseData->bAdditionalSenseCodeQualifier + = additionalSenseCodeQualifier; +} + +/** + * \brief Return information about the transfer length and direction expected + * by the device for a particular command. + * \param command Pointer to a buffer holding the command to evaluate + * \param length Expected length of the data transfer + * \param type Expected direction of data transfer + * \param lun Pointer to the LUN affected by the command + */ +unsigned char SBC_GetCommandInformation(void *command, + unsigned int *length, + unsigned char *type, + MSDLun *lun) +{ + SBCCommand *sbcCommand = (SBCCommand *) command; + unsigned char isCommandSupported = 1; + + /* Identify command */ + + switch (sbcCommand->bOperationCode) { + /*--------------- */ + + case SBC_INQUIRY: + /*--------------- */ + + (*type) = MSDD_DEVICE_TO_HOST; + + /* Allocation length is stored in big-endian format */ + + (*length) = WORDB(sbcCommand->inquiry.pAllocationLength); + break; + + /*-------------------- */ + + case SBC_MODE_SENSE_6: + /*-------------------- */ + + (*type) = MSDD_DEVICE_TO_HOST; + if (sbcCommand->modeSense6.bAllocationLength > + sizeof(SBCModeParameterHeader6)) { + + *length = sizeof(SBCModeParameterHeader6); + } + else { + + *length = sbcCommand->modeSense6.bAllocationLength; + } + break; + + /*------------------------------------ */ + + case SBC_PREVENT_ALLOW_MEDIUM_REMOVAL: + /*------------------------------------ */ + + (*type) = MSDD_NO_TRANSFER; + break; + + /*--------------------- */ + + case SBC_REQUEST_SENSE: + /*--------------------- */ + + (*type) = MSDD_DEVICE_TO_HOST; + (*length) = sbcCommand->requestSense.bAllocationLength; + break; + + /*----------------------- */ + + case SBC_TEST_UNIT_READY: + /*----------------------- */ + + (*type) = MSDD_NO_TRANSFER; + break; + + /*--------------------- */ + + case SBC_READ_CAPACITY_10: + /*--------------------- */ + + (*type) = MSDD_DEVICE_TO_HOST; + (*length) = sizeof(SBCReadCapacity10Data); + break; + + /*--------------- */ + + case SBC_READ_10: + /*--------------- */ + + (*type) = MSDD_DEVICE_TO_HOST; + (*length) = WORDB(sbcCommand->read10.pTransferLength) + * lun->blockSize * lun->media->blockSize; + break; + + /*---------------- */ + + case SBC_WRITE_10: + /*---------------- */ + + (*type) = MSDD_HOST_TO_DEVICE; + (*length) = WORDB(sbcCommand->write10.pTransferLength) + * lun->blockSize * lun->media->blockSize; + break; + + /*----------------- */ + + case SBC_VERIFY_10: + /*----------------- */ + + (*type) = MSDD_NO_TRANSFER; + break; + /*------ */ + + default: + /*------ */ + + isCommandSupported = 0; + } + + /* If length is 0, no transfer is expected */ + + if ((*length) == 0) { + + (*type) = MSDD_NO_TRANSFER; + } + + return isCommandSupported; +} + +/** + * \brief Processes a SBC command by dispatching it to a subfunction. + * \param lun Pointer to the affected LUN + * \param commandState Pointer to the current command state + * \return Operation result code + */ +unsigned char SBC_ProcessCommand(MSDLun *lun, + MSDCommandState *commandState) +{ + unsigned char result = MSDD_STATUS_INCOMPLETE; + SBCCommand *command = (SBCCommand *) commandState->cbw.pCommand; + + /* Identify command */ + + switch (command->bOperationCode) { + /*--------------- */ + case SBC_READ_10: + /*--------------- */ + + TRACE_DEBUG_WP("Read(10) "); + + /* Perform the Read10 command */ + + result = SBC_Read10(lun, commandState); + break; + + /*---------------- */ + case SBC_WRITE_10: + /*---------------- */ + + TRACE_DEBUG_WP("Write(10) "); + + /* Perform the Write10 command */ + + result = SBC_Write10(lun, commandState); + break; + + /*--------------------- */ + case SBC_READ_CAPACITY_10: + /*--------------------- */ + + TRACE_INFO_WP("RdCapacity(10) "); + + /* Perform the ReadCapacity command */ + + result = SBC_ReadCapacity10(lun, commandState); + break; + + /*--------------------- */ + case SBC_VERIFY_10: + /*--------------------- */ + + TRACE_INFO_WP("Verify(10) "); + + /* Flush media */ + + MED_Flush(lun->media); + result = MSDD_STATUS_SUCCESS; + break; + + /*--------------- */ + case SBC_INQUIRY: + /*--------------- */ + + TRACE_INFO_WP("Inquiry "); + + /* Process Inquiry command */ + result = SBC_Inquiry(lun, commandState); + break; + + /*-------------------- */ + case SBC_MODE_SENSE_6: + /*-------------------- */ + + TRACE_INFO_WP("ModeSense(6) "); + + /* Process ModeSense6 command */ + result = SBC_ModeSense6(lun, commandState); + break; + + /*----------------------- */ + case SBC_TEST_UNIT_READY: + /*----------------------- */ + + TRACE_INFO_WP("TstUnitRdy "); + + /* Process TestUnitReady command */ + /*MED_Flush(lun->media); */ + result = SBC_TestUnitReady(lun); + break; + + /*--------------------- */ + case SBC_REQUEST_SENSE: + /*--------------------- */ + + TRACE_INFO_WP("ReqSense "); + + /* Perform the RequestSense command */ + result = SBC_RequestSense(lun, commandState); + break; + + /*------------------------------------ */ + case SBC_PREVENT_ALLOW_MEDIUM_REMOVAL: + /*------------------------------------ */ + + TRACE_INFO_WP("PrevAllowRem "); + + /* Check parameter */ + + result = command->mediumRemoval.bPrevent ? + MSDD_STATUS_PARAMETER : MSDD_STATUS_SUCCESS; + break; + /*------ */ + default: + /*------ */ + + result = MSDD_STATUS_PARAMETER; + } + + return result; +} + +/**@}*/ diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/AUDDFunction.h b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDFunction.h new file mode 100644 index 00000000..ed2482c6 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDFunction.h @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ +/** \file */ +#ifndef AUDDFUNCTION_H +#define AUDDFUNCTION_H +/** \addtogroup usbd_aud_fun + *@{ + */ + +/*----------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +/*----------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +/** \addtogroup audd_fun_desc USBD Audio Function definitions + * @{ + */ +/** ID for Speaker */ +#define AUDDFunction_Speaker 0 +/** ID for Microphone */ +#define AUDDFunction_Microhpone 1 +/** Max number of interfaces that supported by the function (AC + 2*AS) */ +#define AUDDFunction_MaxNumInterfaces 3 +/** Max number of channels supported by speaker stream (including master) */ +#define AUDDFunction_MaxNumSpeakerChannels 3 +/** Max number of channels supported by microphone stream (including master) */ +#define AUDDFunction_MaxNumMicrophoneChannels 3 + +/** Endpoint polling interval 2^(x-1) * 125us */ +#define AUDDFunction_HS_INTERVAL 0x04 +/** Endpoint polling interval 2^(x-1) * ms */ +#define AUDDFunction_FS_INTERVAL 0x01 + +/** Playback input terminal ID */ +#define AUDDFunction_INPUTTERMINAL AUDD_ID_SpeakerIT +/** Playback output terminal ID */ +#define AUDDFunction_OUTPUTTERMINAL AUDD_ID_SpeakerOT +/** Playback feature unit ID */ +#define AUDDFunction_FEATUREUNIT AUDD_ID_SpeakerFU +/** Record input terminal ID */ +#define AUDDFunction_INPUTTERMINAL_REC AUDD_ID_MicrophoneIT +/** Record output terminal ID */ +#define AUDDFunction_OUTPUTTERMINAL_REC AUDD_ID_MicrophoneOT +/** Record feature unit ID */ +#define AUDDFunction_FEATUREUNIT_REC AUDD_ID_MicrophoneFU + +/** @}*/ + +/*----------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +extern void AUDDFunction_Initialize( + USBDDriver *pUsbd, uint8_t bInterface); +extern void AUDDFunction_Configure( + USBGenericDescriptor * pDescriptors, uint16_t wLength); +extern void AUDDFunction_InterfaceSettingChangedHandler( + uint8_t interface,uint8_t setting); +extern uint32_t AUDDFunction_RequestHandler(const USBGenericRequest * request); +extern uint8_t AUDDFunction_Read( + void * buffer, uint32_t length, + TransferCallback callback, void * argument); +extern uint8_t AUDDFunction_SetupWrite( + void * pListInit, void * pDmaInit, uint16_t listSize, uint16_t delaySize, + TransferCallback callback,void * argument); +extern uint8_t AUDDFunction_Write(void * buffer, uint16_t length); + +extern void AUDDFunction_MuteChanged( + uint8_t idMic, uint8_t ch, uint8_t mute); +extern void AUDDFunction_StreamSettingChanged( + uint8_t idMic, uint8_t setting); + +/**@}*/ +#endif // #define AUDDFUNCTIONDRIVER_H + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerDriver.h new file mode 100644 index 00000000..87393f4c --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerDriver.h @@ -0,0 +1,256 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definition of a USB Audio Speaker Driver with two playback channels. + * + * \section Usage + * + * -# Enable and setup USB related pins (see pio & board.h). + * -# Configure the USB Audio Speaker driver using AUDDSpeakerDriver_Initialize + * -# To get %audio stream frames from host, use AUDDSpeakerDriver_Read + */ + +#ifndef AUDDSPEAKERDRIVER_H +#define AUDDSPEAKERDRIVER_H + +/** \addtogroup usbd_audio_speaker + *@{ + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include + +#include +#include +#include + +#include +#include + +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usbd_audio_ch USB Device Audio Speaker Channel Numbers + * @{ + * This page lists codes for USB Audio Speaker channel numbers. + * + * \par Playback channel numbers + * - \ref AUDDSpeakerDriver_MASTERCHANNEL + * - \ref AUDDSpeakerDriver_LEFTCHANNEL + * - \ref AUDDSpeakerDriver_RIGHTCHANNEL + * + * \par Record channel number + * - \ref AUDDSpeakerDriver_RECCHANNEL + */ +/** Master channel of playback. */ +#define AUDDSpeakerDriver_MASTERCHANNEL 0 +/** Front left channel of playback. */ +#define AUDDSpeakerDriver_LEFTCHANNEL 1 +/** Front right channel of playback. */ +#define AUDDSpeakerDriver_RIGHTCHANNEL 2 + +/** Channel of record. */ +#define AUDDSpeakerDriver_RECCHANNEL 0 + +/** Max Number of channels in audio stream (excluding master). */ +#define AUDDSpeakerDriver_NUMCHANNELS 2 +/** @}*/ + +/** \addtogroup usbd_audio_speaker_if USB Device Audio Speaker Interface IDs + * @{ + * This page lists the interface numbers for USB Audio Speaker device. + * - \ref AUDDSpeakerDriverDescriptors_CONTROL + * - \ref AUDDSpeakerDriverDescriptors_STREAMING + * Total number of integrated interfaces + * - \ref AUDDSpeakerDriver_NUMINTERFACES + */ +/** Audio control interface ID. */ +#define AUDDSpeakerDriverDescriptors_CONTROL 0 +/** Audio streaming interface ID (OUT, for playback). */ +#define AUDDSpeakerDriverDescriptors_STREAMING 1 + +/** Audio speaker total number of interfaces */ +#define AUDDSpeakerDriver_NUMINTERFACES 2 +/** @}*/ + +/** \addtogroup usbd_audio_entity USB Device Audio Speaker Entity IDs + * @{ + * This page lists the entity IDs for USB Audio Speaker device. + * - \ref AUDDSpeakerDriverDescriptors_INPUTTERMINAL + * - \ref AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL + * - \ref AUDDSpeakerDriverDescriptors_FEATUREUNIT + */ +/** Playback input terminal ID. */ +#define AUDDSpeakerDriverDescriptors_INPUTTERMINAL AUDD_ID_SpeakerIT +/** Playback output terminal ID. */ +#define AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL AUDD_ID_SpeakerOT +/** Playback feature unit ID. */ +#define AUDDSpeakerDriverDescriptors_FEATUREUNIT AUDD_ID_SpeakerFU +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR*/ +#pragma pack(1) /* IAR*/ +#define __attribute__(...) /* IAR*/ +#endif /* IAR*/ + +/** + * \typedef AUDHeaderDescriptor1 + * \brief Header descriptor with 1 interface. + */ +typedef struct _AUDHeaderDescriptor1 { + + /** Header descriptor. */ + AUDHeaderDescriptor header; + /** Id of the first grouped interface - Speaker. */ + uint8_t bInterface0; + +} __attribute__ ((packed)) AUDHeaderDescriptor1; /* GCC*/ + +/** + * \typedef AUDFeatureUnitDescriptor3 + * \brief Feature unit descriptor with 3 channel controls + * (master, right, left). + */ +typedef struct _AUDFeatureUnitDescriptor3 { + + /** Feature unit descriptor. */ + AUDFeatureUnitDescriptor feature; + /** Available controls for each channel. */ + uint8_t bmaControls[3]; + /** Index of a string descriptor for the feature unit. */ + uint8_t iFeature; + +} __attribute__ ((packed)) AUDFeatureUnitDescriptor3; /* GCC */ + +/** + * \typedef AUDDSpeakerDriverAudioControlDescriptors + * \brief List of descriptors for detailling the audio control interface of a + * device using a USB audio speaker driver. + */ +typedef struct _AUDDSpeakerDriverAudioControlDescriptors { + + /** 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*/ + +/** + * \typedef AUDFormatTypeOneDescriptor1 + * \brief Format type I descriptor with one discrete sampling frequency. + */ +typedef struct _AUDFormatTypeOneDescriptor1 { + + /** Format type I descriptor. */ + AUDFormatTypeOneDescriptor formatType; + /** Sampling frequency in Hz. */ + uint8_t tSamFreq[3]; + +} __attribute__ ((packed)) AUDFormatTypeOneDescriptor1; /* GCC*/ + +/** + * \typedef AUDDSpeakerDriverConfigurationDescriptors + * \brief Holds a list of descriptors returned as part of the configuration of + * a USB audio speaker device. + */ +typedef struct _AUDDSpeakerDriverConfigurationDescriptors { + + /** Standard configuration. */ + USBConfigurationDescriptor configuration; + /** Audio control interface. */ + USBInterfaceDescriptor control; + /** Descriptors for the audio control interface. */ + AUDDSpeakerDriverAudioControlDescriptors controlDescriptors; + /* - AUDIO OUT */ + /** Streaming out interface descriptor (with no endpoint, required). */ + USBInterfaceDescriptor streamingOutNoIsochronous; + /** Streaming out interface descriptor. */ + USBInterfaceDescriptor streamingOut; + /** Audio class descriptor for the streaming out interface. */ + AUDStreamingInterfaceDescriptor streamingOutClass; + /** Stream format descriptor. */ + AUDFormatTypeOneDescriptor1 streamingOutFormatType; + /** Streaming out endpoint descriptor. */ + AUDEndpointDescriptor streamingOutEndpoint; + /** Audio class descriptor for the streaming out endpoint. */ + AUDDataEndpointDescriptor streamingOutDataEndpoint; + +} __attribute__ ((packed)) AUDDSpeakerDriverConfigurationDescriptors; /* GCC */ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Exported functions + *----------------------------------------------------------------------------*/ + +extern void AUDDSpeakerDriver_Initialize( + const USBDDriverDescriptors *pDescriptors); + +extern void AUDDSpeakerDriver_ConfigurationChangeHandler(uint8_t cfgnum); + +extern void AUDDSpeakerDriver_InterfaceSettingChangedHandler( + uint8_t interface, uint8_t setting); + +extern void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request); + +extern uint8_t AUDDSpeakerDriver_Read(void *buffer, + uint32_t length, + TransferCallback callback, + void *argument); + +extern void AUDDSpeakerDriver_MuteChanged(uint8_t channel,uint8_t muted); + +extern void AUDDSpeakerDriver_StreamSettingChanged(uint8_t newSetting); + +/**@}*/ +#endif /*#ifndef AUDDSPEAKERDRIVER_H */ + + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerPhone.h b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerPhone.h new file mode 100644 index 00000000..ae5a22a0 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerPhone.h @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * USB Audio Speaker & Microphone Function. + */ + +/** \addtogroup usbd_audio_speakerphone + *@{ + * Implement speakerphone function that combine 1 AC interface, 1 AS interface + * for speaker and 1 AS interface for microphone. + */ + +#ifndef _AUDD_SPEAKERPHONE_H_ +#define _AUDD_SPEAKERPHONE_H_ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include + +#include +#include + +/*------------------------------------------------------------------------------ + * Defines + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_audio_ids Audio Device IDs required by driver + * @{ + * The driver uses following fixed entity IDs, use them to define your + * descriptor. + * \ref AUDD_ID_SpeakerIT + * \ref AUDD_ID_SpeakerOT + * \ref AUDD_ID_SpeakerFU + * \ref AUDD_ID_MicrophoneIT + * \ref AUDD_ID_MicrophoneOT + * \ref AUDD_ID_MicrophoneFU + */ +/** Speaker input terminal ID */ +#define AUDD_ID_SpeakerIT 0x01 +/** Speaker output terminal ID */ +#define AUDD_ID_SpeakerOT 0x02 +/** Speaker feature unit ID */ +#define AUDD_ID_SpeakerFU 0x03 +/** Microphone input terminal ID */ +#define AUDD_ID_MicrophoneIT 0x04 +/** Microphone output terminal ID */ +#define AUDD_ID_MicrophoneOT 0x05 +/** Microphone feature unit ID */ +#define AUDD_ID_MicrophoneFU 0x06 +/** @}*/ + +/** \addtogroup usbd_audio_chs Audio Device Channels + * @{ + */ +/** Master channel ID */ +#define AUDD_CH_Master 0x0 +/** Left channel ID */ +#define AUDD_CH_L 0x1 +/** Right channel ID */ +#define AUDD_CH_R 0x2 +/** @}*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** + * Struct of USB Audio Speakerphone Function, with + * - 1 control interface for features, + * - 1 input stream for microphone (Audio IN), + * - 1 output stream for speaker (Audio OUT). + */ +typedef struct _AUDDSpeakerPhone { + /** Pointer to USBD Driver Interface */ + USBDDriver *pUsbd; + /** Pointer to AUDDStream Instance */ + AUDDStream *pSpeaker; + /** Pointer to AUDDStream Instance */ + AUDDStream *pMicrophone; +} AUDDSpeakerPhone; + +/*------------------------------------------------------------------------------ + * Functions + *------------------------------------------------------------------------------*/ + +extern void AUDDSpeakerPhone_InitializeStream( + AUDDStream * pAuds, + uint8_t numChannels,uint16_t wChannelVolumes [ ], + AUDDStreamEventCallback fCallback,void * pArg); + +extern void AUDDSpeakerPhone_Initialize( + AUDDSpeakerPhone * pAudf, + USBDDriver * pUsbd, + AUDDStream * pSpeaker,AUDDStream * pMicrophone); + +extern USBGenericDescriptor* AUDDSpeakerPhone_ParseInterfaces( + AUDDSpeakerPhone * pAudf, + USBGenericDescriptor * pDescriptors, + uint32_t dwLength); + +extern uint32_t AUDDSpeakerPhone_RequestHandler( + AUDDSpeakerPhone * pAudf, + const USBGenericRequest * pRequest); + +extern uint32_t AUDDSpeakerPhone_CloseStream( + AUDDSpeakerPhone * pAudf, + uint32_t bInterface); + +extern uint32_t AUDDSpeakerPhone_SetupWrite( + AUDDSpeakerPhone * pAudf, + void * pListInit, void * pDmaInit, uint16_t listSize, uint16_t delaySize, + TransferCallback callback,void * argument); + +extern uint32_t AUDDSpeakerPhone_Write( + AUDDSpeakerPhone * pAudf, + void * pBuffer,uint16_t wLength); + +extern uint32_t AUDDSpeakerPhone_Read( + AUDDSpeakerPhone * pAudf, + void * pData, uint32_t dwSize, + TransferCallback fCallback,void * pArg); + +/**@}*/ +#endif /* _AUDD_SPEAKERPHONE_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerPhoneDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerPhoneDriver.h new file mode 100644 index 00000000..32d84716 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDSpeakerPhoneDriver.h @@ -0,0 +1,311 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definition of a USB Audio Speakerphone Driver with two playback channels + * and one record channel. + * + * \section Usage + * + * -# Enable and setup USB related pins (see pio & board.h). + * -# Inplement a descriptor list using definitions + * - \ref usbd_audio_speakerphone_channel_num + * - \ref usbd_audio_speaker_interface_ids + * - \ref usbd_audio_speaker_entity_ids + * -# Configure the USB Audio Speakerphone driver using + * AUDDSpeakerPhoneDriver_Initialize + * -# To get %audio stream frames from host, use + * AUDDSpeakerPhoneDriver_Read + * -# To send %audio sampling stream to host, use + * AUDDSpeakerPhoneDriver_Write + * + */ + +#ifndef AUDDSpeakerPhoneDriver_H +#define AUDDSpeakerPhoneDriver_H + +/** \addtogroup usbd_audio_speakerphone + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include +#include + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_audio_speakerphone_channel_num Audio SpeakerPhone Channel Numbers + * @{ + * This page lists codes for USB Audio Speakerphone channel numbers. + * + * \section Playback channel numbers + * - AUDDSpeakerPhoneDriver_MASTERCHANNEL + * - AUDDSpeakerPhoneDriver_LEFTCHANNEL + * - AUDDSpeakerPhoneDriver_RIGHTCHANNEL + * + * \section Record channel number + * - AUDDSpeakerPhoneDriver_RECCHANNEL + */ + +/** Master channel of playback. */ +#define AUDDSpeakerPhoneDriver_MASTERCHANNEL 0 +/** Front left channel of playback. */ +#define AUDDSpeakerPhoneDriver_LEFTCHANNEL 1 +/** Front right channel of playback. */ +#define AUDDSpeakerPhoneDriver_RIGHTCHANNEL 2 +/** Channel of record. */ +#define AUDDSpeakerPhoneDriver_RECCHANNEL 0 +/** @}*/ + +/** \addtogroup usbd_audio_speaker_interface_ids Audio SpeakerPhone Interface IDs + * @{ + * This page lists the interface numbers for USB Audio Speakerphone device. + * + * \section Interfaces + * - AUDDSpeakerPhoneDriverDescriptors_CONTROL + * - AUDDSpeakerPhoneDriverDescriptors_STREAMING + * - AUDDSpeakerPhoneDriverDescriptors_STREAMINGIN + */ + +/** Audio control interface ID */ +#define AUDDSpeakerPhoneDriverDescriptors_CONTROL 0 +/** Audio streaming interface ID (OUT, for playback) */ +#define AUDDSpeakerPhoneDriverDescriptors_STREAMING 1 +/** Audio streaming interface ID (IN, for record) */ +#define AUDDSpeakerPhoneDriverDescriptors_STREAMINGIN 2 +/** @}*/ + +/** \addtogroup usbd_audio_speaker_entity_ids Audio SpeakerPhone Entity IDs + * @{ + * This page lists the entity IDs for USB Audio Speaker device. + * + * \section Entities + * - AUDDSpeakerPhoneDriverDescriptors_INPUTTERMINAL + * - AUDDSpeakerPhoneDriverDescriptors_OUTPUTTERMINAL + * - AUDDSpeakerPhoneDriverDescriptors_FEATUREUNIT + * - AUDDSpeakerPhoneDriverDescriptors_INPUTTERMINAL_REC + * - AUDDSpeakerPhoneDriverDescriptors_OUTPUTTERMINAL_REC + * - AUDDSpeakerPhoneDriverDescriptors_FEATUREUNIT_REC + */ + +/** Playback input terminal ID */ +#define AUDDSpeakerPhoneDriverDescriptors_INPUTTERMINAL 0 +/** Playback output terminal ID */ +#define AUDDSpeakerPhoneDriverDescriptors_OUTPUTTERMINAL 1 +/** Playback feature unit ID */ +#define AUDDSpeakerPhoneDriverDescriptors_FEATUREUNIT 2 +/** Record input terminal ID */ +#define AUDDSpeakerPhoneDriverDescriptors_INPUTTERMINAL_REC 3 +/** Record output terminal ID */ +#define AUDDSpeakerPhoneDriverDescriptors_OUTPUTTERMINAL_REC 4 +/** Record feature unit ID */ +#define AUDDSpeakerPhoneDriverDescriptors_FEATUREUNIT_REC 5 +/** @}*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Audio control header descriptor with one slave interface. + *------------------------------------------------------------------------------*/ +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef AUDHeaderDescriptor2 + * \brief Header descriptor with 1 interface. + */ +typedef struct _AUDHeaderDescriptor2 { + + /** Header descriptor. */ + AUDHeaderDescriptor header; + /** Id of the first grouped interface - Speaker. */ + unsigned char bInterface0; + /** Id of the second grouped interface - Speakerphone. */ + unsigned char bInterface1; + +} __attribute__ ((packed)) AUDHeaderDescriptor2; /* GCC */ + +/** + * \typedef AUDFeatureUnitDescriptor3 + * \brief Feature unit descriptor with 3 channel controls (master, right, left). + */ +typedef struct _AUDFeatureUnitDescriptor3 { + + /** 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 */ + +/** + * \typedef AUDDSpeakerPhoneDriverAudioControlDescriptors + * \brief List of descriptors for detailling the audio control interface of a + * device using a USB Audio Speakerphoneer driver. + */ +typedef struct _AUDDSpeakerPhoneDriverAudioControlDescriptors { + + /** Header descriptor (with one slave interface). */ + AUDHeaderDescriptor2 header; + /** Input terminal descriptor. */ + AUDInputTerminalDescriptor inputSpeakerPhone; + /** Output terminal descriptor. */ + AUDOutputTerminalDescriptor outputSpeakerPhone; + /** Feature unit descriptor - SpeakerPhone. */ + AUDFeatureUnitDescriptor3 featureSpeakerPhone; + /** Input terminal descriptor. */ + AUDInputTerminalDescriptor inputRec; + /** Output terminal descriptor. */ + AUDOutputTerminalDescriptor outputRec; + /** Feature unit descriptor - SpeakerPhonephone. */ + AUDFeatureUnitDescriptor3 featureRec; + +} __attribute__ ((packed)) AUDDSpeakerPhoneDriverAudioControlDescriptors; /* GCC */ + +/** + * \typedef AUDFormatTypeOneDescriptor1 + * \brief Format type I descriptor with one discrete sampling frequency. + */ +typedef struct _AUDFormatTypeOneDescriptor1 { + + /** Format type I descriptor. */ + AUDFormatTypeOneDescriptor formatType; + /** Sampling frequency in Hz. */ + unsigned char tSamFreq[3]; + +} __attribute__ ((packed)) AUDFormatTypeOneDescriptor1; /* GCC */ + +/** + * \typedef AUDDSpeakerPhoneDriverConfigurationDescriptors + * \brief Holds a list of descriptors returned as part of the configuration of + * a USB Audio Speakerphone device. + */ +typedef struct _AUDDSpeakerPhoneDriverConfigurationDescriptors { + + /** Standard configuration. */ + USBConfigurationDescriptor configuration; + /** Audio control interface. */ + USBInterfaceDescriptor control; + /** Descriptors for the audio control interface. */ + AUDDSpeakerPhoneDriverAudioControlDescriptors controlDescriptors; + /*- AUDIO OUT */ + /** Streaming out interface descriptor (with no endpoint, required). */ + USBInterfaceDescriptor streamingOutNoIsochronous; + /** Streaming out interface descriptor. */ + USBInterfaceDescriptor streamingOut; + /** Audio class descriptor for the streaming out interface. */ + AUDStreamingInterfaceDescriptor streamingOutClass; + /** Stream format descriptor. */ + AUDFormatTypeOneDescriptor1 streamingOutFormatType; + /** Streaming out endpoint descriptor. */ + AUDEndpointDescriptor streamingOutEndpoint; + /** Audio class descriptor for the streaming out endpoint. */ + AUDDataEndpointDescriptor streamingOutDataEndpoint; + /*- AUDIO IN */ + /** Streaming in interface descriptor (with no endpoint, required). */ + USBInterfaceDescriptor streamingInNoIsochronous; + /** Streaming in interface descriptor. */ + USBInterfaceDescriptor streamingIn; + /** Audio class descriptor for the streaming in interface. */ + AUDStreamingInterfaceDescriptor streamingInClass; + /** Stream format descriptor. */ + AUDFormatTypeOneDescriptor1 streamingInFormatType; + /** Streaming in endpoint descriptor. */ + AUDEndpointDescriptor streamingInEndpoint; + /** Audio class descriptor for the streaming in endpoint. */ + AUDDataEndpointDescriptor streamingInDataEndpoint; + +} __attribute__ ((packed)) AUDDSpeakerPhoneDriverConfigurationDescriptors; /* GCC */ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern void AUDDSpeakerPhoneDriver_Initialize( + const USBDDriverDescriptors *pDescriptors); + +extern void AUDDSpeakerPhoneDriver_ConfigurationChangeHandler(uint8_t cfgnum); + +extern void AUDDSpeakerPhoneDriver_InterfaceSettingChangedHandler( + uint8_t interface, + uint8_t setting); + +extern void AUDDSpeakerPhoneDriver_RequestHandler( + const USBGenericRequest *request); + +extern uint8_t AUDDSpeakerPhoneDriver_Read(void *buffer, + uint32_t length, + TransferCallback callback, + void *argument); + +extern uint8_t AUDDSpeakerPhoneDriver_SetupWrite(void * pListInit, + void * pDmaInit, + uint16_t listSize, + uint16_t delaySize, + TransferCallback callback, + void * argument); + +extern uint8_t AUDDSpeakerPhoneDriver_Write(void * buffer,uint16_t length); + + +extern void AUDDSpeakerPhoneDriver_MuteChanged(uint8_t mic, + uint8_t channel, + uint8_t muted); + +extern void AUDDSpeakerPhoneDriver_StreamSettingChanged(uint8_t mic, + uint8_t newSetting); + +/**@}*/ + +#endif /*#ifndef AUDDSpeakerPhoneDriver_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/AUDDStream.h b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDStream.h new file mode 100644 index 00000000..571711bc --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDStream.h @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * USB Audio Device Streaming interface with controls. + * (3 channels (including master) supported). + */ + +/** \addtogroup usbd_audio_speakerphone + *@{ + * Implement speakerphone function that combine 1 AC interface, 1 AS interface + * for speaker and 1 AS interface for microphone. + */ + +#ifndef _AUDD_STREAM_H_ +#define _AUDD_STREAM_H_ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include +#include + +/*------------------------------------------------------------------------------ + * Defines + *------------------------------------------------------------------------------*/ + +/** \addtopage usbd_audio_ec Audio Device Event codes + * @{ + */ +/** Mute status changed */ +#define AUDD_EC_MuteChanged 1 +/** Volume status changed */ +#define AUDD_EC_VolumeChanged 2 +/** @}*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** Callback function for Audio Stream Event */ +typedef void (*AUDDStreamEventCallback)(uint32_t ec, + uint8_t channel, + void* pArg); + +/** + * Struct of USB Audio Stream Interface. + * Support 1 control interface, with I & O stream. + * Unit ID 0xFF is reserved for not implemented. + */ +typedef struct _AUDDStream { + /** AudioControl Interface number */ + uint8_t bAcInterface; + /** AudioControl Feature Unit ID for IN */ + uint8_t bFeatureUnitOut; + /** AudioControl Feature Unit ID for OUT */ + uint8_t bFeatureUnitIn; + /** AudioStreaming Interface number */ + uint8_t bAsInterface; + /** Streaming OUT endpoint address */ + uint8_t bEndpointOut; + /** Streaming IN endpoint address */ + uint8_t bEndpointIn; + /** Number of channels (<=8) */ + uint8_t bNumChannels; + /** Mute control bits (8b) */ + uint8_t bmMute; + /** Volume control data */ + uint16_t *pwVolumes; + + /** Audio Streaming Events Callback */ + AUDDStreamEventCallback fCallback; + /** Callback arguments */ + void* pArg; +} AUDDStream; + +/*------------------------------------------------------------------------------ + * Functions + *------------------------------------------------------------------------------*/ + +extern void AUDDStream_Initialize( + AUDDStream * pAuds, + uint8_t numChannels, + uint16_t wChannelVolumes [ ], + AUDDStreamEventCallback fCallback, + void * pArg); + +extern uint32_t AUDDStream_ChangeMute( + AUDDStream * pAuds, + uint8_t bChannel, + uint8_t bMute); + +extern uint32_t AUDDStream_SetVolume( + AUDDStream * pAuds, + uint8_t bChannel, + uint16_t wVolume); + +extern uint32_t AUDDStream_IsRequestAccepted( + AUDDStream *pAuds, + const USBGenericRequest *pReq); + +extern uint32_t AUDDStream_Read( + AUDDStream * pAuds, + void * pData, uint32_t dwSize, + TransferCallback fCallback,void * pArg); + +extern uint32_t AUDDStream_SetupWrite( + AUDDStream * pAuds, + void * pListInit, void * pDmaInit, uint16_t listSize, + uint16_t delaySize, + TransferCallback callback,void * argument); + +extern uint32_t AUDDStream_Write( + AUDDStream * pAuds, + void * pBuffer,uint16_t wLength); + +extern uint32_t AUDDStream_Close(AUDDStream * pStream); + +#endif /* _AUDD_STREAM_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/AUDDescriptors.h b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDescriptors.h new file mode 100644 index 00000000..43d5e6b2 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/AUDDescriptors.h @@ -0,0 +1,546 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * Definitions and classes for USB Audio class descriptors. + * + * - For a USB %device: + * -# When declaring an Audio-specific descriptor, use the descriptor types + * and subtypes defined in this unit (see "USB Audio descriptor types" + * and "USB Audio descriptor subtypes"). + * -# When declaring the %device descriptor of a USB %audio %device, use + * "USB Audio device descriptor values" defined here. + * -# Declare an AUDStreamingInterfaceDescriptor instance as part of the + * configuration descriptors returned by a USB %audio %device. + * -# Declare a AUDHeaderDescriptor as part of the configuration + * descriptors of the %device. + * -# Declare an AUDFeatureUnitDescriptor instance as part of the + * configuration descriptors returned by a USB %audio %device. + * -# Declare an instance of AUDFormatTypeOneDescriptor as part of the + * configuration descriptors of an audio device. + */ + +#ifndef _AUDDESCRIPTORS_H_ +#define _AUDDESCRIPTORS_H_ +/** \addtogroup usb_audio + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_audio_desc_type USB Audio descriptor types + * @{ + * This section lists the available types for USB audio-specific descriptors. + * - \ref AUDGenericDescriptor_DEVICE + * - \ref AUDGenericDescriptor_CONFIGURATION + * - \ref AUDGenericDescriptor_STRING + * - \ref AUDGenericDescriptor_INTERFACE + * - \ref AUDGenericDescriptor_ENDPOINT + */ + +/** Descriptor gives detail about the whole device.*/ +#define AUDGenericDescriptor_DEVICE 0x21 +/** Descriptor gives detail about a configuration.*/ +#define AUDGenericDescriptor_CONFIGURATION 0x22 +/** Descriptor gives detail about a string.*/ +#define AUDGenericDescriptor_STRING 0x23 +/** Descriptor gives detail about an interface.*/ +#define AUDGenericDescriptor_INTERFACE 0x24 +/** Descriptor gives detail about an endpoint. */ +#define AUDGenericDescriptor_ENDPOINT 0x25 +/** @}*/ + +/** \addtogroup usb_audio_desc_subtype USB Audio descriptor subtypes + * @{ + * This section lists the possible subtypes for USB audio-specific descriptors. + * - \ref AUDGenericDescriptor_HEADER + * - \ref AUDGenericDescriptor_INPUTTERMINAL + * - \ref AUDGenericDescriptor_OUTPUTTERMINAL + * - \ref AUDGenericDescriptor_MIXERUNIT + * - \ref AUDGenericDescriptor_SELECTORUNIT + * - \ref AUDGenericDescriptor_FEATUREUNIT + * - \ref AUDGenericDescriptor_PROCESSINGUNIT + * - \ref AUDGenericDescriptor_EXTENSIONUNIT + */ +/** Header descriptor subtype.*/ +#define AUDGenericDescriptor_HEADER 0x01 +/** Input terminal descriptor subtype.*/ +#define AUDGenericDescriptor_INPUTTERMINAL 0x02 +/** Output terminal descriptor subtype.*/ +#define AUDGenericDescriptor_OUTPUTTERMINAL 0x03 +/** Mixer unit descriptor subtype.*/ +#define AUDGenericDescriptor_MIXERUNIT 0x04 +/** Selector unit descriptor subtype.*/ +#define AUDGenericDescriptor_SELECTORUNIT 0x05 +/** Feature unit descriptor subtype.*/ +#define AUDGenericDescriptor_FEATUREUNIT 0x06 +/** Processing unit descriptor subtype.*/ +#define AUDGenericDescriptor_PROCESSINGUNIT 0x07 +/** Extension unit descriptor subtype.*/ +#define AUDGenericDescriptor_EXTENSIONUNIT 0x08 +/** @}*/ + + +/** \addtogroup usb_audio_desc USB Audio Descriptors + * @{ + * USB Audio device descriptor values + * + * This section lists the class, subclass & protocol codes that a USB audio + * device should display in its device descriptor. + * - \ref AUDDeviceDescriptor_CLASS + * - \ref AUDDeviceDescriptor_SUBCLASS + * - \ref AUDDeviceDescriptor_PROTOCOL + */ +/** Class code for a USB audio device. */ +#define AUDDeviceDescriptor_CLASS 0x00 +/** Subclass code for a USB audio device. */ +#define AUDDeviceDescriptor_SUBCLASS 0x00 +/** Protocol code for a USB audio device. */ +#define AUDDeviceDescriptor_PROTOCOL 0x00 +/** @}*/ + + +/** + * \addtogroup usb_audio_stream_if USB Audio streaming interface codes + * @{ + * This section lists the class, subclass and protocol codes that an Audio + * Streaming interface should display in its descriptor. + * - \ref AUDStreamingInterfaceDescriptor_CLASS + * - \ref AUDStreamingInterfaceDescriptor_SUBCLASS + * - \ref AUDStreamingInterfaceDescriptor_PROTOCOL + */ +/** Class code for an USB audio streaming interface.*/ +#define AUDStreamingInterfaceDescriptor_CLASS 0x01 + +/** Subclass code for an audio streaming interface.*/ +#define AUDStreamingInterfaceDescriptor_SUBCLASS 0x02 + +/** Protocol code for an audio streaming interface.*/ +#define AUDStreamingInterfaceDescriptor_PROTOCOL 0x00 +/** @}*/ + +/** + * \addtogroup usb_audio_stream_subtype USB Audio streaming descriptor subtypes + * @{ + * This section lists the possible subtypes for audio-specific descriptor + * appended to an Audio Streaming interface. + * - \ref AUDStreamingInterfaceDescriptor_GENERAL + * - \ref AUDStreamingInterfaceDescriptor_FORMATTYPE + * - \ref AUDStreamingInterfaceDescriptor_FORMATSPECIFIC + */ +/** General descriptor subtype.*/ +#define AUDStreamingInterfaceDescriptor_GENERAL 0x01 + +/** Format type descriptor subtype.*/ +#define AUDStreamingInterfaceDescriptor_FORMATTYPE 0x02 + +/** Format specific descriptor subtype.*/ +#define AUDStreamingInterfaceDescriptor_FORMATSPECIFIC 0x03 +/** @}*/ + + +/** \addtogroup usb_audio_ctrl_if USB Audio Control Interface + * @{ + * This section lists the class, subclass and protocol codes that a USB Audio + * Control interface descriptor should display. + * - \ref AUDControlInterfaceDescriptor_CLASS + * - \ref AUDControlInterfaceDescriptor_SUBCLASS + * - \ref AUDControlInterfaceDescriptor_PROTOCOL + */ +/** Class code for an audio control interface. */ +#define AUDControlInterfaceDescriptor_CLASS 0x01 +/** Subclass code for an audio control interface. */ +#define AUDControlInterfaceDescriptor_SUBCLASS 0x01 +/** Protocol code for an audio control interface. */ +#define AUDControlInterfaceDescriptor_PROTOCOL 0x00 +/** @}*/ + + +/** Descriptor subtype for an Audio data endpoint. */ +#define AUDDataEndpointDescriptor_SUBTYPE 0x01 + +/** \addtogroup usb_audio_lock_delay USB Audio Lock delay units + * @{ + * This section lists the valid lock delay unit types. + * - \ref AUDDataEndpointDescriptor_MILLISECONDS + * - \ref AUDDataEndpointDescriptor_PCMSAMPLES + */ +/** Lock delay is expressed in milliseconds. */ +#define AUDDataEndpointDescriptor_MILLISECONDS 1 +/** Lock delay is expressed in decoded PCM samples. */ +#define AUDDataEndpointDescriptor_PCMSAMPLES 2 +/** @}*/ + + +/** \addtogroup usb_audio_class_ver USB Audio class releases + * @{ + * This section lists the existing versions of the Audio class specification. + * - \ref AUDHeaderDescriptor_AUD1_00 + */ + +/** Indentifies the USB audio specification release 1.00.*/ +#define AUDHeaderDescriptor_AUD1_00 0x0100 +/** @}*/ + +#define AUDTerminalDescriptor_USBSTREAMING 0x0101 +#define AUDTerminalDescriptor_MICROPHONE 0x0201 +#define AUDTerminalDescriptor_HANDSETIN 0x0401 +#define AUDTerminalDescriptor_SPEAKERPHONE 0x0403 +#define AUDTerminalDescriptor_LINEIN 0x0501 + +/** \addtogroup usb_audio_in_term USB Audio Input terminal types + * @{ + * This section lists the available types for an Input terminal. + * - \ref AUDInputTerminalDescriptor_USBSTREAMING + * - \ref AUDInputTerminalDescriptor_MICROPHONE + * - \ref AUDInputTerminalDescriptor_SPEAKERPHONE + * - \ref AUDInputTerminalDescriptor_LINEIN + */ + +/** A terminal receiving its data from a USB isochronous endpoint.*/ +#define AUDInputTerminalDescriptor_USBSTREAMING 0x0101 +/** A terminal sampling data from a microphone.*/ +#define AUDInputTerminalDescriptor_MICROPHONE 0x0201 +/** A terminal sampling data from a Handset In.*/ +#define AUDInputTerminalDescriptor_HANDSETIN 0x0401 +/** A terminal sampling data from a speakerphone*/ +#define AUDInputTerminalDescriptor_SPEAKERPHONE 0x0403 +/** A terminal sampling data from a Phone Line In.*/ +#define AUDInputTerminalDescriptor_LINEIN 0x0501 +/** @}*/ + +/** \addtogroup usb_audio_ch_loc USB Audio Channel spatial locations + * @{ + * This section lists the possible spatial locations for audio channels. + * - \ref AUDInputTerminalDescriptor_LEFTFRONT + * - \ref AUDInputTerminalDescriptor_RIGHTFRONT + * - \ref AUDInputTerminalDescriptor_CENTERFRONT + */ +/** Front left channel.*/ +#define AUDInputTerminalDescriptor_LEFTFRONT (1 << 0) +/** Front right channel.*/ +#define AUDInputTerminalDescriptor_RIGHTFRONT (1 << 1) +/** Front center channel.*/ +#define AUDInputTerminalDescriptor_CENTERFRONT (1 << 2) +/** @}*/ + + +/** \addtogroup usb_audio_out_term USB Audio Output terminal types + * @{ + * This section lists the available types for an output terminal. + * - \ref AUDOutputTerminalDescriptor_USBTREAMING + * - \ref AUDOutputTerminalDescriptor_SPEAKER + * - \ref AUDOutputTerminalDescriptor_HANDSETOUT + * - \ref AUDOutputTerminalDescriptor_LINEOUT + */ +/** A terminal sending data through USB isochronous endpoint.*/ +#define AUDOutputTerminalDescriptor_USBTREAMING 0x0101 +/** A terminal sending data to a USB host through an Isochronous endpoint.*/ +#define AUDOutputTerminalDescriptor_SPEAKER 0x0301 +/** A terminal sending data to Handset Out.*/ +#define AUDOutputTerminalDescriptor_HANDSETOUT 0x0401 +/** A terminal sending data to Phone Line Out.*/ +#define AUDOutputTerminalDescriptor_LINEOUT 0x0501 +/** @}*/ + +/** \addtogroup usb_audio_ch_ctrl USB Audio Channel controls + * @{ + * This section lists the available controls for each channel of the audio + * interface. Each channel can have any control combination; simply perform + * a bitwise OR ('|') to combine several values. + * -# \ref AUDFeatureUnitDescriptor_MUTE + * -# \ref AUDFeatureUnitDescriptor_VOLUME + * -# \ref AUDFeatureUnitDescriptor_BASS + * -# \ref AUDFeatureUnitDescriptor_MID + * -# \ref AUDFeatureUnitDescriptor_TREBLE + */ +/** Channel mute control. */ +#define AUDFeatureUnitDescriptor_MUTE (1 << 0) +/** Channel volume control. */ +#define AUDFeatureUnitDescriptor_VOLUME (1 << 1) +/** Channel bass control. */ +#define AUDFeatureUnitDescriptor_BASS (1 << 2) +/** Channel middle control. */ +#define AUDFeatureUnitDescriptor_MID (1 << 3) +/** Channel treble control. */ +#define AUDFeatureUnitDescriptor_TREBLE (1 << 4) +/** @}*/ + + +/** Format type for a format type I descriptor. */ +#define AUDFormatTypeOneDescriptor_FORMATTYPEONE 0x01 + +/** AUDFormatTypeOneDescriptor_PCM - PCM format. */ +#define AUDFormatTypeOneDescriptor_PCM 0x0001 + +/** Indicates the sampling frequency can have any value in the provided range. */ +#define AUDFormatTypeOneDescriptor_CONTINUOUS 0 + + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef AUDStreamingInterfaceDescriptor + * \brief Provides additional information about an audio streaming interface to + * the USB host. + */ +typedef struct _AUDStreamingInterfaceDescriptor { + + /** Size of descriptor in bytes.*/ + uint8_t bLength; + /** Descriptor type (AUDGenericDescriptor_INTERFACE).*/ + uint8_t bDescriptorType; + /** Descriptor subtype (AUDStreamingInterfaceDescriptor_GENERAL).*/ + uint8_t bDescriptorSubType; + /** Terminal ID to which the interface is connected.*/ + uint8_t bTerminalLink; + /** Delay introduced by the data path, in number of frames.*/ + uint8_t bDelay; + /** Audio data format used by this interface.*/ + uint16_t wFormatTag; + +} __attribute__ ((packed)) AUDStreamingInterfaceDescriptor; /* GCC */ + +/** + * \typedef AUDEndpointDescriptor + * \brief Modified endpoint descriptor with two additional fields, with are + * USB audio specific. + */ +typedef struct _AUDEndpointDescriptor { + + /** Size of the descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (USBGenericDescriptor_ENDPOINT). */ + uint8_t bDescriptorType; + /** Address and direction of the endpoint. */ + uint8_t bEndpointAddress; + /** Endpoint type and additional characteristics (for isochronous endpoints). */ + uint8_t bmAttributes; + /** Maximum packet size (in bytes) of the endpoint. */ + uint16_t wMaxPacketSize; + /** Polling rate of the endpoint. */ + uint8_t bInterval; + /** Refresh rate for a feedback endpoint. */ + uint8_t bRefresh; + /** Address of the associated feedback endpoint if any. */ + uint8_t bSyncAddress; + +} __attribute__ ((packed)) AUDEndpointDescriptor; /* GCC */ + +/** + * \typedef AUDDataEndpointDescriptor + * \brief Gives additional information about an USB endpoint used to transmit audio + * data to or from the host. + */ +typedef struct _AUDDataEndpointDescriptor { + + /** Size of descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type + (\ref AUDGenericDescriptor_ENDPOINT). */ + uint8_t bDescriptorType; + /** Descriptor subtype + (\ref AUDDataEndpointDescriptor_SUBTYPE). */ + uint8_t bDescriptorSubType; + /** Indicates available controls and requirement on packet sizes. */ + uint8_t bmAttributes; + /** Indicates the units of the wLockDelay fields. + \sa usb_audio_lock_delay USB Audio Lock delay units */ + uint8_t bLockDelayUnits; + /** Time it takes for the endpoint to lock its internal clock circuitry. */ + uint16_t wLockDelay; + +} __attribute__ ((packed)) AUDDataEndpointDescriptor; /* GCC */ + +/** + * \typedef AUDHeaderDescriptor + * \brief Groups the various audio interfaces to display one single function to + * the USB host. Subclass this structure to add a particular number of + * slave interface descriptors. + */ +typedef struct _AUDHeaderDescriptor { + + /** Size of descriptor in bytes.*/ + uint8_t bLength; + /** Descriptor type (\ref AUDGenericDescriptor_INTERFACE).*/ + uint8_t bDescriptorType; + /** Descriptor subtype (\ref AUDGenericDescriptor_HEADER).*/ + uint8_t bDescriptorSubType; + /** Audio class release number in BCD format + * \sa usb_audio_class_ver USB Audio class releases */ + uint16_t bcdADC; + /** Length of all descriptors used to qualify the Audio Control interface.*/ + uint16_t wTotalLength; + /** Number of Streaming interfaces contained in this collection.*/ + uint8_t bInCollection; + +} __attribute__ ((packed)) AUDHeaderDescriptor; /* GCC */ + +/** + * \typedef AUDInputTerminalDescriptor + * \brief Describes an input of a USB audio device. + */ +typedef struct _AUDInputTerminalDescriptor { + + /** Size of descriptor in bytes.*/ + uint8_t bLength; + /** Descriptor type (AUDGenericDescriptor_INTERFACE).*/ + uint8_t bDescriptorType; + /** Descriptor subtype (AUDGenericDescriptor_INPUTTERMINAL).*/ + uint8_t bDescriptorSubType; + /** ID of the terminal in the audio function.*/ + uint8_t bTerminalID; + /** Terminal type. + * \sa usb_audio_in_term USB Audio Input terminal types + */ + uint16_t wTerminalType; + /** ID of the output terminal to which this input terminal is associated.*/ + uint8_t bAssocTerminal; + /** Number of logical output channels in this terminal.*/ + uint8_t bNrChannels; + /** Spatial configuration of the logical channels.*/ + uint16_t wChannelConfig; + /** Index of a string descriptor for the first logical channel.*/ + uint8_t iChannelNames; + /** Index of a string descriptor for this terminal. */ + uint8_t iTerminal; + +} __attribute__ ((packed)) AUDInputTerminalDescriptor; /* GCC */ + +/** + * \typedef AUDOutputTerminalDescriptor + * \brief Describes an output of the USB audio function. + */ +typedef struct _AUDOutputTerminalDescriptor { + + /** Size of descriptor in bytes.*/ + uint8_t bLength; + /** Descriptor type (\ref AUDGenericDescriptor_INTERFACE).*/ + uint8_t bDescriptorType; + /** Descriptor subtype (\ref AUDGenericDescriptor_OUTPUTTERMINAL). */ + uint8_t bDescriptorSubType; + /** Identifier for this terminal.*/ + uint8_t bTerminalID; + /** Terminal type. + * \sa "USB Audio Output terminal types" */ + uint16_t wTerminalType; + /** Identifier of the associated input terminal.*/ + uint8_t bAssocTerminal; + /** Identifier of the unit or terminal to which this terminal + * is connected.*/ + uint8_t bSourceID; + /** Index of a string descriptor for this terminal.*/ + uint8_t iTerminal; + +} __attribute__ ((packed)) AUDOutputTerminalDescriptor; /* GCC */ + +/** + * \typedef AUDFeatureUnitDescriptor + * \brief Describes available controls for each channel of the unit or terminal + * it is connected to. + * + * This type must be augmented with the relevant number + * of bmaControls fields and the iFeature field. + **/ +typedef struct _AUDFeatureUnitDescriptor { + + /** Size of descriptor in bytes.*/ + uint8_t bLength; + /** Descriptor type (AUDGenericDescriptor_INTERFACE). */ + uint8_t bDescriptorType; + /** Descriptor subtype (AUDGenericDescriptor_FEATURE). */ + uint8_t bDescriptorSubType; + /** Identifier of this feature unit. */ + uint8_t bUnitID; + /** Identifier of the unit or terminal this feature unit is connected to. */ + uint8_t bSourceID; + /** Size in bytes of a channel controls field. */ + uint8_t bControlSize; + +} __attribute__ ((packed)) AUDFeatureUnitDescriptor; /* GCC */ + +/** + * \typedef AUDFormatTypeOneDescriptor + * \brief Describes an audio data stream that is constructed on a sample-by-sample + * basis. + * + * This type must be augmented with either the continuous sampling frequency range + * (if bSamFreqType = <\ref AUDFormatTypeOneDescriptor_CONTINUOUS>) + * or with an array containing the possible discrete frequencies. + */ +typedef struct _AUDFormatTypeOneDescriptor { + + /** Size of descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (\ref AUDGenericDescriptor_INTERFACE). */ + uint8_t bDescriptorType; + /** Descriptor subtype (\ref AUDStreamingInterfaceDescriptor_FORMATTYPE).*/ + uint8_t bDescriptorSubType; + /** Format type (\ref AUDFormatTypeOneDescriptor_FORMATTYPEONE).*/ + uint8_t bFormatType; + /** Number of physical channels in the audio stream.*/ + uint8_t bNrChannels; + /** Number of bytes occupied by one audio subframe.*/ + uint8_t bSubFrameSize; + /** Number of bits effectively used in an audio subframe.*/ + uint8_t bBitResolution; + /** Number of supported discrete sampling frequencies, or + * \ref AUDFormatTypeOneDescriptor_CONTINUOUS.*/ + uint8_t bSamFreqType; + +} __attribute__ ((packed)) AUDFormatTypeOneDescriptor; /* GCC */ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + + + +/**@}*/ +#endif /* _AUDDESCRIPTORS_H_ */ diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/AUDRequests.h b/sam3s_example/atmel_softpack_libraries/usb/include/AUDRequests.h new file mode 100644 index 00000000..93d16621 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/AUDRequests.h @@ -0,0 +1,123 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * Definitions and classes for USB Audio class requests. + * + * - For a USB %device: + * -# After receiving an Audio request from the host, use + * AUDGenericRequest_GetEntity to determine the target Unit or Terminal. + * -# After receiving an Audio request from the host, use + * AUDGenericRequest_GetInterface to know which interface is referenced. + * -# Use AUDFeatureUnitRequest_GetControl to determine which control + * shall be tweaked following a host request. + * -# Use AUDFeatureUnitRequest_GetChannel to identify the channel which + * will have its control altered. + */ + +#ifndef _AUDREQUESTS_H_ +#define _AUDREQUESTS_H_ +/** \addtogroup usb_audio + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_audio_request USB Audio request codes + * @{ + * This section lists the codes of the existing Audio requests. + * - \ref AUDGenericRequest_SETCUR + * - \ref AUDGenericRequest_GETCUR + */ +/** SET_CUR request code.*/ +#define AUDGenericRequest_SETCUR 0x01 +/** GET_CUR request code.*/ +#define AUDGenericRequest_GETCUR 0x81 +/** GET_MIN request code.*/ +#define AUDGenericRequest_GETMIN 0x82 +/** GET_MAX request code.*/ +#define AUDGenericRequest_GETMAX 0x83 +/** GET_RES request code.*/ +#define AUDGenericRequest_GETRES 0x84 +/** @}*/ + +/** \addtogroup usb_audio_ctrl_sel USB Audio Control selector values + * @{ + * This section lists the available control selectors for a Feature Unit request. + * - \ref AUDFeatureUnitRequest_MUTE + */ +/** Mute control selector (MUTE_CONTROL). */ +#define AUDFeatureUnitRequest_MUTE 0x01 +/** Volume control selector (VOLUME_CONTROL). */ +#define AUDFeatureUnitRequest_VOLUME 0x02 +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + + + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + +extern uint8_t AUDGenericRequest_GetEntity( + const USBGenericRequest *request); + +extern uint8_t AUDGenericRequest_GetInterface( + const USBGenericRequest *request); + + +extern uint8_t AUDFeatureUnitRequest_GetControl( + const USBGenericRequest *request); + +extern uint8_t AUDFeatureUnitRequest_GetChannel( + const USBGenericRequest *request); + +/**@}*/ +#endif /* _AUDREQUESTS_H_ */ diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCAUDDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCAUDDDriver.h new file mode 100644 index 00000000..50ee688d --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCAUDDDriver.h @@ -0,0 +1,307 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definitions and methods for USB composite device implement. + * + */ + +#ifndef CDCAUDDDRIVER_H +#define CDCAUDDDRIVER_H +/** \addtogroup usbd_cdc_aud + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +/** \addtogroup usbd_cdc_aud_desc USB CDC(Serial) + AUD(Speaker) Definitions + * @{ + */ +/** Number of interfaces of the device (5, can be 4 if no mic support */ +#define CDCAUDDDriverDescriptors_MaxNumInterfaces 5 +/** Number of the CDC interface. */ +#define CDCAUDDDriverDescriptors_CDC_INTERFACE 0 +/** Number of the Audio interface. */ +#define CDCAUDDDriverDescriptors_AUD_INTERFACE 2 +/** Number of Audio function channels (M,L,R) */ +#define AUDD_NumChannels 3 +/** @}*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** Audio header descriptor with 1 interface */ +typedef struct _AUDHeaderDescriptor1{ + + /** Header descriptor.*/ + AUDHeaderDescriptor header; + /** Id of the first grouped interface.*/ + uint8_t bInterface0; + +} __attribute__ ((packed)) AUDHeaderDescriptor1; + +/** Audio header descriptor with 2 interface */ +typedef struct _AUDHeaderDescriptor2 { + + /** Header descriptor. */ + AUDHeaderDescriptor header; + /** Id of the first grouped interface - Speaker. */ + uint8_t bInterface0; + /** Id of the second grouped interface - Speakerphone. */ + uint8_t bInterface1; + +} __attribute__ ((packed)) AUDHeaderDescriptor2; /* GCC */ + +/** + * Feature unit descriptor with 3 channel controls (master, right, left). + */ +typedef struct _AUDFeatureUnitDescriptor3{ + + /** Feature unit descriptor.*/ + AUDFeatureUnitDescriptor feature; + /** Available controls for each channel.*/ + uint8_t bmaControls[AUDD_NumChannels]; + /** Index of a string descriptor for the feature unit.*/ + uint8_t iFeature; + +} __attribute__ ((packed)) AUDFeatureUnitDescriptor3; + +/** + * List of descriptors for detailling the audio control interface of a + * device using a USB audio speaker function. + */ +typedef struct _AUDDSpeakerAcDescriptors{ + + /** 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)) AUDDSpeakerAcDescriptors; + +/** + * List of descriptors for detailling the audio control interface of a + * device using a USB Audio Speakerphoneer function. + */ +typedef struct _AUDDSpeakerPhoneAcDescriptors { + + /** Header descriptor (with one slave interface). */ + AUDHeaderDescriptor2 header; + /** Input terminal descriptor. */ + AUDInputTerminalDescriptor inputSpeakerPhone; + /** Output terminal descriptor. */ + AUDOutputTerminalDescriptor outputSpeakerPhone; + /** Feature unit descriptor - SpeakerPhone. */ + AUDFeatureUnitDescriptor3 featureSpeakerPhone; + /** Input terminal descriptor. */ + AUDInputTerminalDescriptor inputRec; + /** Output terminal descriptor. */ + AUDOutputTerminalDescriptor outputRec; + /** Feature unit descriptor - SpeakerPhonephone. */ + AUDFeatureUnitDescriptor3 featureRec; + +} __attribute__ ((packed)) AUDDSpeakerPhoneAcDescriptors; + +/** + * Format type I descriptor with one discrete sampling frequency. + */ +typedef struct _AUDFormatTypeOneDescriptor1{ + + /** Format type I descriptor.*/ + AUDFormatTypeOneDescriptor formatType; + /** Sampling frequency in Hz.*/ + uint8_t tSamFreq[3]; + +} __attribute__ ((packed)) AUDFormatTypeOneDescriptor1; + +/** + * Configuration descriptor list for a device implementing + * CDC(Serial) + Audio(Speaker) composite driver. + */ +typedef struct _CdcAudspkdDriverConfigurationDescriptors { + + /** 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; + + /* --- AUDIO (AC) */ + /** IAD 1*/ + USBInterfaceAssociationDescriptor audIAD; + /** Audio control interface.*/ + USBInterfaceDescriptor audInterface; + /** Descriptors for the audio control interface.*/ + AUDDSpeakerAcDescriptors audControl; + /* -- AUDIO out (AS) */ + /** 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; + +} __attribute__ ((packed)) CdcAudspkdDriverConfigurationDescriptors; + +/** + * Configuration descriptor list for a device implementing + * CDC(Serial) + Audio(SpeakerPhone) composite driver. + */ +typedef struct _CdcAuddDriverConfigurationDescriptors { + + /** 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; + + /* --- AUDIO (AC) */ + /** IAD 1*/ + USBInterfaceAssociationDescriptor audIAD; + /** Audio control interface.*/ + USBInterfaceDescriptor audInterface; + /** Descriptors for the audio control interface.*/ + AUDDSpeakerPhoneAcDescriptors audControl; + /* -- AUDIO out (AS) */ + /** 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; + /*- AUDIO IN */ + /** Streaming in interface descriptor (with no endpoint, required). */ + USBInterfaceDescriptor streamingInNoIsochronous; + /** Streaming in interface descriptor. */ + USBInterfaceDescriptor streamingIn; + /** Audio class descriptor for the streaming in interface. */ + AUDStreamingInterfaceDescriptor streamingInClass; + /** Stream format descriptor. */ + AUDFormatTypeOneDescriptor1 streamingInFormatType; + /** Streaming in endpoint descriptor. */ + AUDEndpointDescriptor streamingInEndpoint; + /** Audio class descriptor for the streaming in endpoint. */ + AUDDataEndpointDescriptor streamingInDataEndpoint; + +} __attribute__ ((packed)) CdcAuddDriverConfigurationDescriptors; + + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +extern void CDCAUDDDriver_Initialize(const USBDDriverDescriptors * pDescriptors); +extern void CDCAUDDDriver_ConfigurationChangedHandler(uint8_t cfgnum); +extern void CDCAUDDDriver_InterfaceSettingChangedHandler( + uint8_t interface, uint8_t setting); +extern void CDCAUDDDriver_RequestHandler(const USBGenericRequest *request); + +/**@}*/ +#endif //#ifndef CDCHIDDDRIVER_H + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerial.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerial.h new file mode 100644 index 00000000..4d1656c0 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerial.h @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * Single CDC Serial Port Function for USB device & composite driver. + */ + +#ifndef CDCDSERIAL_H +#define CDCDSERIAL_H + +/** \addtogroup usbd_cdc + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 + by working group ISO/IEC JTC1/SC22/WG14. */ +#include + +#include + +#include +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern void CDCDSerial_Initialize( + USBDDriver * pUsbd, uint8_t bInterfaceNb); + +extern uint32_t CDCDSerial_RequestHandler( + const USBGenericRequest *request); + +extern void CDCDSerial_ConfigureFunction( + USBGenericDescriptor * pDescriptors, uint16_t wLength); + +extern uint32_t CDCDSerial_Write( + void *data, + uint32_t size, + TransferCallback callback, + void *argument); + +extern uint32_t CDCDSerial_Read( + void *data, + uint32_t size, + TransferCallback callback, + void *argument); + +extern void CDCDSerial_GetLineCoding(CDCLineCoding * pLineCoding); + +extern uint8_t CDCDSerial_GetControlLineState(void); + +extern uint16_t CDCDSerial_GetSerialState(void); + +extern void CDCDSerial_SetSerialState(uint16_t serialState); + +extern uint8_t CDCDSerial_LineCodingIsToChange( + CDCLineCoding * pLineCoding); + +extern void CDCDSerial_ControlLineStateChanged( + uint8_t DTR,uint8_t RTS); + +/**@}*/ + +#endif /*#ifndef CDCSERIAL_H*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerialDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerialDriver.h new file mode 100644 index 00000000..41e0fda3 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerialDriver.h @@ -0,0 +1,245 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definition of a class for implementing a USB device CDC serial driver. + * + * \section Usage + * + * -# Re-implement the USBDCallbacks_RequestReceived method to pass + * received requests to CDCDSerialDriver_RequestHandler. *This is + * automatically done unless the NOAUTOCALLBACK symbol is defined*. + * -# Initialize the CDC serial and USB drivers using + * CDCDSerialDriver_Initialize. + * -# Logically connect the device to the host using USBD_Connect. + * -# Send serial data to the USB host using CDCDSerialDriver_Write. + * -# Receive serial data from the USB host using CDCDSerialDriver_Read. + */ + +#ifndef CDCDSERIALDRIVER_H +#define CDCDSERIALDRIVER_H + +/** \addtogroup usbd_cdc + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 + by working group ISO/IEC JTC1/SC22/WG14. */ +#include + +#include +#include +#include +#include + +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_cdc_if USB Device CDC Serial Interface IDs + * @{ + */ +/** Communication Class Interface ID */ +#define CDCDSerialDriver_CC_INTERFACE 0 +/** Data Class Interface ID */ +#define CDCDSerialDriver_DC_INTERFACE 1 +/** @}*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** + * \typedef CDCDSerialDriverConfigurationDescriptors + * \brief Configuration descriptor list for a device implementing a + * CDC serial driver. + */ +typedef struct _CDCDSerialDriverConfigurationDescriptors { + + /** Standard configuration descriptor. */ + USBConfigurationDescriptor configuration; + /** Communication interface descriptor. */ + USBInterfaceDescriptor communication; + /** CDC header functional descriptor. */ + CDCHeaderDescriptor header; + /** CDC call management functional descriptor. */ + CDCCallManagementDescriptor callManagement; + /** CDC abstract control management functional descriptor. */ + CDCAbstractControlManagementDescriptor abstractControlManagement; + /** CDC union functional descriptor (with one slave interface). */ + CDCUnionDescriptor union1; + /** Notification endpoint descriptor. */ + USBEndpointDescriptor notification; + /** Data interface descriptor. */ + USBInterfaceDescriptor data; + /** Data OUT endpoint descriptor. */ + USBEndpointDescriptor dataOut; + /** Data IN endpoint descriptor. */ + USBEndpointDescriptor dataIn; + +} __attribute__ ((packed)) CDCDSerialDriverConfigurationDescriptors; + +/** + * \typedef CDCDSerialDriverConfigurationDescriptorsOTG + * \brief Configuration descriptor list for a device implementing a + * CDC serial OTG driver. + */ +typedef struct _CDCDSerialDriverConfigurationDescriptorsOTG { + + /** Standard configuration descriptor. */ + USBConfigurationDescriptor configuration; + /* OTG descriptor */ + USBOtgDescriptor otgDescriptor; + /** Communication interface descriptor. */ + USBInterfaceDescriptor communication; + /** CDC header functional descriptor. */ + CDCHeaderDescriptor header; + /** CDC call management functional descriptor. */ + CDCCallManagementDescriptor callManagement; + /** CDC abstract control management functional descriptor. */ + CDCAbstractControlManagementDescriptor abstractControlManagement; + /** CDC union functional descriptor (with one slave interface). */ + CDCUnionDescriptor union1; + /** Notification endpoint descriptor. */ + USBEndpointDescriptor notification; + /** Data interface descriptor. */ + USBInterfaceDescriptor data; + /** Data OUT endpoint descriptor. */ + USBEndpointDescriptor dataOut; + /** Data IN endpoint descriptor. */ + USBEndpointDescriptor dataIn; + +} __attribute__ ((packed)) CDCDSerialDriverConfigurationDescriptorsOTG; + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern void CDCDSerialDriver_Initialize( + const USBDDriverDescriptors *pDescriptors); + +extern void CDCDSerialDriver_ConfigurationChangedHandler(uint8_t cfgnum); + +extern void CDCDSerialDriver_RequestHandler( + const USBGenericRequest *request); + +extern uint8_t CDCDSerialDriver_LineCodingIsToChange( + CDCLineCoding * pLineCoding); + +extern void CDCDSerialDriver_ControlLineStateChanged( + uint8_t DTR,uint8_t RTS); + +/** + * Sends a data buffer through the virtual COM port created by the CDC + * device serial driver. This function behaves exactly like USBD_Write. + * \param data Pointer to the data buffer to send. + * \param size Size of the data buffer in bytes. + * \param callback Optional callback function to invoke when the transfer + * finishes. + * \param argument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +static inline uint32_t CDCDSerialDriver_Write( + void *data, + uint32_t size, + TransferCallback callback, + void *argument) +{ + return CDCDSerial_Write(data, size, callback, argument); +} + +/** + * Receives data from the host through the virtual COM port created by + * the CDC device serial driver. This function behaves like USBD_Read. + * \param data Pointer to the data buffer to put received data. + * \param size Size of the data buffer in bytes. + * \param callback Optional callback function to invoke when the transfer + * finishes. + * \param argument Optional argument to the callback function. + * \return USBD_STATUS_SUCCESS if the read operation has been started normally; + * otherwise, the corresponding error code. + */ +static inline uint32_t CDCDSerialDriver_Read( + void *data, + uint32_t size, + TransferCallback callback, + void *argument) +{ + return CDCDSerial_Read(data, size, callback, argument); +} + +/** + * Copy current line coding settings to pointered space. + * \param pLineCoding Pointer to CDCLineCoding instance. + */ +static inline void CDCDSerialDriver_GetLineCoding(CDCLineCoding * pLineCoding) +{ + CDCDSerial_GetLineCoding(pLineCoding); +} + +/** + * Returns the current control line state of the RS-232 line. + */ +static inline uint8_t CDCDSerialDriver_GetControlLineState(void) +{ + return CDCDSerial_GetControlLineState(); +} + +/** + * Returns the current status of the RS-232 line. + */ +static inline uint16_t CDCDSerialDriver_GetSerialState(void) +{ + return CDCDSerial_GetSerialState(); +} + +/** + * Sets the current serial state of the device to the given value. + * \param serialState New device state. + */ +static inline void CDCDSerialDriver_SetSerialState(uint16_t serialState) +{ + CDCDSerial_SetSerialState(serialState); +} + +/**@}*/ + +#endif /*#ifndef CDCSERIALDRIVER_H*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerialPort.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerialPort.h new file mode 100644 index 00000000..6a6f2ea1 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDSerialPort.h @@ -0,0 +1,167 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Definition of a class for implementing a USB device + * CDC serial port function. + */ + +#ifndef _CDCDSERIALPORT_H_ +#define _CDCDSERIALPORT_H_ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 + by working group ISO/IEC JTC1/SC22/WG14. */ +#include + +#include +#include +#include +#include +#include +/** \addtogroup usbd_cdc + *@{ + */ + +/*------------------------------------------------------------------------------ + * Defines + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_cdc_serial_desc USB Device Serial Port Descriptor Values + * @{ + */ +/** Default CDC interrupt endpoints max packat size (8). */ +#define CDCDSerialPort_INTERRUPT_MAXPACKETSIZE 8 +/** Default CDC interrupt endpoint polling rate of High Speed (16ms). */ +#define CDCDSerialPort_INTERRUPT_INTERVAL_HS 8 +/** Default CDC interrupt endpoint polling rate of Full Speed (16ms). */ +#define CDCDSerialPort_INTERRUPT_INTERVAL_FS 16 +/** Default CDC bulk endpoints max packat size (512, for HS actually). */ +#define CDCDSerialPort_BULK_MAXPACKETSIZE_HS 512 +/** Default CDC bulk endpoints max packat size (64, for FS actually). */ +#define CDCDSerialPort_BULK_MAXPACKETSIZE_FS 64 +/** @}*/ + +/** \addtogroup usbd_cdc_serial_events USB Device Serial Port Events + * @{ + */ +/** SetControlLineState event, value is changed */ +#define CDCDSerialPortEvent_SETCONTROLLINESTATE 0 +/** SetLineCoding event, value is to changed according to return value */ +#define CDCDSerialPortEvent_SETLINECODING 1 +/** @}*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** Callback function for serial port events */ +typedef uint32_t (*CDCDSerialPortEventHandler)(uint32_t dwEvent, + uint32_t dwParam, + void * pArguments); + +/** + * Struct for USB CDC virtual COM serial port function. + */ +typedef struct _CDCDSerialPort { + /** USB Driver for the %device */ + USBDDriver *pUsbd; + /** Callback for serial port events */ + CDCDSerialPortEventHandler fEventHandler; + /** Callback arguments */ + void *pArg; + /** USB starting interface index */ + uint8_t bInterfaceNdx; + /** USB number of interfaces */ + uint8_t bNumInterface; + /** USB interrupt IN endpoint address */ + uint8_t bIntInPIPE; + /** USB bulk IN endpoint address */ + uint8_t bBulkInPIPE; + /** USB bulk OUT endpoint address */ + uint8_t bBulkOutPIPE; + + /** Serial port ControlLineState */ + uint8_t bControlLineState; + /** Serial port SerialState */ + uint16_t wSerialState; + /** Serial port linecoding */ + CDCLineCoding lineCoding; + + uint8_t bReserved; +} CDCDSerialPort; + +/*------------------------------------------------------------------------------ + * Functions + *------------------------------------------------------------------------------*/ + +extern void CDCDSerialPort_Initialize(CDCDSerialPort *pCdcd, + USBDDriver *pUsbd, + CDCDSerialPortEventHandler fCallback, + void *pArg, + uint8_t firstInterface, + uint8_t numInterface); + +extern USBGenericDescriptor * CDCDSerialPort_ParseInterfaces( + CDCDSerialPort * pCdcd, + USBGenericDescriptor * pDescriptors, uint32_t dwLength); + +extern uint32_t CDCDSerialPort_RequestHandler( + CDCDSerialPort *pCdcd, + const USBGenericRequest *pRequest); + +extern uint32_t CDCDSerialPort_Write( + const CDCDSerialPort *pCdcd, + void *pData, uint32_t dwSize, + TransferCallback fCallback, void* pArg); + +extern uint32_t CDCDSerialPort_Read( + const CDCDSerialPort *pCdcd, + void *pData, uint32_t dwSize, + TransferCallback fCallback, void* pArg); + +extern uint16_t CDCDSerialPort_GetSerialState( + const CDCDSerialPort *pCdcd); + +extern void CDCDSerialPort_SetSerialState( + CDCDSerialPort *pCdcd, + uint16_t wSerialState); + +extern uint8_t CDCDSerialPort_GetControlLineState( + const CDCDSerialPort * pCdcd); + +extern void CDCDSerialPort_GetLineCoding( + const CDCDSerialPort * pCdcd, + CDCLineCoding * pLineCoding); + +/**@}*/ +#endif /* #ifndef _CDCDSERIALPORT_H_ */ diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCDescriptors.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDescriptors.h new file mode 100644 index 00000000..b4719b8a --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCDescriptors.h @@ -0,0 +1,275 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * Definitions and classes for USB CDC class descriptors. + */ + +#ifndef _CDCDESCRIPTORS_H_ +#define _CDCDESCRIPTORS_H_ +/** \addtogroup usb_cdc + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_cdc_ver USB CDC Specification Release Numbers + * @{ + * This section list the CDC Spec. Release Numbers. + * - \ref CDCGenericDescriptor_CDC1_10 + */ + +/** Identify CDC specification version 1.10. */ +#define CDCGenericDescriptor_CDC1_10 0x0110 +/** @}*/ + +/** \addtogroup usb_cdc_desc_type CDC Descriptro Types + * @{ + * This section lists CDC descriptor types. + * - \ref CDCGenericDescriptor_INTERFACE + * - \ref CDCGenericDescriptor_ENDPOINT + */ +/**Indicates that a CDC descriptor applies to an interface. */ +#define CDCGenericDescriptor_INTERFACE 0x24 +/** Indicates that a CDC descriptor applies to an endpoint. */ +#define CDCGenericDescriptor_ENDPOINT 0x25 +/** @}*/ + +/** \addtogroup usb_cdc_desc_subtype CDC Descriptor Subtypes + * @{ + * This section lists CDC descriptor sub types + * - \ref CDCGenericDescriptor_HEADER + * - \ref CDCGenericDescriptor_CALLMANAGEMENT + * - \ref CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT + * - \ref CDCGenericDescriptor_UNION + */ + +/** Header functional descriptor subtype. */ +#define CDCGenericDescriptor_HEADER 0x00 +/** Call management functional descriptor subtype. */ +#define CDCGenericDescriptor_CALLMANAGEMENT 0x01 +/** Abstract control management descriptor subtype. */ +#define CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT 0x02 +/** Union descriptor subtype. */ +#define CDCGenericDescriptor_UNION 0x06 +/** @}*/ + +/** \addtogroup usb_cdc_descriptor USB CDC Device Descriptor Values + * @{ + * This section lists the values for CDC Device Descriptor. + * - \ref CDCDeviceDescriptor_CLASS + * - \ref CDCDeviceDescriptor_SUBCLASS + * - \ref CDCDeviceDescriptor_PROTOCOL + */ +/** Device class code when using the CDC class. */ +#define CDCDeviceDescriptor_CLASS 0x02 +/** Device subclass code when using the CDC class. */ +#define CDCDeviceDescriptor_SUBCLASS 0x00 +/** Device protocol code when using the CDC class. */ +#define CDCDeviceDescriptor_PROTOCOL 0x00 +/** @}*/ + +/** \addtogroup usb_cdc_if_desc USB CDC Communication Interface Descriptor + * @{ + * This section lists the values for CDC Communication Interface Descriptor. + * - \ref CDCCommunicationInterfaceDescriptor_CLASS + * - \ref CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL + * - \ref CDCCommunicationInterfaceDescriptor_NOPROTOCOL + */ +/** Interface class code for a CDC communication class interface. */ +#define CDCCommunicationInterfaceDescriptor_CLASS 0x02 +/** Interface subclass code for an Abstract Control Model interface descriptor. + */ +#define CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL 0x02 +/** Interface protocol code when a CDC communication interface does not + implemenent any particular protocol. */ +#define CDCCommunicationInterfaceDescriptor_NOPROTOCOL 0x00 +/** @}*/ + +/** \addtogroup usb_cdc_data_if USB CDC Data Interface Values + * @{ + * This section lists the values for CDC Data Interface Descriptor. + * - \ref CDCDataInterfaceDescriptor_CLASS + * - \ref CDCDataInterfaceDescriptor_SUBCLASS + * - \ref CDCDataInterfaceDescriptor_NOPROTOCOL + */ + +/** Interface class code for a data class interface. */ +#define CDCDataInterfaceDescriptor_CLASS 0x0A +/** Interface subclass code for a data class interface. */ +#define CDCDataInterfaceDescriptor_SUBCLASS 0x00 +/** Protocol code for a data class interface which does not implement any + particular protocol. */ +#define CDCDataInterfaceDescriptor_NOPROTOCOL 0x00 +/** @}*/ + +/** \addtogroup usb_cdc_cb_man_desc USB CDC CallManagement Capabilities + * @{ + * This section lists CDC CallManagement Capabilities. + * - \ref CDCCallManagementDescriptor_SELFCALLMANAGEMENT + * - \ref CDCCallManagementDescriptor_DATACALLMANAGEMENT + */ +/** Device handles call management itself. */ +#define CDCCallManagementDescriptor_SELFCALLMANAGEMENT (1 << 0) +/** Device can exchange call management information over a Data class interface. + */ +#define CDCCallManagementDescriptor_DATACALLMANAGEMENT (1 << 1) +/** @}*/ + +/** \addtogroup usb_cdc_acm USB CDC ACM Capabilities + * @{ + * + * This section lists the capabilities of the CDC ACM. + * - \ref CDCAbstractControlManagementDescriptor_COMMFEATURE + * - \ref CDCAbstractControlManagementDescriptor_LINE + * - \ref CDCAbstractControlManagementDescriptor_SENDBREAK + * - \ref CDCAbstractControlManagementDescriptor_NETWORKCONNECTION + */ + +/** Device supports the request combination of SetCommFeature, ClearCommFeature + and GetCommFeature. */ +#define CDCAbstractControlManagementDescriptor_COMMFEATURE (1 << 0) +/** Device supports the request combination of SetLineCoding, GetLineCoding and + SetControlLineState. */ +#define CDCAbstractControlManagementDescriptor_LINE (1 << 1) +/** Device supports the SendBreak request. */ +#define CDCAbstractControlManagementDescriptor_SENDBREAK (1 << 2) +/** Device supports the NetworkConnection notification. */ +#define CDCAbstractControlManagementDescriptor_NETWORKCONNECTION (1 << 3) +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef CDCHeaderDescriptor + * \brief Marks the beginning of the concatenated set of functional descriptors + * for the interface. + */ +typedef struct _CDCHeaderDescriptor { + + /** Size of this descriptor in bytes. */ + uint8_t bFunctionLength; + /** Descriptor type . */ + uint8_t bDescriptorType; + /** Descriptor sub-type . */ + uint8_t bDescriptorSubtype; + /** USB CDC specification release number. */ + uint16_t bcdCDC; + +} __attribute__ ((packed)) CDCHeaderDescriptor; /* GCC */ + +/** + * \typedef CDCUnionDescriptor + * \brief Describes the relationship between a group of interfaces that can + * be considered to form a functional unit. + */ +typedef struct _CDCUnionDescriptor { + + /** Size of the descriptor in bytes. */ + uint8_t bFunctionLength; + /** Descriptor type . */ + uint8_t bDescriptorType; + /** Descriptor subtype . */ + uint8_t bDescriptorSubtype; + /** Number of the master interface for this union. */ + uint8_t bMasterInterface; + /** Number of the first slave interface for this union. */ + uint8_t bSlaveInterface0; + +} __attribute__ ((packed)) CDCUnionDescriptor; /* GCC */ + +/** + * \typedef CDCCallManagementDescriptor + * \brief Describes the processing of calls for the communication class + * interface. + */ +typedef struct _CDCCallManagementDescriptor { + + /** Size of this descriptor in bytes. */ + uint8_t bFunctionLength; + /** Descriptor type . */ + uint8_t bDescriptorType; + /** Descriptor sub-type . */ + uint8_t bDescriptorSubtype; + /** Configuration capabilities + \sa usb_cdc_cb_man_desc CDC CallManagement Capabilities. */ + uint8_t bmCapabilities; + /** Interface number of the data class interface used for call management + (optional). */ + uint8_t bDataInterface; + +} __attribute__ ((packed)) CDCCallManagementDescriptor; /* GCC */ + +/** + * \typedef CDCAbstractControlManagementDescriptor + * \brief Describes the command supported by the communication interface class + * with the Abstract Control Model subclass code. + */ +typedef struct _CDCAbstractControlManagementDescriptor { + + /** Size of this descriptor in bytes. */ + uint8_t bFunctionLength; + /** Descriptor type . */ + uint8_t bDescriptorType; + /** Descriptor subtype . */ + uint8_t bDescriptorSubtype; + /** Configuration capabilities. + \sa usb_cdc_acm CDC ACM Capabilities. */ + uint8_t bmCapabilities; + +} __attribute__ ((packed)) CDCAbstractControlManagementDescriptor; /* GCC */ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + + +/**@}*/ +#endif /* #ifndef _CDCDESCRIPTORS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCHIDDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCHIDDDriver.h new file mode 100644 index 00000000..b0026111 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCHIDDDriver.h @@ -0,0 +1,152 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definitions and methods for USB composite device implement. + * + * \section 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 +/** \addtogroup usbd_cdc_hid + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +/** \addtogroup usbd_cdc_hid_desc USB CDC(Serial) + HID(Kbd) Descriptors define + * @{ + */ +/** Number of interfaces of the device */ +#define CDCHIDDDriverDescriptors_NUMINTERFACE 3 +/** Number of the CDC interface. */ +#define CDCHIDDDriverDescriptors_CDC_INTERFACE 0 +/** Number of the HID interface. */ +#define CDCHIDDDriverDescriptors_HID_INTERFACE 2 +/** @}*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef CdcHidDriverConfigurationDescriptors + * \brief Configuration descriptor list for a device implementing a + * composite driver. + */ +typedef struct _CdcHidDriverConfigurationDescriptors { + + /** 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; + HIDDescriptor1 hid; + USBEndpointDescriptor hidInterruptIn; + USBEndpointDescriptor hidInterruptOut; + +} __attribute__ ((packed)) CdcHidDriverConfigurationDescriptors; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/* -CDCHID */ +extern void CDCHIDDDriver_Initialize( + const USBDDriverDescriptors * pDescriptors); + +extern void CDCHIDDDriver_ConfigurationChangedHandler(uint8_t cfgnum); + +extern void CDCHIDDDriver_RequestHandler(const USBGenericRequest *request); + +extern void CDCHIDDDriver_RemoteWakeUp(void); + +/**@}*/ +#endif //#ifndef CDCHIDDDRIVER_H + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCMSDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCMSDDriver.h new file mode 100644 index 00000000..6f01f1ab --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCMSDDriver.h @@ -0,0 +1,155 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definitions and methods for USB CDCMSD device implement. + * + * \section 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 +/** \addtogroup usbd_composite_cdcmsd + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Consts + *---------------------------------------------------------------------------*/ + +/** \addtogroup usbd_cdc_msd_desc USB CDC(Serial) + MS Descriptors define + * @{ + */ +/** Number of interfaces of the device */ +#define CDCMSDDriverDescriptors_NUMINTERFACE 3 +/** Number of the CDC interface. */ +#define CDCMSDDriverDescriptors_CDC_INTERFACE 0 +/** Number of the HID interface. */ +#define CDCMSDDriverDescriptors_MSD_INTERFACE 2 +/** @}*/ + + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef CDCMSDDriverConfigurationDescriptors + * \brief Configuration descriptor list for a device implementing + * a CDCMSD driver. + */ +typedef struct _CDCMSDDriverConfigurationDescriptors { + + /** 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 functions + *---------------------------------------------------------------------------*/ + +/* -CDCMSD */ +extern void CDCMSDDriver_Initialize( + const USBDDriverDescriptors *pDescriptors, + MSDLun *pLuns, unsigned char numLuns); + +extern void CDCMSDDriver_ConfigurationChangedHandler(unsigned char cfgnum); + +extern void CDCMSDDriver_RequestHandler(const USBGenericRequest *request); + +/**@}*/ +#endif /* #ifndef CDCMSDDDRIVER_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCNotifications.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCNotifications.h new file mode 100644 index 00000000..c37631cb --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCNotifications.h @@ -0,0 +1,111 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Definitions and methods for USB CDC Notifications. + */ + +#ifndef _CDCNOTIFICATIONS_H_ +#define _CDCNOTIFICATIONS_H_ +/** \addtogroup usb_cdc + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup cdc_serial_states CDC SerialState bits + * @{ + * This page lists the bit map for CDC Serial States. + * + * - \ref CDCSerialState_RXDRIVER + * - \ref CDCSerialState_TXCARRIER + * - \ref CDCSerialState_BREAK + * - \ref CDCSerialState_RINGSIGNAL + * - \ref CDCSerialState_FRAMING + * - \ref CDCSerialState_PARITY + * - \ref CDCSerialState_OVERRUN + */ + +/** Indicates the receiver carrier signal is present */ +#define CDCSerialState_RXDRIVER (1 << 0) +/** Indicates the transmission carrier signal is present */ +#define CDCSerialState_TXCARRIER (1 << 1) +/** Indicates a break has been detected */ +#define CDCSerialState_BREAK (1 << 2) +/** Indicates a ring signal has been detected */ +#define CDCSerialState_RINGSIGNAL (1 << 3) +/** Indicates a framing error has occured */ +#define CDCSerialState_FRAMING (1 << 4) +/** Indicates a parity error has occured */ +#define CDCSerialState_PARITY (1 << 5) +/** Indicates a data overrun error has occured */ +#define CDCSerialState_OVERRUN (1 << 6) +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** USB CDC SerialState struct (bitmap) */ +typedef struct _CDCSerialState { + uint16_t bRxCarrier:1, /**< State of receive carrier detection (V2.4 signal + 109 and RS-232 signal DCD) */ + bTxCarrier:1, /**< State of transmission carrier */ + bBreak:1, /**< State of break detection */ + bRingSignal:1, /**< State of ring signal */ + bFraming:1, /**< Framing error */ + bParity:1, /**< Parity error */ + bOverRun:1, /**< Received data discarded due to overrun error */ + reserved:9; /**< Reserved */ +} __attribute__ ((packed)) CDCSerialState; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + +/**@}*/ +#endif /* #ifndef _CDCNOTIFICATIONS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/CDCRequests.h b/sam3s_example/atmel_softpack_libraries/usb/include/CDCRequests.h new file mode 100644 index 00000000..eb30b999 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/CDCRequests.h @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * Definitions and classes for USB CDC class requests + * (mostly for ACM). + * + * \section CDCLineCoding + * + * -# Initialize a CDCLineCoding instance using CDCLineCoding_Initialize. + * -# Send a CDCLineCoding object to the host in response to a GetLineCoding + * request. + * -# Receive a CDCLineCoding object from the host after a SetLineCoding + * request. + * + */ + +#ifndef _CDCREQUESTS_H_ +#define _CDCREQUESTS_H_ +/** \addtogroup usb_cdc + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_cdc_request USB CDC Request Codes + * @{ + * This section lists USB CDC Request Codes. + * - \ref CDCGenericRequest_SETLINECODING + * - \ref CDCGenericRequest_GETLINECODING + * - \ref CDCGenericRequest_SETCONTROLLINESTATE + */ + +/** SetLineCoding request code. */ +#define CDCGenericRequest_SETLINECODING 0x20 +/** GetLineCoding request code. */ +#define CDCGenericRequest_GETLINECODING 0x21 +/** SetControlLineState request code. */ +#define CDCGenericRequest_SETCONTROLLINESTATE 0x22 +/** @}*/ + +/** \addtogroup usb_cdc_ctrl_line_state USB CDC ControlLineState bitmap + * @{ + * This section lists CDC ControlLineState bitmap. + * - \ref CDCControlLineState_DTR, CDCControlLineState_DTE_PRESENT + * - \ref CDCControlLineState_RTS, CDCControlLineState_CARRIER_ON + */ +/** Indicates to DCE if DTE is present or not. */ +#define CDCControlLineState_DTE_PRESENT (1 << 0) +/** RS232 signal DTR: Data Terminal Ready. */ +#define CDCControlLineState_DTR (1 << 0) +/** Carrier control for half duplex modems. */ +#define CDCControlLineState_CARRIER_ON (1 << 1) +/** RS232 signal RTS: Request to send. */ +#define CDCControlLineState_RTS (1 << 1) +/** @}*/ + +/** \addtogroup usb_cdc_stop USB CDC LineCoding StopBits + * @{ + * This section lists Stop Bits for CDC Line Coding. + * - \ref CDCLineCoding_ONESTOPBIT + * - \ref CDCLineCoding_ONE5STOPBIT + * - \ref CDCLineCoding_TWOSTOPBITS + */ +/** The transmission protocol uses one stop bit. */ +#define CDCLineCoding_ONESTOPBIT 0 +/** The transmission protocol uses 1.5 stop bit. */ +#define CDCLineCoding_ONE5STOPBIT 1 +/** The transmissin protocol uses two stop bits. */ +#define CDCLineCoding_TWOSTOPBITS 2 +/** @}*/ + +/** \addtogroup usb_cdc_parity USB CDC LineCoding ParityCheckings + * @{ + * This section lists Parity checkings for CDC Line Coding. + * - \ref CDCLineCoding_NOPARITY + * - \ref CDCLineCoding_ODDPARITY + * - \ref CDCLineCoding_EVENPARITY + * - \ref CDCLineCoding_MARKPARITY + * - \ref CDCLineCoding_SPACEPARITY + */ +/** No parity checking. */ +#define CDCLineCoding_NOPARITY 0 +/** Odd parity checking. */ +#define CDCLineCoding_ODDPARITY 1 +/** Even parity checking. */ +#define CDCLineCoding_EVENPARITY 2 +/** Mark parity checking. */ +#define CDCLineCoding_MARKPARITY 3 +/** Space parity checking. */ +#define CDCLineCoding_SPACEPARITY 4 +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef CDCLineCoding + * \brief Format of the data returned when a GetLineCoding request is received. + */ +typedef struct _CDCLineCoding { + + /** Data terminal rate in bits per second. */ + uint32_t dwDTERate; + /** Number of stop bits. + \sa usb_cdc_stop CDC LineCoding StopBits. */ + uint8_t bCharFormat; + /** Type of parity checking used. + \sa usb_cdc_parity CDC LineCoding ParityCheckings. */ + uint8_t bParityType; + /** Number of data bits (5, 6, 7, 8 or 16). */ + uint8_t bDataBits; + +} __attribute__ ((packed)) CDCLineCoding; /* GCC */ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + +extern uint8_t CDCSetControlLineStateRequest_IsDtePresent( + const USBGenericRequest *request); + +extern uint8_t CDCSetControlLineStateRequest_ActivateCarrier( + const USBGenericRequest *request); + +extern void CDCLineCoding_Initialize(CDCLineCoding *lineCoding, + uint32_t bitrate, + uint8_t stopbits, + uint8_t parity, + uint8_t databits); + + +/**@}*/ +#endif /* #define _CDCREQUESTS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/DUALCDCDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/DUALCDCDDriver.h new file mode 100644 index 00000000..4478fbe9 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/DUALCDCDDriver.h @@ -0,0 +1,157 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definitions and methods for USB composite device implement. + * + */ + +#ifndef DUALCDCDDRIVER_H +#define DUALCDCDDRIVER_H +/** \addtogroup usbd_composite_cdccdc + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include +#include + +#include +#include + + +/*--------------------------------------------------------------------------- + * Defines + *---------------------------------------------------------------------------*/ + +/** \addtogroup usbd_composite_cdccdc_desc + * The driver uses these interface numbers in configuration descriptor. + * @{ + */ +/** Number of interfaces of the device */ +#define DUALCDCDDriverDescriptors_NUMINTERFACE 4 +/** Number of the CDC0 interface. */ +#define DUALCDCDDriverDescriptors_INTERFACENUM0 0 +/** Number of the CDC1 interface. */ +#define DUALCDCDDriverDescriptors_INTERFACENUM1 2 +/** @}*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef DualCdcDriverConfigurationDescriptors + * \brief Configuration descriptor list for a device implementing a + * dual CDC serial composite driver. + */ +typedef struct _DualCdcDriverConfigurationDescriptors { + + /** 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 functions + *---------------------------------------------------------------------------*/ + +/* -DUALCDC */ +extern void DUALCDCDDriver_Initialize( + const USBDDriverDescriptors* pDescriptors); + +extern void DUALCDCDDriver_ConfigurationChangeHandler(uint8_t cfgnum); + +extern void DUALCDCDDriver_RequestHandler(const USBGenericRequest *request); + +extern CDCDSerialPort* DUALCDCDDriver_GetSerialPort(uint32_t port); + +/**@}*/ +#endif /* #ifndef DUALCDCDDRIVER_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDAUDDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDAUDDDriver.h new file mode 100644 index 00000000..d355e417 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDAUDDDriver.h @@ -0,0 +1,191 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definitions and methods for USB composite device implement. + * + */ + +#ifndef HIDAUDDDRIVER_H +#define HIDAUDDDRIVER_H +/** \addtogroup usbd_hid_aud + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +/** \addtogroup usbd_hid_aud_desc USB HID(Keyboard) + AUD(Speaker) Definitions + * @{ + */ +/** Number of interfaces of the device 1+2 */ +#define HIDAUDDDriverDescriptors_NUMINTERFACE 3 +/** Number of the CDC interface. */ +#define HIDAUDDDriverDescriptors_HID_INTERFACE 0 +/** Number of the Audio interface. */ +#define HIDAUDDDriverDescriptors_AUD_INTERFACE 1 +/** @}*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** Structure of audio header descriptor*/ +typedef struct _AUDHeaderDescriptor1{ + + /** Header descriptor.*/ + AUDHeaderDescriptor header; + /** Id of the first grouped interface.*/ + unsigned char bInterface0; + +} __attribute__ ((packed)) AUDHeaderDescriptor1; + +/** + * Feature unit descriptor with 3 channel controls (master, right, left). + */ +typedef struct _AUDFeatureUnitDescriptor3{ + + /** 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; + +/** + * List of descriptors for detailling the audio control interface of a + * device using a USB audio speaker driver. + */ +typedef struct _AUDDSpeakerDriverAudioControlDescriptors{ + + /** 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 _AUDFormatTypeOneDescriptor1{ + + /** Format type I descriptor.*/ + AUDFormatTypeOneDescriptor formatType; + /** Sampling frequency in Hz.*/ + unsigned char tSamFreq[3]; + +} __attribute__ ((packed)) AUDFormatTypeOneDescriptor1; // GCC + +/** + * \typedef CdcAudDriverConfigurationDescriptors + * \brief Configuration descriptor list for a device implementing a + * composite HID (Keyboard) + Audio (Speaker) driver. + */ +typedef struct _HidAuddDriverConfigurationDescriptors { + + /** Standard configuration descriptor. */ + USBConfigurationDescriptor configuration; + + /* --- HID */ + /** HID interface. */ + USBInterfaceDescriptor hidInterface; + /** HID descriptor */ + HIDDescriptor1 hid; + /** HID interrupt IN */ + USBEndpointDescriptor hidInterruptIn; + /** HID interrupt OUT */ + USBEndpointDescriptor hidInterruptOut; + + /* --- AUDIO (AC) */ + /** Audio IAD */ + USBInterfaceAssociationDescriptor audIAD; + /** Audio control interface.*/ + USBInterfaceDescriptor audInterface; + /** Descriptors for the audio control interface.*/ + AUDDSpeakerDriverAudioControlDescriptors audControl; + /* -- AUDIO out (AS) */ + /** 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; + +} __attribute__ ((packed)) HidAuddDriverConfigurationDescriptors; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +extern void HIDAUDDDriver_Initialize(const USBDDriverDescriptors * pDescriptors); +extern void HIDAUDDDriver_ConfigurationChangedHandler(uint8_t cfgnum); +extern void HIDAUDDDriver_InterfaceSettingChangedHandler( + uint8_t interface, uint8_t setting); +extern void HIDAUDDDriver_RequestHandler(const USBGenericRequest *request); + +/**@}*/ +#endif //#ifndef CDCHIDDDRIVER_H + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDDFunction.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDFunction.h new file mode 100644 index 00000000..8fa93243 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDFunction.h @@ -0,0 +1,210 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * + * Definitions used for general HID support. + * + * The HID Function supports following: + * - 1 interface with 1 pipe in and 1 pipe out; + * - An input report list; + * - An output report list; + * - handles requests: + * - handles: GET_IDLE/SET_IDLE, + * GET_REPORT/SET_REPORT, + * SET_PROTOCOL/GET_PROTOCOL; + * - stall : SET_DESCRIPTOR. + */ + +#ifndef _HIDDFUNCTION_H_ +#define _HIDDFUNCTION_H_ +/** \addtogroup usbd_hid + * @{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + +#include +#include + +#include +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usbd_hid_events HIDD Event codes + * @{ + */ +/** Report sent */ +#define HIDD_EC_REPORTSENT 1 +/** Report changed */ +#define HIDD_EC_REPORTCHANGED 2 +/** Report sent because of GET_REPORT Request */ +#define HIDD_EC_GETREPORT 3 +/** Report changed because of SET_REPORT Request */ +#define HIDD_EC_SETREPORT 4 +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +/** + * Callback function for HID report events. + */ +typedef void(*HIDDReportEventCallback)(uint32_t ec, void *pArg); + +/** + * Struct for a header of basic HID report descriptor. + */ +typedef struct _HIDDReportHeader { + /** Callback when report done */ + HIDDReportEventCallback fCallback; + /** Callback arguments */ + void* pArg; + + /** Report size (ID + DATA) */ + uint16_t wMaxSize; + /** Transfered size */ + uint16_t wTransferred; + /** Report idle rate */ + uint8_t bIdleRate; + /** Delay count for Idle */ + uint8_t bDelay; + /** Report ID */ + uint8_t bID; +} HIDDReportHeader; + +/** + * Struct for an basic HID report descriptor. + */ +typedef struct _HIDDReport { + /** Callback when report done */ + HIDDReportEventCallback fCallback; + /** Callback arguments */ + void* pArg; + + /** Report size (ID + DATA) */ + uint16_t wMaxSize; + /** Transfered size */ + uint16_t wTransferred; + /** Report idle rate */ + uint8_t bIdleRate; + /** Delay count for Idle */ + uint8_t bDelay; + /** Report ID */ + uint8_t bID; + /** Report data block start ... */ + uint8_t bData[1]; +} HIDDReport; + +/** + * Struct for an HID general function. + * Supports Input/Output reports. No feature report support. + */ +typedef struct _HIDDFunction { + /** USB Driver for the %device */ + USBDDriver *pUsbd; + /** HID descriptor */ + HIDDescriptor *pHidDescriptor; + /** HID Specific report descriptor */ + uint8_t *pReportDescriptor; + /** USB interface for HID function */ + uint8_t bInterface; + /** USB interrupt IN EP */ + uint8_t bPipeIN; + /** USB interrupt OUT EP */ + uint8_t bPipeOUT; + + /** HID Protocol */ + uint8_t bProtocol; + + /** HID Input reports list */ + HIDDReport **pInputList; + /** HID Output reports list */ + HIDDReport **pOutputList; + /** HID Input report list size */ + uint8_t bInputListSize; + /** Current input report */ + uint8_t bCurrInput; + /** HID Output reports list */ + uint8_t bOutputListSize; + /** Current output report */ + uint8_t bCurrOutput; +} HIDDFunction; + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + +extern void HIDDFunction_Initialize( + HIDDFunction * pHidd, + USBDDriver * pUsbd, uint8_t bInterfaceNb, + const uint8_t * pReportDescriptor, + HIDDReport * pInputList [ ], uint8_t bInputListSize, + HIDDReport * pOutputList [ ], uint8_t bOutputListSize); + +extern USBGenericDescriptor* HIDDFunction_ParseInterface( + HIDDFunction * pHidd, + USBGenericDescriptor * pDescriptors, + uint32_t dwLength); + +extern uint32_t HIDDFunction_RequestHandler( + HIDDFunction * pHidd, + const USBGenericRequest * request); + +extern uint32_t HIDDFunction_StartSendingInputs(HIDDFunction * pHidd); + +extern uint32_t HIDDFunction_StartPollingOutputs(HIDDFunction * pHidd); + +extern uint32_t HIDDFunction_Read( + const HIDDFunction * pHidd, + void * pData, uint32_t dwLength, + TransferCallback fCallback, void * pArg); + +extern uint32_t HIDDFunction_Write( + const HIDDFunction * pHidd, + void * pData, uint32_t dwLength, + TransferCallback fCallback, void * pArg); + +extern void HIDDFunction_InitializeReport( + HIDDReport * pReport, + uint16_t wSize, + uint8_t bID, + HIDDReportEventCallback fCallback, void* pArg); + +/**@}*/ +#endif /* #define _HIDDFUNCTION_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDDKeyboard.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDKeyboard.h new file mode 100644 index 00000000..26ca8087 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDKeyboard.h @@ -0,0 +1,216 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * Definition of methods for using a HID keyboard function. + */ + +#ifndef HIDDKEYBOARD_H +#define HIDDKEYBOARD_H + +/** \addtogroup usbd_hid_key + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "board.h" + +#include "USBDescriptors.h" +#include "USBRequests.h" + +#include "HIDDescriptors.h" +#include "USBDDriver.h" + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_hid_kbd_desc HIDD Keyboard Driver Definitions + * @{ + */ + +/** Maximum number of simultaneous key presses. */ +#define HIDDKeyboardInputReport_MAXKEYPRESSES 3 + +/** \addtogroup usbd_hid_kbd_keys HID Keypad keys + * @{ + * This page lists definition for HID keypad keys. + * + * \section Keys + * - HIDDKeyboardDescriptors_FIRSTMODIFIERKEY + * - HIDDKeyboardDescriptors_LASTMODIFIERKEY + * - HIDDKeyboardDescriptors_FIRSTSTANDARDKEY + * - HIDDKeyboardDescriptors_LASTSTANDARDKEY + */ +/** Key code of the first accepted modifier key */ +#define HIDDKeyboardDescriptors_FIRSTMODIFIERKEY HIDKeypad_LEFTCONTROL +/** Key code of the last accepted modifier key */ +#define HIDDKeyboardDescriptors_LASTMODIFIERKEY HIDKeypad_RIGHTGUI +/** Key code of the first accepted standard key */ +#define HIDDKeyboardDescriptors_FIRSTSTANDARDKEY 0 +/** Key code of the last accepted standard key */ +#define HIDDKeyboardDescriptors_LASTSTANDARDKEY HIDKeypad_NUMLOCK +/** @}*/ + +/** \addtogroup usbd_hid_kbd_polling HID Keyboard Default Polling Rates + * @{ + */ +/** Default HID interrupt IN endpoint polling rate FS (16ms). */ +#define HIDDKeyboardDescriptors_INTERRUPTIN_POLLING_FS 16 +/** Default HID interrupt IN endpoint polling rate HS (16ms). */ +#define HIDDKeyboardDescriptors_INTERRUPTIN_POLLING_HS 8 +/** Default interrupt OUT endpoint polling rate FS (16ms). */ +#define HIDDKeyboardDescriptors_INTERRUPTOUT_POLLING_FS 16 +/** Default interrupt OUT endpoint polling rate HS (16ms). */ +#define HIDDKeyboardDescriptors_INTERRUPTOUT_POLLING_HS 8 +/** @}*/ + +/** Size of the report descriptor in bytes */ +#define HIDDKeyboard_REPORTDESCRIPTORSIZE 61 + +/** @}*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef HIDDKeyboardOutputReport + * \brief HID output report structure used by the host to control the state of + * the keyboard LEDs. + * + * Only the first three bits are relevant, the other 5 are used as + * padding bits. + */ +typedef struct _HIDDKeyboardOutputReport { + + uint8_t numLockStatus:1, /** State of the num. lock LED. */ + capsLockStatus:1, /** State of the caps lock LED. */ + scrollLockStatus:1, /** State of the scroll lock LED. */ + padding:5; /** Padding bits. */ + +} __attribute__ ((packed)) HIDDKeyboardOutputReport; /* GCC */ + +/** + * \typedef HIDDKeyboardInputReport + * \brief HID input report structure used by the keyboard driver to notify the + * host of pressed keys. + * + * The first byte is used to report the state of modifier keys. The + * other three contains the keycodes of the currently pressed keys. + */ +typedef struct _HIDDKeyboardInputReport { + + /** State of modifier keys. */ + uint8_t bmModifierKeys:8; + /** Key codes of pressed keys. */ + uint8_t pressedKeys[HIDDKeyboardInputReport_MAXKEYPRESSES]; +} __attribute__ ((packed)) HIDDKeyboardInputReport; /* GCC */ + + +/** + * \typedef HIDDKeyboardDriverConfigurationDescriptors + * \brief List of descriptors that make up the configuration descriptors of a + * device using the HID keyboard driver. + */ +typedef struct _HIDDKeyboardDriverConfigurationDescriptors { + + /** Configuration descriptor. */ + USBConfigurationDescriptor configuration; + /** Interface descriptor. */ + USBInterfaceDescriptor interface; + /** HID descriptor. */ + HIDDescriptor1 hid; + /** Interrupt IN endpoint descriptor. */ + USBEndpointDescriptor interruptIn; + /** Interrupt OUT endpoint descriptor. */ + USBEndpointDescriptor interruptOut; + +} __attribute__ ((packed)) HIDDKeyboardDriverConfigurationDescriptors; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern void HIDDKeyboard_Initialize(USBDDriver * pUsbd,uint8_t bInterfaceNb); + +extern void HIDDKeyboard_ConfigureFunction( USBGenericDescriptor * pDescriptors, uint16_t wLength); + +extern uint32_t HIDDKeyboard_RequestHandler( const USBGenericRequest *request); + +extern uint32_t HIDDKeyboard_ChangeKeys( + uint8_t *pressedKeys, + uint8_t pressedKeysSize, + uint8_t *releasedKeys, + uint8_t releasedKeysSize); + +extern void HIDDKeyboard_RemoteWakeUp(void); + +extern void HIDDKeyboardCallbacks_LedsChanged( + uint8_t numLockStatus, + uint8_t capsLockStatus, + uint8_t scrollLockStatus); + + +extern void HIDDKeyboardInputReport_Initialize(HIDDKeyboardInputReport *report); + +extern void HIDDKeyboardInputReport_PressStandardKey( HIDDKeyboardInputReport *report, uint8_t key ) ; + +extern void HIDDKeyboardInputReport_ReleaseStandardKey( HIDDKeyboardInputReport *report, uint8_t key ) ; + +extern void HIDDKeyboardInputReport_PressModifierKey( HIDDKeyboardInputReport *report, uint8_t key); + +extern void HIDDKeyboardInputReport_ReleaseModifierKey( HIDDKeyboardInputReport *report, uint8_t key); + + +extern void HIDDKeyboardOutputReport_Initialize( HIDDKeyboardOutputReport *report); + +extern uint8_t HIDDKeyboardOutputReport_GetNumLockStatus( const HIDDKeyboardOutputReport *report); + +extern uint8_t HIDDKeyboardOutputReport_GetCapsLockStatus( const HIDDKeyboardOutputReport *report); + +extern uint8_t HIDDKeyboardOutputReport_GetScrollLockStatus( const HIDDKeyboardOutputReport *report); + +/**@}*/ + +#endif /*#ifndef HIDDKEYBOARD_H*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDDKeyboardDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDKeyboardDriver.h new file mode 100644 index 00000000..e7fa5f49 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDKeyboardDriver.h @@ -0,0 +1,125 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Definition of methods for using a HID keyboard device driver. + * + * \section Usage + * + * -# Re-implement the USBDCallbacks_RequestReceived callback to forward + * requests to HIDDKeyboardDriver_RequestHandler. This is done + * automatically unless the NOAUTOCALLBACK symbol is defined during + * compilation. + * -# Initialize the driver using HIDDKeyboardDriver_Initialize. The + * USB driver is automatically initialized by this method. + * -# Call the HIDDKeyboardDriver_ChangeKeys method when one or more + * keys are pressed/released. + */ + +#ifndef HIDDKEYBOARDDRIVER_H +#define HIDDKEYBOARDDRIVER_H + +/** \addtogroup usbd_hid_key + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include + +#include + +#include + +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern void HIDDKeyboardDriver_Initialize( + const USBDDriverDescriptors *pDescriptors); + +extern void HIDDKeyboardDriver_ConfigurationChangedHandler( + uint8_t cfgnum); + +extern void HIDDKeyboardDriver_RequestHandler( + const USBGenericRequest *request); + +/** + * Reports a change in which keys are currently pressed or release to the + * host. + * + * \param pressedKeys Pointer to an array of key codes indicating keys that have + * been pressed since the last call to + * HIDDKeyboardDriver_ChangeKeys(). + * \param pressedKeysSize Number of key codes in the pressedKeys array. + * \param releasedKeys Pointer to an array of key codes indicates keys that have + * been released since the last call to + * HIDDKeyboardDriver_ChangeKeys(). + * \param releasedKeysSize Number of key codes in the releasedKeys array. + * \return USBD_STATUS_SUCCESS if the report has been sent to the host; + * otherwise an error code. + */ +static inline uint32_t HIDDKeyboardDriver_ChangeKeys( + uint8_t *pressedKeys, + uint8_t pressedKeysSize, + uint8_t *releasedKeys, + uint8_t releasedKeysSize){ + return HIDDKeyboard_ChangeKeys(pressedKeys, pressedKeysSize, + releasedKeys, releasedKeysSize); +} + +/** + * Starts a remote wake-up sequence if the host has explicitely enabled it + * by sending the appropriate SET_FEATURE request. + */ +static inline void HIDDKeyboardDriver_RemoteWakeUp(void) { + HIDDKeyboard_RemoteWakeUp(); +} + +/**@}*/ + +#endif /*#ifndef HIDDKEYBOARDDRIVER_H*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDDMouseDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDMouseDriver.h new file mode 100644 index 00000000..546f8350 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDMouseDriver.h @@ -0,0 +1,151 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * + * \section Purpose + * + * Definition of methods for using a HID mouse device driver. + * + * \section Usage + * + * -# Re-implement the USBDCallbacks_RequestReceived callback to forward + * requests to HIDDMouseDriver_RequestHandler. This is done + * automatically unless the NOAUTOCALLBACK symbol is defined during + * compilation. + * -# Initialize the driver using HIDDMouseDriver_Initialize. The + * USB driver is automatically initialized by this method. + * -# Call the HIDDMouseDriver_ChangePoints method when one or more + * keys are pressed/released. + */ + +#ifndef HIDDKEYBOARDDRIVER_H +#define HIDDKEYBOARDDRIVER_H + +/** \addtogroup usbd_hid_mouse + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include +#include + +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_hid_mouse_button_bitmaps HID Mouse Button bitmaps + * @{ + * \section Bits + * - HIDDMouse_LEFT_BUTTON + * - HIDDMouse_RIGHT_BUTTON + * - HIDDMouse_MIDDLE_BUTTON + */ + +/** Left mouse button */ +#define HIDDMouse_LEFT_BUTTON (1 << 0) +/** Right mouse button */ +#define HIDDMouse_RIGHT_BUTTON (1 << 1) +/** Middle mouse button */ +#define HIDDMouse_MIDDLE_BUTTON (1 << 2) +/** @}*/ + +/** Size of the report descriptor in bytes. */ +#define HIDDMouseDriver_REPORTDESCRIPTORSIZE 50 + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef HIDDMouseDriverConfigurationDescriptors + * \brief List of descriptors that make up the configuration descriptors of a + * device using the HID Mouse driver. + */ +typedef struct _HIDDMouseDriverConfigurationDescriptors { + + /** Configuration descriptor. */ + USBConfigurationDescriptor configuration; + /** Interface descriptor. */ + USBInterfaceDescriptor interface; + /** HID descriptor. */ + HIDDescriptor1 hid; + /** Interrupt IN endpoint descriptor. */ + USBEndpointDescriptor interruptIn; + +} __attribute__ ((packed)) HIDDMouseDriverConfigurationDescriptors; + +/** + * \typedef HIDDMouseInputReport + * \brief HID input report data struct used by the Mouse driver to notify the + * host of pressed keys. + */ +typedef struct _HIDDMouseInputReport { + + uint8_t bmButtons; /**< Bitmap state of three mouse buttons. */ + int8_t bX; /**< Pointer displacement along the X axis. */ + int8_t bY; /**< Pointer displacement along the Y axis. */ +} __attribute__ ((packed)) HIDDMouseInputReport; /* GCC */ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern void HIDDMouseDriver_Initialize(const USBDDriverDescriptors *pDescriptors); + +extern void HIDDMouseDriver_ConfigurationChangedHandler(uint8_t cfgnum); + +extern void HIDDMouseDriver_RequestHandler(const USBGenericRequest *request); + +extern uint8_t HIDDMouseDriver_ChangePoints(uint8_t bmButtons, + int8_t deltaX, + int8_t deltaY); + +extern void HIDDMouseDriver_RemoteWakeUp(void); + +/**@}*/ + +#endif /*#ifndef HIDDKEYBOARDDRIVER_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDDTransferDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDTransferDriver.h new file mode 100644 index 00000000..76dcdff1 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDTransferDriver.h @@ -0,0 +1,141 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + *\file + * + *\section Purpose + * + *Definition of methods for using a HID transfer %device driver. + * + *\section Usage + * + *-# Re-implement the USBDCallbacks_RequestReceived callback to forward + * requests to HIDDTransferDriver_RequestHandler. This is done + * automatically unless the NOAUTOCALLBACK symbol is defined during + * compilation. + *-# Initialize the driver using HIDDTransferDriver_Initialize. The + * USB driver is automatically initialized by this method. + *-# Call the HIDDTransferDriver_Write method when sendint data to host. + *-# Call the HIDDTransferRead, HIDDTransferReadReport when checking and getting + * received data from host. + */ + +#ifndef HIDDKEYBOARDDRIVER_H +#define HIDDKEYBOARDDRIVER_H + +/** \addtogroup usbd_hid_tran + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include + +#include + +#include +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** Size of the input and output report, in bytes */ +#define HIDDTransferDriver_REPORTSIZE 32 + +/** Size of the report descriptor, in bytes */ +#define HIDDTransferDriver_REPORTDESCRIPTORSIZE 32 + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef HIDDTransferDriverConfigurationDescriptors + * \brief List of descriptors that make up the configuration descriptors of a + * device using the HID Transfer driver. + */ +typedef struct _HIDDTransferDriverConfigurationDescriptors { + + /** Configuration descriptor. */ + USBConfigurationDescriptor configuration; + /** Interface descriptor. */ + USBInterfaceDescriptor interface; + /** HID descriptor. */ + HIDDescriptor1 hid; + /** Interrupt IN endpoint descriptor. */ + USBEndpointDescriptor interruptIn; + /** Interrupt OUT endpoint descriptor. */ + USBEndpointDescriptor interruptOut; + +} __attribute__ ((packed)) HIDDTransferDriverConfigurationDescriptors; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern void HIDDTransferDriver_Initialize( + const USBDDriverDescriptors * pDescriptors); + +extern void HIDDTransferDriver_ConfigurationChangedHandler(uint8_t cfgnum); + +extern void HIDDTransferDriver_RequestHandler( + const USBGenericRequest *request); + +extern uint16_t HIDDTransferDriver_Read(void *pData, + uint32_t dLength); + +extern uint16_t HIDDTransferDriver_ReadReport(void *pData, + uint32_t dLength); + +extern uint8_t HIDDTransferDriver_Write(const void *pData, + uint32_t size, + TransferCallback callback, + void *pArg); + + +extern void HIDDTransferDriver_RemoteWakeUp(void); + +/**@}*/ + +#endif /*#ifndef HIDDKEYBOARDDRIVER_H*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDDescriptors.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDescriptors.h new file mode 100644 index 00000000..41104be6 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDDescriptors.h @@ -0,0 +1,229 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * + * \section Purpose + * + * Definitions used for declaring the descriptors of a HID device. + * + */ + +#ifndef _HIDDESCRIPTORS_H_ +#define _HIDDESCRIPTORS_H_ +/** \addtogroup usb_hid + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + +#include "HIDReports.h" +#include "HIDUsages.h" + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_hid_device_descriptor_codes HID Device Descriptor Codes + * @{ + * This page lists HID device class, subclass and protocol codes. + * + * \section Codes + * - HIDDeviceDescriptor_CLASS + * - HIDDeviceDescriptor_SUBCLASS + * - HIDDeviceDescriptor_PROTOCOL + */ + +/** Class code for a HID device. */ +#define HIDDeviceDescriptor_CLASS 0 +/** Subclass code for a HID device. */ +#define HIDDeviceDescriptor_SUBCLASS 0 +/** Protocol code for a HID device. */ +#define HIDDeviceDescriptor_PROTOCOL 0 +/** @}*/ + +/** \addtogroup usb_hid_interface_descriptor_codes HID Interface Descriptor Codes + * @{ + * This page lists HID Interface class, subclass and protocol codes. + * + * \section Codes + * - HIDInterfaceDescriptor_CLASS + * - HIDInterfaceDescriptor_SUBCLASS_NONE + * - HIDInterfaceDescriptor_SUBCLASS_BOOT + * - HIDInterfaceDescriptor_PROTOCOL_NONE + * - HIDInterfaceDescriptor_PROTOCOL_KEYBOARD + * - HIDInterfaceDescriptor_PROTOCOL_MOUSE + */ + +/** HID interface class code. */ +#define HIDInterfaceDescriptor_CLASS 0x03 +/** Indicates the interface does not implement a particular subclass. */ +#define HIDInterfaceDescriptor_SUBCLASS_NONE 0x00 +/** Indicates the interface is compliant with the boot specification. */ +#define HIDInterfaceDescriptor_SUBCLASS_BOOT 0x01 +/** Indicates the interface does not implement a particular protocol. */ +#define HIDInterfaceDescriptor_PROTOCOL_NONE 0x00 +/** Indicates the interface supports the boot specification as a keyboard. */ +#define HIDInterfaceDescriptor_PROTOCOL_KEYBOARD 0x01 +/** Indicates the interface supports the boot specification as a mouse. */ +#define HIDInterfaceDescriptor_PROTOCOL_MOUSE 0x02 +/** @}*/ + +/** \addtogroup usb_hid_ver HID Release Numbers + * @{ + * - \ref HIDDescriptor_HID1_11 + */ + +/** Identifies version 1.11 of the HID specification. */ +#define HIDDescriptor_HID1_11 0x0111 +/** @}*/ + +/** \addtogroup usb_descriptors_types HID Descriptors Types + * @{ + * + * \section Types + * - HIDGenericDescriptor_HID + * - HIDGenericDescriptor_REPORT + * - HIDGenericDescriptor_PHYSICAL + */ + +/** HID descriptor type. */ +#define HIDGenericDescriptor_HID 0x21 +/** Report descriptor type. */ +#define HIDGenericDescriptor_REPORT 0x22 +/** Physical descriptor type. */ +#define HIDGenericDescriptor_PHYSICAL 0x23 +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef HIDDescriptor + * \brief Identifies the length of type of subordinate descriptors of a HID + * device. This particular type has no subordinate descriptor. + */ +typedef struct _HIDDescriptor { + + /** Size of descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (\ref HIDGenericDescriptor_HID). */ + uint8_t bDescriptorType; + /** HID class specification release number in BCD format. */ + uint16_t bcdHID; + /** Country code of the device if it is localized. */ + uint8_t bCountryCode; + /** Number of subordinate descriptors. */ + uint8_t bNumDescriptors; + +} __attribute__ ((packed)) HIDDescriptor; /* GCC */ + +/** + * \typedef HIDDescriptor + * \brief Identifies the length of type of subordinate descriptors of a HID + * device. This particular type only supports one subordinate descriptor. + */ +typedef struct _HIDDescriptor1 { + + /** Size of descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (\ref HIDGenericDescriptor_HID). */ + uint8_t bDescriptorType; + /** HID class specification release number in BCD format. */ + uint16_t bcdHID; + /** Country code of the device if it is localized. */ + uint8_t bCountryCode; + /** Number of subordinate descriptors. */ + uint8_t bNumDescriptors; + /** Type of the first subordinate descriptor. */ + uint8_t bDescriptorType0; + /** Size in bytes of the first subordinate descriptor. */ + /* uint8_t bDescriptorLength0[2]; */ + uint16_t wDescriptorLength0; + +} __attribute__ ((packed)) HIDDescriptor1; /* GCC */ + +/** + * HID Physical Descriptor set 0: specifies the number of additional + * descriptor sets. + */ +typedef struct _HIDPhysicalDescriptor0 { + /** Numeric expression specifying the number of Physical Descriptor sets + Physical Descriptor 0 itself not included */ + uint8_t bNumber; + /** Numeric expression identifying the length of each Physical descriptor */ + uint8_t bLength[2]; +} __attribute__ ((packed)) HIDPhysicalDescriptor0; /* GCC */ + +/** + * HID Physical information + */ +typedef union _HIDPhysicalInfo { + /** Bits specifying physical information: 7..5 Bias, 4..0 Preference */ + uint8_t bData; + struct { + uint8_t Preference:5, /**< 0=Most preferred */ + Bias:3; /**< indicates which hand the descriptor + set is characterizing */ + } sPhysicalInfo; +} HIDPhysicalInfo; + +/** + * HID Physical Descriptor + */ +typedef struct _HIDPhysicalDescriptor { + /** Designator: indicates which part of the body affects the item */ + uint8_t bDesignator; + /** Bits specifying flags: + 7..5 Qualifier; + 4..0 Effort */ + uint8_t bFlags; +} __attribute__ ((packed)) HIDPhysicalDescriptor; /* GCC */ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + +/**@}*/ +#endif /* #ifndef _HIDDESCRIPTORS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDMSDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDMSDDriver.h new file mode 100644 index 00000000..795f1df0 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDMSDDriver.h @@ -0,0 +1,140 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * \section Purpose + * + * Definitions and methods for USB HID + MSD device implement. + * + * \section 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 + +/** \addtogroup usbd_composite_hidmsd + *@{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Consts + *---------------------------------------------------------------------------*/ + +/** \addtogroup usbd_hid_msd_desc USB HID(Kbd) + MSD Descriptors define + * @{ + */ +/** Number of interfaces of the device */ +#define HIDMSDDriverDescriptors_NUMINTERFACE 2 +/** Number of the HID (Keyboard) interface. */ +#define HIDMSDDriverDescriptors_HID_INTERFACE 0 +/** Number of the MSD interface. */ +#define HIDMSDDriverDescriptors_MSD_INTERFACE 1 +/** @}*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef HidMsdDriverConfigurationDescriptors + * \brief Configuration descriptor list for a device implementing a + * HID MSD composite driver. + */ +typedef struct _HidMsdDriverConfigurationDescriptors { + + /** Standard configuration descriptor. */ + USBConfigurationDescriptor configuration; + + /* --- HID */ + USBInterfaceDescriptor hidInterface; + HIDDescriptor1 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 */ + +/*--------------------------------------------------------------------------- + * Exported functions + *---------------------------------------------------------------------------*/ + +/* -HIDMSD Composite device */ +extern void HIDMSDDriver_Initialize( + const USBDDriverDescriptors *pDescriptors, + MSDLun *pLuns, uint8_t numLuns); + +extern void HIDMSDDriver_ConfigurationChangedHandler(uint8_t cfgnum); + +extern void HIDMSDDriver_RequestHandler(const USBGenericRequest *request); + +extern void HIDMSDDriver_RemoteWakeUp(void); + +/**@}*/ +#endif //#ifndef HIDMSDDDRIVER_H + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDReports.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDReports.h new file mode 100644 index 00000000..2b2b551b --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDReports.h @@ -0,0 +1,299 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * + * \section Purpose + * + * Definitions used when declaring an HID report descriptors. + * + * \section Usage + * + * Use the definitions provided here when declaring a report descriptor, + * which shall be an uint8_t array. +*/ + +#ifndef _HIDREPORTS_H_ +#define _HIDREPORTS_H_ +/** \addtogroup usb_hid + *@{ + * \addtogroup usb_hid_report USB HID Report + * @{ + */ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_hid_item HID Items Definitions + * @{ + */ +/** Item size 0 bytes */ +#define HIDItemSize_0B 0 +/** Item size 1 bytes */ +#define HIDItemSize_1B 1 +/** Item size 2 bytes */ +#define HIDItemSize_2B 2 +/** Item size 4 bytes */ +#define HIDItemSize_4B 3 + +/** Item type: Main */ +#define HIDItemType_MAIN 0 +/** Item type: Global */ +#define HIDItemType_GLOBAL 1 +/** Item type: Local */ +#define HIDItemType_LOCAL 2 + +/** Item prefix for long items */ +#define HIDItem_LONGITEM 0xFE +/** @}*/ + +/** \addtogroup usb_hid_main HID Main Item Tags + * @{ + * This section lists the Main Item Tags defined for HID device. + * ( HID Spec. 6.2.2.4 ) + * + * - \ref HIDReport_INPUT + * - \ref HIDReport_FEATURE + * - \ref HIDReport_COLLECTION + * - \ref HIDReport_ENDCOLLECTION + */ +/** Input item. */ +#define HIDReport_INPUT 0x80 +/** Output item. */ +#define HIDReport_OUTPUT 0x90 +/** Feature item. */ +#define HIDReport_FEATURE 0xB0 +/** Collection item. */ +#define HIDReport_COLLECTION 0xA0 +/** End of collection item. */ +#define HIDReport_ENDCOLLECTION 0xC0 +/** @}*/ + +/** \addtogroup usb_hid_data HID Items for Data Fields + * @{ + * This section lists defintions for HID Input, Output and Feature items that + * are used to create the data fields within a report. + * ( HID Spec. 6.2.2.5 ) + * - \ref HIDReport_CONSTANT + * - \ref HIDReport_VARIABLE + * - \ref HIDReport_RELATIVE + * - \ref HIDReport_WRAP + * - \ref HIDReport_NONLINEAR + * - \ref HIDReport_NOPREFERRED + * - \ref HIDReport_NULLSTATE + * - \ref HIDReport_VOLATILE + * - \ref HIDReport_BUFFEREDBYTES + */ +/** The report value is constant (vs. variable). */ +#define HIDReport_CONSTANT (1 << 0) +/** Data reported is a variable (vs. array). */ +#define HIDReport_VARIABLE (1 << 1) +/** Data is relative (vs. absolute). */ +#define HIDReport_RELATIVE (1 << 2) +/** Value rolls over when it reach a maximum/minimum. */ +#define HIDReport_WRAP (1 << 3) +/** Indicates that the data reported has been processed and is no longuer */ +/** linear with the original measurements. */ +#define HIDReport_NONLINEAR (1 << 4) +/** Device has no preferred state to which it automatically returns. */ +#define HIDReport_NOPREFERRED (1 << 5) +/** Device has a null state, in which it does not report meaningful */ +/** information. */ +#define HIDReport_NULLSTATE (1 << 6) +/** Indicates data can change without the host intervention. */ +#define HIDReport_VOLATILE (1 << 7) +/** Indicates the device produces a fixed-length stream of bytes. */ +#define HIDReport_BUFFEREDBYTES (1 << 8) +/** @}*/ + +/** \addtogroup usb_hid_collection HID Collection Items + * @{ + * This section lists definitions for HID Collection Items. + * ( HID Spec. 6.2.2.6 ) + * - \ref HIDReport_COLLECTION_PHYSICAL + * - \ref HIDReport_COLLECTION_APPLICATION + * - \ref HIDReport_COLLECTION_LOGICAL + * - \ref HIDReport_COLLECTION_REPORT + * - \ref HIDReport_COLLECTION_NAMEDARRAY + * - \ref HIDReport_COLLECTION_USAGESWITCH + * - \ref HIDReport_COLLECTION_USAGEMODIFIER + */ +/** Physical collection. */ +#define HIDReport_COLLECTION_PHYSICAL 0x00 +/** Application collection. */ +#define HIDReport_COLLECTION_APPLICATION 0x01 +/** Logical collection. */ +#define HIDReport_COLLECTION_LOGICAL 0x02 +/** Report collection. */ +#define HIDReport_COLLECTION_REPORT 0x03 +/** Named array collection. */ +#define HIDReport_COLLECTION_NAMEDARRAY 0x04 +/** Usage switch collection. */ +#define HIDReport_COLLECTION_USAGESWITCH 0x05 +/** Usage modifier collection */ +#define HIDReport_COLLECTION_USAGEMODIFIER 0x06 +/** @}*/ + +/** \addtogroup usb_hid_global HID Global Items + * @{ + * This section lists HID Global Items. + * ( HID Spec. 6.2.2.7 ) + * - \ref HIDReport_GLOBAL_USAGEPAGE + * - \ref HIDReport_GLOBAL_LOGICALMINIMUM + * - \ref HIDReport_GLOBAL_LOGICALMAXIMUM + * - \ref HIDReport_GLOBAL_PHYSICALMINIMUM + * - \ref HIDReport_GLOBAL_PHYSICALMAXIMUM + * - \ref HIDReport_GLOBAL_UNITEXPONENT + * - \ref HIDReport_GLOBAL_UNIT + * - \ref HIDReport_GLOBAL_REPORTSIZE + * - \ref HIDReport_GLOBAL_REPORTID + * - \ref HIDReport_GLOBAL_REPORTCOUNT + * - \ref HIDReport_GLOBAL_PUSH + * - \ref HIDReport_GLOBAL_POP + */ +/** Current usage page. */ +#define HIDReport_GLOBAL_USAGEPAGE 0x04 +/** Minimum value that a variable or array item will report. */ +#define HIDReport_GLOBAL_LOGICALMINIMUM 0x14 +/** Maximum value that a variable or array item will report. */ +#define HIDReport_GLOBAL_LOGICALMAXIMUM 0x24 +/** Minimum value for the physical extent of a variable item. */ +#define HIDReport_GLOBAL_PHYSICALMINIMUM 0x34 +/** Maximum value for the physical extent of a variable item. */ +#define HIDReport_GLOBAL_PHYSICALMAXIMUM 0x44 +/** Value of the unit exponent in base 10. */ +#define HIDReport_GLOBAL_UNITEXPONENT 0x54 +/** Unit values. */ +#define HIDReport_GLOBAL_UNIT 0x64 +/** Size of the report fields in bits. */ +#define HIDReport_GLOBAL_REPORTSIZE 0x74 +/** Specifies the report ID. */ +#define HIDReport_GLOBAL_REPORTID 0x84 +/** Number of data fields for an item. */ +#define HIDReport_GLOBAL_REPORTCOUNT 0x94 +/** Places a copy of the global item state table on the stack. */ +#define HIDReport_GLOBAL_PUSH 0xA4 +/** Replaces the item state table with the top structure from the stack. */ +#define HIDReport_GLOBAL_POP 0xB4 +/** @}*/ + +/** \addtogroup usb_hid_local HID Local Items + * @{ + * This section lists definitions for HID Local Items. + * ( HID Spec. 6.2.2.8 ) + * - \ref HIDReport_LOCAL_USAGE + * - \ref HIDReport_LOCAL_USAGEMINIMUM + * - \ref HIDReport_LOCAL_USAGEMAXIMUM + * - \ref HIDReport_LOCAL_DESIGNATORINDEX + * - \ref HIDReport_LOCAL_DESIGNATORMINIMUM + * - \ref HIDReport_LOCAL_DESIGNATORMAXIMUM + * - \ref HIDReport_LOCAL_STRINGINDEX + * - \ref HIDReport_LOCAL_STRINGMINIMUM + * - \ref HIDReport_LOCAL_STRINGMAXIMUM + * - \ref HIDReport_LOCAL_DELIMITER + */ +/** Suggested usage for an item or collection. */ +#define HIDReport_LOCAL_USAGE 0x08 +/** Defines the starting usage associated with an array or bitmap. */ +#define HIDReport_LOCAL_USAGEMINIMUM 0x18 +/** Defines the ending usage associated with an array or bitmap. */ +#define HIDReport_LOCAL_USAGEMAXIMUM 0x28 +/** Determines the body part used for a control. */ +#define HIDReport_LOCAL_DESIGNATORINDEX 0x38 +/** Defines the index of the starting designator associated with an array or */ +/** bitmap. */ +#define HIDReport_LOCAL_DESIGNATORMINIMUM 0x48 +/** Defines the index of the ending designator associated with an array or */ +/** bitmap. */ +#define HIDReport_LOCAL_DESIGNATORMAXIMUM 0x58 +/** String index for a string descriptor. */ +#define HIDReport_LOCAL_STRINGINDEX 0x78 +/** Specifies the first string index when assigning a group of sequential */ +/** strings to controls in an array or bitmap. */ +#define HIDReport_LOCAL_STRINGMINIMUM 0x88 +/** Specifies the last string index when assigning a group of sequential */ +/** strings to controls in an array or bitmap. */ +#define HIDReport_LOCAL_STRINGMAXIMUM 0x98 +/** Defines the beginning or end of a set of local items. */ +#define HIDReport_LOCAL_DELIMITER 0xA8 +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** HID Short Item Header, followed by bSize bytes of data */ +typedef struct _HIDShortItem { + uint8_t bSize:2, /**< data size (0, 1, 2 or 4) */ + bType:2, /**< fundamental type */ + bTag:4; /**< item type */ +} HIDShortItem; + +/** HID Long Item Header, followed by bDataSize bytes of data */ +typedef struct _HIDLongItem { + uint8_t bPrefix; /**< Prefix, 0xFE */ + uint8_t bDataSize; /**< data size */ + uint16_t bLongItemTag; /**< item type */ +} HIDLongItem; + +/** HID Report without ID (with one byte data) */ +typedef struct _HIDReportNoID { + uint8_t bData[1]; /**< First report data byte */ +} HIDReportNoID; + +/** HID Report with ID (with one byte data) */ +typedef struct _HIDReport { + uint8_t bID; /**< Report ID */ + uint8_t bData[1]; /**< First report data byte */ +} HIDReport; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + +/** @}*/ +/**@}*/ +#endif /*#ifndef _HIDREPORTS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDRequests.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDRequests.h new file mode 100644 index 00000000..5e1c5877 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDRequests.h @@ -0,0 +1,154 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * + * \section Purpose + * + * Definitions used for declaring the requests of a HID device. + * + * -# Receive a GET_REPORT or SET_REPORT request from the host. + * -# Retrieve the report type using HIDReportRequest_GetReportType. + * -# Retrieve the report ID using HIDReportRequest_GetReportId. + * -# Retrieve the idle rate indicated by a GET_IDLE or SET_IDLE request + * with HIDIdleRequest_GetIdleRate. + */ + +#ifndef _HIDREQUESTS_H_ +#define _HIDREQUESTS_H_ +/** \addtogroup usb_hid + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include +#include + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_hid_request_codes HID Request Codes + * @{ + * + * \section Codes + * - HIDGenericRequest_GETREPORT + * - HIDGenericRequest_GETIDLE + * - HIDGenericRequest_GETPROTOCOL + * - HIDGenericRequest_SETREPORT + * - HIDGenericRequest_SETIDLE + * - HIDGenericRequest_SETPROTOCOL + */ + +/** GetReport request code. */ +#define HIDGenericRequest_GETREPORT 0x01 +/** GetIdle request code. */ +#define HIDGenericRequest_GETIDLE 0x02 +/** GetProtocol request code. */ +#define HIDGenericRequest_GETPROTOCOL 0x03 +/** SetReport request code. */ +#define HIDGenericRequest_SETREPORT 0x09 +/** SetIdle request code. */ +#define HIDGenericRequest_SETIDLE 0x0A +/** SetProtocol request code. */ +#define HIDGenericRequest_SETPROTOCOL 0x0B +/** @}*/ + +/** \addtogroup usb_hid_report_types HID Report Types + * @{ + * This page lists the types for USB HID Reports. + * + * \section Types + * - HIDReportRequest_INPUT + * - HIDReportRequest_OUTPUT + * - HIDReportRequest_FEATURE + */ + +/** Input report. */ +#define HIDReportRequest_INPUT 1 +/** Output report. */ +#define HIDReportRequest_OUTPUT 2 +/** Feature report. */ +#define HIDReportRequest_FEATURE 3 +/** @}*/ + +/** \addtogroup usb_hid_protocol_types HID Protocol Types + * @{ + */ +/** Boot Protocol */ +#define HIDProtocol_BOOT 0 +/** Report Protocol */ +#define HIDProtocol_REPORT 1 + +/** Infinite idle rate.*/ +#define HIDIdleRequest_INFINITE 0 + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + + + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*---------------------------------------------------------------------------- + * Functions + *----------------------------------------------------------------------------*/ + +extern uint8_t HIDReportRequest_GetReportType( + const USBGenericRequest *request); + +extern uint8_t HIDReportRequest_GetReportId( + const USBGenericRequest *request); + + +static inline uint16_t HIDProtocolRequest_GetProtocol( + const USBGenericRequest *request) +{ + return USBGenericRequest_GetValue(request); +} + +extern uint8_t HIDIdleRequest_GetReportId( + const USBGenericRequest * request); + +extern uint8_t HIDIdleRequest_GetIdleRate( + const USBGenericRequest *request); + +/**@}*/ +#endif /* #define _HIDREQUESTS_H_ */ diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/HIDUsages.h b/sam3s_example/atmel_softpack_libraries/usb/include/HIDUsages.h new file mode 100644 index 00000000..bc135429 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/HIDUsages.h @@ -0,0 +1,393 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/**\file + * + * \section Purpose + * + * Definitions used for declaring the usages of a HID device. + * + */ + +#ifndef _HIDUSAGES_H_ +#define _HIDUSAGES_H_ +/** \addtogroup usb_hid + *@{ + */ + +/*---------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include + + +/*---------------------------------------------------------------------------- + * Defines + *----------------------------------------------------------------------------*/ + +/** \addtogroup usb_hid_usage_pages HID Usage Pages' IDs + * @{ + * (HUT section 3) + */ + +/** ID for the HID Generic Desktop Controls. */ +#define HIDUsage_GENERICDESKTOP 1 +/** ID for the HID Game Controls. */ +#define HIDUsage_GAME 5 +/** ID for the HID Generic Device Controls. */ +#define HIDUsage_GENERICDEVICE 6 +/** ID for the HID Keyboard/Keypad */ +#define HIDUsage_KEYBOARD 7 +/** ID for the HID LEDs. */ +#define HIDUsage_LEDS 8 +/** ID for the HID buttons. */ +#define HIDUsage_BUTTON 9 +/** ID for Bar Code Scanner page. */ +#define HIDUsage_BARCODE 0x8C +/** ID for Camera Control Page. */ +#define HIDUsage_CAMERA 0x90 +/** ID for vendor-defined controls. */ +#define HIDUsage_VENDOR 0xFF +/** @}*/ + +/** \addtogroup usb_hid_genericdesktop_page_id HID GenericDesktop Page ID + * @{ + * + * \section ID + * - HIDGenericDesktop_PAGEID + */ + +/** ID for the HID generic desktop usage page. */ +#define HIDGenericDesktop_PAGEID 0x01 +/** @}*/ + +/** \addtogroup usb_hid_genericdesktop_usages HID GenericDesktop Usages + * @{ + * + * \section Usages + * - HIDGenericDesktop_POINTER + * - HIDGenericDesktop_MOUSE + * - HIDGenericDesktop_JOYSTICK + * - HIDGenericDesktop_GAMEPAD + * - HIDGenericDesktop_KEYBOARD + * - HIDGenericDesktop_KEYPAD + * - HIDGenericDesktop_MULTIAXIS + * - HIDGenericDesktop_X + * - HIDGenericDesktop_Y + */ + +/** Pointer usage ID. */ +#define HIDGenericDesktop_POINTER 0x01 +/** Mouse usage ID. */ +#define HIDGenericDesktop_MOUSE 0x02 +/** Joystick usage ID. */ +#define HIDGenericDesktop_JOYSTICK 0x04 +/** Gamepad usage ID. */ +#define HIDGenericDesktop_GAMEPAD 0x05 +/** Keyboard usage ID. */ +#define HIDGenericDesktop_KEYBOARD 0x06 +/** Keypad usage ID. */ +#define HIDGenericDesktop_KEYPAD 0x07 +/** Multi-axis controller usage ID. */ +#define HIDGenericDesktop_MULTIAXIS 0x08 + +/** Axis Usage X direction ID. */ +#define HIDGenericDesktop_X 0x30 +/** Axis Usage Y direction ID. */ +#define HIDGenericDesktop_Y 0x31 +/** @}*/ + + +/** \addtogroup usb_hid_keypad_page_id HID Keypad Page ID + * @{ + * This page lists HID Keypad page ID. + * + * \section ID + * - HIDKeypad_PAGEID + */ + +/** Identifier for the HID keypad usage page */ +#define HIDKeypad_PAGEID 0x07 +/** @}*/ + +/** \addtogroup usb_hid_alphabetic_keys HID Alphabetic Keys + * @{ + * + * \section Keys + * - HIDKeypad_A + * - HIDKeypad_B + * - HIDKeypad_C + * - HIDKeypad_D + * - HIDKeypad_E + * - HIDKeypad_F + * - HIDKeypad_G + * - HIDKeypad_H + * - HIDKeypad_I + * - HIDKeypad_J + * - HIDKeypad_K + * - HIDKeypad_L + * - HIDKeypad_M + * - HIDKeypad_N + * - HIDKeypad_O + * - HIDKeypad_P + * - HIDKeypad_Q + * - HIDKeypad_R + * - HIDKeypad_S + * - HIDKeypad_T + * - HIDKeypad_U + * - HIDKeypad_V + * - HIDKeypad_W + * - HIDKeypad_X + * - HIDKeypad_Y + * - HIDKeypad_Z + */ + +/** Key code for 'a' and 'A'. */ +#define HIDKeypad_A 4 +/** Key code for 'b' and 'B'. */ +#define HIDKeypad_B 5 +/** Key code for 'c' and 'C'. */ +#define HIDKeypad_C 6 +/** Key code for 'd' and 'D'. */ +#define HIDKeypad_D 7 +/** Key code for 'e' and 'E'. */ +#define HIDKeypad_E 8 +/** Key code for 'f' and 'F'. */ +#define HIDKeypad_F 9 +/** Key code for 'g' and 'G'. */ +#define HIDKeypad_G 10 +/** Key code for 'h' and 'H'. */ +#define HIDKeypad_H 11 +/** Key code for 'i' and 'I'. */ +#define HIDKeypad_I 12 +/** Key code for 'j' and 'J'. */ +#define HIDKeypad_J 13 +/** Key code for 'k' and 'K'. */ +#define HIDKeypad_K 14 +/** Key code for 'l' and 'L'. */ +#define HIDKeypad_L 15 +/** Key code for 'm' and 'M'. */ +#define HIDKeypad_M 16 +/** Key code for 'n' and 'N'. */ +#define HIDKeypad_N 17 +/** Key code for 'o' and 'O'. */ +#define HIDKeypad_O 18 +/** Key code for 'p' and 'P'. */ +#define HIDKeypad_P 19 +/** Key code for 'q' and 'Q'. */ +#define HIDKeypad_Q 20 +/** Key code for 'r' and 'R'. */ +#define HIDKeypad_R 21 +/** Key code for 's' and 'S'. */ +#define HIDKeypad_S 22 +/** Key code for 't' and 'T'. */ +#define HIDKeypad_T 23 +/** Key code for 'u' and 'U'. */ +#define HIDKeypad_U 24 +/** Key code for 'v' and 'V'. */ +#define HIDKeypad_V 25 +/** Key code for 'w' and 'W'. */ +#define HIDKeypad_W 26 +/** Key code for 'x' and 'X'. */ +#define HIDKeypad_X 27 +/** Key code for 'y' and 'Y'. */ +#define HIDKeypad_Y 28 +/** Key code for 'z' and 'Z'. */ +#define HIDKeypad_Z 29 +/** @}*/ + +/** \addtogroup usb_hid_numeric_keys HID Numeric Keys + * @{ + * + * \section Keys + * - HIDKeypad_1 + * - HIDKeypad_2 + * - HIDKeypad_3 + * - HIDKeypad_4 + * - HIDKeypad_5 + * - HIDKeypad_6 + * - HIDKeypad_7 + * - HIDKeypad_8 + * - HIDKeypad_9 + * - HIDKeypad_0 + */ + +/** Key code for '1' and '!'. */ +#define HIDKeypad_1 30 +/** Key code for '2' and '@'. */ +#define HIDKeypad_2 31 +/** Key code for '3' and '#'. */ +#define HIDKeypad_3 32 +/** Key code for '4' and '$'. */ +#define HIDKeypad_4 33 +/** Key code for '5' and '%'. */ +#define HIDKeypad_5 34 +/** Key code for '6' and '^'. */ +#define HIDKeypad_6 35 +/** Key code for '7' and '&'. */ +#define HIDKeypad_7 36 +/** Key code for '8' and '*'. */ +#define HIDKeypad_8 37 +/** Key code for '9' and '('. */ +#define HIDKeypad_9 38 +/** Key code for '0' and ')'. */ +#define HIDKeypad_0 39 +/** @}*/ + +/** \addtogroup usb_hid_special_keys HID Special Keys + * @{ + * + * \section Keys + * - HIDKeypad_ENTER + * - HIDKeypad_ESCAPE + * - HIDKeypad_BACKSPACE + * - HIDKeypad_TAB + * - HIDKeypad_SPACEBAR + * - HIDKeypad_PRINTSCREEN + * - HIDKeypad_SCROLLLOCK + * - HIDKeypad_NUMLOCK + */ + +/** Enter key code. */ +#define HIDKeypad_ENTER 40 +/** Escape key code. */ +#define HIDKeypad_ESCAPE 41 +/** Backspace key code. */ +#define HIDKeypad_BACKSPACE 42 +/** Tab key code. */ +#define HIDKeypad_TAB 43 +/** Spacebar key code. */ +#define HIDKeypad_SPACEBAR 44 +/** Printscreen key code. */ +#define HIDKeypad_PRINTSCREEN 70 +/** Scroll lock key code. */ +#define HIDKeypad_SCROLLLOCK 71 +/** Num lock key code. */ +#define HIDKeypad_NUMLOCK 83 +/** @}*/ + +/** \addtogroup usb_hid_modified_keys HID Modified Keys + * @{ + * + * \section Keys + * - HIDKeypad_LEFTCONTROL + * - HIDKeypad_LEFTSHIFT + * - HIDKeypad_LEFTALT + * - HIDKeypad_LEFTGUI + * - HIDKeypad_RIGHTCONTROL + * - HIDKeypad_RIGHTSHIFT + * - HIDKeypad_RIGHTALT + * - HIDKeypad_RIGHTGUI + */ + +/** Key code for the left 'Control' key. */ +#define HIDKeypad_LEFTCONTROL 224 +/** Key code for the left 'Shift' key. */ +#define HIDKeypad_LEFTSHIFT 225 +/** Key code for the left 'Alt' key. */ +#define HIDKeypad_LEFTALT 226 +/** Key code for the left 'GUI' (e.g. Windows) key. */ +#define HIDKeypad_LEFTGUI 227 +/** Key code for the right 'Control' key. */ +#define HIDKeypad_RIGHTCONTROL 228 +/** Key code for the right 'Shift' key. */ +#define HIDKeypad_RIGHTSHIFT 229 +/** Key code for the right 'Alt' key. */ +#define HIDKeypad_RIGHTALT 230 +/** Key code for the right 'GUI' key. */ +#define HIDKeypad_RIGHTGUI 231 +/** @}*/ + +/** \addtogroup usb_hid_error_codes HID Error Codes + * @{ + * + * \section Codes + * - HIDKeypad_ERRORROLLOVER + * - HIDKeypad_POSTFAIL + * - HIDKeypad_ERRORUNDEFINED + */ + +/** Indicates that too many keys have been pressed at the same time. */ +#define HIDKeypad_ERRORROLLOVER 1 +/** postfail */ +#define HIDKeypad_POSTFAIL 2 +/** Indicates an undefined error. */ +#define HIDKeypad_ERRORUNDEFINED 3 +/** @}*/ + + +/** \addtogroup usb_hid_leds_page_id HID LEDs Page ID + * @{ + * This page lists the page ID of the HID LEDs usage page. + * + * \section ID + * - HIDLeds_PAGEID + */ + +/** ID of the HID LEDs usage page. */ +#define HIDLeds_PAGEID 0x08 +/** @}*/ + +/** \addtogroup usb_hid_leds_usage HID LEDs Usages + * @{ + * This page lists the Usages of the HID LEDs. + * + * \section Usages + * - HIDLeds_NUMLOCK + * - HIDLeds_CAPSLOCK + * - HIDLeds_SCROLLLOCK + */ + +/** Num lock LED usage. */ +#define HIDLeds_NUMLOCK 0x01 +/** Caps lock LED usage. */ +#define HIDLeds_CAPSLOCK 0x02 +/** Scroll lock LED usage. */ +#define HIDLeds_SCROLLLOCK 0x03 +/** @}*/ + + +/** \addtogroup usb_hid_buttons_page_id HID BUTTONs Page ID + * @{ + */ +/** Identifier for the HID button usage page*/ +#define HIDButton_PAGEID 0x09 +/** @}*/ + + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern uint8_t HIDKeypad_IsModifierKey(uint8_t key); + +/**@}*/ +#endif /* #define _HIDUSAGES_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/MSD.h b/sam3s_example/atmel_softpack_libraries/usb/include/MSD.h new file mode 100644 index 00000000..ba8ef388 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/MSD.h @@ -0,0 +1,245 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * Mass Storage class definitions. + * + * See + * - + * USB Mass Storage Class Spec. Overview + * - + * USB Mass Storage Class Bulk-Only Transport + * + * \section Usage + * + * -# Uses "MSD Requests" to check incoming requests from USB Host. + * -# Uses "MSD Subclass Codes" and "MSD Protocol Codes" to fill %device + * interface descriptors for a MSD %device. + * -# Handle the incoming Bulk data with "MSD CBW Definitions" and MSCbw + * structure. + * -# Prepare the outgoing Bulk data with "MSD CSW Definitions" and MSCsw + * structure. + */ + +#ifndef MSD_H +#define MSD_H + +/** \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Includes + *------------------------------------------------------------------------------*/ + +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/* + * MSD Requests + * This section lists MSD-specific requests ( Actually for Bulk-only protocol ). + * + * \section Requests + * - MSD_BULK_ONLY_RESET + * - MSD_GET_MAX_LUN + */ + +/** Reset the mass storage %device and its associated interface. */ +#define MSD_BULK_ONLY_RESET 0xFF +/** Return the maximum LUN number supported by the %device. */ +#define MSD_GET_MAX_LUN 0xFE + +/** \addtogroup usbd_msd_subclass MSD Subclass Codes + * @{ + * This page lists the Subclass Codes for bInterfaceSubClass field. + * (Table 2.1, USB Mass Storage Class Spec. Overview) + * + * \section SubClasses + * - MSD_SUBCLASS_RBC + * - MSD_SUBCLASS_SFF_MCC + * - MSD_SUBCLASS_QIC + * - MSD_SUBCLASS_UFI + * - MSD_SUBCLASS_SFF + * - MSD_SUBCLASS_SCSI + */ + +/** Reduced Block Commands (RBC) T10 */ +#define MSD_SUBCLASS_RBC 0x01 +/** C/DVD devices */ +#define MSD_SUBCLASS_SFF_MCC 0x02 +/** Tape device */ +#define MSD_SUBCLASS_QIC 0x03 +/** Floppy disk drive (FDD) device */ +#define MSD_SUBCLASS_UFI 0x04 +/** Floppy disk drive (FDD) device */ +#define MSD_SUBCLASS_SFF 0x05 +/** SCSI transparent command set */ +#define MSD_SUBCLASS_SCSI 0x06 +/** @} */ + + +/** \addtogroup usbd_msd_protocol_codes MSD Protocol Codes + * @{ + * This page lists the Transport Protocol codes for MSD. + * (Table 3.1, USB Mass Storage Class Spec. Overview) + * + * \section Protocols + * - MSD_PROTOCOL_CBI_COMPLETION + * - MSD_PROTOCOL_CBI + * - MSD_PROTOCOL_BULK_ONLY + */ + +/** Control/Bulk/Interrupt (CBI) Transport (with command complete interrupt) */ +#define MSD_PROTOCOL_CBI_COMPLETION 0x00 +/** Control/Bulk/Interrupt (CBI) Transport (no command complete interrupt) */ +#define MSD_PROTOCOL_CBI 0x01 +/** Bulk-Only Transport */ +#define MSD_PROTOCOL_BULK_ONLY 0x50 +/** @}*/ + +/** \addtogroup usbd_msd_cbw_def MSD CBW Definitions + * @{ + * This page lists the Command Block Wrapper (CBW) definitions. + * + * \section Constants + * - MSD_CBW_SIZE + * - MSD_CBW_SIGNATURE + * + * \section Fields + * - MSD_CBW_DEVICE_TO_HOST + */ + +/** Command Block Wrapper Size */ +#define MSD_CBW_SIZE 31 +/** 'USBC' 0x43425355 */ +#define MSD_CBW_SIGNATURE 0x43425355 + +/** CBW bmCBWFlags field */ +#define MSD_CBW_DEVICE_TO_HOST (1 << 7) +/** @}*/ + +/** \addtogroup usbd_msd_csw_def MSD CSW Definitions + * @{ + * This page lists the Command Status Wrapper (CSW) definitions. + * + * \section Constants + * - MSD_CSW_SIZE + * - MSD_CSW_SIGNATURE + * + * \section Command Block Status Values + * (Table 5.3 , USB Mass Storage Class Bulk-Only Transport) + * - MSD_CSW_COMMAND_PASSED + * - MSD_CSW_COMMAND_FAILED + * - MSD_CSW_PHASE_ERROR + */ + +/** Command Status Wrapper Size */ +#define MSD_CSW_SIZE 13 +/** 'USBS' 0x53425355 */ +#define MSD_CSW_SIGNATURE 0x53425355 + +/** Command Passed (good status) */ +#define MSD_CSW_COMMAND_PASSED 0 +/** Command Failed */ +#define MSD_CSW_COMMAND_FAILED 1 +/** Phase Error */ +#define MSD_CSW_PHASE_ERROR 2 +/** @}*/ + + +/*------------------------------------------------------------------------------ + * Structures + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Command Block Wrapper (CBW), + * See Table 5.1, USB Mass Storage Class Bulk-Only Transport. + * + * The CBW shall start on a packet boundary and shall end as a + * short packet with exactly 31 (1Fh) bytes transferred. + *------------------------------------------------------------------------------*/ +typedef struct { + + /** 'USBC' 0x43425355 (little endian) */ + uint32_t dCBWSignature; + /** Must be the same as dCSWTag */ + uint32_t dCBWTag; + /** Number of bytes transfer */ + uint32_t dCBWDataTransferLength; + /** Indicates the directin of the transfer: + * - 0x80=IN=device-to-host; + * - 0x00=OUT=host-to-device + */ + uint8_t bmCBWFlags; + /** bits 0->3: bCBWLUN */ + uint8_t bCBWLUN :4, + bReserved1:4; /** reserved */ + /** bits 0->4: bCBWCBLength */ + uint8_t bCBWCBLength:5, + bReserved2 :3; /** reserved */ + /** Command block */ + uint8_t pCommand[16]; + +} MSCbw; + +/*------------------------------------------------------------------------------ + * Command Status Wrapper (CSW), + * See Table 5.2, USB Mass Storage Class Bulk-Only Transport. + *------------------------------------------------------------------------------*/ +typedef struct +{ + /** 'USBS' 0x53425355 (little endian) */ + uint32_t dCSWSignature; + /** Must be the same as dCBWTag */ + uint32_t dCSWTag; + /** + * For Data-Out the device shall report in the dCSWDataResidue the + * difference between the amount of data expected as stated in the + * dCBWDataTransferLength, and the actual amount of data processed by + * the device. For Data-In the device shall report in the dCSWDataResidue + * the difference between the amount of data expected as stated in the + * dCBWDataTransferLength and the actual amount of relevant data sent by + * the device. The dCSWDataResidue shall not exceed the value sent in the + * dCBWDataTransferLength. + */ + uint32_t dCSWDataResidue; + /** Indicates the success or failure of the command. */ + uint8_t bCSWStatus; + +} MSCsw; + +/**@}*/ +#endif /*#ifndef MSD_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/MSDDStateMachine.h b/sam3s_example/atmel_softpack_libraries/usb/include/MSDDStateMachine.h new file mode 100644 index 00000000..2df59075 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/MSDDStateMachine.h @@ -0,0 +1,256 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * Definitions, structs, functions required by a Mass Storage device driver + * state machine.. + * + * \section Usage + * + * - For a USB device: + * -# MSDD_StateMachine is invoked to run the MSD state machine. + * + *-----------------------------------------------------------------------------*/ + +#ifndef MSDDSTATEMACHINE_H +#define MSDDSTATEMACHINE_H + +/** \addtogroup usbd_msd + *@{ + */ + +/*----------------------------------------------------------------------------- + * Headers + *-----------------------------------------------------------------------------*/ + +#include "MSD.h" +#include "MSDLun.h" +#include +#include + +/*----------------------------------------------------------------------------- + * Definitions + *-----------------------------------------------------------------------------*/ + +/** \addtogroup usbd_msd_driver_possible_states MSD Driver Possible states + * @{ + * + * - MSDD_STATE_READ_CBW + * - MSDD_STATE_WAIT_CBW + * - MSDD_STATE_PROCESS_CBW + * - MSDD_STATE_WAIT_HALT + * - MSDD_STATE_SEND_CSW + * - MSDD_STATE_WAIT_CSW + * - MSDD_STATE_WAIT_RESET + */ + +/** \brief Driver is expecting a command block wrapper */ +#define MSDD_STATE_READ_CBW (1 << 0) + +/** \brief Driver is waiting for the transfer to finish */ +#define MSDD_STATE_WAIT_CBW (1 << 1) + +/** \brief Driver is processing the received command */ +#define MSDD_STATE_PROCESS_CBW (1 << 2) + +/** \brief Driver is halted because pipe halt or wait reset */ +#define MSDD_STATE_WAIT_HALT (1 << 3) + +/** \brief Driver is starting the transmission of a command status wrapper */ +#define MSDD_STATE_SEND_CSW (1 << 4) + +/** \brief Driver is waiting for the CSW transmission to finish */ +#define MSDD_STATE_WAIT_CSW (1 << 5) + +/** \brief Driver is waiting for the MassStorageReset */ +#define MSDD_STATE_WAIT_RESET (1 << 6) +/** @}*/ + +/** \addtogroup usbd_msd_driver_result_codes MSD Driver Result Codes + * @{ + * This page lists result codes for MSD functions. + * + * \section Codes + * - MSDD_STATUS_SUCCESS + * - MSDD_STATUS_ERROR + * - MSDD_STATUS_INCOMPLETE + * - MSDD_STATUS_PARAMETER + * - MSDD_STATUS_RW + */ + +/** \brief Method was successful */ +#define MSDD_STATUS_SUCCESS 0x00 + +/** \brief There was an error when trying to perform a method */ +#define MSDD_STATUS_ERROR 0x01 + +/** \brief No error was encountered but the application should call the + method again to continue the operation */ +#define MSDD_STATUS_INCOMPLETE 0x02 + +/** \brief A wrong parameter has been passed to the method */ +#define MSDD_STATUS_PARAMETER 0x03 + +/** \brief An error when reading/writing disk (protected or not present) */ +#define MSDD_STATUS_RW 0x04 +/** @}*/ + +/** \addtogroup usbd_msd_driver_action_cases MSD Driver Action Cases + * @{ + * This page lists actions to perform during the post-processing phase of a + * command. + * + * \section Actions + * - MSDD_CASE_PHASE_ERROR + * - MSDD_CASE_STALL_IN + * - MSDD_CASE_STALL_OUT + */ + +/** \brief Indicates that the CSW should report a phase error */ +#define MSDD_CASE_PHASE_ERROR (1 << 0) + +/** \brief The driver should halt the Bulk IN pipe after the transfer */ +#define MSDD_CASE_STALL_IN (1 << 1) + +/** \brief The driver should halt the Bulk OUT pipe after the transfer */ +#define MSDD_CASE_STALL_OUT (1 << 2) +/** @}*/ + +/*------------------------------------------------------------------------------ */ + +/** \addtogroup usbd_msd_driver_xfr_directions MSD Driver Xfr Directions + * @{ + * This page lists possible direction values for a data transfer + * - MSDD_DEVICE_TO_HOST + * - MSDD_HOST_TO_DEVICE + * - MSDD_NO_TRANSFER + */ +/** Data transfer from device to host (READ) */ +#define MSDD_DEVICE_TO_HOST 0 +/** Data transfer from host to device (WRITE) */ +#define MSDD_HOST_TO_DEVICE 1 +/** No data transfer */ +#define MSDD_NO_TRANSFER 2 +/** @}*/ + +/*----------------------------------------------------------------------------- + * Types + *-----------------------------------------------------------------------------*/ + +/** + * \typedef MSDTransfer + * \brief Structure for holding the result of a USB transfer + * \see MSDDriver_Callback + */ +typedef struct _MSDTransfer { + + uint32_t transferred; /** Number of bytes transferred */ + uint32_t remaining; /** Number of bytes not transferred */ + volatile uint16_t semaphore; /** Semaphore to indicate transfer completion */ + uint16_t status; /** Operation result code */ +} MSDTransfer; + +/** + * \typedef MSDCommandState + * \brief Status of an executing command + * \see MSDCbw + * \see MSDCsw + * \see MSDTransfer + *------------------------------------------------------------------------------*/ +typedef struct _MSDCommandState { + + MSDTransfer transfer; /**< Current transfer status (USB) */ + MSDTransfer disktransfer;/**< Current transfer status (Disk) */ + uint32_t length; /**< Remaining length of command */ + MSCbw cbw; /**< Received CBW (31 bytes) */ + uint8_t state; /**< Current command state */ + MSCsw csw; /**< CSW to send (13 bytes) */ + uint8_t postprocess; /**< Actions to perform when command is complete */ + uint8_t pipeIN; /**< Pipe ID for input */ + uint8_t pipeOUT; /**< Pipe ID for output */ +} MSDCommandState; + +/** + * \typedef MSDDriver + * \brief MSD driver state variables + * \see MSDCommandState + * \see MSDLun + */ +typedef struct _MSDDriver { + + /** USB Driver for the %device. */ + USBDDriver *pUsbd; + /** LUN list for the %device. */ + MSDLun *luns; + /** State of the currently executing command */ + MSDCommandState commandState; + /** Associated interface number */ + uint8_t interfaceNb; + /** Maximum LUN index */ + uint8_t maxLun; + /** Current state of the driver */ + uint8_t state; + /** Indicates if the driver is waiting for a reset recovery */ + uint8_t waitResetRecovery; +} MSDDriver; + +/*----------------------------------------------------------------------------- + * Inline functions + *-----------------------------------------------------------------------------*/ +/** + * This function is to be used as a callback for USB or LUN transfers. + * \param transfer Pointer to the transfer structure to update + * \param status Operation result code + * \param transferred Number of bytes transferred by the command + * \param remaining Number of bytes not transferred + */ +static inline void MSDDriver_Callback(MSDTransfer *transfer, + uint8_t status, + uint32_t transferred, + uint32_t remaining) +{ + TRACE_DEBUG( "Cbk " ) ; + transfer->semaphore++; + transfer->status = status; + transfer->transferred = transferred; + transfer->remaining = remaining; +} + +/*----------------------------------------------------------------------------- + * Exported functions + *-----------------------------------------------------------------------------*/ + +extern void MSDD_StateMachine(MSDDriver * pMsdDriver); + +/**@}*/ + +#endif /* #define MSDDSTATEMACHINE_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/MSDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/MSDDriver.h new file mode 100644 index 00000000..37ea63a9 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/MSDDriver.h @@ -0,0 +1,141 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * Mass storage %device driver implementation. + * + * \section Usage + * + * -# Enable and setup USB related pins (see pio & board.h). + * -# Configure the memory interfaces used for Mass Storage LUNs + * (see memories, MSDLun.h). + * -# Instance the USB device configure descriptor as + * MSDConfigurationDescriptors or MSDConfigurationDescriptorsOTG defined. + * Interface number should be 0. + * -# Configure the USB MSD %driver using MSDDriver_Initialize. + * -# Invoke MSDDriver_StateMachine in main loop to handle all Mass Storage + * operations. + */ + +#ifndef MSDDRIVER_H +#define MSDDRIVER_H + +/** \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef MSDConfigurationDescriptors + * \brief List of configuration descriptors used by a Mass Storage device driver. + */ +typedef struct _MSDConfigurationDescriptors { + + /** Standard configuration descriptor. */ + USBConfigurationDescriptor configuration; + /** Mass storage interface descriptor. */ + USBInterfaceDescriptor interface; + /** Bulk-out endpoint descriptor. */ + USBEndpointDescriptor bulkOut; + /** Bulk-in endpoint descriptor. */ + USBEndpointDescriptor bulkIn; + +} __attribute__ ((packed)) MSDConfigurationDescriptors; + +/** + * \typedef MSDConfigurationDescriptorsOTG + * \brief List of configuration descriptors used by a + * Mass Storage device driver, with OTG support. + */ +typedef struct _MSDConfigurationDescriptorsOTG { + + /** Standard configuration descriptor. */ + USBConfigurationDescriptor configuration; + /* OTG descriptor */ + USBOtgDescriptor otgDescriptor; + /** Mass storage interface descriptor. */ + USBInterfaceDescriptor interface; + /** Bulk-out endpoint descriptor. */ + USBEndpointDescriptor bulkOut; + /** Bulk-in endpoint descriptor. */ + USBEndpointDescriptor bulkIn; + +} __attribute__ ((packed)) MSDConfigurationDescriptorsOTG; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*------------------------------------------------------------------------------ + * Global functions + *------------------------------------------------------------------------------*/ + +extern void MSDDriver_Initialize( + const USBDDriverDescriptors *pDescriptors, + MSDLun *luns, uint8_t numLuns); + +extern void MSDDriver_RequestHandler( + const USBGenericRequest *request); + +extern void MSDDriver_ConfigurationChangeHandler( + uint8_t cfgnum); + +/** + * State machine for the MSD driver + * \param pMsdDriver Pointer to MSDDriver instance. + */ +static inline void MSDDriver_StateMachine(void) { + MSDFunction_StateMachine(); +} + +/**@}*/ + +#endif /* #ifndef MSDDRIVER_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/MSDFunction.h b/sam3s_example/atmel_softpack_libraries/usb/include/MSDFunction.h new file mode 100644 index 00000000..0cffc59b --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/MSDFunction.h @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Mass storage function driver definitions. + */ + +#ifndef MSDFUNCTION_H +#define MSDFUNCTION_H + +/** \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Global functions + *------------------------------------------------------------------------------*/ + +extern void MSDFunction_Initialize( + USBDDriver * pUsbd, uint8_t bInterfaceNb, + MSDLun * pLuns, uint8_t numLuns); + +extern uint32_t MSDFunction_RequestHandler( + const USBGenericRequest *request); + +extern void MSDFunction_Configure( + USBGenericDescriptor * pDescriptors, uint16_t wLength); + +extern void MSDFunction_StateMachine(void); + +/**@}*/ + +#endif /* #ifndef MSDDRIVER_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/MSDIOFifo.h b/sam3s_example/atmel_softpack_libraries/usb/include/MSDIOFifo.h new file mode 100644 index 00000000..4ed70fc5 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/MSDIOFifo.h @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------------------- + * 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 _MSDIOFIFO_H +#define _MSDIOFIFO_H + +/** \file + * \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** Idle state, do nothing */ +#define MSDIO_IDLE 0 +/** Start, to start IO operation */ +#define MSDIO_START 1 +/** Wait, waiting for IO operation done */ +#define MSDIO_WAIT 2 +/** Next, to check if the next block can be performed */ +#define MSDIO_NEXT 3 +/** Pause, to pause the process for buffer full or null */ +#define MSDIO_PAUSE 4 +/** Abort, to abort the process */ +#define MSDIO_ABORT 5 +/** Done, finish without error */ +#define MSDIO_DONE 6 +/** Error, any error happens */ +#define MSDIO_ERROR 7 + +/** FIFO offset before USB transmit start */ +/*#define MSDIO_FIFO_OFFSET (4*512) */ + + +/** FIFO trunk size (in each transfer, large amount of data) */ +#if !defined(MSD_OP_BUFFER) +#define MSDIO_READ10_CHUNK_SIZE (4*512) +#define MSDIO_WRITE10_CHUNK_SIZE (4*512) +#endif + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** \brief FIFO buffer for READ/WRITE (disk) operation of a mass storage device */ +typedef struct _MSDIOFifo { + + /** Pointer to the ring buffer allocated for read/write */ + unsigned char * pBuffer; + /** The size of the buffer allocated */ + unsigned int bufferSize; +#ifdef MSDIO_FIFO_OFFSET + /** The offset to start USB transfer (READ10) */ + unsigned int bufferOffset; +#endif + /** The index of input data (loaded to fifo buffer) */ + unsigned int inputNdx; + /** The total size of the loaded data */ + unsigned int inputTotal; + /** The index of output data (sent from the fifo buffer) */ + unsigned int outputNdx; + /** The total size of the output data */ + unsigned int outputTotal; + + /** The total size of the data */ + unsigned int dataTotal; + /** The size of the block in bytes */ + unsigned short blockSize; +#if defined(MSDIO_READ10_CHUNK_SIZE) || defined(MSDIO_WRITE10_CHUNK_SIZE) + /** The size of one chunk */ + /** (1 block, or several blocks for large amount data R/W) */ + unsigned int chunkSize; +#endif + /** State of input & output */ + unsigned char inputState; + unsigned char outputState; + + /*- Statistics */ + + /** Times when fifo has no data to send */ + unsigned short nullCnt; + /** Times when fifo can not load more input data */ + unsigned short fullCnt; +} MSDIOFifo, *PMSDIOFifo; + +/*------------------------------------------------------------------------------ + * MACROS + *------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------ + * Increase the index, by defined block size, in the ring buffer + * \param ndx The index to be increased + * \param sectSize The defined block size + * \param bufSize The ring buffer size + *------------------------------------------------------------------------------*/ +#define MSDIOFifo_IncNdx(ndx, sectSize, bufSize) \ + if ((ndx) >= (bufSize) - (sectSize)) (ndx) = 0; \ + else (ndx) += (sectSize) + + +/*------------------------------------------------------------------------------ + * Exported Functions + *------------------------------------------------------------------------------*/ + + +extern void MSDIOFifo_Init(MSDIOFifo *pFifo, + void * pBuffer, unsigned short bufferSize); + +/**@}*/ + +#endif /* _MSDIOFIFO_H */ + + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/MSDLun.h b/sam3s_example/atmel_softpack_libraries/usb/include/MSDLun.h new file mode 100644 index 00000000..57114000 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/MSDLun.h @@ -0,0 +1,176 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * Logical Unit Number (LUN) used by the Mass Storage driver and the SCSI + * protocol. Represents a logical hard-drive. + * + * \section Usage + * -# Initialize Memory related pins (see pio & board.h). + * -# Initialize a Media instance for the LUN (see memories). + * -# Initlalize the LUN with LUN_Init, and link to the initialized Media. + * -# To read data from the LUN linked media, uses LUN_Read. + * -# To write data to the LUN linked media, uses LUN_Write. + * -# To unlink the media, uses LUN_Eject. + */ + +#ifndef MSDLUN_H +#define MSDLUN_H + +/** \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include +#include "memories.h" + +#include "SBC.h" +#include "MSDIOFifo.h" +#include "USBD.h" + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** LUN RC: success */ +#define LUN_STATUS_SUCCESS 0x00 +/** LUN RC: error */ +#define LUN_STATUS_ERROR 0x02 + +/** Media of LUN is removed */ +#define LUN_NOT_PRESENT 0x00 +/** LUN is ejected by host */ +#define LUN_EJECTED 0x01 +/** Media of LUN is changed */ +#define LUN_CHANGED 0x10 +/** LUN Not Ready to Ready transition */ +#define LUN_TRANS_READY LUN_CHANGED +/** Media of LUN is ready */ +#define LUN_READY 0x11 + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** Mass storage device data flow monitor function type + * \param flowDirection 1 - device to host (READ10) + * 0 - host to device (WRITE10) + * \param dataLength Length of data transferred in bytes. + * \param fifoNullCount Times that FIFO is NULL to wait + * \param fifoFullCount Times that FIFO is filled to wait + */ +typedef void(*MSDLunDataMonitorFunction)(uint8_t flowDirection, + uint32_t dataLength, + uint32_t fifoNullCount, + uint32_t fifoFullCount); + +/*------------------------------------------------------------------------------ + * Structures + *------------------------------------------------------------------------------*/ + +/** \brief LUN structure */ +typedef struct { + + /** Pointer to a SBCInquiryData instance. */ + SBCInquiryData *inquiryData; + /** Fifo for USB transfer, must be assigned. */ + MSDIOFifo ioFifo; + /** Pointer to Media instance for the LUN. */ + Media *media; + /** Pointer to a Monitor Function to analyze the flow of LUN. + * \param flowDirection 1 - device to host (READ10) + * 0 - host to device (WRITE10) + * \param dataLength Length of data transferred in bytes. + * \param fifoNullCount Times that FIFO is NULL to wait + * \param fifoFullCount Times that FIFO is filled to wait + */ + void (*dataMonitor)(uint8_t flowDirection, + uint32_t dataLength, + uint32_t fifoNullCount, + uint32_t fifoFullCount); + /** The start position of the media (blocks) allocated to the LUN. */ + uint32_t baseAddress; + /** The size of the media (blocks) allocated to the LUN. */ + uint32_t size; + /** Sector size of the media in number of media blocks */ + uint16_t blockSize; + /** The LUN can be readonly even the media is writable */ + uint8_t protected; + /** The LUN status (Ejected/Changed/) */ + uint8_t status; + + /** Data for the RequestSense command. */ + SBCRequestSenseData requestSenseData; + /** Data for the ReadCapacity command. */ + SBCReadCapacity10Data readCapacityData; + +} MSDLun; + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ +extern void LUN_Init(MSDLun *lun, + Media *media, + uint8_t *ioBuffer, + uint32_t ioBufferSize, + uint32_t baseAddress, + uint32_t size, + uint16_t blockSize, + uint8_t protected, + void (*dataMonitor)(uint8_t flowDirection, + uint32_t dataLength, + uint32_t fifoNullCount, + uint32_t fifoFullCount)); + +extern uint32_t LUN_Eject(MSDLun *lun); + +extern uint32_t LUN_Write(MSDLun *lun, + uint32_t blockAddress, + void *data, + uint32_t length, + TransferCallback callback, + void *argument); + +extern uint32_t LUN_Read(MSDLun *lun, + uint32_t blockAddress, + void *data, + uint32_t length, + TransferCallback callback, + void *argument); + +/**@}*/ + +#endif /*#ifndef MSDLUN_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/MSDescriptors.h b/sam3s_example/atmel_softpack_libraries/usb/include/MSDescriptors.h new file mode 100644 index 00000000..c5bcc290 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/MSDescriptors.h @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * + * \section ms_dev_desc Device Descriptors + * + * Declaration of constants for using Device Descriptors with a Mass Storage + * driver. + * + * - For a USB device: + * -# When declaring a USBDeviceDescriptor instance, use the Mass Storage + * codes defined in this file (see "MS device codes"). + * + * \section ms_if_desc Interface Descriptors + * + * Definition of several constants used when manipulating Mass Storage interface + * descriptors. + * + * - For a USB device: + * -# When declaring an interface descriptor for a Mass Storage device, use + * the class, subclass and protocol codes defined here (see + * "MS interface codes"). + */ + +#ifndef _MSDESCRIPTORS_H_ +#define _MSDESCRIPTORS_H_ +/**\addtogroup usb_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_ms_device_codes MS device codes + * @{ + * This page lists the class, subclass & protocol codes used by a device with + * a Mass Storage driver. + * + * \section Codes + * + * - MSDeviceDescriptor_CLASS + * - MSDeviceDescriptor_SUBCLASS + * - MSDeviceDescriptor_PROTOCOL + */ + +/** Class code for a Mass Storage device. */ +#define MSDeviceDescriptor_CLASS 0 + +/** Subclass code for a Mass Storage device. */ +#define MSDeviceDescriptor_SUBCLASS 0 + +/** Protocol code for a Mass Storage device. */ +#define MSDeviceDescriptor_PROTOCOL 0 +/** @}*/ + + +/** \addtogroup usb_ms_interface_code MS interface codes + * @{ + * This page lists the available class, subclass & protocol codes for a Mass + * Storage interface. + * + * \section Codes + * + * - MSInterfaceDescriptor_CLASS + * - MSInterfaceDescriptor_SCSI + * - MSInterfaceDescriptor_BULKONLY + */ + +/** Class code for a Mass Storage interface. */ +#define MSInterfaceDescriptor_CLASS 0x08 + +/** Subclass code for a Mass Storage interface using the SCSI protocol. */ +#define MSInterfaceDescriptor_SCSI 0x06 + +/** Protocol code for a Mass Storage interface using Bulk-Only Transport. */ +#define MSInterfaceDescriptor_BULKONLY 0x50 +/** @}*/ + +/**@}*/ +#endif /* #ifndef _MSDESCRIPTORS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/SBC.h b/sam3s_example/atmel_softpack_libraries/usb/include/SBC.h new file mode 100644 index 00000000..163c9a84 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/SBC.h @@ -0,0 +1,678 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * SCSI definitions. + * + * \section Usage + * + * -# After command block received, Access and decode the SCSI command block + * with SBCCommand structure. + */ + +#ifndef SBC_H +#define SBC_H + +/** \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_sbc_operation_codes SBC Operation Codes + * @{ + * This page lists operation codes of commands described in the SBC-3 + * standard. + * + * \note That most commands are actually defined in other standards, + * like SPC-4. Optional commands are not included here. + * + * \see sbc3r07.pdf - Section 5.1 - Table 12 + * \see spc4r06.pdf + * \see SBCCommand + * + * \section Codes + * - SBC_INQUIRY + * - SBC_READ_10 + * - SBC_READ_CAPACITY_10 + * - SBC_REQUEST_SENSE + * - SBC_TEST_UNIT_READY + * - SBC_WRITE_10 + * + * \section Optional Codes but required by Windows + * - SBC_PREVENT_ALLOW_MEDIUM_REMOVAL + * - SBC_MODE_SENSE_6 + * - SBC_VERIFY_10 + * - SBC_READ_FORMAT_CAPACITIES + */ + +/** Request information regarding parameters of the target and Logical Unit. */ +#define SBC_INQUIRY 0x12 +/** Request the transfer data to the host. */ +#define SBC_READ_10 0x28 +/** Request capacities of the currently installed medium. */ +#define SBC_READ_CAPACITY_10 0x25 +/** Request that the device server transfer sense data. */ +#define SBC_REQUEST_SENSE 0x03 +/** Check if the LUN is ready */ +#define SBC_TEST_UNIT_READY 0x00 +/** Request that the device write the data transferred by the host. */ +#define SBC_WRITE_10 0x2A + +/** Request that the target enable or disable the removal of the medium in */ +/** the Logical Unit. */ +#define SBC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E +/** Report parameters. */ +#define SBC_MODE_SENSE_6 0x1A +/** Request that the %device verify the data on the medium. */ +#define SBC_VERIFY_10 0x2F +/** Request a list of the possible capacities that can be formatted on medium */ +#define SBC_READ_FORMAT_CAPACITIES 0x23 +/** @}*/ + +/** \addtogroup usbd_sbc_periph_quali SBC Periph. Qualifiers + * @{ + * This page lists the peripheral qualifier values specified in the INQUIRY + * data + * \see spc4r06.pdf - Section 6.4.2 - Table 83 + * \see SBCInquiryData + * + * \section Qualifiers + * - SBC_PERIPHERAL_DEVICE_CONNECTED + * - SBC_PERIPHERAL_DEVICE_NOT_CONNECTED + * - SBC_PERIPHERAL_DEVICE_NOT_SUPPORTED + */ + +#define SBC_PERIPHERAL_DEVICE_CONNECTED 0x00 +#define SBC_PERIPHERAL_DEVICE_NOT_CONNECTED 0x01 +#define SBC_PERIPHERAL_DEVICE_NOT_SUPPORTED 0x03 +/** @}*/ + +/** \addtogroup usbd_sbc_periph_types SBC Periph. Types + * @{ + * This page lists peripheral device types specified in the INQUIRY data + * \see spc4r06.pdf - Section 6.4.2 - Table 84 + * \see SBCInquiryData + * + * \section Types + * - SBC_DIRECT_ACCESS_BLOCK_DEVICE + * - SBC_SEQUENTIAL_ACCESS_DEVICE + * - SBC_PRINTER_DEVICE + * - SBC_PROCESSOR_DEVICE + * - SBC_WRITE_ONCE_DEVICE + * - SBC_CD_DVD_DEVICE + * - SBC_SCANNER_DEVICE + * - SBC_OPTICAL_MEMORY_DEVICE + * - SBC_MEDIA_CHANGER_DEVICE + * - SBC_COMMUNICATION_DEVICE + * - SBC_STORAGE_ARRAY_CONTROLLER_DEVICE + * - SBC_ENCLOSURE_SERVICES_DEVICE + * - SBC_SIMPLIFIED_DIRECT_ACCESS_DEVICE + * - SBC_OPTICAL_CARD_READER_WRITER_DEVICE + * - SBC_BRIDGE_CONTROLLER_COMMANDS + * - SBC_OBJECT_BASED_STORAGE_DEVICE + */ + +#define SBC_DIRECT_ACCESS_BLOCK_DEVICE 0x00 +#define SBC_SEQUENTIAL_ACCESS_DEVICE 0x01 +#define SBC_PRINTER_DEVICE 0x02 +#define SBC_PROCESSOR_DEVICE 0x03 +#define SBC_WRITE_ONCE_DEVICE 0x04 +#define SBC_CD_DVD_DEVICE 0x05 +#define SBC_SCANNER_DEVICE 0x06 +#define SBC_OPTICAL_MEMORY_DEVICE 0x07 +#define SBC_MEDIA_CHANGER_DEVICE 0x08 +#define SBC_COMMUNICATION_DEVICE 0x09 +#define SBC_STORAGE_ARRAY_CONTROLLER_DEVICE 0x0C +#define SBC_ENCLOSURE_SERVICES_DEVICE 0x0D +#define SBC_SIMPLIFIED_DIRECT_ACCESS_DEVICE 0x0E +#define SBC_OPTICAL_CARD_READER_WRITER_DEVICE 0x0F +#define SBC_BRIDGE_CONTROLLER_COMMANDS 0x10 +#define SBC_OBJECT_BASED_STORAGE_DEVICE 0x11 +/** @}*/ + +/*------------------------------------------------------------------------------ */ +/** \brief Version value for the SBC-3 specification */ +/** \see spc4r06.pdf - Section 6.4.2 - Table 85 */ +#define SBC_SPC_VERSION_4 0x06 +/*------------------------------------------------------------------------------ */ + +/*------------------------------------------------------------------------------ */ +/** \brief Values for the TPGS field returned in INQUIRY data */ +/** \see spc4r06.pdf - Section 6.4.2 - Table 86 */ +#define SBC_TPGS_NONE 0x0 +#define SBC_TPGS_ASYMMETRIC 0x1 +#define SBC_TPGS_SYMMETRIC 0x2 +#define SBC_TPGS_BOTH 0x3 +/*------------------------------------------------------------------------------ */ + +/*------------------------------------------------------------------------------ */ +/** \brief Version descriptor value for the SBC-3 specification */ +/** \see spc4r06.pdf - Section 6.4.2 - Table 87 */ +#define SBC_VERSION_DESCRIPTOR_SBC_3 0x04C0 +/*------------------------------------------------------------------------------ */ + +/** \addtogroup usbd_sbc_secse_codes SBC Sense Response Codes + * @{ + * This page lists sense data response codes returned in REQUEST SENSE data + * \see spc4r06.pdf - Section 4.5.1 - Table 12 + * + * \section Codes + * - SBC_SENSE_DATA_FIXED_CURRENT + * - SBC_SENSE_DATA_FIXED_DEFERRED + * - SBC_SENSE_DATA_DESCRIPTOR_CURRENT + * - SBC_SENSE_DATA_DESCRIPTOR_DEFERRED + */ + +#define SBC_SENSE_DATA_FIXED_CURRENT 0x70 +#define SBC_SENSE_DATA_FIXED_DEFERRED 0x71 +#define SBC_SENSE_DATA_DESCRIPTOR_CURRENT 0x72 +#define SBC_SENSE_DATA_DESCRIPTOR_DEFERRED 0x73 +/** @}*/ + +/** \addtogroup usbd_sbc_sense_keys SBC Sense Keys + * @{ + * This page lists sense key values returned in the REQUEST SENSE data + * \see spc4r06.pdf - Section 4.5.6 - Table 27 + * + * \section Keys + * - SBC_SENSE_KEY_NO_SENSE + * - SBC_SENSE_KEY_RECOVERED_ERROR + * - SBC_SENSE_KEY_NOT_READY + * - SBC_SENSE_KEY_MEDIUM_ERROR + * - SBC_SENSE_KEY_HARDWARE_ERROR + * - SBC_SENSE_KEY_ILLEGAL_REQUEST + * - SBC_SENSE_KEY_UNIT_ATTENTION + * - SBC_SENSE_KEY_DATA_PROTECT + * - SBC_SENSE_KEY_BLANK_CHECK + * - SBC_SENSE_KEY_VENDOR_SPECIFIC + * - SBC_SENSE_KEY_COPY_ABORTED + * - SBC_SENSE_KEY_ABORTED_COMMAND + * - SBC_SENSE_KEY_VOLUME_OVERFLOW + * - SBC_SENSE_KEY_MISCOMPARE + */ + +/** No specific sense key. Successful command. */ +#define SBC_SENSE_KEY_NO_SENSE 0x00 +/** Command completed succesfully with some recovery action by the %device. */ +#define SBC_SENSE_KEY_RECOVERED_ERROR 0x01 +/** The device can not be accessed. */ +#define SBC_SENSE_KEY_NOT_READY 0x02 +/** Command terminated with a error condition that was probably caused by a */ +/** flaw in the medium or an error in the recorded data. */ +#define SBC_SENSE_KEY_MEDIUM_ERROR 0x03 +/** Hardware failure while performing the command or during a self test. */ +#define SBC_SENSE_KEY_HARDWARE_ERROR 0x04 +/** Illegal parameter found in the command or additional parameters. */ +#define SBC_SENSE_KEY_ILLEGAL_REQUEST 0x05 +/** Removable medium may have been changed or the %device has been reset. */ +#define SBC_SENSE_KEY_UNIT_ATTENTION 0x06 +/** Write on a block that is protected. */ +#define SBC_SENSE_KEY_DATA_PROTECT 0x07 +/** Indicates that a write-once device or a sequential-access device */ +/** encountered blank medium or format-defined end-of-data indication while */ +/** reading or a write-once device encountered a non-blank medium while writing. */ +#define SBC_SENSE_KEY_BLANK_CHECK 0x08 +/** Reporting vendor specific conditions. */ +#define SBC_SENSE_KEY_VENDOR_SPECIFIC 0x09 +/** EXTENDED COPY command was aborted. */ +#define SBC_SENSE_KEY_COPY_ABORTED 0x0A +/** Device aborted the command. */ +#define SBC_SENSE_KEY_ABORTED_COMMAND 0x0B +/** A buffered peripheral device is overflow. */ +#define SBC_SENSE_KEY_VOLUME_OVERFLOW 0x0D +/** The source data did not match the data read from the medium. */ +#define SBC_SENSE_KEY_MISCOMPARE 0x0E +/** @}*/ + +/** \addtogroup usbd_sbc_sense_additionals SBC Sense Additionals + * @{ + * This page lists additional sense code values returned in REQUEST SENSE data + * \see spc4r06.pdf - Section 4.5.6 - Table 28 + * + * \section Additional Codes + * - SBC_ASC_LOGICAL_UNIT_NOT_READY + * - SBC_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE + * - SBC_ASC_INVALID_FIELD_IN_CDB + * - SBC_ASC_WRITE_PROTECTED + * - SBC_ASC_FORMAT_CORRUPTED + * - SBC_ASC_INVALID_COMMAND_OPERATION_CODE + * - SBC_ASC_TOO_MUCH_WRITE_DATA + * - SBC_ASC_NOT_READY_TO_READY_CHANGE + * - SBC_ASC_MEDIUM_NOT_PRESENT + */ + +#define SBC_ASC_LOGICAL_UNIT_NOT_READY 0x04 +#define SBC_ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 +#define SBC_ASC_INVALID_FIELD_IN_CDB 0x24 +#define SBC_ASC_WRITE_PROTECTED 0x27 +#define SBC_ASC_FORMAT_CORRUPTED 0x31 +#define SBC_ASC_INVALID_COMMAND_OPERATION_CODE 0x20 +#define SBC_ASC_TOO_MUCH_WRITE_DATA 0x26 +#define SBC_ASC_NOT_READY_TO_READY_CHANGE 0x28 +#define SBC_ASC_MEDIUM_NOT_PRESENT 0x3A +/** @}*/ + +/*------------------------------------------------------------------------------ */ +/** \brief MEDIUM TYPE field value for direct-access block devices */ +/** \see sbc3r06.pdf - Section 6.3.1 */ +#define SBC_MEDIUM_TYPE_DIRECT_ACCESS_BLOCK_DEVICE 0x00 +/*------------------------------------------------------------------------------ */ + +/*------------------------------------------------------------------------------ */ +/** \brief MRIE field values */ +/** \see sbc3r06.pdf - Section 7.4.11 - Table 286 */ +#define SBC_MRIE_NO_REPORTING 0x00 +#define SBC_MRIE_ASYNCHRONOUS 0x01 +#define SBC_MRIE_GENERATE_UNIT_ATTENTION 0x02 +#define SBC_MRIE_COND_GENERATE_RECOVERED_ERROR 0x03 +#define SBC_MRIE_UNCOND_GENERATE_RECOVERED_ERROR 0x04 +#define SBC_MRIE_GENERATE_NO_SENSE 0x05 +#define SBC_MRIE_ON_REQUEST 0x06 +/*------------------------------------------------------------------------------ */ + +/*------------------------------------------------------------------------------ */ +/** \brief Supported mode pages */ +/** \see sbc3r06.pdf - Section 6.3.1 - Table 115 */ +#define SBC_PAGE_READ_WRITE_ERROR_RECOVERY 0x01 +#define SBC_PAGE_INFORMATIONAL_EXCEPTIONS_CONTROL 0x1C +#define SBC_PAGE_RETURN_ALL 0x3F +#define SBC_PAGE_VENDOR_SPECIFIC 0x00 +/*------------------------------------------------------------------------------ */ + +/** \addtogroup usbd_msd_endian_macros MSD Endian Macros + * @{ + * This page lists the macros for endianness conversion. + * + * \section Macros + * - WORDB + * - DWORDB + * - STORE_DWORDB + * - STORE_WORDB + */ + + /** \brief Converts a byte array to a word value using the big endian format */ +#define WORDB(bytes) ((unsigned short) ((bytes[0] << 8) | bytes[1])) + +/** \brief Converts a byte array to a dword value using the big endian format */ +#define DWORDB(bytes) ((unsigned int) ((bytes[0] << 24) | (bytes[1] << 16) \ + | (bytes[2] << 8) | bytes[3])) + +/** \brief Stores a dword value in a byte array, in big endian format */ +#define STORE_DWORDB(dword, bytes) \ + bytes[0] = (unsigned char) (((dword) >> 24) & 0xFF); \ + bytes[1] = (unsigned char) (((dword) >> 16) & 0xFF); \ + bytes[2] = (unsigned char) (((dword) >> 8) & 0xFF); \ + bytes[3] = (unsigned char) ((dword) & 0xFF); + +/** \brief Stores a word value in a byte array, in big endian format */ +#define STORE_WORDB(word, bytes) \ + bytes[0] = (unsigned char) (((word) >> 8) & 0xFF); \ + bytes[1] = (unsigned char) ((word) & 0xFF); +/** @}*/ + +/*------------------------------------------------------------------------------ + * Structures + *------------------------------------------------------------------------------*/ + +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * \typedef SBCInquiry + * \brief Structure for the INQUIRY command + * \see spc4r06.pdf - Section 6.4.1 - Table 81 + */ +typedef struct _SBCInquiry { + + unsigned char bOperationCode; /*!< 0x12 : SBC_INQUIRY */ + unsigned char isEVPD:1, /*!< Type of requested data */ + bReserved1:7; /*!< Reserved bits */ + unsigned char bPageCode; /*!< Specifies the VPD to return */ + unsigned char pAllocationLength[2]; /*!< Size of host buffer */ + unsigned char bControl; /*!< 0x00 */ + +} __attribute__ ((packed)) SBCInquiry; /* GCC */ + +/** + * \typedef SBCInquiryData + * \brief Standard INQUIRY data format returned by the device + * \see spc4r06.pdf - Section 6.4.2 - Table 82 + */ +typedef struct _SBCInquiryData { + + unsigned char bPeripheralDeviceType:5, /*!< Peripheral device type */ + bPeripheralQualifier :3; /*!< Peripheral qualifier */ + unsigned char bReserved1:7, /*!< Reserved bits */ + isRMB :1; /*!< Is media removable ? */ + unsigned char bVersion; /*!< SPC version used */ + unsigned char bResponseDataFormat:4, /*!< Must be 0x2 */ + isHIGHSUP :1, /*!< Hierarchical addressing used ? */ + isNORMACA :1, /*!< ACA attribute supported ? */ + bObsolete1 :2; /*!< Obsolete bits */ + unsigned char bAdditionalLength; /*!< Length of remaining INQUIRY data */ + unsigned char isSCCS :1, /*!< Embedded SCC ? */ + isACC :1, /*!< Access control coordinator ? */ + bTPGS :2, /*!< Target port support group */ + is3PC :1, /*!< Third-party copy supported ? */ + bReserved2:2, /*!< Reserved bits */ + isProtect :1; /*!< Protection info supported ? */ + unsigned char bObsolete2:1, /*!< Obsolete bit */ + isEncServ :1, /*!< Embedded enclosure service comp? */ + isVS :1, /*!< ??? */ + isMultiP :1, /*!< Multi-port device ? */ + bObsolete3:3, /*!< Obsolete bits */ + bUnused1 :1; /*!< Unused feature */ + unsigned char bUnused2:6, /*!< Unused features */ + isCmdQue:1, /*!< Task management model supported ? */ + isVS2 :1; /*!< ??? */ + unsigned char pVendorID[8]; /*!< T10 vendor identification */ + unsigned char pProductID[16]; /*!< Vendor-defined product ID */ + unsigned char pProductRevisionLevel[4];/*!< Vendor-defined product revision */ + unsigned char pVendorSpecific[20]; /*!< Vendor-specific data */ + unsigned char bUnused3; /*!< Unused features */ + unsigned char bReserved3; /*!< Reserved bits */ + unsigned short pVersionDescriptors[8]; /*!< Standards the device complies to */ + unsigned char pReserved4[22]; /*!< Reserved bytes */ + +} __attribute__ ((packed)) SBCInquiryData; /* GCC */ + +/** + * \typedef SBCRead10 + * \brief Data structure for the READ (10) command + * \see sbc3r07.pdf - Section 5.7 - Table 34 + */ +typedef struct _SBCRead10 { + + unsigned char bOperationCode; /*!< 0x28 : SBC_READ_10 */ + unsigned char bObsolete1:1, /*!< Obsolete bit */ + isFUA_NV:1, /*!< Cache control bit */ + bReserved1:1, /*!< Reserved bit */ + isFUA:1, /*!< Cache control bit */ + isDPO:1, /*!< Cache control bit */ + bRdProtect:3; /*!< Protection information to send */ + unsigned char pLogicalBlockAddress[4]; /*!< Index of first block to read */ + unsigned char bGroupNumber:5, /*!< Information grouping */ + bReserved2:3; /*!< Reserved bits */ + unsigned char pTransferLength[2]; /*!< Number of blocks to transmit */ + unsigned char bControl; /*!< 0x00 */ + +} __attribute__ ((packed)) SBCRead10; /* GCC */ + +/** + * \typedef SBCReadCapacity10 + * \brief Structure for the READ CAPACITY (10) command + * \see sbc3r07.pdf - Section 5.11.1 - Table 40 + */ +typedef struct _SBCReadCapacity10 { + + unsigned char bOperationCode; /*!< 0x25 : RBC_READ_CAPACITY */ + unsigned char bObsolete1:1, /*!< Obsolete bit */ + bReserved1:7; /*!< Reserved bits */ + unsigned char pLogicalBlockAddress[4]; /*!< Block to evaluate if PMI is set */ + unsigned char pReserved2[2]; /*!< Reserved bytes */ + unsigned char isPMI:1, /*!< Partial medium indicator bit */ + bReserved3:7; /*!< Reserved bits */ + unsigned char bControl; /*!< 0x00 */ + +} SBCReadCapacity10; + +/*------------------------------------------------------------------------------ + * \brief Data returned by the device after a READ CAPACITY (10) command + * \see sbc3r07.pdf - Section 5.11.2 - Table 41 + *------------------------------------------------------------------------------*/ +typedef struct { + + unsigned char pLogicalBlockAddress[4]; /*!< Address of last logical block */ + unsigned char pLogicalBlockLength[4]; /*!< Length of each logical block */ + +} SBCReadCapacity10Data; + +/*------------------------------------------------------------------------------ + * \brief Structure for the REQUEST SENSE command + * \see spc4r06.pdf - Section 6.26 - Table 170 + *------------------------------------------------------------------------------*/ +typedef struct { + + unsigned char bOperationCode; /*!< 0x03 : SBC_REQUEST_SENSE */ + unsigned char isDesc :1, /*!< Type of information expected */ + bReserved1:7; /*!< Reserved bits */ + unsigned char pReserved2[2]; /*!< Reserved bytes */ + unsigned char bAllocationLength; /*!< Size of host buffer */ + unsigned char bControl; /*!< 0x00 */ + +} SBCRequestSense; + +/*------------------------------------------------------------------------------ + * \brief Fixed format sense data returned after a REQUEST SENSE command has + * been received with a DESC bit cleared. + * \see spc4r06.pdf - Section 4.5.3 - Table 26 + *------------------------------------------------------------------------------*/ +typedef struct { + + unsigned char bResponseCode:7, /*!< Sense data format */ + isValid :1; /*!< Information field is standard */ + unsigned char bObsolete1; /*!< Obsolete byte */ + unsigned char bSenseKey :4, /*!< Generic error information */ + bReserved1:1, /*!< Reserved bit */ + isILI :1, /*!< SSC */ + isEOM :1, /*!< SSC */ + isFilemark:1; /*!< SSC */ + unsigned char pInformation[4]; /*!< Command-specific */ + unsigned char bAdditionalSenseLength; /*!< sizeof(SBCRequestSense_data)-8 */ + unsigned char pCommandSpecificInformation[4]; /*!< Command-specific */ + unsigned char bAdditionalSenseCode; /*!< Additional error information */ + unsigned char bAdditionalSenseCodeQualifier; /*!< Further error information */ + unsigned char bFieldReplaceableUnitCode; /*!< Specific component code */ + unsigned char bSenseKeySpecific:7, /*!< Additional exception info */ + isSKSV :1; /*!< Is sense key specific valid? */ + unsigned char pSenseKeySpecific[2]; /*!< Additional exception info */ + +} SBCRequestSenseData; + +/** + * \brief SBCTestUnitReady + * Data structure for the TEST UNIT READY command + * \see spc4r06.pdf - Section 6.34 - Table 192 + */ +typedef struct _SBCTestUnitReady { + + unsigned char bOperationCode; /*!< 0x00 : SBC_TEST_UNIT_READY */ + unsigned char pReserved1[4]; /*!< Reserved bits */ + unsigned char bControl; /*!< 0x00 */ + +} __attribute__ ((packed)) SBCTestUnitReady; /* GCC */ + +/** + * \typedef SBCWrite10 + * \brief Structure for the WRITE (10) command + * \see sbc3r07.pdf - Section 5.26 - Table 70 + */ +typedef struct _SBCWrite10 { + + unsigned char bOperationCode; /*!< 0x2A : SBC_WRITE_10 */ + unsigned char bObsolete1:1, /*!< Obsolete bit */ + isFUA_NV:1, /*!< Cache control bit */ + bReserved1:1, /*!< Reserved bit */ + isFUA:1, /*!< Cache control bit */ + isDPO:1, /*!< Cache control bit */ + bWrProtect:3; /*!< Protection information to send */ + unsigned char pLogicalBlockAddress[4]; /*!< First block to write */ + unsigned char bGroupNumber:5, /*!< Information grouping */ + bReserved2:3; /*!< Reserved bits */ + unsigned char pTransferLength[2]; /*!< Number of blocks to write */ + unsigned char bControl; /*!< 0x00 */ + +} SBCWrite10; + +/** + * \typedef SBCMediumRemoval + * \brief Structure for the PREVENT/ALLOW MEDIUM REMOVAL command + * \see sbc3r07.pdf - Section 5.5 - Table 30 + */ +typedef struct _SBCMediumRemoval { + + unsigned char bOperationCode; /*!< 0x1E : SBC_PREVENT_ALLOW_MEDIUM_REMOVAL */ + unsigned char pReserved1[3]; /*!< Reserved bytes */ + unsigned char bPrevent:2, /*!< Accept/prohibit removal */ + bReserved2:6; /*!< Reserved bits */ + unsigned char bControl; /*!< 0x00 */ + +} __attribute__ ((packed)) SBCMediumRemoval; /* GCC */ + +/** + * \typedef SBCModeSense6 + * \brief Structure for the MODE SENSE (6) command + * \see spc4r06 - Section 6.9.1 - Table 98 + */ +typedef struct _SBCModeSense6 { + + unsigned char bOperationCode; /*!< 0x1A : SBC_MODE_SENSE_6 */ + unsigned char bReserved1:3, /*!< Reserved bits */ + isDBD:1, /*!< Disable block descriptors bit */ + bReserved2:4; /*!< Reserved bits */ + unsigned char bPageCode:6, /*!< Mode page to return */ + bPC:2; /*!< Type of parameter values to return */ + unsigned char bSubpageCode; /*!< Mode subpage to return */ + unsigned char bAllocationLength; /*!< Host buffer allocated size */ + unsigned char bControl; /*!< 0x00 */ + +} __attribute__ ((packed)) SBCModeSense6; /* GCC */ + +/** + * \typedef SBCModeParameterHeader6 + * \brief Header for the data returned after a MODE SENSE (6) command + * \see spc4r06.pdf - Section 7.4.3 - Table 268 + */ +typedef struct _SBCModeParameterHeader6 { + + unsigned char bModeDataLength; /*!< Length of mode data to follow */ + unsigned char bMediumType; /*!< Type of medium (SBC_MEDIUM_TYPE_DIRECT_ACCESS_BLOCK_DEVICE) */ + unsigned char bReserved1:4, /*!< Reserved bits */ + isDPOFUA:1, /*!< DPO/FUA bits supported ? */ + bReserved2:2, /*!< Reserved bits */ + isWP:1; /*!< Is medium write-protected ? */ + unsigned char bBlockDescriptorLength; /*!< Length of all block descriptors */ + +} __attribute__ ((packed)) SBCModeParameterHeader6; /* GCC */ + +/** + * \typedef SBCInformationalExceptionsControl + * \brief Informational exceptions control mode page + * \see spc4r06.pdf - Section 7.4.11 - Table 285 + */ +typedef struct _SBCInformationalExceptionsControl { + + unsigned char bPageCode:6, /*!< 0x1C : SBC_PAGE_INFORMATIONAL_EXCEPTIONS_CONTROL */ + isSPF:1, /*!< Page or subpage data format */ + isPS:1; /*!< Parameters saveable ? */ + unsigned char bPageLength; /*!< Length of page data (0x0A) */ + unsigned char isLogErr:1, /*!< Should informational exceptions be logged ? */ + isEBackErr:1, /*!< Enable background error bit */ + isTest:1, /*!< Create a device test failure ? */ + isDExcpt:1, /*!< Disable exception control bit */ + isEWasc:1, /*!< Report warnings ? */ + isEBF:1, /*!< Enable background function bit */ + bReserved1:1, /*!< Reserved bit */ + isPerf:1; /*!< Delay acceptable when treating exceptions ? */ + unsigned char bMRIE:4, /*!< Method of reporting informational exceptions */ + bReserved2:4; /*!< Reserved bits */ + unsigned char pIntervalTimer[4]; /*!< Error reporting period */ + unsigned char pReportCount[4]; /*!< Maximum number of time a report can be issued */ + +} __attribute__ ((packed)) SBCInformationalExceptionsControl; /* GCC */ + +/** + * \typedef SBCReadWriteErrorRecovery + * \brief Read/write error recovery mode page + * \see sbc3r07.pdf - Section 6.3.5 - Table 122 + */ +typedef struct _SBCReadWriteErrorRecovery { + + unsigned char bPageCode:6, /*!< 0x01 : SBC_PAGE_READ_WRITE_ERROR_RECOVERY */ + isSPF:1, /*!< Page or subpage data format */ + isPS:1; /*!< Parameters saveable ? */ + unsigned char bPageLength; /*!< Length of page data (0x0A) */ + unsigned char isDCR:1, /*!< Disable correction bit */ + isDTE:1, /*!< Data terminate on error bit */ + isPER:1, /*!< Post error bit */ + isEER:1, /*!< Enable early recovery bit */ + isRC:1, /*!< Read continuous bit */ + isTB:1, /*!< Transfer block bit */ + isARRE:1, /*!< Automatic read reallocation enabled bit */ + isAWRE:1; /*!< Automatic write reallocation enabled bit */ + unsigned char bReadRetryCount; /*!< Number of retries when reading */ + unsigned char pObsolete1[3]; /*!< Obsolete bytes */ + unsigned char bReserved1; /*!< Reserved byte */ + unsigned char bWriteRetryCount; /*!< Number of retries when writing */ + unsigned char bReserved2; /*!< Reserved byte */ + unsigned char pRecoveryTimeLimit[2]; /*!< Maximum time duration for error recovery */ + +} __attribute__ ((packed)) SBCReadWriteErrorRecovery; /* GCC */ + +/** + * \typedef SBCCommand + * \brief Generic structure for holding information about SBC commands + * \see SBCInquiry + * \see SBCRead10 + * \see SBCReadCapacity10 + * \see SBCRequestSense + * \see SBCTestUnitReady + * \see SBCWrite10 + * \see SBCMediumRemoval + * \see SBCModeSense6 + */ +typedef union _SBCCommand { + + unsigned char bOperationCode; /*!< Operation code of the command */ + SBCInquiry inquiry; /*!< INQUIRY command */ + SBCRead10 read10; /*!< READ (10) command */ + SBCReadCapacity10 readCapacity10; /*!< READ CAPACITY (10) command */ + SBCRequestSense requestSense; /*!< REQUEST SENSE command */ + SBCTestUnitReady testUnitReady; /*!< TEST UNIT READY command */ + SBCWrite10 write10; /*!< WRITE (10) command */ + SBCMediumRemoval mediumRemoval; /*!< PREVENT/ALLOW MEDIUM REMOVAL command */ + SBCModeSense6 modeSense6; /*!< MODE SENSE (6) command */ + +} SBCCommand; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/**@}*/ + +#endif /*#ifndef SBC_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/SBCMethods.h b/sam3s_example/atmel_softpack_libraries/usb/include/SBCMethods.h new file mode 100644 index 00000000..3e78b4e3 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/SBCMethods.h @@ -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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * SCSI commands implementation. + * + * section Usage + * + * -# After a CBW is received from host, use SBC_GetCommandInformation to check + * if the command is supported, and get the command length and type + * information before processing it. + * -# Then SBC_ProcessCommand can be used to handle a valid command, to + * perform the command operations. + * -# SBC_UpdateSenseData is used to update the sense data that will be sent + * to host. + */ + +#ifndef SBCMETHODS_H +#define SBCMETHODS_H + +/** \addtogroup usbd_msd + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +#include "SBC.h" +#include "MSDLun.h" +#include "MSDDStateMachine.h" + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/** \addtogroup usbd_sbc_command_state SBC Command States + * @{ + * This page lists the possible states of a SBC command. + * + * \section States + * - SBC_STATE_READ + * - SBC_STATE_WAIT_READ + * - SBC_STATE_WRITE + * - SBC_STATE_WAIT_WRITE + * - SBC_STATE_NEXT_BLOCK + */ + +/** Start of reading bulk data */ +#define SBC_STATE_READ 0x01 +/** Waiting for the bulk data reading complete */ +#define SBC_STATE_WAIT_READ 0x02 +/** Read error state */ +#define SBC_STATE_READ_ERROR 0x03 +/** Start next read block */ +#define SBC_STATE_NEXT_READ 0x04 +/** Start writing bulk data to host */ +#define SBC_STATE_WRITE 0x05 +/** Waiting for the bulk data sending complete */ +#define SBC_STATE_WAIT_WRITE 0x06 +/** Write error state */ +#define SBC_STATE_WRITE_ERROR 0x07 +/** Start next write block */ +#define SBC_STATE_NEXT_WRITE 0x08 +/** Start next command block */ +#define SBC_STATE_NEXT_BLOCK 0x09 +/** @}*/ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +void SBC_UpdateSenseData(SBCRequestSenseData *requestSenseData, + unsigned char senseKey, + unsigned char additionalSenseCode, + unsigned char additionalSenseCodeQualifier); + +unsigned char SBC_GetCommandInformation(void *command, + unsigned int *length, + unsigned char *type, + MSDLun *lun); + +unsigned char SBC_ProcessCommand(MSDLun *lun, + MSDCommandState *commandState); + +/**@}*/ + +#endif /*#ifndef SBCMETHODS_H */ + + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/USBD.h b/sam3s_example/atmel_softpack_libraries/usb/include/USBD.h new file mode 100644 index 00000000..15a68595 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/USBD.h @@ -0,0 +1,276 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * Collection of methods for using the USB device controller on AT91 + * microcontrollers. + * + * \section Usage + * + * Please refer to the corresponding application note. + * - \ref usbd_framework AT91 USB device framework + * - \ref usbd_api USBD API + * + */ + +#ifndef USBD_H +#define USBD_H + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + + +#include "USBDescriptors.h" +#include "USBRequests.h" + +#include "USBLib_Types.h" + +#include + +/*------------------------------------------------------------------------------ + * Definitions + *------------------------------------------------------------------------------*/ + +/* Define attribute */ +#if defined ( __CC_ARM ) /* Keil µVision 4 */ + #define WEAK __attribute__ ((weak)) +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ + #define WEAK __weak +#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ + #define WEAK __attribute__ ((weak)) +#endif + +/* Define NO_INIT attribute */ +#if defined ( __CC_ARM ) + #define NO_INIT +#elif defined ( __ICCARM__ ) + #define NO_INIT __no_init +#elif defined ( __GNUC__ ) + #define NO_INIT +#endif + + +/** \addtogroup usbd_interface + *@{*/ + +/** + * \addtogroup usbd_rc USB device API return codes + * @{ + * This section lists the return codes for the USB device driver API + * - \ref USBD_STATUS_SUCCESS + * - \ref USBD_STATUS_LOCKED + * - \ref USBD_STATUS_ABORTED + * - \ref USBD_STATUS_RESET + */ + +/** Indicates the operation was successful. */ +#define USBD_STATUS_SUCCESS USBRC_SUCCESS +/** Endpoint/device is already busy. */ +#define USBD_STATUS_LOCKED USBRC_BUSY +/** Operation has been aborted (error or stall). */ +#define USBD_STATUS_ABORTED USBRC_ABORTED +/** Operation has been canceled (by user). */ +#define USBD_STATUS_CANCELED USBRC_CANCELED +/** Operation has been aborted because the device init/reset/un-configure. */ +#define USBD_STATUS_RESET USBRC_RESET +/** Part ot operation successfully done. */ +#define USBD_STATUS_PARTIAL_DONE USBRC_PARTIAL_DONE +/** Operation failed because parameter error */ +#define USBD_STATUS_INVALID_PARAMETER USBRC_PARAM_ERR +/** Operation failed because in unexpected state */ +#define USBD_STATUS_WRONG_STATE USBRC_STATE_ERR +/** Operation failed because SW not supported */ +#define USBD_STATUS_SW_NOT_SUPPORTED USBRC_SW_NOT_SUPPORTED +/** Operation failed because HW not supported */ +#define USBD_STATUS_HW_NOT_SUPPORTED USBRC_HW_NOT_SUPPORTED +/** @}*/ + +/** \addtogroup usbd_states USB device states + * @{ + * This section lists the device states of the USB device driver. + * - \ref USBD_STATE_SUSPENDED + * - \ref USBD_STATE_ATTACHED + * - \ref USBD_STATE_POWERED + * - \ref USBD_STATE_DEFAULT + * - \ref USBD_STATE_ADDRESS + * - \ref USBD_STATE_CONFIGURED + */ + +/** The device is currently suspended. */ +#define USBD_STATE_SUSPENDED 0 +/** USB cable is plugged into the device. */ +#define USBD_STATE_ATTACHED 1 +/** Host is providing +5V through the USB cable. */ +#define USBD_STATE_POWERED 2 +/** Device has been reset. */ +#define USBD_STATE_DEFAULT 3 +/** The device has been given an address on the bus. */ +#define USBD_STATE_ADDRESS 4 +/** A valid configuration has been selected. */ +#define USBD_STATE_CONFIGURED 5 +/** @}*/ + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +/** + * \brief Buffer struct used for multi-buffer-listed transfer. + * + * The driver can process 255 bytes of buffers or buffer list window. + */ +typedef struct _USBDTransferBuffer { + /** Pointer to frame buffer */ + uint8_t * pBuffer; + /** Size of the frame (up to 64K-1) */ + uint16_t size; + /** Bytes transferred */ + uint16_t transferred; + /** Bytes in FIFO */ + uint16_t buffered; + /** Bytes remaining */ + uint16_t remaining; +} USBDTransferBuffer; + +#ifdef __ICCARM__ /* IAR*/ +#define __attribute__(...) /* IAR*/ +#endif /* IAR*/ + +/** + * \brief Struct used for USBD DMA Link List Transfer Descriptor, must be 16-bytes + * aligned. + * + * (For USB, DMA transfer is linked to EPs and FIFO address is EP defined) + */ +typedef struct _USBDDmaDescriptor { + /** Pointer to Next Descriptor */ + void* pNxtDesc; + /** Pointer to data buffer address */ + void* pDataAddr; + /** DMA Control setting register value */ + uint32_t ctrlSettings:8, /** Control settings */ + reserved:8, /** Not used */ + bufferLength:16; /** Length of buffer */ + /** Loaded to DMA register, OK to modify */ + uint32_t used; +} __attribute__((aligned(16))) USBDDmaDescriptor; + +#ifdef __ICCARM__ /* IAR*/ +#pragma pack() /* IAR*/ +#endif /* IAR*/ + +/** + * Callback used by transfer functions (USBD_Read & USBD_Write) to notify + * that a transaction is complete. + */ +typedef void (*TransferCallback)(void *pArg, + uint8_t status, + uint32_t transferred, + uint32_t remaining); + +/** + * Callback used by MBL transfer functions (USBD_Read & USBD_Write) to notify + * that a transaction is complete. + * \param pArg Pointer to callback arguments. + * \param status USBD status. + */ +typedef void (*MblTransferCallback)(void *pArg, + uint8_t status); + +/**@}*/ + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +//extern void USBD_IrqHandler(void); + +extern void USBD_Init(void); + +extern void USBD_ConfigureSpeed(uint8_t forceFS); + +extern void USBD_Connect(void); + +extern void USBD_Disconnect(void); + +extern uint8_t USBD_Write( + uint8_t bEndpoint, + const void *pData, + uint32_t size, + TransferCallback callback, + void *pArg); + +extern uint8_t USBD_Read( + uint8_t bEndpoint, + void *pData, + uint32_t dLength, + TransferCallback fCallback, + void *pArg); + +extern uint8_t USBD_Stall(uint8_t bEndpoint); + +extern void USBD_Halt(uint8_t bEndpoint); + +extern void USBD_Unhalt(uint8_t bEndpoint); + +extern void USBD_ConfigureEndpoint(const USBEndpointDescriptor *pDescriptor); + +extern uint8_t USBD_IsHalted(uint8_t bEndpoint); + +extern void USBD_RemoteWakeUp(void); + +extern void USBD_SetAddress(uint8_t address); + +extern void USBD_SetConfiguration(uint8_t cfgnum); + +extern uint8_t USBD_GetState(void); + +extern uint8_t USBD_IsHighSpeed(void); + +extern void USBD_Test(uint8_t bIndex); + +extern void USBD_SuspendHandler(void); +extern void USBD_ResumeHandler(void); +extern void USBD_ResetHandler(void); +extern void USBD_RequestHandler(uint8_t bEndpoint, + const USBGenericRequest * pRequest); + +extern void USBDCallbacks_Initialized(void); +extern void USBDCallbacks_Reset(void); +extern void USBDCallbacks_Suspended(void); +extern void USBDCallbacks_Resumed(void); +extern void USBDCallbacks_RequestReceived(const USBGenericRequest *request); + +#endif /*#ifndef USBD_H*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/USBDDriver.h b/sam3s_example/atmel_softpack_libraries/usb/include/USBDDriver.h new file mode 100644 index 00000000..79ccb2d4 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/USBDDriver.h @@ -0,0 +1,148 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \section Purpose + * + * USB Device Driver class definition. + * + * \section Usage + * + * -# Instanciate a USBDDriver object and initialize it using + * USBDDriver_Initialize. + * -# When a USB SETUP request is received, forward it to the standard + * driver using USBDDriver_RequestHandler. + * -# Check the Remote Wakeup setting via USBDDriver_IsRemoteWakeUpEnabled. + */ + +#ifndef USBDDRIVER_H +#define USBDDRIVER_H + +/** \addtogroup usbd_interface + *@{ + */ + +/*------------------------------------------------------------------------------ + * Headers + *------------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 by working group + * ISO/IEC JTC1/SC22/WG14. + */ +#include +#include +#include + +#include +#include +#include + +/*------------------------------------------------------------------------------ + * Types + *------------------------------------------------------------------------------*/ + +/** + * \typedef USBDDriverDescriptors + * \brief List of all descriptors used by a USB device driver. Each descriptor + * can be provided in two versions: full-speed and high-speed. Devices + * which are not high-speed capable do not need to provided high-speed + * descriptors and the full-speed qualifier & other speed descriptors. + */ +typedef struct _USBDDriverDescriptors { + + /** Pointer to the full-speed device descriptor */ + const USBDeviceDescriptor *pFsDevice; + /** Pointer to the full-speed configuration descriptor */ + const USBConfigurationDescriptor *pFsConfiguration; + /** Pointer to the full-speed qualifier descriptor */ + const USBDeviceQualifierDescriptor *pFsQualifier; + /** Pointer to the full-speed other speed configuration descriptor */ + const USBConfigurationDescriptor *pFsOtherSpeed; + /** Pointer to the high-speed device descriptor */ + const USBDeviceDescriptor *pHsDevice; + /** Pointer to the high-speed configuration descriptor */ + const USBConfigurationDescriptor *pHsConfiguration; + /** Pointer to the high-speed qualifier descriptor */ + const USBDeviceQualifierDescriptor *pHsQualifier; + /** Pointer to the high-speed other speed configuration descriptor */ + const USBConfigurationDescriptor *pHsOtherSpeed; + /** Pointer to the list of string descriptors */ + const uint8_t **pStrings; + /** Number of string descriptors in list */ + uint8_t numStrings; + +} USBDDriverDescriptors; + +/** + * \typedef USBDDriver + * \brief USB device driver structure, holding a list of descriptors identifying + * the device as well as the driver current state. + */ +typedef struct _USBDDriver { + + /** List of descriptors used by the device. */ + const USBDDriverDescriptors *pDescriptors; + /** Current setting for each interface. */ + uint8_t *pInterfaces; + /** Current configuration number (0 -> device is not configured). */ + uint8_t cfgnum; + /** Indicates if remote wake up has been enabled by the host. */ + uint8_t isRemoteWakeUpEnabled; + /** Features supported by OTG */ + uint8_t otg_features_supported; +} USBDDriver; + +/*------------------------------------------------------------------------------ + * Exported functions + *------------------------------------------------------------------------------*/ + +extern USBDDriver *USBD_GetDriver(void); +extern void USBDDriver_Initialize( + USBDDriver *pDriver, + const USBDDriverDescriptors *pDescriptors, + uint8_t *pInterfaces); +extern USBConfigurationDescriptor* USBDDriver_GetCfgDescriptors( + USBDDriver * pDriver, + uint8_t cfgNum); +extern void USBDDriver_RequestHandler( + USBDDriver *pDriver, + const USBGenericRequest *pRequest); +extern uint8_t USBDDriver_IsRemoteWakeUpEnabled(const USBDDriver *pDriver); +extern uint8_t USBDDriver_returnOTGFeatures(const USBDDriver *pDriver); +extern void USBDDriver_clearOTGFeatures(USBDDriver *pDriver); + +extern void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum); +extern void USBDDriverCallbacks_InterfaceSettingChanged(uint8_t interface, uint8_t setting); + +/**@}*/ + +#endif /*#ifndef USBDDRIVER_H*/ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/USBD_HAL.h b/sam3s_example/atmel_softpack_libraries/usb/include/USBD_HAL.h new file mode 100644 index 00000000..76f6c403 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/USBD_HAL.h @@ -0,0 +1,107 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2009, 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 USBD_HAL_H +#define USBD_HAL_H + +/** + * \file + * + * This file defines functions for USB Device Hardware Access Level. + */ + +/** \addtogroup usbd_hal + *@{*/ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +/* Introduced in C99 by working group ISO/IEC JTC1/SC22/WG14. */ +#include +#include +#include + +#include "USBD.h" +#include +#include + +/*---------------------------------------------------------------------------- + * Consts + *----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Macros + *----------------------------------------------------------------------------*/ + +/** Get bitmap for an endpoint */ +#define bmEP(bEP) (1 << (bEP)) + +/*---------------------------------------------------------------------------- + * Types + *----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Exported functoins + *----------------------------------------------------------------------------*/ + +extern void USBD_HAL_Init(void); +extern void USBD_HAL_Connect(void); +extern void USBD_HAL_Disconnect(void); + +extern void USBD_HAL_RemoteWakeUp(void); +extern void USBD_HAL_SetConfiguration(uint8_t cfgnum); +extern void USBD_HAL_SetAddress(uint8_t address); +extern uint8_t USBD_HAL_IsHighSpeed(void); + +extern void USBD_HAL_Suspend(void); +extern void USBD_HAL_Activate(void); + +extern void USBD_HAL_ResetEPs(uint32_t bmEPs,uint8_t bStatus, uint8_t bKeepCfg); +extern void USBD_HAL_CancelIo(uint32_t bmEPs); +extern uint8_t USBD_HAL_ConfigureEP(const USBEndpointDescriptor * pDescriptor); + +extern uint8_t USBD_HAL_SetTransferCallback(uint8_t bEP, + TransferCallback fCallback, + void * pCbData); +extern uint8_t USBD_HAL_SetupMblTransfer(uint8_t bEndpoint, + USBDTransferBuffer * pMbList, + uint16_t mblSize, + uint16_t startOffset); +extern uint8_t USBD_HAL_Write(uint8_t bEndpoint, + const void * pData, + uint32_t dLength); +extern uint8_t USBD_HAL_Read(uint8_t bEndpoint, + void * pData, + uint32_t dLength); +extern uint8_t USBD_HAL_Stall(uint8_t bEP); +extern uint8_t USBD_HAL_Halt(uint8_t bEndpoint,uint8_t ctl); +/**@}*/ + +#endif // #define USBD_HAL_H diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/USBDescriptors.h b/sam3s_example/atmel_softpack_libraries/usb/include/USBDescriptors.h new file mode 100644 index 00000000..84b5ef69 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/USBDescriptors.h @@ -0,0 +1,552 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * Definitions and methods for USB descriptor structures described by the + * USB specification. + * + * \section Usage + * + */ + +#ifndef _USBDESCRIPTORS_H_ +#define _USBDESCRIPTORS_H_ +/** \addtogroup usb_general + * @{ + * \addtogroup usb_descriptor USB Descriptors + * @{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 by working group + * ISO/IEC JTC1/SC22/WG14. + */ +#include + +/*--------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +/*--------- Generic Descriptors --------*/ + +/** \addtogroup usb_desc_type USB Descriptor types + * @{ + * This section lists the codes of the usb descriptor types + * - \ref USBGenericDescriptor_DEVICE + * - \ref USBGenericDescriptor_CONFIGURATION + * - \ref USBGenericDescriptor_STRING + * - \ref USBGenericDescriptor_INTERFACE + * - \ref USBGenericDescriptor_ENDPOINT + * - \ref USBGenericDescriptor_DEVICEQUALIFIER + * - \ref USBGenericDescriptor_OTHERSPEEDCONFIGURATION + * - \ref USBGenericDescriptor_INTERFACEPOWER + * - \ref USBGenericDescriptor_OTG + * - \ref USBGenericDescriptor_DEBUG + * - \ref USBGenericDescriptor_INTERFACEASSOCIATION + */ +/** Device descriptor type. */ +#define USBGenericDescriptor_DEVICE 1 +/** Configuration descriptor type. */ +#define USBGenericDescriptor_CONFIGURATION 2 +/** String descriptor type. */ +#define USBGenericDescriptor_STRING 3 +/** Interface descriptor type. */ +#define USBGenericDescriptor_INTERFACE 4 +/** Endpoint descriptor type. */ +#define USBGenericDescriptor_ENDPOINT 5 +/** Device qualifier descriptor type. */ +#define USBGenericDescriptor_DEVICEQUALIFIER 6 +/** Other speed configuration descriptor type. */ +#define USBGenericDescriptor_OTHERSPEEDCONFIGURATION 7 +/** Interface power descriptor type. */ +#define USBGenericDescriptor_INTERFACEPOWER 8 +/** On-The-Go descriptor type. */ +#define USBGenericDescriptor_OTG 9 +/** Debug descriptor type. */ +#define USBGenericDescriptor_DEBUG 10 +/** Interface association descriptor type. */ +#define USBGenericDescriptor_INTERFACEASSOCIATION 11 +/** @}*/ + + +/*--------- Device Descriptors --------*/ + +/** \addtogroup usb_release_number USB release numbers + * @{ + * This section lists the codes of USB release numbers. + * - \ref USBDeviceDescriptor_USB2_00 + */ + +/** The device supports USB 2.00. */ +#define USBDeviceDescriptor_USB2_00 0x0200 +/** @}*/ + + +/*--------- Configuration Descriptors --------*/ + +/** \addtogroup usb_attributes USB Device Attributes + * @{ + * This section lists the codes of the usb attributes. + * - \ref USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP + * - \ref USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP + * - \ref USBConfigurationDescriptor_BUSPOWERED_RWAKEUP + * - \ref USBConfigurationDescriptor_SELFPOWERED_RWAKEUP + * - \ref USBConfigurationDescriptor_POWER + */ +/** Device is bus-powered and not support remote wake-up. */ +#define USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP 0x80 +/** Device is self-powered and not support remote wake-up. */ +#define USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP 0xC0 +/** Device is bus-powered and supports remote wake-up. */ +#define USBConfigurationDescriptor_BUSPOWERED_RWAKEUP 0xA0 +/** Device is self-powered and supports remote wake-up. */ +#define USBConfigurationDescriptor_SELFPOWERED_RWAKEUP 0xE0 +/** Calculates the value of the power consumption field given the value in mA. + * \param power The power consumption value in mA + * \return The value that should be set to the field in descriptor + */ +#define USBConfigurationDescriptor_POWER(power) (power / 2) +/** @}*/ + + +/*--------- Endpoint Descriptors --------*/ + +/** \addtogroup usb_ep_define USB Endpoint definitions + * @{ + * This section lists definitions and macro for endpoint descriptors. + * - \ref usb_ep_dir USB Endpoint directions + * - \ref USBEndpointDescriptor_OUT + * - \ref USBEndpointDescriptor_IN + * + * - \ref usb_ep_type USB Endpoint types + * - \ref USBEndpointDescriptor_CONTROL + * - \ref USBEndpointDescriptor_ISOCHRONOUS + * - \ref USBEndpointDescriptor_BULK + * - \ref USBEndpointDescriptor_INTERRUPT + * + * - \ref usb_ep_size USB Endpoint maximun sizes + * - \ref USBEndpointDescriptor_MAXCTRLSIZE_FS + * - \ref USBEndpointDescriptor_MAXCTRLSIZE_HS + * - \ref USBEndpointDescriptor_MAXBULKSIZE_FS + * - \ref USBEndpointDescriptor_MAXBULKSIZE_HS + * - \ref USBEndpointDescriptor_MAXINTERRUPTSIZE_FS + * - \ref USBEndpointDescriptor_MAXINTERRUPTSIZE_HS + * - \ref USBEndpointDescriptor_MAXISOCHRONOUSSIZE_FS + * - \ref USBEndpointDescriptor_MAXISOCHRONOUSSIZE_HS + * + * - \ref usb_ep_addr USB Endpoint address define + * - \ref USBEndpointDescriptor_ADDRESS + */ + +/** \addtogroup usb_ep_dir USB Endpoint directions + * @{ + * This section lists definitions of USB endpoint directions. + * - USBEndpointDescriptor_OUT + * - USBEndpointDescriptor_IN + */ +/** Endpoint receives data from the host. */ +#define USBEndpointDescriptor_OUT 0 +/** Endpoint sends data to the host. */ +#define USBEndpointDescriptor_IN 1 +/** @}*/ + +/** \addtogroup usb_ep_type USB Endpoint types + * @{ + * This section lists definitions of USB endpoint types. + * - \ref USBEndpointDescriptor_CONTROL + * - \ref USBEndpointDescriptor_ISOCHRONOUS + * - \ref USBEndpointDescriptor_BULK + * - \ref USBEndpointDescriptor_INTERRUPT + */ +/** Control endpoint type. */ +#define USBEndpointDescriptor_CONTROL 0 +/** Isochronous endpoint type. */ +#define USBEndpointDescriptor_ISOCHRONOUS 1 +/** Bulk endpoint type. */ +#define USBEndpointDescriptor_BULK 2 +/** Interrupt endpoint type. */ +#define USBEndpointDescriptor_INTERRUPT 3 +/** @}*/ + +/** \addtogroup usb_ep_size USB Endpoint maximun sizes + * @{ + * This section lists definitions of USB endpoint maximun sizes. + * - \ref USBEndpointDescriptor_MAXCTRLSIZE_FS + * - \ref USBEndpointDescriptor_MAXCTRLSIZE_HS + * - \ref USBEndpointDescriptor_MAXBULKSIZE_FS + * - \ref USBEndpointDescriptor_MAXBULKSIZE_HS + * - \ref USBEndpointDescriptor_MAXINTERRUPTSIZE_FS + * - \ref USBEndpointDescriptor_MAXINTERRUPTSIZE_HS + * - \ref USBEndpointDescriptor_MAXISOCHRONOUSSIZE_FS + * - \ref USBEndpointDescriptor_MAXISOCHRONOUSSIZE_HS + */ +/** Maximum size for a full-speed control endpoint. */ +#define USBEndpointDescriptor_MAXCTRLSIZE_FS 64 +/** Maximum size for a high-speed control endpoint. */ +#define USBEndpointDescriptor_MAXCTRLSIZE_HS 64 +/** Maximum size for a full-speed bulk endpoint. */ +#define USBEndpointDescriptor_MAXBULKSIZE_FS 64 +/** Maximum size for a high-speed bulk endpoint. */ +#define USBEndpointDescriptor_MAXBULKSIZE_HS 512 +/** Maximum size for a full-speed interrupt endpoint. */ +#define USBEndpointDescriptor_MAXINTERRUPTSIZE_FS 64 +/** Maximum size for a high-speed interrupt endpoint. */ +#define USBEndpointDescriptor_MAXINTERRUPTSIZE_HS 1024 +/** Maximum size for a full-speed isochronous endpoint. */ +#define USBEndpointDescriptor_MAXISOCHRONOUSSIZE_FS 1023 +/** Maximum size for a high-speed isochronous endpoint. */ +#define USBEndpointDescriptor_MAXISOCHRONOUSSIZE_HS 1024 +/** @}*/ + +/** \addtogroup usb_ep_addr USB Endpoint address define + * @{ + * This section lists macro for USB endpoint address definition. + * - \ref USBEndpointDescriptor_ADDRESS + */ +/** + * Calculates the address of an endpoint given its number and direction + * \param direction USB endpoint direction definition + * \param number USB endpoint number + * \return The value used to set the endpoint descriptor based on input number + * and direction + */ +#define USBEndpointDescriptor_ADDRESS(direction, number) \ + (((direction & 0x01) << 7) | (number & 0xF)) +/** @}*/ +/** @}*/ + + +/*--------- Generic Descriptors --------*/ + +/** \addtogroup usb_string_descriptor USB String Descriptor Definitions + * @{ + * This section lists the codes and macros for USB string descriptor definition. + * + * \par Language IDs + * - USBStringDescriptor_ENGLISH_US + * + * \par String Descriptor Length + * - USBStringDescriptor_LENGTH + * + * \par ASCII to UNICODE convertion + * - USBStringDescriptor_UNICODE + */ +/** Language ID for US english. */ +#define USBStringDescriptor_ENGLISH_US 0x09, 0x04 +/** + * Calculates the length of a string descriptor given the number of ascii + * characters/language IDs in it. + * \param length The ascii format string length. + * \return The actual data length in bytes. + */ +#define USBStringDescriptor_LENGTH(length) ((length) * 2 + 2) +/** + * Converts an ascii character to its unicode representation. + * \param ascii The ASCII character to convert + * \return A 2-byte-array for the UNICODE based on given ASCII + */ +#define USBStringDescriptor_UNICODE(ascii) (ascii), 0 +/** @}*/ + + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/* + * Function types + */ + +typedef uint32_t (*USBDescriptorParseFunction)(void *descriptor, void *parseArg); + + +/* + * Descriptor structs types + */ +#pragma pack(1) + +#if defined ( __CC_ARM ) /* Keil µVision 4 */ +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ +#define __attribute__(...) +#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ + +#endif + + + +/** + \typedef USBGenericDescriptor + \brief Holds the few fields shared by all USB descriptors. + */ +typedef struct _USBGenericDescriptor { + + /** Length of the descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type. */ + uint8_t bDescriptorType; + +} __attribute__ ((packed)) USBGenericDescriptor; /* GCC */ + +/** + * \typedef USBDeviceDescriptor + * \brief USB standard device descriptor structure. + */ +typedef struct _USBDeviceDescriptor { + + /** Size of this descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (USBGenericDescriptor_DEVICE). */ + uint8_t bDescriptorType; + /** USB specification release number in BCD format. */ + uint16_t bcdUSB; + /** Device class code. */ + uint8_t bDeviceClass; + /** Device subclass code. */ + uint8_t bDeviceSubClass; + /** Device protocol code. */ + uint8_t bDeviceProtocol; + /** Maximum packet size of endpoint 0 (in bytes). */ + uint8_t bMaxPacketSize0; + /** Vendor ID. */ + uint16_t idVendor; + /** Product ID. */ + uint16_t idProduct; + /** Device release number in BCD format. */ + uint16_t bcdDevice; + /** Index of the manufacturer string descriptor. */ + uint8_t iManufacturer; + /** Index of the product string descriptor. */ + uint8_t iProduct; + /** Index of the serial number string descriptor. */ + uint8_t iSerialNumber; + /** Number of possible configurations for the device. */ + uint8_t bNumConfigurations; + +} __attribute__ ((packed)) USBDeviceDescriptor; /* GCC */ + +/** + * \typedef USBOtgDescriptor + * \brief USB On-The-Go descriptor struct. + */ +typedef struct _USBOtgDescriptor { + + /** Size of this descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (USBGenericDescriptor_OTG). */ + uint8_t bDescriptorType; + /** Attribute Fields D7?: Reserved D1: HNP support D0: SRP support */ + uint8_t bmAttributes; + +} __attribute__ ((packed)) USBOtgDescriptor; /* GCC */ + +/** + * \typedef USBDeviceQualifierDescriptor + * \brief Alternate device descriptor indicating the capabilities of the device + * in full-speed, if currently in high-speed; or in high-speed, if it is + * currently in full-speed. Only relevant for devices supporting the + * high-speed mode. + */ +typedef struct _USBDeviceQualifierDescriptor { + + /** Size of the descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (USBDESC_DEVICE_QUALIFIER or "USB device types"). */ + uint8_t bDescriptorType; + /** USB specification release number (in BCD format). */ + uint16_t bcdUSB; + /** Device class code. */ + uint8_t bDeviceClass; + /** Device subclass code. */ + uint8_t bDeviceSubClass; + /** Device protocol code. */ + uint8_t bDeviceProtocol; + /** Maximum packet size of endpoint 0. */ + uint8_t bMaxPacketSize0; + /** Number of possible configurations for the device. */ + uint8_t bNumConfigurations; + /** Reserved. */ + uint8_t bReserved; + +} __attribute__ ((packed)) USBDeviceQualifierDescriptor; /* GCC */ + +/** + * \typedef USBConfigurationDescriptor + * \brief USB standard configuration descriptor structure. + */ +typedef struct _USBConfigurationDescriptor { + + /** Size of the descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type + (USBDESC_CONFIGURATION of \ref usb_desc_type USB Descriptor types). */ + uint8_t bDescriptorType; + /** Length of all descriptors returned along with this configuration + descriptor. */ + uint16_t wTotalLength; + /** Number of interfaces in this configuration. */ + uint8_t bNumInterfaces; + /** Value for selecting this configuration. */ + uint8_t bConfigurationValue; + /** Index of the configuration string descriptor. */ + uint8_t iConfiguration; + /** Configuration characteristics. */ + uint8_t bmAttributes; + /** Maximum power consumption of the device when in this configuration. */ + uint8_t bMaxPower; + +} __attribute__ ((packed)) USBConfigurationDescriptor; /* GCC*/ + +/** + * \typedef USBInterfaceAssociationDescriptor + * \brief + */ +typedef struct _USBInterfaceAssociationDescriptor { + + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bFirstInterface; + unsigned char bInterfaceCount; + unsigned char bFunctionClass; + unsigned char bFunctionSubClass; + unsigned char bFunctionProtocol; + unsigned char iFunction; +} __attribute__ ((packed)) USBInterfaceAssociationDescriptor; /* GCC*/ + +/** + * \typedef USBInterfaceDescriptor + * \brief USB standard interface descriptor structure. + */ +typedef struct _USBInterfaceDescriptor { + + /** Size of the descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (USBGenericDescriptor_INTERFACE). */ + uint8_t bDescriptorType; + /** Number of the interface in its configuration. */ + uint8_t bInterfaceNumber; + /** Value to select this alternate interface setting. */ + uint8_t bAlternateSetting; + /** Number of endpoints used by the inteface (excluding endpoint 0). */ + uint8_t bNumEndpoints; + /** Interface class code. */ + uint8_t bInterfaceClass; + /** Interface subclass code. */ + uint8_t bInterfaceSubClass; + /** Interface protocol code. */ + uint8_t bInterfaceProtocol; + /** Index of the interface string descriptor. */ + uint8_t iInterface; + +} __attribute__ ((packed)) USBInterfaceDescriptor; /* GCC */ + +/** + * \typedef USBEndpointDescriptor + * \brief USB standard endpoint descriptor structure. + */ +typedef struct _USBEndpointDescriptor { + + /** Size of the descriptor in bytes. */ + uint8_t bLength; + /** Descriptor type (\ref USBGenericDescriptor_ENDPOINT). */ + uint8_t bDescriptorType; + /** Address and direction of the endpoint. */ + uint8_t bEndpointAddress; + /** Endpoint type and additional characteristics + (for isochronous endpoints). */ + uint8_t bmAttributes; + /** Maximum packet size (in bytes) of the endpoint. */ + uint16_t wMaxPacketSize; + /** Polling rate of the endpoint. */ + uint8_t bInterval; + +} __attribute__ ((packed)) USBEndpointDescriptor; /* GCC*/ + + +#pragma pack() + +/*--------------------------------------------------------------------------- + * Exported Functions + *---------------------------------------------------------------------------*/ + +extern uint32_t USBGenericDescriptor_GetLength( + const USBGenericDescriptor *descriptor); + +extern uint8_t USBGenericDescriptor_GetType( + const USBGenericDescriptor *descriptor); + +extern USBGenericDescriptor *USBGenericDescriptor_GetNextDescriptor( + const USBGenericDescriptor *descriptor); + +extern USBGenericDescriptor *USBGenericDescriptor_Parse( + const USBGenericDescriptor * descriptor, + uint32_t totalLength, + USBDescriptorParseFunction parseFunction, + void * parseArg); + + +extern uint32_t USBConfigurationDescriptor_GetTotalLength( + const USBConfigurationDescriptor *configuration); + +extern uint8_t USBConfigurationDescriptor_GetNumInterfaces( + const USBConfigurationDescriptor *configuration); + +extern uint8_t USBConfigurationDescriptor_IsSelfPowered( + const USBConfigurationDescriptor *configuration); + +extern void USBConfigurationDescriptor_Parse( + const USBConfigurationDescriptor *configuration, + USBInterfaceDescriptor **interfaces, + USBEndpointDescriptor **endpoints, + USBGenericDescriptor **others); + +extern uint8_t USBEndpointDescriptor_GetNumber( + const USBEndpointDescriptor *endpoint); + +extern uint8_t USBEndpointDescriptor_GetDirection( + const USBEndpointDescriptor *endpoint); + +extern uint8_t USBEndpointDescriptor_GetType( + const USBEndpointDescriptor *endpoint); + +extern uint16_t USBEndpointDescriptor_GetMaxPacketSize( + const USBEndpointDescriptor *endpoint); + +extern uint8_t USBEndpointDescriptor_GetInterval( + const USBEndpointDescriptor *endpoint); + + +/** @}*/ +/**@}*/ +#endif /* #ifndef _USBDESCRIPTORS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/USBLib_Trace.h b/sam3s_example/atmel_softpack_libraries/usb/include/USBLib_Trace.h new file mode 100644 index 00000000..ae35266e --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/USBLib_Trace.h @@ -0,0 +1,209 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file + * + * \par Purpose + * + * Standard output methods for reporting debug information, warnings and + * errors, which can be easily be turned on/off. + * + * \par Usage + * -# Initialize the debug message port in application, for stdio printf(). + * -# Uses the TRACE_DEBUG(), TRACE_INFO(), TRACE_WARNING(), TRACE_ERROR() + * TRACE_FATAL() macros to output traces throughout the program. + * -# Each type of trace has a level : Debug 5, Info 4, Warning 3, Error 2 + * and Fatal 1. Disable a group of traces by changing the value of + * TRACE_LEVEL during compilation; traces with a level bigger than TRACE_LEVEL + * are not generated. To generate no trace, use the reserved value 0. + * -# Trace disabling can be static or dynamic. If dynamic disabling is selected + * the trace level can be modified in runtime. If static disabling is selected + * the disabled traces are not compiled. + * + * \par traceLevels Trace level description + * -# TRACE_DEBUG (5): Traces whose only purpose is for debugging the program, + * and which do not produce meaningful information otherwise. + * -# TRACE_INFO (4): Informational trace about the program execution. Should + * enable the user to see the execution flow. + * -# TRACE_WARNING (3): Indicates that a minor error has happened. In most case + * it can be discarded safely; it may even be expected. + * -# TRACE_ERROR (2): Indicates an error which may not stop the program execution, + * but which indicates there is a problem with the code. + * -# TRACE_FATAL (1): Indicates a major error which prevents the program from going + * any further. + */ + +#ifndef _USBLIB_TRACE_H +#define _USBLIB_TRACE_H + +/* + * Headers + */ + +#include + +/* + * Global Definitions + */ + +/** Softpack Version */ +#define USBLIB_VERSION "0.1" + +#define TRACE_LEVEL_DEBUG 5 +#define TRACE_LEVEL_INFO 4 +#define TRACE_LEVEL_WARNING 3 +#define TRACE_LEVEL_ERROR 2 +#define TRACE_LEVEL_FATAL 1 +#define TRACE_LEVEL_NO_TRACE 0 + +/* By default, all traces are output except the debug one. */ +#if !defined(TRACE_LEVEL) +#define TRACE_LEVEL TRACE_LEVEL_INFO +#endif + +/* By default, trace level is static (not dynamic) */ +#if !defined(DYN_TRACES) +#define DYN_TRACES 0 +#endif + +#if defined(NOTRACE) +#error "Error: NOTRACE has to be not defined !" +#endif + +#undef NOTRACE +#if (DYN_TRACES==0) + #if (TRACE_LEVEL == TRACE_LEVEL_NO_TRACE) + #define NOTRACE + #endif +#endif + + + +/* ------------------------------------------------------------------------------ + * Global Macros + * ------------------------------------------------------------------------------ + */ + +#ifndef DYNTRACE +#define DYNTRACE 0 +#endif + + +/** + * Outputs a formatted string using 'printf' if the log level is high + * enough. Can be disabled by defining TRACE_LEVEL=0 during compilation. + * \param ... Additional parameters depending on formatted string. + */ +#if defined(NOTRACE) + +/* Empty macro */ +#define TRACE_DEBUG(...) { } +#define TRACE_INFO(...) { } +#define TRACE_WARNING(...) { } +#define TRACE_ERROR(...) { } +#define TRACE_FATAL(...) { while(1); } + +#define TRACE_DEBUG_WP(...) { } +#define TRACE_INFO_WP(...) { } +#define TRACE_WARNING_WP(...) { } +#define TRACE_ERROR_WP(...) { } +#define TRACE_FATAL_WP(...) { while(1); } + +#elif (DYN_TRACES == 1) + +/* Trace output depends on dwTraceLevel value */ +#define TRACE_DEBUG(...) { if (dwTraceLevel >= TRACE_LEVEL_DEBUG) { printf("-D- " __VA_ARGS__); } } +#define TRACE_INFO(...) { if (dwTraceLevel >= TRACE_LEVEL_INFO) { printf("-I- " __VA_ARGS__); } } +#define TRACE_WARNING(...) { if (dwTraceLevel >= TRACE_LEVEL_WARNING) { printf("-W- " __VA_ARGS__); } } +#define TRACE_ERROR(...) { if (dwTraceLevel >= TRACE_LEVEL_ERROR) { printf("-E- " __VA_ARGS__); } } +#define TRACE_FATAL(...) { if (dwTraceLevel >= TRACE_LEVEL_FATAL) { printf("-F- " __VA_ARGS__); while(1); } } + +#define TRACE_DEBUG_WP(...) { if (dwTraceLevel >= TRACE_LEVEL_DEBUG) { printf(__VA_ARGS__); } } +#define TRACE_INFO_WP(...) { if (dwTraceLevel >= TRACE_LEVEL_INFO) { printf(__VA_ARGS__); } } +#define TRACE_WARNING_WP(...) { if (dwTraceLevel >= TRACE_LEVEL_WARNING) { printf(__VA_ARGS__); } } +#define TRACE_ERROR_WP(...) { if (dwTraceLevel >= TRACE_LEVEL_ERROR) { printf(__VA_ARGS__); } } +#define TRACE_FATAL_WP(...) { if (dwTraceLevel >= TRACE_LEVEL_FATAL) { printf(__VA_ARGS__); while(1); } } + +#else + +/* Trace compilation depends on TRACE_LEVEL value */ +#if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG) +#define TRACE_DEBUG(...) { printf("-D- " __VA_ARGS__); } +#define TRACE_DEBUG_WP(...) { printf(__VA_ARGS__); } +#else +#define TRACE_DEBUG(...) { } +#define TRACE_DEBUG_WP(...) { } +#endif + +#if (TRACE_LEVEL >= TRACE_LEVEL_INFO) +#define TRACE_INFO(...) { printf("-I- " __VA_ARGS__); } +#define TRACE_INFO_WP(...) { printf(__VA_ARGS__); } +#else +#define TRACE_INFO(...) { } +#define TRACE_INFO_WP(...) { } +#endif + +#if (TRACE_LEVEL >= TRACE_LEVEL_WARNING) +#define TRACE_WARNING(...) { printf("-W- " __VA_ARGS__); } +#define TRACE_WARNING_WP(...) { printf(__VA_ARGS__); } +#else +#define TRACE_WARNING(...) { } +#define TRACE_WARNING_WP(...) { } +#endif + +#if (TRACE_LEVEL >= TRACE_LEVEL_ERROR) +#define TRACE_ERROR(...) { printf("-E- " __VA_ARGS__); } +#define TRACE_ERROR_WP(...) { printf(__VA_ARGS__); } +#else +#define TRACE_ERROR(...) { } +#define TRACE_ERROR_WP(...) { } +#endif + +#if (TRACE_LEVEL >= TRACE_LEVEL_FATAL) +#define TRACE_FATAL(...) { printf("-F- " __VA_ARGS__); while(1); } +#define TRACE_FATAL_WP(...) { printf(__VA_ARGS__); while(1); } +#else +#define TRACE_FATAL(...) { while(1); } +#define TRACE_FATAL_WP(...) { while(1); } +#endif + +#endif + + +/** + * Exported variables + */ +/** Depending on DYN_TRACES, dwTraceLevel is a modifable runtime variable or a define */ +#if !defined(NOTRACE) && (DYN_TRACES == 1) + extern uint32_t dwTraceLevel ; +#endif + +#endif /* #ifndef _USBLIB_TRACE_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/USBLib_Types.h b/sam3s_example/atmel_softpack_libraries/usb/include/USBLib_Types.h new file mode 100644 index 00000000..8a58a65d --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/USBLib_Types.h @@ -0,0 +1,65 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * Definitions for USB Lib compiling. + */ + +#ifndef USBLIB_TYPES_H +#define USBLIB_TYPES_H + +/*---------------------------------------------------------------------------- + * Defines + *----------------------------------------------------------------------------*/ + +/** USB status ReturnCode */ +typedef enum _USBRC { + USBRC_OK = 0, /**< Operation was successful */ + USBRC_SUCCESS = 0, /**< Operation was successful */ + /* Bool codes */ + USBRC_FALSE = 0, /**< As boolean TRUE */ + USBRC_TRUE = 1, /**< As boolean FALSE */ + /* Error codes */ + USBRC_BUSY, /**< EP/Device is already busy */ + USBRC_ABORTED, /**< Operation aborted due to error or stall */ + USBRC_CANCELED, /**< Operation canceled by user */ + USBRC_RESET, /**< Operation aborted due to init/reset/un-configure */ + USBRC_PARTIAL_DONE,/**< Part of operation successfully done */ + USBRC_FINISHED, /**< All operation successfully done and terminate */ + + USBRC_PARAM_ERR, /**< Failed due to parameter error */ + USBRC_STATE_ERR, /**< Failed due to state error */ + USBRC_ERROR, /**< General error */ + + USBRC_SW_NOT_SUPPORTED = 0xFD, /**< Failed due to SW not supported */ + USBRC_HW_NOT_SUPPORTED = 0xFE /**< Failed due to HW not supported */ +} USBRC; + +#endif /* #define USBLIB_TYPES_H */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/include/USBRequests.h b/sam3s_example/atmel_softpack_libraries/usb/include/USBRequests.h new file mode 100644 index 00000000..af646cf7 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/include/USBRequests.h @@ -0,0 +1,354 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2010, 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. + * ---------------------------------------------------------------------------- + */ + +/** \file + * \section Purpose + * + * Definitions and methods for USB request structures described by the + * USB specification. + * + * \section Usage + * + */ + +#ifndef _USBREQUESTS_H_ +#define _USBREQUESTS_H_ +/** \addtogroup usb_general + * @{ + * \addtogroup usb_request USB Requests + * @{ + */ + +/*--------------------------------------------------------------------------- + * Headers + *---------------------------------------------------------------------------*/ + +/* These headers were introduced in C99 by working group + * ISO/IEC JTC1/SC22/WG14. + */ +#include + +/*--------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +/*----------- Generic Request ------------*/ + +/** \addtogroup usb_request_define USB Generic Request definitions + * @{ + * This section lists the codes of USB generic request. + * + * - \ref usb_request_code USB Request codes + * - \ref USBGenericRequest_GETSTATUS + * - \ref USBGenericRequest_CLEARFEATURE + * - \ref USBGenericRequest_SETFEATURE + * - \ref USBGenericRequest_SETADDRESS + * - \ref USBGenericRequest_GETDESCRIPTOR + * - \ref USBGenericRequest_SETDESCRIPTOR + * - \ref USBGenericRequest_GETCONFIGURATION + * - \ref USBGenericRequest_SETCONFIGURATION + * - \ref USBGenericRequest_GETINTERFACE + * - \ref USBGenericRequest_SETINTERFACE + * - \ref USBGenericRequest_SYNCHFRAME + * + * - \ref usb_request_recipient USB Request Recipients + * - \ref USBGenericRequest_DEVICE + * - \ref USBGenericRequest_INTERFACE + * - \ref USBGenericRequest_ENDPOINT + * - \ref USBGenericRequest_OTHER + * + * - \ref usb_request_type USB Request Types + * - \ref USBGenericRequest_STANDARD + * - \ref USBGenericRequest_CLASS + * - \ref USBGenericRequest_VENDOR + * + * - \ref usb_request_dir USB Request Directions + * - \ref USBGenericRequest_IN + * - \ref USBGenericRequest_OUT + */ + +/** \addtogroup usb_request_code USB Request codes + * @{ + * This section lists the USB generic request codes. + * - \ref USBGenericRequest_GETSTATUS + * - \ref USBGenericRequest_CLEARFEATURE + * - \ref USBGenericRequest_SETFEATURE + * - \ref USBGenericRequest_SETADDRESS + * - \ref USBGenericRequest_GETDESCRIPTOR + * - \ref USBGenericRequest_SETDESCRIPTOR + * - \ref USBGenericRequest_GETCONFIGURATION + * - \ref USBGenericRequest_SETCONFIGURATION + * - \ref USBGenericRequest_GETINTERFACE + * - \ref USBGenericRequest_SETINTERFACE + * - \ref USBGenericRequest_SYNCHFRAME + */ +/** GET_STATUS request code. */ +#define USBGenericRequest_GETSTATUS 0 +/** CLEAR_FEATURE request code. */ +#define USBGenericRequest_CLEARFEATURE 1 +/** SET_FEATURE request code. */ +#define USBGenericRequest_SETFEATURE 3 +/** SET_ADDRESS request code. */ +#define USBGenericRequest_SETADDRESS 5 +/** GET_DESCRIPTOR request code. */ +#define USBGenericRequest_GETDESCRIPTOR 6 +/** SET_DESCRIPTOR request code. */ +#define USBGenericRequest_SETDESCRIPTOR 7 +/** GET_CONFIGURATION request code. */ +#define USBGenericRequest_GETCONFIGURATION 8 +/** SET_CONFIGURATION request code. */ +#define USBGenericRequest_SETCONFIGURATION 9 +/** GET_INTERFACE request code. */ +#define USBGenericRequest_GETINTERFACE 10 +/** SET_INTERFACE request code. */ +#define USBGenericRequest_SETINTERFACE 11 +/** SYNCH_FRAME request code. */ +#define USBGenericRequest_SYNCHFRAME 12 +/** @}*/ + +/** \addtogroup usb_request_recipient USB Request Recipients + * @{ + * This section lists codes of USB request recipients. + * - \ref USBGenericRequest_DEVICE + * - \ref USBGenericRequest_INTERFACE + * - \ref USBGenericRequest_ENDPOINT + * - \ref USBGenericRequest_OTHER + */ +/** Recipient is the whole device. */ +#define USBGenericRequest_DEVICE 0 +/** Recipient is an interface. */ +#define USBGenericRequest_INTERFACE 1 +/** Recipient is an endpoint. */ +#define USBGenericRequest_ENDPOINT 2 +/** Recipient is another entity. */ +#define USBGenericRequest_OTHER 3 +/** @}*/ + +/** \addtogroup usb_request_type USB Request Types + * @{ + * This section lists codes of USB request types. + * - \ref USBGenericRequest_STANDARD + * - \ref USBGenericRequest_CLASS + * - \ref USBGenericRequest_VENDOR + */ +/** Request is standard. */ +#define USBGenericRequest_STANDARD 0 +/** Request is class-specific. */ +#define USBGenericRequest_CLASS 1 +/** Request is vendor-specific. */ +#define USBGenericRequest_VENDOR 2 +/** @}*/ + +/** \addtogroup usb_request_dir USB Request Directions + * @{ + * This section lists codes of USB request directions. + * - \ref USBGenericRequest_IN + * - \ref USBGenericRequest_OUT + */ +/** Transfer occurs from device to the host. */ +#define USBGenericRequest_OUT 0 +/** Transfer occurs from the host to the device. */ +#define USBGenericRequest_IN 1 +/** @}*/ +/** @}*/ + + +/*----------- Feature Request ------------*/ + +/** \addtogroup usb_feature_def USB Feature Request Definitions + * @{ + * This section lists codes of USB Feature Request + * + * - \ref usb_feature_sel USB Feature selectors + * - \ref USBFeatureRequest_ENDPOINTHALT + * - \ref USBFeatureRequest_DEVICEREMOTEWAKEUP + * - \ref USBFeatureRequest_TESTMODE + * + * - \ref usb_test_sel USB Test mode selectors + * - \ref USBFeatureRequest_TESTJ + * - \ref USBFeatureRequest_TESTK + * - \ref USBFeatureRequest_TESTSE0NAK + * - \ref USBFeatureRequest_TESTPACKET + * - \ref USBFeatureRequest_TESTFORCEENABLE + * - \ref USBFeatureRequest_TESTSENDZLP + */ + +/** \addtogroup usb_feature_sel USB Feature selectors + * @{ + * This section lists codes of USB feature selectors. + * - \ref USBFeatureRequest_ENDPOINTHALT + * - \ref USBFeatureRequest_DEVICEREMOTEWAKEUP + * - \ref USBFeatureRequest_TESTMODE + */ +/** Halt feature of an endpoint. */ +#define USBFeatureRequest_ENDPOINTHALT 0 +/** Remote wake-up feature of the device. */ +#define USBFeatureRequest_DEVICEREMOTEWAKEUP 1 +/** Test mode of the device. */ +#define USBFeatureRequest_TESTMODE 2 +/** OTG set feature */ +#define USBFeatureRequest_OTG 0x0B +/** OTG b_hnp_enable */ +#define USBFeatureRequest_OTG_B_HNP_ENABLE 3 +/** OTG a_hnp_support */ +#define USBFeatureRequest_OTG_A_HNP_SUPPORT 4 +/** OTG a_alt_hnp_support */ +#define USBFeatureRequest_OTG_A_ALT_HNP_SUPPORT 5 +/** @}*/ + +/** \addtogroup usb_test_sel USB Test mode selectors + * @{ + * This section lists codes of USB high speed test mode selectors. + * - \ref USBFeatureRequest_TESTJ + * - \ref USBFeatureRequest_TESTK + * - \ref USBFeatureRequest_TESTSE0NAK + * - \ref USBFeatureRequest_TESTPACKET + * - \ref USBFeatureRequest_TESTFORCEENABLE + * - \ref USBFeatureRequest_TESTSENDZLP + */ + +/** Tests the high-output drive level on the D+ line. */ +#define USBFeatureRequest_TESTJ 1 +/** Tests the high-output drive level on the D- line. */ +#define USBFeatureRequest_TESTK 2 +/** Tests the output impedance, low-level output voltage and loading + characteristics. */ +#define USBFeatureRequest_TESTSE0NAK 3 +/** Tests rise and fall times, eye patterns and jitter. */ +#define USBFeatureRequest_TESTPACKET 4 +/** Tests the hub disconnect detection. */ +#define USBFeatureRequest_TESTFORCEENABLE 5 +/** Send a ZLP in Test Mode. */ +#define USBFeatureRequest_TESTSENDZLP 6 +/** @}*/ +/** @}*/ + +/*--------------------------------------------------------------------------- + * Types + *---------------------------------------------------------------------------*/ + +/* + * Function types + */ + +/* + * Descriptor structs types + */ +#ifdef __ICCARM__ /* IAR */ +#pragma pack(1) /* IAR */ +#define __attribute__(...) /* IAR */ +#endif /* IAR */ + +/** + * Generic USB SETUP request sent over Control endpoints. + */ +typedef struct { + + /** Type of request + * \sa usb_request_recipient "USB Request Recipients" + * \sa usb_request_type "USB Request Types" + * \sa usb_request_dir "USB Request Directions" */ + uint8_t bmRequestType:8; + /** Request code + * \sa usb_request_code "USB Request Codes" */ + uint8_t bRequest:8; + /** Request-specific value parameter. */ + uint16_t wValue:16; + /** Request-specific index parameter. */ + uint16_t wIndex:16; + /** Expected length (in bytes) of the data phase. */ + uint16_t wLength:16; + +} USBGenericRequest; + +#ifdef __ICCARM__ /* IAR */ +#pragma pack() /* IAR */ +#endif /* IAR */ + +/*--------------------------------------------------------------------------- + * Exported Functions + *---------------------------------------------------------------------------*/ + +extern uint8_t USBGenericRequest_GetType( + const USBGenericRequest *request); + +extern uint8_t USBGenericRequest_GetRequest( + const USBGenericRequest *request); + +extern uint16_t USBGenericRequest_GetValue( + const USBGenericRequest *request); + +extern uint16_t USBGenericRequest_GetIndex( + const USBGenericRequest *request); + +extern uint16_t USBGenericRequest_GetLength( + const USBGenericRequest *request); + +extern uint8_t USBGenericRequest_GetEndpointNumber( + const USBGenericRequest *request); + +extern uint8_t USBGenericRequest_GetRecipient( + const USBGenericRequest *request); + +extern uint8_t USBGenericRequest_GetDirection( + const USBGenericRequest *request); + + +extern uint8_t USBGetDescriptorRequest_GetDescriptorType( + const USBGenericRequest *request); + +extern uint8_t USBGetDescriptorRequest_GetDescriptorIndex( + const USBGenericRequest *request); + + +extern uint8_t USBSetAddressRequest_GetAddress( + const USBGenericRequest *request); + + +extern uint8_t USBSetConfigurationRequest_GetConfiguration( + const USBGenericRequest *request); + + +extern uint8_t USBInterfaceRequest_GetInterface( + const USBGenericRequest *request); + +extern uint8_t USBInterfaceRequest_GetAlternateSetting( + const USBGenericRequest *request); + + +extern uint8_t USBFeatureRequest_GetFeatureSelector( + const USBGenericRequest *request); + +extern uint8_t USBFeatureRequest_GetTestSelector( + const USBGenericRequest *request); + +/** @}*/ +/**@}*/ +#endif /* #ifndef _USBREQUESTS_H_ */ + diff --git a/sam3s_example/atmel_softpack_libraries/usb/lib/libusb_sam3s_gcc_dbg.a b/sam3s_example/atmel_softpack_libraries/usb/lib/libusb_sam3s_gcc_dbg.a new file mode 100644 index 00000000..bbf50062 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/lib/libusb_sam3s_gcc_dbg.a differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/lib/libusb_sam3s_gcc_rel.a b/sam3s_example/atmel_softpack_libraries/usb/lib/libusb_sam3s_gcc_rel.a new file mode 100644 index 00000000..bc10b1e4 Binary files /dev/null and b/sam3s_example/atmel_softpack_libraries/usb/lib/libusb_sam3s_gcc_rel.a differ diff --git a/sam3s_example/atmel_softpack_libraries/usb/usb.h b/sam3s_example/atmel_softpack_libraries/usb/usb.h new file mode 100644 index 00000000..b74cc109 --- /dev/null +++ b/sam3s_example/atmel_softpack_libraries/usb/usb.h @@ -0,0 +1,99 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2009, 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. + * ---------------------------------------------------------------------------- + */ + +/** + * \file usb.h + * + * Definition of SAM3S-EK usb library + * + */ + +#ifndef _usb_ +#define _usb_ + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ +#include "board.h" + +#include "include/USBD.h" +#include "include/USBD_HAL.h" + +#include "include/USBDescriptors.h" + +#include "include/USBDDriver.h" + +#include "include/AUDDescriptors.h" +#include "include/AUDDFunction.h" +#include "include/AUDDSpeakerDriver.h" +#include "include/AUDDSpeakerPhone.h" +#include "include/AUDDSpeakerPhoneDriver.h" +#include "include/AUDDStream.h" +#include "include/AUDRequests.h" + +#include "include/CDCAUDDDriver.h" +#include "include/CDCDescriptors.h" +#include "include/CDCDSerial.h" +#include "include/CDCDSerialDriver.h" +#include "include/CDCDSerialPort.h" +#include "include/CDCHIDDDriver.h" +#include "include/CDCMSDDriver.h" +#include "include/CDCNotifications.h" +#include "include/CDCRequests.h" + +#include "include/DUALCDCDDriver.h" + +#include "include/HIDAUDDDriver.h" +#include "include/HIDDescriptors.h" +#include "include/HIDDFunction.h" +#include "include/HIDDKeyboard.h" +#include "include/HIDDKeyboardDriver.h" +#include "include/HIDDMouseDriver.h" +#include "include/HIDDTransferDriver.h" +#include "include/HIDMSDDriver.h" +#include "include/HIDReports.h" +#include "include/HIDRequests.h" +#include "include/HIDUsages.h" + +#include "include/MSD.h" +#include "include/MSDDriver.h" +#include "include/MSDDStateMachine.h" +#include "include/MSDescriptors.h" +#include "include/MSDFunction.h" +#include "include/MSDIOFifo.h" +#include "include/MSDLun.h" + +#include "include/SBC.h" +#include "include/SBCMethods.h" + +#include "include/USBLib_Trace.h" +#include "include/USBLib_Types.h" +#include "include/USBRequests.h" + +#endif /* #ifndef _usb_ */