blob: 9a3ebea4164fdd578b4e105172f6bc37e034029d [file] [log] [blame]
Christina Quastb123d742014-12-23 13:03:36 +01001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2008, Atmel Corporation
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the disclaimer below.
13 *
14 * Atmel's name may not be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * ----------------------------------------------------------------------------
28 */
29/** \file */
30
31/** \addtogroup usbd_aud_fun
32 *@{
33 */
34
35/*------------------------------------------------------------------------------
36 * Headers
37 *------------------------------------------------------------------------------*/
38
39#include <USBLib_Trace.h>
40
41#include <AUDDFunction.h>
42#include <AUDDSpeakerPhone.h>
43
44#include <AUDRequests.h>
45
46#include <USBD.h>
47#include <USBD_HAL.h>
48#include <USBDDriver.h>
49
50/*----------------------------------------------------------------------------
51 * Internal types
52 *----------------------------------------------------------------------------*/
53
54/**
55 * \brief Audio speaker driver struct.
56 */
57typedef struct _AUDDFunction {
58 /** Speaker & Phone function */
59 AUDDSpeakerPhone drv;
60 /** Stream instance for speaker */
61 AUDDStream speaker;
62 /** Stream instance for microphone */
63 AUDDStream mic;
64} AUDDFunction;
65
66/*----------------------------------------------------------------------------
67 * Internal variables
68 *----------------------------------------------------------------------------*/
69
70/** Global USB audio function driver instance. */
71static AUDDFunction auddFunction;
72
73/*----------------------------------------------------------------------------
74 * Internal functions
75 *----------------------------------------------------------------------------*/
76
77/**
78 * Callback triggerred after the mute or volume status of the channel has been
79 * changed.
80 * \param ec Event code.
81 * \param channel Channel number.
82 * \param pArg Pointer to AUDDStream instance.
83 */
84static void AUDDFunction_EventCallback(uint32_t ec,
85 uint8_t channel,
86 AUDDStream *pArg)
87{
88 AUDDFunction *pAudf = &auddFunction;
89 uint8_t mic = ((uint32_t)pArg == (uint32_t)(&pAudf->mic));
90 if (ec == AUDD_EC_MuteChanged) {
91 if (AUDDFunction_MuteChanged)
92 AUDDFunction_MuteChanged(mic, channel, pArg->bmMute);
93 }
94 else if (ec == AUDD_EC_VolumeChanged) {
95 /* Not supported now */
96 }
97}
98
99/*---------------------------------------------------------------------------
100 * Exported functions
101 *---------------------------------------------------------------------------*/
102
103/**
104 * Initializes an USB audio speaker device driver, as well as the underlying
105 * USB controller.
106 */
107void AUDDFunction_Initialize(USBDDriver *pUsbd, uint8_t bInterface)
108{
109 AUDDFunction *pAudf = &auddFunction;
110 AUDDSpeakerPhone *pDrv = &pAudf->drv;
111 AUDDStream *pSpk = &pAudf->speaker;
112 AUDDStream *pMic = &pAudf->mic;
113
114 /* 0: Speaker */
115 AUDDSpeakerPhone_InitializeStream(
116 pSpk, AUDDFunction_MaxNumSpeakerChannels, 0,
117 (AUDDStreamEventCallback)AUDDFunction_EventCallback,
118 (void*)pSpk);
119 /* 1: Mic */
120 AUDDSpeakerPhone_InitializeStream(
121 pMic, AUDDFunction_MaxNumMicrophoneChannels, 0,
122 (AUDDStreamEventCallback)AUDDFunction_EventCallback,
123 (void*)pMic);
124 /* Audio Driver initialize */
125 AUDDSpeakerPhone_Initialize(pDrv, pUsbd, pSpk, pMic);
126
127}
128
129/**
130 * Configure function with expected descriptors and start functionality.
131 * Usually invoked when device is configured.
132 * \pDescriptors Pointer to the descriptors for function configure.
133 * \wLength Length of descriptors in number of bytes.
134 */
135void AUDDFunction_Configure(USBGenericDescriptor *pDescriptors,
136 uint16_t wLength)
137{
138 AUDDFunction *pAudf = &auddFunction;
139 AUDDSpeakerPhone *pDrv = &pAudf->drv;
140 AUDDSpeakerPhone_ParseInterfaces(pDrv, pDescriptors, wLength);
141}
142
143/**
144 * Invoked whenever the active setting of an interface is changed by the
145 * host. Changes the status of the third LED accordingly.
146 * \param interface Interface number.
147 * \param setting Newly active setting.
148 */
149void AUDDFunction_InterfaceSettingChangedHandler(uint8_t interface,
150 uint8_t setting)
151{
152 AUDDFunction *pAudf = &auddFunction;
153 AUDDSpeakerPhone *pDrv = &pAudf->drv;
154 if (setting == 0) AUDDSpeakerPhone_CloseStream(pDrv, interface);
155 if (AUDDFunction_StreamSettingChanged) {
156 uint8_t mic = (interface == pDrv->pMicrophone->bAsInterface);
157 AUDDFunction_StreamSettingChanged(mic, setting);
158 }
159}
160
161/**
162 * Handles AUDIO-specific USB requests sent by the host
163 * \param request Pointer to a USBGenericRequest instance.
164 * \return USBRC_SUCCESS if request is handled.
165 */
166uint32_t AUDDFunction_RequestHandler(
167 const USBGenericRequest *request)
168{
169 AUDDFunction *pAudf = &auddFunction;
170 AUDDSpeakerPhone *pDrv = &pAudf->drv;
171 return AUDDSpeakerPhone_RequestHandler(pDrv, request);
172}
173
174/**
175 * Reads incoming audio data sent by the USB host into the provided buffer.
176 * When the transfer is complete, an optional callback function is invoked.
177 * \param buffer Pointer to the data storage buffer.
178 * \param length Size of the buffer in bytes.
179 * \param callback Optional callback function.
180 * \param argument Optional argument to the callback function.
181 * \return <USBD_STATUS_SUCCESS> if the transfer is started successfully;
182 * otherwise an error code.
183 */
184uint8_t AUDDFunction_Read(void *buffer,
185 uint32_t length,
186 TransferCallback callback,
187 void *argument)
188{
189 AUDDFunction *pAudf = &auddFunction;
190 AUDDSpeakerPhone *pDrv = &pAudf->drv;
191 return AUDDSpeakerPhone_Read(pDrv, buffer, length, callback, argument);
192}
193
194/**
195 * Initialize Frame List for sending audio data.
196 *
197 * \param pListInit Pointer to the allocated list for audio write.
198 * \param pDmaInit Pointer to the allocated DMA descriptors for autio write
199 * (if DMA supported).
200 * \param listSize Circular list size.
201 * \param delaySize Start transfer after delaySize frames filled in.
202 * \param callback Optional callback function for transfer.
203 * \param argument Optional callback argument.
204 * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code.
205 */
206uint8_t AUDDFunction_SetupWrite(void * pListInit,
207 void * pDmaInit,
208 uint16_t listSize,
209 uint16_t delaySize,
210 TransferCallback callback,
211 void * argument)
212{
213 AUDDFunction *pAudf = &auddFunction;
214 AUDDSpeakerPhone *pDrv = &pAudf->drv;
215 return AUDDSpeakerPhone_SetupWrite(pDrv,
216 pListInit, pDmaInit, listSize, delaySize,
217 callback, argument);
218}
219
220/**
221 * Add frame buffer to audio sending list.
222 * \buffer Pointer to data frame to send.
223 * \length Frame size in bytes.
224 * \return USBD_STATUS_SUCCESS if the transfer is started successfully;
225 * otherwise an error code.
226 */
227uint8_t AUDDFunction_Write(void* buffer, uint16_t length)
228{
229 AUDDFunction *pAudf = &auddFunction;
230 AUDDSpeakerPhone *pDrv = &pAudf->drv;
231 return AUDDSpeakerPhone_Write(pDrv, buffer, length);
232}
233
234/**@}*/
235