From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- usb/device/audio-speaker/AUDDSpeakerChannel.c | 129 +++++ usb/device/audio-speaker/AUDDSpeakerChannel.h | 92 +++ usb/device/audio-speaker/AUDDSpeakerDriver.c | 378 +++++++++++++ usb/device/audio-speaker/AUDDSpeakerDriver.h | 201 +++++++ .../audio-speaker/AUDDSpeakerDriverDescriptors.c | 620 +++++++++++++++++++++ .../audio-speaker/AUDDSpeakerDriverDescriptors.h | 146 +++++ usb/device/audio-speaker/USBAudioSpeaker.png | Bin 0 -> 3711 bytes .../audio-speaker/USBAudioSpeakerDescriptors.png | Bin 0 -> 8026 bytes .../audio-speaker/USBAudioSpeakerRecorder.png | Bin 0 -> 5053 bytes .../USBAudioSpeakerRecorderDescriptors.png | Bin 0 -> 10906 bytes usb/device/audio-speaker/audio-speaker.dir | 617 ++++++++++++++++++++ 11 files changed, 2183 insertions(+) create mode 100644 usb/device/audio-speaker/AUDDSpeakerChannel.c create mode 100644 usb/device/audio-speaker/AUDDSpeakerChannel.h create mode 100644 usb/device/audio-speaker/AUDDSpeakerDriver.c create mode 100644 usb/device/audio-speaker/AUDDSpeakerDriver.h create mode 100644 usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.c create mode 100644 usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.h create mode 100644 usb/device/audio-speaker/USBAudioSpeaker.png create mode 100644 usb/device/audio-speaker/USBAudioSpeakerDescriptors.png create mode 100644 usb/device/audio-speaker/USBAudioSpeakerRecorder.png create mode 100644 usb/device/audio-speaker/USBAudioSpeakerRecorderDescriptors.png create mode 100644 usb/device/audio-speaker/audio-speaker.dir (limited to 'usb/device/audio-speaker') diff --git a/usb/device/audio-speaker/AUDDSpeakerChannel.c b/usb/device/audio-speaker/AUDDSpeakerChannel.c new file mode 100644 index 0000000..30f39c5 --- /dev/null +++ b/usb/device/audio-speaker/AUDDSpeakerChannel.c @@ -0,0 +1,129 @@ +/* ---------------------------------------------------------------------------- + * 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. + * ---------------------------------------------------------------------------- + */ + +/* + Title: AUDDSpeakerChannel implementation + + About: Purpose + Implementation of the AUDDSpeakerChannel functions. +*/ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "AUDDSpeakerChannel.h" +#include + +//------------------------------------------------------------------------------ +// Callbacks +//------------------------------------------------------------------------------ +/* + Function: AUDDSpeakerChannel_MuteChanged + Callback triggered when the mute status of a channel changes. This is + a default implementation which does nothing and must be overriden. + + Parameters: + channel - Pointer to a AUDDSpeakerChannel instance. + muted - New mute status. +*/ +//__attribute__ ((weak)) void AUDDSpeakerChannel_MuteChanged( +// AUDDSpeakerChannel *channel, +// unsigned char muted) +//{ +// TRACE_DEBUG("MuteChanged(%d, %d) ", channel->number, muted); +//} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Initializes the member variables of an AUDDSpeakerChannel object to the +/// given values. +/// \param channel Pointer to an AUDDSpeakerChannel instance. +/// \param number Channel number in the audio function. +/// \param muted Indicates if the channel is muted. +//------------------------------------------------------------------------------ +void AUDDSpeakerChannel_Initialize(AUDDSpeakerChannel *channel, + unsigned char number, + unsigned char muted) +{ + channel->number = number; + channel->muted = muted; +} + +//------------------------------------------------------------------------------ +/// Indicates the number of a channel. +/// \param channel Pointer to an AUDDSpeakerChannel instance. +/// \return Channel number. +//------------------------------------------------------------------------------ +unsigned char AUDDSpeakerChannel_GetNumber(const AUDDSpeakerChannel *channel) +{ + return channel->number; +} + +//------------------------------------------------------------------------------ +/// Mutes the given channel and triggers the MuteChanged callback if +/// necessary. +/// \param channel Pointer to an AUDDSpeakerChannelInstance. +//------------------------------------------------------------------------------ +void AUDDSpeakerChannel_Mute(AUDDSpeakerChannel *channel) +{ + if (!channel->muted) { + + channel->muted = 1; + AUDDSpeakerChannel_MuteChanged(channel, 1); + } +} + +//------------------------------------------------------------------------------ +/// Unmutes the given channel and triggers the MuteChanged callback if +/// necessary. +/// \param channel Pointer to an AUDDSpeakerChannelInstance. +//------------------------------------------------------------------------------ +void AUDDSpeakerChannel_Unmute(AUDDSpeakerChannel *channel) +{ + if (channel->muted) { + + channel->muted = 0; + AUDDSpeakerChannel_MuteChanged(channel, 0); + } +} + +//------------------------------------------------------------------------------ +/// Indicates if the given channel is currently muted or not. +/// \param channel Pointer an AUDDSpeakerChannel instance. +/// \return 1 if the channel is muted; otherwise 0. +//------------------------------------------------------------------------------ +unsigned char AUDDSpeakerChannel_IsMuted(const AUDDSpeakerChannel *channel) +{ + return channel->muted; +} + diff --git a/usb/device/audio-speaker/AUDDSpeakerChannel.h b/usb/device/audio-speaker/AUDDSpeakerChannel.h new file mode 100644 index 0000000..5eeca7e --- /dev/null +++ b/usb/device/audio-speaker/AUDDSpeakerChannel.h @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !Purpose + + Manipulation of the channels of an USB audio speaker device. + + !Usage + + -# Initialize a AUDDSpeakerChannel instance using + AUDDSpeakerChannel_Initialize. + -# Retrieves the current status of a channel with the + AUDDSpeakerChannel_IsMuted method. + -# Re-implement the AUDDSpeakerChannel_MuteChanged callback to get + notified when the status of a channel changes. +*/ + +#ifndef AUDDSPEAKERCHANNEL_H +#define AUDDSPEAKERCHANNEL_H + +//------------------------------------------------------------------------------ +// Types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Modelizes a channel of an USB audio speaker device. +//------------------------------------------------------------------------------ +typedef struct { + + /// Zero-based channel number in the audio function. + unsigned char number; + /// Indicates if the channel is currently muted. + unsigned char muted; + +} AUDDSpeakerChannel; + +//------------------------------------------------------------------------------ +// Callbacks +//------------------------------------------------------------------------------ + +extern void AUDDSpeakerChannel_MuteChanged(AUDDSpeakerChannel *channel, + unsigned char muted); + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern void AUDDSpeakerChannel_Initialize(AUDDSpeakerChannel *channel, + unsigned char number, + unsigned char muted); + +extern unsigned char AUDDSpeakerChannel_GetNumber( + const AUDDSpeakerChannel *channel); + +extern void AUDDSpeakerChannel_Mute(AUDDSpeakerChannel *channel); + +extern void AUDDSpeakerChannel_Unmute(AUDDSpeakerChannel *channel); + +extern unsigned char AUDDSpeakerChannel_IsMuted( + const AUDDSpeakerChannel *channel); + +#endif //#ifndef AUDDSPEAKERCHANNEL_H + diff --git a/usb/device/audio-speaker/AUDDSpeakerDriver.c b/usb/device/audio-speaker/AUDDSpeakerDriver.c new file mode 100644 index 0000000..7ca58bd --- /dev/null +++ b/usb/device/audio-speaker/AUDDSpeakerDriver.c @@ -0,0 +1,378 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "AUDDSpeakerDriver.h" +#include "AUDDSpeakerDriverDescriptors.h" +#include "AUDDSpeakerChannel.h" +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Internal types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Audio speaker driver internal state. +//------------------------------------------------------------------------------ +typedef struct { + + /// USB device driver instance. + USBDDriver usbdDriver; + /// List of AUDDSpeakerChannel instances for playback. + AUDDSpeakerChannel channels[AUDDSpeakerDriver_NUMCHANNELS+1]; + +} AUDDSpeakerDriver; + +//------------------------------------------------------------------------------ +// Internal variables +//------------------------------------------------------------------------------ + +/// Global USB audio speaker driver instance. +static AUDDSpeakerDriver auddSpeakerDriver; +/// Array for storing the current setting of each interface. +static unsigned char auddSpeakerDriverInterfaces[2]; +/// Intermediate storage variable for the mute status of a channel. +static unsigned char muted; + +//------------------------------------------------------------------------------ +// Internal functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Callback triggered after the new mute status of a channel has been read +/// by AUDDSpeakerDriver_SetFeatureCurrentValue. Changes the mute status +/// of the given channel accordingly. +/// \param channel Number of the channel whose mute status has changed. +//------------------------------------------------------------------------------ +static void AUDDSpeakerDriver_MuteReceived(unsigned int channel) +{ + if (muted) { + + AUDDSpeakerChannel_Mute(&(auddSpeakerDriver.channels[channel])); + } + else { + + AUDDSpeakerChannel_Unmute(&(auddSpeakerDriver.channels[channel])); + } + + USBD_Write(0, 0, 0, 0, 0); +} + +//------------------------------------------------------------------------------ +/// Sets the current value of a particular Feature control of a channel. +/// \param entity Entity number. +/// \param channel Channel number. +/// \param control Control selector value (see TODO). +/// \param length Length of the data containing the new value. +//------------------------------------------------------------------------------ +static void AUDDSpeakerDriver_SetFeatureCurrentValue(unsigned char entity, + unsigned char channel, + unsigned char control, + unsigned short length) +{ + TRACE_INFO_WP("sFeature "); + TRACE_DEBUG("\b(E%d, CS%d, CN%d, L%d) ", + entity, control, channel, length); + + // Check the the requested control is supported + // Control/channel combination not supported + if ((control == AUDFeatureUnitRequest_MUTE) + && (channel < (AUDDSpeakerDriver_NUMCHANNELS+1)) + && (length == 1)) { + + unsigned int argument = channel; // Avoids compiler warning + USBD_Read(0, // Endpoint #0 + &muted, + sizeof(muted), + (TransferCallback) AUDDSpeakerDriver_MuteReceived, + (void *) argument); + } + // Control/channel combination not supported + else { + + USBD_Stall(0); + } +} + +//------------------------------------------------------------------------------ +/// Sends the current value of a particular channel Feature to the USB host. +/// \param entity Entity number. +/// \param channel Channel number. +/// \param control Control selector value (see TODO). +/// \param length Length of the data to return. +//------------------------------------------------------------------------------ +static void AUDDSpeakerDriver_GetFeatureCurrentValue(unsigned char entity, + unsigned char channel, + unsigned char control, + unsigned char length) +{ + TRACE_INFO_WP("gFeature "); + TRACE_DEBUG("\b(CS%d, CN%d, L%d) ", control, channel, length); + + // Check that the requested control is supported + // Master channel mute control + if ((control == AUDFeatureUnitRequest_MUTE) + && (channel < (AUDDSpeakerDriver_NUMCHANNELS+1)) + && (length == 1)) { + + muted = AUDDSpeakerChannel_IsMuted(&(auddSpeakerDriver.channels[channel])); + USBD_Write(0, &muted, sizeof(muted), 0, 0); + } + else { + + USBD_Stall(0); + } +} + +///* +// Function: AUDDSpeakerDriver_SetInterface +// Changes the current active alternate setting of the given interface. +// +// Parameters: +// +//*/ +//TRACE_DEBUG_M("SetInterface(%d,%d) ", setup->wIndex, setup->wValue); +// +// /* Check that interface is AudioStreaming OUT */ +// if (setup->wIndex == INTERFACE_ID_AUDIOSTREAMING_OUT) { +// +// /* Check desired alternate setting */ +// switch (setup->wValue) { +// case 0: +// case 1: +// if (speakerDriver->isOutStreamEnabled != setup->wValue) { +// +// speakerDriver->isOutStreamEnabled = setup->wValue; +// SPK_OutStreamStatusChanged(speakerDriver); +// LED_SetGlowing(LED_OTHER, setup->wValue); +// } +// USB_SendZLP0(usbDriver, 0, 0); +// break; +// +// default: +// USB_Stall(usbDriver, 0); +// } +// } +// else { +// +// USB_Stall(usbDriver, 0); +// } +// + +//------------------------------------------------------------------------------ +// Callback re-implementation +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Triggered when the USB host emits a new SETUP request. The request is +/// forward to . +/// \param request Pointer to a USBGenericRequest instance. +//------------------------------------------------------------------------------ +#if !defined(NOAUTOCALLBACK) +void USBDCallbacks_RequestReceived(const USBGenericRequest *request) +{ + AUDDSpeakerDriver_RequestHandler(request); +} +#endif + +//------------------------------------------------------------------------------ +/// Invoked whenever the active setting of an interface is changed by the +/// host. Changes the status of the third LED accordingly. +/// \param interface Interface number. +/// \param setting Newly active setting. +//------------------------------------------------------------------------------ +void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface, + unsigned char setting) +{ + if ((interface == AUDDSpeakerDriverDescriptors_STREAMING) + && (setting == 0)) { + + LED_Clear(USBD_LEDOTHER); + } + else { + + LED_Set(USBD_LEDOTHER); + } +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Initializes an USB audio speaker device driver, as well as the underlying +/// USB controller. +//------------------------------------------------------------------------------ +void AUDDSpeakerDriver_Initialize() +{ + // Initialize speaker channels + AUDDSpeakerChannel_Initialize(&(auddSpeakerDriver.channels[0]), + AUDDSpeakerDriver_MASTERCHANNEL, + 0); + AUDDSpeakerChannel_Initialize(&(auddSpeakerDriver.channels[1]), + AUDDSpeakerDriver_LEFTCHANNEL, + 0); + AUDDSpeakerChannel_Initialize(&(auddSpeakerDriver.channels[2]), + AUDDSpeakerDriver_RIGHTCHANNEL, + 0); + + // Initialize the USB driver + USBDDriver_Initialize(&(auddSpeakerDriver.usbdDriver), + &auddSpeakerDriverDescriptors, + auddSpeakerDriverInterfaces); + USBD_Init(); + + // Initialize the third LED to indicate when the audio interface is active + LED_Configure(USBD_LEDOTHER); +} + +//------------------------------------------------------------------------------ +/// Handles audio-specific USB requests sent by the host, and forwards +/// standard ones to the USB device driver. +/// \param request Pointer to a USBGenericRequest instance. +//------------------------------------------------------------------------------ +void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request) +{ + unsigned char entity; + unsigned char interface; + + 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: + TRACE_INFO_WP( + "sCur(0x%04X) ", + USBGenericRequest_GetIndex(request)); + + // Check the target interface and entity + entity = AUDGenericRequest_GetEntity(request); + interface = AUDGenericRequest_GetInterface(request); + if ((entity == AUDDSpeakerDriverDescriptors_FEATUREUNIT) + && (interface == AUDDSpeakerDriverDescriptors_CONTROL)) { + + AUDDSpeakerDriver_SetFeatureCurrentValue( + entity, + AUDFeatureUnitRequest_GetChannel(request), + AUDFeatureUnitRequest_GetControl(request), + USBGenericRequest_GetLength(request)); + } + else { + + TRACE_WARNING( + "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r", + USBGenericRequest_GetIndex(request)); + USBD_Stall(0); + } + break; + + case AUDGenericRequest_GETCUR: + TRACE_INFO_WP( + "gCur(0x%04X) ", + USBGenericRequest_GetIndex(request)); + + // Check the target interface and entity + entity = AUDGenericRequest_GetEntity(request); + interface = AUDGenericRequest_GetInterface(request); + if ((entity == AUDDSpeakerDriverDescriptors_FEATUREUNIT) + && (interface == AUDDSpeakerDriverDescriptors_CONTROL)) { + + AUDDSpeakerDriver_GetFeatureCurrentValue( + entity, + AUDFeatureUnitRequest_GetChannel(request), + AUDFeatureUnitRequest_GetControl(request), + USBGenericRequest_GetLength(request)); + } + else { + + TRACE_WARNING( + "AUDDSpeakerDriver_RequestHandler: Unsupported entity/interface combination (0x%04X)\n\r", + USBGenericRequest_GetIndex(request)); + USBD_Stall(0); + } + break; + + default: + + TRACE_WARNING( + "AUDDSpeakerDriver_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(&(auddSpeakerDriver.usbdDriver), request); + } + // Unsupported request type + else { + + TRACE_WARNING( + "AUDDSpeakerDriver_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. +//------------------------------------------------------------------------------ +unsigned char AUDDSpeakerDriver_Read(void *buffer, + unsigned int length, + TransferCallback callback, + void *argument) +{ + return USBD_Read(AUDDSpeakerDriverDescriptors_DATAOUT, + buffer, + length, + callback, + argument); +} + diff --git a/usb/device/audio-speaker/AUDDSpeakerDriver.h b/usb/device/audio-speaker/AUDDSpeakerDriver.h new file mode 100644 index 0000000..133d6df --- /dev/null +++ b/usb/device/audio-speaker/AUDDSpeakerDriver.h @@ -0,0 +1,201 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !Purpose + + Definition of a USB Audio Speaker Driver with two playback channels and one + record channel. + + !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 + -# To send %audio sampling stream to host, use + AUDDSpeakerDriver_Write + +*/ + +#ifndef AUDDSPEAKERDRIVER_H +#define AUDDSPEAKERDRIVER_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "Audio Speaker stream information" +/// +/// This page lists codes for USB Audio Speaker stream information. +/// +/// !Code +/// - AUDDSpeakerDriver_SAMPLERATE +/// - AUDDSpeakerDriver_NUMCHANNELS +/// - AUDDSpeakerDriver_BYTESPERSAMPLE +/// - AUDDSpeakerDriver_BITSPERSAMPLE +/// - AUDDSpeakerDriver_SAMPLESPERFRAME +/// - AUDDSpeakerDriver_BYTESPERFRAME + +#if defined(at91sam7s) + /// Sample rate in Hz. + #define AUDDSpeakerDriver_SAMPLERATE 32000 + /// Number of channels in audio stream. + #define AUDDSpeakerDriver_NUMCHANNELS 1 + /// Number of bytes in one sample. + #define AUDDSpeakerDriver_BYTESPERSAMPLE 2 +#else + /// Sample rate in Hz. + #define AUDDSpeakerDriver_SAMPLERATE 48000 + /// Number of channels in audio stream. + #define AUDDSpeakerDriver_NUMCHANNELS 2 + /// Number of bytes in one sample. + #define AUDDSpeakerDriver_BYTESPERSAMPLE 2 +#endif +/// Number of bits in one sample. +#define AUDDSpeakerDriver_BITSPERSAMPLE (AUDDSpeakerDriver_BYTESPERSAMPLE * 8) +/// Number of bytes in one USB subframe. +#define AUDDSpeakerDriver_BYTESPERSUBFRAME (AUDDSpeakerDriver_NUMCHANNELS * \ + AUDDSpeakerDriver_BYTESPERSAMPLE) +/// Number of samples in one USB frame. +#define AUDDSpeakerDriver_SAMPLESPERFRAME (AUDDSpeakerDriver_SAMPLERATE / 1000 \ + * AUDDSpeakerDriver_NUMCHANNELS) +/// Number of bytes in one USB frame. +#define AUDDSpeakerDriver_BYTESPERFRAME (AUDDSpeakerDriver_SAMPLESPERFRAME * \ + AUDDSpeakerDriver_BYTESPERSAMPLE) +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "Audio Speaker Channel Numbers" +/// +/// This page lists codes for USB Audio Speaker channel numbers. +/// +/// !Playback channel numbers +/// - AUDDSpeakerDriver_MASTERCHANNEL +/// - AUDDSpeakerDriver_LEFTCHANNEL +/// - AUDDSpeakerDriver_RIGHTCHANNEL +/// +/// !Record channel number +/// - 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 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern void AUDDSpeakerDriver_Initialize(); + +extern void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request); + +extern unsigned char AUDDSpeakerDriver_Read(void *buffer, + unsigned int length, + TransferCallback callback, + void *argument); + +#endif //#ifndef AUDDSPEAKERDRIVER_H + +//#ifndef SPEAKER_DRIVER_H +//#define SPEAKER_DRIVER_H +// +////------------------------------------------------------------------------------ +//// Definitions +////------------------------------------------------------------------------------ +// +///*! Sampling frequency in Hz */ +//#define SPEAKER_SAMPLERATE 48000 +///*! Number of samples in one isochronous packet (1ms frame) */ +//#define SPEAKER_SAMPLESPERPACKET (SPEAKER_SAMPLERATE / 1000) +///*! Size of one sample (in bytes) */ +//#define SPEAKER_SAMPLESIZE 2 +///*! Number of channels */ +//#define SPEAKER_NUMCHANNELS 2 +///*! Size of one frame (number of bytes sent for one sample on all channels) */ +//#define SPEAKER_FRAMESIZE (SPEAKER_SAMPLESIZE * SPEAKER_NUMCHANNELS) +///*! Required bit rate given the sample frequency, sample size and number of +// channels. */ +//#define SPEAKER_BITRATE (SPEAKER_SAMPLERATE * SPEAKER_FRAMESIZE) +///*! Size of one isochronous packet */ +//#define SPEAKER_PACKETSIZE (SPEAKER_SAMPLESPERPACKET * SPEAKER_FRAMESIZE) +// +////------------------------------------------------------------------------------ +//// Structures +////------------------------------------------------------------------------------ +///*! +// Holds the speaker driver state. +// */ +//typedef struct { +// +// S_std_class standardDriver; +// +// unsigned char isOutStreamEnabled; +// unsigned char isChannelMuted[SPEAKER_NUMCHANNELS+1]; +// +// Callback_f outStreamStatusChanged; +// Callback_f outStreamMuteChanged; +// +//} __attribute__((packed)) S_speaker; +// +////------------------------------------------------------------------------------ +//// Exported functions +////------------------------------------------------------------------------------ +// +//extern void SPK_Init(S_speaker *speakerDriver, const S_usb *usbDriver); +//extern void SPK_SetCallbacks(S_speaker *speakerDriver, +// Callback_f outStreamStatusChanged, +// Callback_f outStreamMuteChanged); +//extern void SPK_RequestHandler(S_speaker *speakerDriver); +//extern char SPK_Read(S_speaker *speakerDriver, +// void *buffer, +// unsigned int length, +// Callback_f callback, +// void *argument); +// +//#endif //#ifndef SPEAKER_DRIVER_H +// diff --git a/usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.c b/usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.c new file mode 100644 index 0000000..2501120 --- /dev/null +++ b/usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.c @@ -0,0 +1,620 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "AUDDSpeakerDriverDescriptors.h" +#include "AUDDSpeakerDriver.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "Audio Speaker Device Codes" +/// +/// This page lists the %device IDs and release number of the USB Audio Speaker +/// %device. +/// +/// !Codes +/// - AUDDSpeakerDriverDescriptors_VENDORID +/// - AUDDSpeakerDriverDescriptors_PRODUCTID +/// - AUDDSpeakerDriverDescriptors_RELEASE + +/// Device vendor ID. +#define AUDDSpeakerDriverDescriptors_VENDORID 0x03EB +/// Device product ID. +#define AUDDSpeakerDriverDescriptors_PRODUCTID 0x6128 +/// Device release number in BCD format. +#define AUDDSpeakerDriverDescriptors_RELEASE 0x0100 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Internal types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Audio control header descriptor with one slave interface. +//------------------------------------------------------------------------------ +#ifdef __ICCARM__ // IAR +#pragma pack(1) // IAR +#define __attribute__(...) // IAR +#endif // IAR + +//------------------------------------------------------------------------------ +/// Header descriptor with 1 interface. +//------------------------------------------------------------------------------ +typedef struct { + + /// Header descriptor. + AUDHeaderDescriptor header; + /// Id of the first grouped interface - Speaker. + unsigned char bInterface0; + +} __attribute__ ((packed)) AUDHeaderDescriptor1; // GCC + +//------------------------------------------------------------------------------ +/// Feature unit descriptor with 3 channel controls (master, right, left). +//------------------------------------------------------------------------------ +typedef struct { + + /// Feature unit descriptor. + AUDFeatureUnitDescriptor feature; + /// Available controls for each channel. + unsigned char bmaControls[3]; + /// Index of a string descriptor for the feature unit. + unsigned char iFeature; + +} __attribute__ ((packed)) AUDFeatureUnitDescriptor3; // GCC + +//------------------------------------------------------------------------------ +/// List of descriptors for detailling the audio control interface of a +/// device using a USB audio speaker driver. +//------------------------------------------------------------------------------ +typedef struct { + + /// Header descriptor (with one slave interface). + AUDHeaderDescriptor1 header; + /// Input terminal descriptor. + AUDInputTerminalDescriptor input; + /// Output terminal descriptor. + AUDOutputTerminalDescriptor output; + /// Feature unit descriptor. + AUDFeatureUnitDescriptor3 feature; + +} __attribute__ ((packed)) AUDDSpeakerDriverAudioControlDescriptors; // GCC + +//------------------------------------------------------------------------------ +/// Format type I descriptor with one discrete sampling frequency. +//------------------------------------------------------------------------------ +typedef struct { + + /// Format type I descriptor. + AUDFormatTypeOneDescriptor formatType; + /// Sampling frequency in Hz. + unsigned char tSamFreq[3]; + +} __attribute__ ((packed)) AUDFormatTypeOneDescriptor1; // GCC + +//------------------------------------------------------------------------------ +/// Holds a list of descriptors returned as part of the configuration of +/// a USB audio speaker device. +//------------------------------------------------------------------------------ +typedef struct { + + /// 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 variables +//------------------------------------------------------------------------------ + +/// Device descriptor for a USB audio speaker driver. +const USBDeviceDescriptor deviceDescriptor = { + + sizeof(USBDeviceDescriptor), + USBGenericDescriptor_DEVICE, + USBDeviceDescriptor_USB2_00, + AUDDeviceDescriptor_CLASS, + AUDDeviceDescriptor_SUBCLASS, + AUDDeviceDescriptor_PROTOCOL, + CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0), + AUDDSpeakerDriverDescriptors_VENDORID, + AUDDSpeakerDriverDescriptors_PRODUCTID, + AUDDSpeakerDriverDescriptors_RELEASE, + 1, // Manufacturer string descriptor index + 2, // Product string descriptor index + 3, // Index of serial number string descriptor + 1 // One possible configuration +}; + +#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS) + +/// USB device qualifier descriptor. +const USBDeviceQualifierDescriptor qualifierDescriptor = { + + sizeof(USBDeviceDescriptor), + USBGenericDescriptor_DEVICE, + USBDeviceDescriptor_USB2_00, + AUDDeviceDescriptor_CLASS, + AUDDeviceDescriptor_SUBCLASS, + AUDDeviceDescriptor_PROTOCOL, + CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0), + 1, // Device has one possible configuration + 0 // Reserved +}; + +#endif + +/// Configuration descriptors for a USB audio speaker driver. +const AUDDSpeakerDriverConfigurationDescriptors fsConfigurationDescriptors = { + + // Configuration descriptor + { + sizeof(USBConfigurationDescriptor), + USBGenericDescriptor_CONFIGURATION, + sizeof(AUDDSpeakerDriverConfigurationDescriptors), + 2, // This configuration has 2 interfaces + 1, // This is configuration #1 + 0, // No string descriptor + BOARD_USB_BMATTRIBUTES, + USBConfigurationDescriptor_POWER(100) + }, + // Audio control interface standard descriptor + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + AUDDSpeakerDriverDescriptors_CONTROL, + 0, // This is alternate setting #0 + 0, // This interface uses no endpoint + AUDControlInterfaceDescriptor_CLASS, + AUDControlInterfaceDescriptor_SUBCLASS, + AUDControlInterfaceDescriptor_PROTOCOL, + 0 // No string descriptor + }, + // Audio control interface descriptors + { + // Header descriptor + { + { + sizeof(AUDHeaderDescriptor1), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_HEADER, + AUDHeaderDescriptor_AUD1_00, + sizeof(AUDDSpeakerDriverAudioControlDescriptors), + 1 // One streaming interface + }, + AUDDSpeakerDriverDescriptors_STREAMING + }, + // Input terminal descriptor + { + sizeof(AUDInputTerminalDescriptor), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_INPUTTERMINAL, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + AUDInputTerminalDescriptor_USBSTREAMING, + AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL, + AUDDSpeakerDriver_NUMCHANNELS, + AUDInputTerminalDescriptor_LEFTFRONT + | AUDInputTerminalDescriptor_RIGHTFRONT, + 0, // No string descriptor for channels + 0 // No string descriptor for input terminal + }, + // Output terminal descriptor + { + sizeof(AUDOutputTerminalDescriptor), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_OUTPUTTERMINAL, + AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL, + AUDOutputTerminalDescriptor_SPEAKER, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + AUDDSpeakerDriverDescriptors_FEATUREUNIT, + 0 // No string descriptor + }, + // Feature unit descriptor + { + { + sizeof(AUDFeatureUnitDescriptor3), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_FEATUREUNIT, + AUDDSpeakerDriverDescriptors_FEATUREUNIT, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + 1, // 1 byte per channel for controls + }, + { + AUDFeatureUnitDescriptor_MUTE, // Master channel controls + 0, // Right channel controls + 0 // Left channel controls + }, + 0 // No string descriptor + } + }, + // Audio streaming interface with 0 endpoints + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + AUDDSpeakerDriverDescriptors_STREAMING, + 0, // This is alternate setting #0 + 0, // This interface uses no endpoints + AUDStreamingInterfaceDescriptor_CLASS, + AUDStreamingInterfaceDescriptor_SUBCLASS, + AUDStreamingInterfaceDescriptor_PROTOCOL, + 0 // No string descriptor + }, + // Audio streaming interface with data endpoint + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + AUDDSpeakerDriverDescriptors_STREAMING, + 1, // This is alternate setting #1 + 1, // This interface uses 1 endpoint + AUDStreamingInterfaceDescriptor_CLASS, + AUDStreamingInterfaceDescriptor_SUBCLASS, + AUDStreamingInterfaceDescriptor_PROTOCOL, + 0 // No string descriptor + }, + // Audio streaming class-specific descriptor + { + sizeof(AUDStreamingInterfaceDescriptor), + AUDGenericDescriptor_INTERFACE, + AUDStreamingInterfaceDescriptor_GENERAL, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + 0, // No internal delay because of data path + AUDFormatTypeOneDescriptor_PCM + }, + // Format type I descriptor + { + { + sizeof(AUDFormatTypeOneDescriptor1), + AUDGenericDescriptor_INTERFACE, + AUDStreamingInterfaceDescriptor_FORMATTYPE, + AUDFormatTypeOneDescriptor_FORMATTYPEONE, + AUDDSpeakerDriver_NUMCHANNELS, + AUDDSpeakerDriver_BYTESPERSAMPLE, + AUDDSpeakerDriver_BYTESPERSAMPLE*8, + 1 // One discrete frequency supported + }, + { + AUDDSpeakerDriver_SAMPLERATE & 0xFF, + (AUDDSpeakerDriver_SAMPLERATE >> 8) & 0xFF, + (AUDDSpeakerDriver_SAMPLERATE >> 16) & 0xFF + } + }, + // Audio streaming endpoint standard descriptor + { + sizeof(AUDEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( + USBEndpointDescriptor_OUT, + AUDDSpeakerDriverDescriptors_DATAOUT), + USBEndpointDescriptor_ISOCHRONOUS, + CHIP_USB_ENDPOINTS_MAXPACKETSIZE(AUDDSpeakerDriverDescriptors_DATAOUT), + AUDDSpeakerDriverDescriptors_FS_INTERVAL, // Polling interval = 1 ms + 0, // This is not a synchronization endpoint + 0 // No associated synchronization endpoint + }, + // Audio streaming endpoint class-specific descriptor + { + sizeof(AUDDataEndpointDescriptor), + AUDGenericDescriptor_ENDPOINT, + AUDDataEndpointDescriptor_SUBTYPE, + 0, // No attributes + 0, // Endpoint is not synchronized + 0 // Endpoint is not synchronized + } +}; + +#if defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS) +/// Configuration descriptors for a USB audio speaker driver. +const AUDDSpeakerDriverConfigurationDescriptors hsConfigurationDescriptors = { + + // Configuration descriptor + { + sizeof(USBConfigurationDescriptor), + USBGenericDescriptor_CONFIGURATION, + sizeof(AUDDSpeakerDriverConfigurationDescriptors), + 2, // This configuration has 2 interfaces + 1, // This is configuration #1 + 0, // No string descriptor + BOARD_USB_BMATTRIBUTES, + USBConfigurationDescriptor_POWER(100) + }, + // Audio control interface standard descriptor + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + AUDDSpeakerDriverDescriptors_CONTROL, + 0, // This is alternate setting #0 + 0, // This interface uses no endpoint + AUDControlInterfaceDescriptor_CLASS, + AUDControlInterfaceDescriptor_SUBCLASS, + AUDControlInterfaceDescriptor_PROTOCOL, + 0 // No string descriptor + }, + // Audio control interface descriptors + { + // Header descriptor + { + { + sizeof(AUDHeaderDescriptor1), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_HEADER, + AUDHeaderDescriptor_AUD1_00, + sizeof(AUDDSpeakerDriverAudioControlDescriptors), + 1 // One streaming interface + }, + AUDDSpeakerDriverDescriptors_STREAMING + }, + // Input terminal descriptor + { + sizeof(AUDInputTerminalDescriptor), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_INPUTTERMINAL, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + AUDInputTerminalDescriptor_USBSTREAMING, + AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL, + AUDDSpeakerDriver_NUMCHANNELS, + AUDInputTerminalDescriptor_LEFTFRONT + | AUDInputTerminalDescriptor_RIGHTFRONT, + 0, // No string descriptor for channels + 0 // No string descriptor for input terminal + }, + // Output terminal descriptor + { + sizeof(AUDOutputTerminalDescriptor), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_OUTPUTTERMINAL, + AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL, + AUDOutputTerminalDescriptor_SPEAKER, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + AUDDSpeakerDriverDescriptors_FEATUREUNIT, + 0 // No string descriptor + }, + // Feature unit descriptor + { + { + sizeof(AUDFeatureUnitDescriptor3), + AUDGenericDescriptor_INTERFACE, + AUDGenericDescriptor_FEATUREUNIT, + AUDDSpeakerDriverDescriptors_FEATUREUNIT, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + 1, // 1 byte per channel for controls + }, + { + AUDFeatureUnitDescriptor_MUTE, // Master channel controls + 0, // Right channel controls + 0 // Left channel controls + }, + 0 // No string descriptor + } + }, + // Audio streaming interface with 0 endpoints + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + AUDDSpeakerDriverDescriptors_STREAMING, + 0, // This is alternate setting #0 + 0, // This interface uses no endpoints + AUDStreamingInterfaceDescriptor_CLASS, + AUDStreamingInterfaceDescriptor_SUBCLASS, + AUDStreamingInterfaceDescriptor_PROTOCOL, + 0 // No string descriptor + }, + // Audio streaming interface with data endpoint + { + sizeof(USBInterfaceDescriptor), + USBGenericDescriptor_INTERFACE, + AUDDSpeakerDriverDescriptors_STREAMING, + 1, // This is alternate setting #1 + 1, // This interface uses 1 endpoint + AUDStreamingInterfaceDescriptor_CLASS, + AUDStreamingInterfaceDescriptor_SUBCLASS, + AUDStreamingInterfaceDescriptor_PROTOCOL, + 0 // No string descriptor + }, + // Audio streaming class-specific descriptor + { + sizeof(AUDStreamingInterfaceDescriptor), + AUDGenericDescriptor_INTERFACE, + AUDStreamingInterfaceDescriptor_GENERAL, + AUDDSpeakerDriverDescriptors_INPUTTERMINAL, + 0, // No internal delay because of data path + AUDFormatTypeOneDescriptor_PCM + }, + // Format type I descriptor + { + { + sizeof(AUDFormatTypeOneDescriptor1), + AUDGenericDescriptor_INTERFACE, + AUDStreamingInterfaceDescriptor_FORMATTYPE, + AUDFormatTypeOneDescriptor_FORMATTYPEONE, + AUDDSpeakerDriver_NUMCHANNELS, + AUDDSpeakerDriver_BYTESPERSAMPLE, + AUDDSpeakerDriver_BYTESPERSAMPLE*8, + 1 // One discrete frequency supported + }, + { + AUDDSpeakerDriver_SAMPLERATE & 0xFF, + (AUDDSpeakerDriver_SAMPLERATE >> 8) & 0xFF, + (AUDDSpeakerDriver_SAMPLERATE >> 16) & 0xFF + } + }, + // Audio streaming endpoint standard descriptor + { + sizeof(AUDEndpointDescriptor), + USBGenericDescriptor_ENDPOINT, + USBEndpointDescriptor_ADDRESS( + USBEndpointDescriptor_OUT, + AUDDSpeakerDriverDescriptors_DATAOUT), + USBEndpointDescriptor_ISOCHRONOUS, + CHIP_USB_ENDPOINTS_MAXPACKETSIZE(AUDDSpeakerDriverDescriptors_DATAOUT), + AUDDSpeakerDriverDescriptors_HS_INTERVAL, // Polling interval = 1 ms + 0, // This is not a synchronization endpoint + 0 // No associated synchronization endpoint + }, + // Audio streaming endpoint class-specific descriptor + { + sizeof(AUDDataEndpointDescriptor), + AUDGenericDescriptor_ENDPOINT, + AUDDataEndpointDescriptor_SUBTYPE, + 0, // No attributes + 0, // Endpoint is not synchronized + 0 // Endpoint is not synchronized + } +}; +#endif // defined(CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS) + +/// String descriptor with the supported languages. +const unsigned char languageIdDescriptor[] = { + + USBStringDescriptor_LENGTH(1), + USBGenericDescriptor_STRING, + USBStringDescriptor_ENGLISH_US +}; + +/// Manufacturer name. +const unsigned char manufacturerDescriptor[] = { + + USBStringDescriptor_LENGTH(5), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('A'), + USBStringDescriptor_UNICODE('t'), + USBStringDescriptor_UNICODE('m'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE('l') +}; + +/// Product name. +const unsigned char productDescriptor[] = { + + USBStringDescriptor_LENGTH(15), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('D'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE('s'), + USBStringDescriptor_UNICODE('k'), + USBStringDescriptor_UNICODE('t'), + USBStringDescriptor_UNICODE('o'), + USBStringDescriptor_UNICODE('p'), + USBStringDescriptor_UNICODE(' '), + USBStringDescriptor_UNICODE('s'), + USBStringDescriptor_UNICODE('p'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE('a'), + USBStringDescriptor_UNICODE('k'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE('r') +}; + +/// Product serial number. +const unsigned char serialNumberDescriptor[] = { + + USBStringDescriptor_LENGTH(4), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('0'), + USBStringDescriptor_UNICODE('1'), + USBStringDescriptor_UNICODE('2'), + USBStringDescriptor_UNICODE('3') +}; + +/// Array of pointers to the four string descriptors. +const unsigned char *stringDescriptors[] = { + + languageIdDescriptor, + manufacturerDescriptor, + productDescriptor, + serialNumberDescriptor, +}; + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +/// List of descriptors required by an USB audio speaker device driver. +const USBDDriverDescriptors auddSpeakerDriverDescriptors = { + + &deviceDescriptor, + (const USBConfigurationDescriptor *) &fsConfigurationDescriptors, +#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS) + &qualifierDescriptor, + (const USBConfigurationDescriptor *) &hsConfigurationDescriptors, + &deviceDescriptor, + (const USBConfigurationDescriptor *) &hsConfigurationDescriptors, + &qualifierDescriptor, + (const USBConfigurationDescriptor *) &hsConfigurationDescriptors, +#else + 0, 0, 0, 0, 0, 0, +#endif + stringDescriptors, + 4 // Number of string descriptors +}; + diff --git a/usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.h b/usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.h new file mode 100644 index 0000000..7bc7352 --- /dev/null +++ b/usb/device/audio-speaker/AUDDSpeakerDriverDescriptors.h @@ -0,0 +1,146 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +/** + \unit + + !!!Purpose + + Declaration of the descriptors required by a USB audio speaker driver. + + !!!Usage + + -# Initialize a USBDDriver instance using the + auddSpeakerDriverDescriptors list. +*/ + +#ifndef AUDDSPEAKERDRIVERDESCRIPTORS_H +#define AUDDSPEAKERDRIVERDESCRIPTORS_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "Audio Speaker Endpoint Numbers" +/// +/// This page lists the endpoint number settings for USB Audio Speaker device. +/// +/// !Endpoints +/// - AUDDSpeakerDriverDescriptors_DATAOUT +/// - AUDDSpeakerDriverDescriptors_DATAIN +/// - AUDDSpeakerDriverDescriptors_FS_INTERVAL +/// - AUDDSpeakerDriverDescriptors_HS_INTERVAL +/// +/// \note for UDP, uses IN EPs that support double buffer; for UDPHS, uses +/// IN EPs that support DMA and High bandwidth. + +#if defined(at91sam7s) || defined(at91sam9xe) + /// Data out endpoint number. + #define AUDDSpeakerDriverDescriptors_DATAOUT 0x01 + /// Data in endpoint number. + #define AUDDSpeakerDriverDescriptors_DATAIN 0x02 +#elif defined(CHIP_USB_UDP) + /// Data out endpoint number. + #define AUDDSpeakerDriverDescriptors_DATAOUT 0x04 + /// Data in endpoint number. + #define AUDDSpeakerDriverDescriptors_DATAIN 0x05 +#else + /// Data out endpoint number. + #define AUDDSpeakerDriverDescriptors_DATAOUT 0x05 + /// Data in endpoint number. + #define AUDDSpeakerDriverDescriptors_DATAIN 0x06 +#endif + +/// Endpoint polling interval 2^(x-1) * 125us +#define AUDDSpeakerDriverDescriptors_HS_INTERVAL 0x04 +/// Endpoint polling interval 2^(x-1) * ms +#define AUDDSpeakerDriverDescriptors_FS_INTERVAL 0x01 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "Audio Speaker Interface IDs" +/// +/// This page lists the interface numbers for USB Audio Speaker device. +/// +/// !Interfaces +/// - AUDDSpeakerDriverDescriptors_CONTROL +/// - AUDDSpeakerDriverDescriptors_STREAMING +/// - AUDDSpeakerDriverDescriptors_STREAMINGIN + +/// Audio control interface ID. +#define AUDDSpeakerDriverDescriptors_CONTROL 0 +/// Audio streaming interface ID (OUT, for playback). +#define AUDDSpeakerDriverDescriptors_STREAMING 1 +/// Audio streaming interface ID (IN, for record). +#define AUDDSpeakerDriverDescriptors_STREAMINGIN 2 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// \page "Audio Speaker Entity IDs" +/// +/// This page lists the entity IDs for USB Audio Speaker device. +/// +/// !Entities +/// - AUDDSpeakerDriverDescriptors_INPUTTERMINAL +/// - AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL +/// - AUDDSpeakerDriverDescriptors_FEATUREUNIT +/// - AUDDSpeakerDriverDescriptors_INPUTTERMINAL_REC +/// - AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL_REC +/// - AUDDSpeakerDriverDescriptors_FEATUREUNIT_REC + +/// Playback input terminal ID. +#define AUDDSpeakerDriverDescriptors_INPUTTERMINAL 0 +/// Playback output terminal ID. +#define AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL 1 +/// Playback feature unit ID. +#define AUDDSpeakerDriverDescriptors_FEATUREUNIT 2 +/// Record input terminal ID. +#define AUDDSpeakerDriverDescriptors_INPUTTERMINAL_REC 3 +/// Record output terminal ID. +#define AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL_REC 4 +/// Record feature unit ID +#define AUDDSpeakerDriverDescriptors_FEATUREUNIT_REC 5 +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Exported variables +//------------------------------------------------------------------------------ + +extern const USBDDriverDescriptors auddSpeakerDriverDescriptors; + +#endif //#ifndef AUDDSPEAKERDRIVERDESCRIPTORS_H + diff --git a/usb/device/audio-speaker/USBAudioSpeaker.png b/usb/device/audio-speaker/USBAudioSpeaker.png new file mode 100644 index 0000000..bcae300 Binary files /dev/null and b/usb/device/audio-speaker/USBAudioSpeaker.png differ diff --git a/usb/device/audio-speaker/USBAudioSpeakerDescriptors.png b/usb/device/audio-speaker/USBAudioSpeakerDescriptors.png new file mode 100644 index 0000000..251a2d1 Binary files /dev/null and b/usb/device/audio-speaker/USBAudioSpeakerDescriptors.png differ diff --git a/usb/device/audio-speaker/USBAudioSpeakerRecorder.png b/usb/device/audio-speaker/USBAudioSpeakerRecorder.png new file mode 100644 index 0000000..ddbd234 Binary files /dev/null and b/usb/device/audio-speaker/USBAudioSpeakerRecorder.png differ diff --git a/usb/device/audio-speaker/USBAudioSpeakerRecorderDescriptors.png b/usb/device/audio-speaker/USBAudioSpeakerRecorderDescriptors.png new file mode 100644 index 0000000..c5c3324 Binary files /dev/null and b/usb/device/audio-speaker/USBAudioSpeakerRecorderDescriptors.png differ diff --git a/usb/device/audio-speaker/audio-speaker.dir b/usb/device/audio-speaker/audio-speaker.dir new file mode 100644 index 0000000..be90df0 --- /dev/null +++ b/usb/device/audio-speaker/audio-speaker.dir @@ -0,0 +1,617 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +/// \dir +/// +/// !!!Purpose +/// +/// This directory provides definitions, structs and functions for a USB Audio +/// Class device - USB audio-speaker demo, to implement an USB desktop speaker. +/// +/// !!!Contents +/// There are two things for the implement of the audio-speaker device driver: +/// - Implement the audio-speaker driver structs and functions for the device, +/// to initialize, to handle audio class specific requests and dispach +/// standard requests in USBD callbacks, to read/write through assigned USB +/// endpoints, +/// - Create the audio-speaker device's descriptors that should be passed to +/// the USBDDriver instance on initialization, so that the host can +/// recognize the device as a USB audio "desktop speaker" device. +/// +/// For more information about what a particular group contains, please refer to +/// "USB Audio Speaker Device". +//------------------------------------------------------------------------------ + +/** + \page "USB Audio Speaker Device" + This page describes how to use the USB framework to produce a USB Audio Class + Device driver. + + !!!References + - "AT91 USB device framework" + - "USB Device Enumeration" + - + Universal Serial Bus Revision 2.0 specification + (.zip file format, size 9.80 MB) + - + Audio Device Document 1.0 + - + Audio Data Formats 1.0 + - + Autio Terminal Types 1.0 + + !!!Audio Speaker Driver API + - AUDDSpeakerDriver_Initialize + - AUDDSpeakerDriver_RequestHandler + - AUDDSpeakerDriver_Read + + !!!Audio Desktop Speaker Description + The %device described here is a USB desktop speaker. It receives a stero + %audio data stream from the Host over its Audio Streaming interface. The used + Audio Data Format is 16-bit 48KHz 2-channel PCM (or mono 16-bit 32KHz PCM for + sam7s chips). The following is the internal topology of the speaker. + + \image USBAudioSpeaker.png "USB Desktop Speaker Topology" + + The %audio function contains one Onput Terminal that represents the actual + speaker output element, followed by the Digital-to-Analog Converter (DAC). + The digital input stream of the host enters the %audio function through the + single Input %Pin of the Output terminal. There is a Feature Unit on the + %audio stream, to mute or unmute the speaker. The Input Terminal is the + representation within the %audio fucntion of the USB OUT endpoint that + eventually receives the %audio data stream from the Host. The internals of the + %audio function are presented to the Host through the (mandatory) AudioControl + interface wheras the USB OUT endpoint resides in the AudioStreaming interface. + + !!!Descriptor Hierarchy + This USB Desktop Speaker %device includes the AudioControl interface + (interface 0) and a single AudioStreaming interface (interface 1). The + AudioStreaming interface features two alternate settings. The first alternate + setting (Alternate Setting 0) has zero bandwidth associated with it so that + switching to this alternate setting effectively frees all allocated bandwidth + on the USB for this device. Zero bandwidth is indicated by the lack of a + streaming endpoint. Alternate Setting 1 is the operational part of the + interface and it has one isochronous OUT endpoint. Figure presents the + descriptor hierarchy. + + \image UsbAudioSpeakerDescriptors.png "USB Desktop Speaker Hierarchy" + + !!!Descriptors + The following sections present all the descriptors that are used to describe + the %device. + + All descriptors are combined into a list and pass to USBDDriver_Initialize + invoked in AUDDSpeakerDriver_Initialize. + +\code +const USBDDriverDescriptors auddSpeakerDriverDescriptors; +\endcode + + !!Device Descriptor +\code +const USBDeviceDescriptor deviceDescriptor; +\endcode +||Offset||Field||Size||Value||Description +|0|bLength|1|0x12|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x01|DEVICE descriptor (USBGenericDescriptor_DEVICE). +|2|bcdUSB|2|0x0200|2.00 - current revision of USB specification. +|4|bDeviceClass|1|0x00|Device defined at interface level. +|5|bDeviceSubClass|1|0x00|Unused. +|6|bDeviceProtocol|1|0x00|Unused. +|7|bMaxPacketSize0|1|0x08|8 bytes (BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0)). +|8|idVendor|2|0x03EB|Atmel Vendor ID (AUDDSpeakerDriverDescriptors_VENDORID). +|10|idProduct|2|0x6128|Product ID (AUDDSpeakerDriverDescriptors_PRODUCTID). +|12|bcdDevice|2|0x0100|Device Release Code\n + (AUDDSpeakerDriverDescriptors_RELEASE). +|14|iManufacturer|1|0x01|Index to manufacture name in Unicode\n + (manufacturerDescriptor). +|15|iProduct|1|0x02|Index to product name in Unicode (productDescriptor). +|16|iSerialNumber|1|0x03|Index to serial number in Unicode\n + (serialNumberDescriptor). +|17|bNumConfigurations|1|0x01|One configuration. + + !!Configuration Descriptor +\code +const AUDDSpeakerDriverConfigurationDescriptors configurationDescriptors; +\endcode +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x02|CONFIGURATION descriptor\n + (USBGenericDescriptor_CONFIGURATION). +|2|wTotalLength|2|0x????|Length of the total configuration block in bytes\n + including this descriptor\n + (AUDDSpeakerDriverConfigurationDescriptors) +|4|bNumInterfaces|1|0x02|Two interfaces. +|5|bConfigurationValue|1|0x01|ID of this configuration. +|6|iConfiguration|1|0x00|Unused. +|7|bmAttributes|1|0x??|BOARD_USB_BMATTRIBUTES +|8|bMaxPower|1|0x32|100mA Max. %power consumption.\n + USBConfigurationDescriptor_POWER(100) + + !!AudioControl Interface Descriptor + The AudioControl interface describes the %device structure (%audio function + topology) and is used to manipulate the Audio Controls. + + !Standard AC Interface Descriptor + The AudioControl interface has no dedicated endpoints associated with it. It + uses the default pipe (endpoint 0) for all communication purposes. Class- + specific AudioControl Requests are sent using the default pipe. There is no + Status Interrupt endpoint provided. + + See USBInterfaceDescriptor. +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x04|INTERFACE descriptor\n + (USBGenericDescriptor_INTERFACE). +|2|bInterfaceNumber|1|0x00|Index of this interface. +|3|bAlternateSetting|1|0x00|Index of this setting. +|4|bNumEndpoints|1|0x00|0 endpoints. +|5|bInterfaceClass|1|0x01|AUDIO (AUDControlInterfaceDescriptor_CLASS). +|6|bInterfaceSubClass|1|0x01|AUDIO_CONTROL\n + (AUDControlInterfaceDescriptor_SUBCLASS). +|7|bInterfaceProtocol|1|0x00|Unused. +|8|iInterface|1|0x00|Unused. + + !Class-specific AC Interface Descriptor + The Class-specific AC interface descriptor is always headed by a Header + descriptor that contains general information about the AudioControl interface. + It contains all the pointers needed to describe the AudioInterface Collection, + associated with the described %audio function. +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubtype|1|0x01|HEADER subtype (AUDGenericDescriptor_HEADER). +|3|bcdADC|2|0x0100|Revision of class specification - 1.0 +|5|wTotalLength|2|0x????|Total size of class specific descriptors\n + (AUDDSpeakerDriverAudioControlDescriptors). +|7|bInCollection|1|0x01|Number of streaming interfaces. +|8|baInterfaceNr(1)|1|0x01|AudioStreaming interface 1 belongs to this AudioControl interface. + + !Input Terminal Descriptor for playback + This descriptor describes the Input Terminal that represents the USB pipe from + the Host PC. Its Output Pin is connected to the Input Pin of the Feature Unit + ... +||Offset||Field||Size||Value||Description +|0|bLength|1|0x0C|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x02|INPUT_TERMINAL subtype\n + (AUDGenericDescriptor_INPUTTERMINAL). +|3|bTerminalID|1|0x00|ID of this Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL). +|4|wTerminalType|2|0x0101|Terminal is USB stream\n + (AUDInputTerminalDescriptor_USBSTREAMING). +|6|bAssocTerminal|1|0x01|Associated to Output Terminal\n + (AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL). +|7|bNrChannels|1|0x02|Two channel. +|8|wChannelConfig|2|0x0003|Left plus right front channel. +|10|iChannelNames|1|0x00|Unused. +|11|iTerminal|1|0x00|Unused. + + !Output Terminal Descriptor for playback + ... +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x03|OUTPUT_TERMINAL subtype\n + (AUDGenericDescriptor_OUTPUTTERMINAL). +|3|bTerminalID|1|0x01|ID of this Output Terminal\n + (AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL). +|4|wTerminalType|2|0x0301|Terminal is Desktop speaker. +|6|bAssocTerminal|1|0x01|Associated to Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL). +|7|bSourceID|1|0x02|From Feature Unit\n + (AUDDSpeakerDriverDescriptors_FEATUREUNIT). +|8|iTerminal|1|0x00|Unused. + + !Feature Unit Descriptor for playback + ... +||Offset||Field||Size||Value||Description +|0|bLength|1|0x0A|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x02|FEATURE_UNIT subtype\n + (AUDGenericDescriptor_FEATUREUNIT). +|3|bUnitID|1|0x02|ID of this Feature Unit\n + (AUDDSpeakerDriverDescriptors_FEATUREUNIT). +|4|bSourceID|1|0x00|From Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL). +|5|bControlSize|1|0x01|1 byte per channel for controls +|6|bmaControls|3|0x000001|Master channel mute control, no other controls. +|9|iFeature|1|0x00|Unused. + + !!AudioStreaming Interface Descriptor + The AudioStreaming interface has two possible alternate settings. + + !Zero-bandwidth Alternate Setting 0 + Alternate setting 0 is a zero-bandwidth setting, used to relinquish the + claimed bandwidth on the bus when the microphone is not in use. It is the + default setting after power-up. The zero bandwidth is implemented by + specifying that this alternate setting of the interface has no endpoints + associated with it (bNumEndpoints=0). The collection of descriptors for this + alternate setting reduces to the standard interface descriptor. + + Standard AS Interface Descriptor (USBInterfaceDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x04|INTERFACE descriptor\n + (USBGenericDescriptor_INTERFACE). +|2|bInterfaceNumber|1|0x01|Index of this interface. +|3|bAlternateSetting|1|0x00|Index of this setting. +|4|bNumEndpoints|1|0x00|0 endpoint. +|5|bInterfaceClass|1|0x01|AUDIO (AUDStreamingInterfaceDescriptor_CLASS). +|6|bInterfaceSubClass|1|0x02|AUDIO_STREAMING\n + (AUDStreamingInterfaceDescriptor_SUBCLASS). +|7|bInterfaceProtocol|1|0x00|Unused (AUDStreamingInterfaceDescriptor_PROTOCOL). +|8|iInterface|1|0x00|Unused. + + !Operational Alternate Setting 1 + Alternate setting 1 is the operational setting of the interface. It contains + the standard and class-specific interface and endpoint descriptors. + + Standard AS Interface Descriptor (USBInterfaceDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of USBInterfaceDescriptor in bytes. +|1|bDescriptorType|1|0x04|INTERFACE descriptor\n + (USBGenericDescriptor_INTERFACE). +|2|bInterfaceNumber|1|0x01|Index of this interface. +|3|bAlternateSetting|1|0x01|Index of this setting. +|4|bNumEndpoints|1|0x01|1 endpoint. +|5|bInterfaceClass|1|0x01|AUDIO (AUDStreamingInterfaceDescriptor_CLASS). +|6|bInterfaceSubClass|1|0x02|AUDIO_STREAMING\n + (AUDStreamingInterfaceDescriptor_SUBCLASS). +|7|bInterfaceProtocol|1|0x00|Unused (AUDStreamingInterfaceDescriptor_PROTOCOL). +|8|iInterface|1|0x00|Unused. + + Class-specific AS General Interface Descriptor (AUDStreamingInterfaceDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x06|Size of AUDStreamingInterfaceDescriptor in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x01|GENERAL subtype\n + (AUDStreamingInterfaceDescriptor_GENERAL). +|3|bTerminalLink|1|0x02|Unit ID of the Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL). +|4|bDelay|1|0x00|No interface delay. +|5|wFormatTag|2|0x0001|PCM Format (AUDFormatTypeOneDescriptor_PCM). + + Type I Format Type Descriptor (AUDFormatTypeOneDescriptor1) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x0B|Size of AUDFormatTypeOneDescriptor1 in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\ + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x02|FORMAT_TYPE subtype\n + (AUDStreamingInterfaceDescriptor_FORMATTYPE). +|3|bFormatType|1|0x01|FORMAT_TYPE_I (AUDFormatTypeOneDescriptor_FORMATTYPEONE). +|4|bNrChannels|1|0x02|2 channels (AUDDSpeakerDriver_NUMCHANNELS). +|5|bSubFrameSize|1|0x02|Two bytes per audio subframe\n + (AUDDSpeakerDriver_BYTESPERSAMPLE). +|6|bBitResolution|1|0x10|16 bits per sample\n + (AUDDSpeakerDriver_BYTESPERSAMPLE * 2). +|7|bSamFreqType|1|0x01|One frequency supported. +|8|tSamFreq|3|4800|4800Hz (AUDDSpeakerDriver_SAMPLERATE). + + Standard %Endpoint Descriptor (AUDEndpointDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of AUDFormatTypeOneDescriptor1 in bytes. +|1|bDescriptorType|1|0x24|ENDPOINT descriptor (USBGenericDescriptor_ENDPOINT). +|2|bEndpointAddress|1|0x04\nTest|OUT endpoint 4\n + See USBEndpointDescriptor_ADDRESS\n + See AUDDSpeakerDriverDescriptors_DATAOUT. +|3|bmAttributes|1|0x01|Isochronous, not shared\n + (USBEndpointDescriptor_ISOCHRONOUS). +|4|wMaxPacketSize|2|0x????|BOARD_USB_ENDPOINTS_MAXPACKETSIZE(). +|6|bInterval|1|0x01|One packet per frame. +|7|bRefresh|1|0x00|Unused. +|8|bSynchAddress|1|0x00|Unused. + + Class-specific Isochronous Audio Data Endpoint Descriptor + (AUDDataEndpointDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x07|Size of AUDDataEndpointDescriptor in bytes. +|1|bDescriptorType|1|0x25|CS_ENDPOINT descriptor\n + (AUDGenericDescriptor_ENDPOINT). +|2|bDescriptorSubType|1|0x01|GENERAL subtype\n + (AUDDataEndpointDescriptor_SUBTYPE). +|3|bmAttributes|1|0x00|No sampling frequency control\n + no pitch control\n + no packet padding. +|4|bLockDelayUnits|1|0x00|Unused. +|5|wLockDelay|2|0x0000|Unused. + + !!String Descriptors + There are three string descriptors available. The Manufacturer, Product and + Serial Number descriptor. + + See manufacturerDescriptor, productDescriptor, serialNumberDescriptor. + + !!!Requests + The Audio Speaker Driver supports all necessary standard requests, and some + class-specific requests. + + USBDCallbacks_RequestReceived is used to filter all requests, + AUDDSpeakerDriver_RequestHandler is invoked to handle Audio Class requests + and forward standard request to AUDDSpeakerDriver_RequestHandler. + + !!Standard requests + Set Interface request should be processed to control bandwidth allocation. + + !Set Interface + USBDDriverCallbacks_InterfaceSettingChanged is re-implemented to handle the + event. +||Offset||Field||Size||Value||Description +|0|bmRequestType|1|0x01|D7:0=Host to Device.\n + D6..5:00=Standard Request.\n + D4..0:00001=Recipient is interface. +|1|bRequest|1|0x0B|SET_INTERFACE. +|2|wValue|2|0x0000\n + or\n + 0x0001|Zero bandwidth or normal isochronous operation. +|4|wIndex|2|0x0001|Interface number of the AudioStreaming interface. +|6|wLength|2|0x0000|No Parameter Block. + + !!Class-specific requests + The only class-specific Request supported is the Set/Get Feature Unit Control + Request. For mute control of the Feature Unit. + + !Set Feature Unit Control Request +||Offset||Field||Size||Value||Description +|0|bmRequestType|1|0x01|D7:0=Host to Device.\n + D6..5:01=Class Request.\n + D4..0:00001=Recipient is interface. +|1|bRequest|1|0x01|SET_CUR. +|2|wValue|2|0x0100|Mute control (AUDFeatureUnitRequest_MUTE) of\n + Master channel (AUDDSpeakerDriver_MASTERCHANNEL). +|4|wIndex|2|0x0200|Feature Unit (AUDDSpeakerDriverDescriptors_FEATUREUNIT)\n + and\n + AudioControl Interface (AUDDSpeakerDriverDescriptors_CONTROL). +|6|wLength|2|0x0001|Paramter Block Length + + The one-byte Parameter Block contains the new bMuted value for Feature + Control. + + !Get Feature Unit Control Request +||Offset||Field||Size||Value||Description +|0|bmRequestType|1|0x01|D7:0=Host to Device.\n + D6..5:01=Class Request.\n + D4..0:00001=Recipient is interface. +|1|bRequest|1|0x81|GET_CUR. +|2|wValue|2|0x0100|Mute control (AUDFeatureUnitRequest_MUTE) of\n + Master channel (AUDDSpeakerDriver_MASTERCHANNEL). +|4|wIndex|2|0x0200|Feature Unit (AUDDSpeakerDriverDescriptors_FEATUREUNIT)\n + and\n + AudioControl Interface (AUDDSpeakerDriverDescriptors_CONTROL). +|6|wLength|2|0x0001|Paramter Block Length + + The one-byte Parameter Block contains the new bMuted value for Feature + Control. + + !!!Modify the Device Driver + You can modify your project from the USB Audio Demoes: + - usb-device-audio-speaker-ac97-project + - usb-device-audio-speaker-project + + !!Change Device ID and Display + All Device ID and Display Strings are in AUDDSpeakerDriverDescriptors.c. + + !Device IDs + You can find "Audio Speaker Device Codes" + - AUDDSpeakerDriverDescriptors_VENDORID + - AUDDSpeakerDriverDescriptors_PRODUCTID + - AUDDSpeakerDriverDescriptors_RELEASE + + !Display Strings + You can modify the string descriptors + - manufacturerDescriptor + - productDescriptor + - serialNumberDescriptor + + !!!Add Recorder Function + See "USB Audio Recorder". + +*/ + +/** + \page "USB Audio Recorder" + This page describes how to add recorder function into the + "USB Audio Speaker Device", So that you can learn how to extend your audio + device driver from current Audio Speaker demo. + + !!!Description + To add %audio record function, new Input Terminal, Output Termnial and Feature + Unit is added. + + \image UsbAudioSpeakerRecorder.png "USB Desktop Speaker Hierarchy" + + + !!!Modify the configuration descriptor: + New descriptor for the terminals and unit should be added, and according + interface, too. + + \image UsbAudioSpeakerRecorderDescriptors.png "USB Desktop Speaker Descriptors" + + + + !!Terminal Descriptors and Unit Descriptor + ... + !Input Terminal Descriptor for recording + ... +||Offset||Field||Size||Value||Description +|0|bLength|1|0x0C|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x03|INPUT_TERMINAL subtype\n + (AUDGenericDescriptor_INPUTTERMINAL). +|3|bTerminalID|1|0x03|ID of this Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL_REC). +|4|wTerminalType|2|0x0403|Terminal is Speaker Phone\n + (AUDInputTerminalDescriptor_SPEAKERPHONE). +|6|bAssocTerminal|1|0x04|Associated to Output Terminal\n + (AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL_REC). +|7|bNrChannels|1|0x02|Two channel. +|8|wChannelConfig|2|0x0003|Left plus right front channel. +|10|iChannelNames|1|0x00|Unused. +|11|iTerminal|1|0x00|Unused. + + !Output Terminal Descriptor for recording + ... +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x04|OUTPUT_TERMINAL subtype\n + (AUDGenericDescriptor_OUTPUTTERMINAL). +|3|bTerminalID|1|0x04|ID of this Output Terminal\n + (AUDDSpeakerDriverDescriptors_OUTPUTTERMINAL_REC). +|4|wTerminalType|2|0x0301|Terminal is USB stream\n + (AUDOutputTerminalDescriptor_USBTREAMING). +|6|bAssocTerminal|1|0x03|Associated to Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL_REC). +|7|bSourceID|1|0x05|From Feature Unit\n + (AUDDSpeakerDriverDescriptors_FEATUREUNIT_REC). +|8|iTerminal|1|0x00|Unused. + + !Feature Unit Descriptor for recording + ... +||Offset||Field||Size||Value||Description +|0|bLength|1|0x0A|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x02|FEATURE_UNIT subtype\n + (AUDGenericDescriptor_FEATUREUNIT). +|3|bUnitID|1|0x05|ID of this Feature Unit\n + (AUDDSpeakerDriverDescriptors_FEATUREUNIT_REC). +|4|bSourceID|1|0x03|From Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL_REC). +|5|bControlSize|1|0x01|1 byte per channel for controls +|6|bmaControls|3|0x000001|Master channel mute control, no other controls. +|9|iFeature|1|0x00|Unused. + + !!Interface Descriptor and Endpoint Descriptor for recording + ... + + !Zero-bandwidth Alternate Setting 0 + Standard AS Interface Descriptor (USBInterfaceDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of this descriptor, in bytes. +|1|bDescriptorType|1|0x04|INTERFACE descriptor\n + (USBGenericDescriptor_INTERFACE). +|2|bInterfaceNumber|1|0x02|Index of this interface. +|3|bAlternateSetting|1|0x00|Index of this setting. +|4|bNumEndpoints|1|0x00|0 endpoint. +|5|bInterfaceClass|1|0x01|AUDIO (AUDStreamingInterfaceDescriptor_CLASS). +|6|bInterfaceSubClass|1|0x02|AUDIO_STREAMING\n + (AUDStreamingInterfaceDescriptor_SUBCLASS). +|7|bInterfaceProtocol|1|0x00|Unused (AUDStreamingInterfaceDescriptor_PROTOCOL). +|8|iInterface|1|0x00|Unused. + + !Operational Alternate Setting 1 + Standard AS Interface Descriptor (USBInterfaceDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of USBInterfaceDescriptor in bytes. +|1|bDescriptorType|1|0x04|INTERFACE descriptor\n + (USBGenericDescriptor_INTERFACE). +|2|bInterfaceNumber|1|0x02|Index of this interface. +|3|bAlternateSetting|1|0x01|Index of this setting. +|4|bNumEndpoints|1|0x01|1 endpoint. +|5|bInterfaceClass|1|0x01|AUDIO (AUDStreamingInterfaceDescriptor_CLASS). +|6|bInterfaceSubClass|1|0x02|AUDIO_STREAMING\n + (AUDStreamingInterfaceDescriptor_SUBCLASS). +|7|bInterfaceProtocol|1|0x00|Unused (AUDStreamingInterfaceDescriptor_PROTOCOL). +|8|iInterface|1|0x00|Unused. + + Class-specific AS General Interface Descriptor (AUDStreamingInterfaceDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x06|Size of AUDStreamingInterfaceDescriptor in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x01|GENERAL subtype\n + (AUDStreamingInterfaceDescriptor_GENERAL). +|3|bTerminalLink|1|0x02|Unit ID of the Input Terminal\n + (AUDDSpeakerDriverDescriptors_INPUTTERMINAL). +|4|bDelay|1|0x00|No interface delay. +|5|wFormatTag|2|0x0001|PCM Format (AUDFormatTypeOneDescriptor_PCM). + + Type I Format Type Descriptor (AUDFormatTypeOneDescriptor1) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x0B|Size of AUDFormatTypeOneDescriptor1 in bytes. +|1|bDescriptorType|1|0x24|CS_INTERFACE descriptor\n + (AUDGenericDescriptor_INTERFACE). +|2|bDescriptorSubType|1|0x02|FORMAT_TYPE subtype\n + (AUDStreamingInterfaceDescriptor_FORMATTYPE). +|3|bFormatType|1|0x01|FORMAT_TYPE_I (AUDFormatTypeOneDescriptor_FORMATTYPEONE). +|4|bNrChannels|1|0x02|2 channels (AUDDSpeakerDriver_NUMCHANNELS). +|5|bSubFrameSize|1|0x02|Two bytes per audio subframe\n + (AUDDSpeakerDriver_BYTESPERSAMPLE). +|6|bBitResolution|1|0x10|16 bits per sample\n + (AUDDSpeakerDriver_BYTESPERSAMPLE * 2). +|7|bSamFreqType|1|0x01|One frequency supported. +|8|tSamFreq|3|4800|4800Hz (AUDDSpeakerDriver_SAMPLERATE). + + Standard %Endpoint Descriptor (AUDEndpointDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x09|Size of AUDFormatTypeOneDescriptor1 in bytes. +|1|bDescriptorType|1|0x24|ENDPOINT descriptor (USBGenericDescriptor_ENDPOINT). +|2|bEndpointAddress|1|0x85|IN endpoint 5\n + USBEndpointDescriptor_ADDRESS()\n + AUDDSpeakerDriverDescriptors_DATAIN +|3|bmAttributes|1|0x01|Isochronous, not shared\n + (USBEndpointDescriptor_ISOCHRONOUS). +|4|wMaxPacketSize|2|0x????|BOARD_USB_ENDPOINTS_MAXPACKETSIZE(5). +|6|bInterval|1|0x01|One packet per frame. +|7|bRefresh|1|0x00|Unused. +|8|bSynchAddress|1|0x00|Unused. + + Class-specific Isochronous Audio Data Endpoint Descriptor + (AUDDataEndpointDescriptor) +||Offset||Field||Size||Value||Description +|0|bLength|1|0x07|Size of AUDDataEndpointDescriptor in bytes. +|1|bDescriptorType|1|0x25|CS_ENDPOINT descriptor\n + (AUDGenericDescriptor_ENDPOINT). +|2|bDescriptorSubType|1|0x01|GENERAL subtype\n + (AUDDataEndpointDescriptor_SUBTYPE). +|3|bmAttributes|1|0x00|No sampling frequency control\n + no pitch control\n + no packet padding +|4|bLockDelayUnits|1|0x00|Unused. +|5|wLockDelay|2|0x0000|Unused. + + !!!Modified methods for new function + Several methods modified for new recorder function. + + !!Request handlers callbacks + Add handler for new Interface, Terminal and Unit IDs. + See AUDDSpeakerDriver_RequestHandler. + + !!Add function for recording USB stream + See AUDDSpeakerDriver_Write. +*/ -- cgit v1.2.3