1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_device_config.h"
10 #include "usb.h"
11 #include "usb_device.h"
12
13 #include "usb_device_class.h"
14
15 #if ((defined(USB_DEVICE_CONFIG_AUDIO)) && (USB_DEVICE_CONFIG_AUDIO > 0U))
16 #include "usb_device_audio.h"
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /*******************************************************************************
23 * Prototypes
24 ******************************************************************************/
25 static usb_status_t USB_DeviceAudioAllocateHandle(usb_device_audio_struct_t **handle);
26 static usb_status_t USB_DeviceAudioFreeHandle(usb_device_audio_struct_t *handle);
27 usb_status_t USB_DeviceAudioInterruptIn(usb_device_handle handle,
28 usb_device_endpoint_callback_message_struct_t *message,
29 void *callbackParam);
30 usb_status_t USB_DeviceAudioIsochronousIn(usb_device_handle handle,
31 usb_device_endpoint_callback_message_struct_t *message,
32 void *callbackParam);
33 usb_status_t USB_DeviceAudioIsochronousOut(usb_device_handle handle,
34 usb_device_endpoint_callback_message_struct_t *message,
35 void *callbackParam);
36 usb_status_t USB_DeviceAudioStreamEndpointsInit(usb_device_audio_struct_t *audioHandle);
37 usb_status_t USB_DeviceAudioStreamEndpointsDeinit(usb_device_audio_struct_t *audioHandle);
38 usb_status_t USB_DeviceAudioControlEndpointsInit(usb_device_audio_struct_t *audioHandle);
39 usb_status_t USB_DeviceAudioControlEndpointsDeinit(usb_device_audio_struct_t *audioHandle);
40 usb_status_t USB_DeviceAudioGetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
41 usb_device_control_request_struct_t *controlRequest);
42 usb_status_t USB_DeviceAudioSetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
43 usb_device_control_request_struct_t *controlRequest);
44 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
45 usb_status_t USB_DeviceAudioGetRangeAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
46 usb_device_control_request_struct_t *controlRequest);
47 usb_status_t USB_DeviceAudioGetClockSource(usb_device_audio_struct_t *audioHandle,
48 usb_device_control_request_struct_t *controlRequest);
49 usb_status_t USB_DeviceAudioSetClockSource(usb_device_audio_struct_t *audioHandle,
50 usb_device_control_request_struct_t *controlRequest);
51 #else
52 usb_status_t USB_DeviceAudioGetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
53 usb_device_control_request_struct_t *controlRequest);
54 usb_status_t USB_DeviceAudioGetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
55 usb_device_control_request_struct_t *controlRequest);
56 usb_status_t USB_DeviceAudioGetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
57 usb_device_control_request_struct_t *controlRequest);
58 usb_status_t USB_DeviceAudioSetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
59 usb_device_control_request_struct_t *controlRequest);
60 usb_status_t USB_DeviceAudioSetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
61 usb_device_control_request_struct_t *controlRequest);
62 usb_status_t USB_DeviceAudioSetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
63 usb_device_control_request_struct_t *controlRequest);
64 #endif
65 usb_status_t USB_DeviceAudioSetFeatureUnit(usb_device_audio_struct_t *audioHandle,
66 usb_device_control_request_struct_t *controlRequest);
67 usb_status_t USB_DeviceAudioSetRequestEndpoint(usb_device_audio_struct_t *audioHandle,
68 usb_device_control_request_struct_t *controlRequest);
69 usb_status_t USB_DeviceAudioGetRequestEndpoint(usb_device_audio_struct_t *audioHandle,
70 usb_device_control_request_struct_t *controlRequest);
71 usb_status_t USB_DeviceAudioSetControlTerminal(usb_device_audio_struct_t *audioHandle,
72 usb_device_control_request_struct_t *controlRequest,
73 uint8_t terminal_type);
74 usb_status_t USB_DeviceAudioGetControlTerminal(usb_device_audio_struct_t *audioHandle,
75 usb_device_control_request_struct_t *controlRequest,
76 uint8_t terminal_type);
77 usb_status_t USB_DeviceAudioGetFeatureUnit(usb_device_audio_struct_t *audioHandle,
78 usb_device_control_request_struct_t *controlRequest);
79 usb_status_t USB_DeviceAudioSetRequestInterface(usb_device_audio_struct_t *audioHandle,
80 usb_device_control_request_struct_t *controlRequest);
81 usb_status_t USB_DeviceAudioGetRequestInterface(usb_device_audio_struct_t *audioHandle,
82 usb_device_control_request_struct_t *controlRequest);
83
84 /*******************************************************************************
85 * Variables
86 ******************************************************************************/
87
USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE)88 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_audio_struct_t
89 s_UsbDeviceAudioHandle[USB_DEVICE_CONFIG_AUDIO];
90
91 /*******************************************************************************
92 * Code
93 ******************************************************************************/
94
95 /*!
96 * @brief Allocate a device audio class handle.
97 *
98 * This function allocates a device audio class handle.
99 *
100 * @param handle It is out parameter, is used to return pointer of the device audio class handle to the caller.
101 *
102 * @retval kStatus_USB_Success Get a device audio class handle successfully.
103 * @retval kStatus_USB_Busy Cannot allocate a device audio class handle.
104 */
105 static usb_status_t USB_DeviceAudioAllocateHandle(usb_device_audio_struct_t **handle)
106 {
107 uint32_t count;
108 OSA_SR_ALLOC();
109
110 OSA_ENTER_CRITICAL();
111 for (count = 0; count < USB_DEVICE_CONFIG_AUDIO; count++)
112 {
113 if (NULL == s_UsbDeviceAudioHandle[count].handle)
114 {
115 *handle = &s_UsbDeviceAudioHandle[count];
116 OSA_EXIT_CRITICAL();
117 return kStatus_USB_Success;
118 }
119 }
120 OSA_EXIT_CRITICAL();
121 return kStatus_USB_Busy;
122 }
123
124 /*!
125 * @brief Free a device audio class handle.
126 *
127 * This function frees a device audio class handle.
128 *
129 * @param handle The device audio class handle.
130 *
131 * @retval kStatus_USB_Success Free device audio class handle successfully.
132 */
USB_DeviceAudioFreeHandle(usb_device_audio_struct_t * handle)133 static usb_status_t USB_DeviceAudioFreeHandle(usb_device_audio_struct_t *handle)
134 {
135 OSA_SR_ALLOC();
136
137 OSA_ENTER_CRITICAL();
138 handle->handle = NULL;
139 handle->configStruct = (usb_device_class_config_struct_t *)NULL;
140 handle->configuration = 0U;
141 handle->controlAlternate = 0U;
142 handle->streamAlternate = 0U;
143 OSA_EXIT_CRITICAL();
144 return kStatus_USB_Success;
145 }
146
147 /*!
148 * @brief Interrupt IN endpoint callback function.
149 *
150 * This callback function is used to notify uplayer the transfser result of a transfer.
151 * This callback pointer is passed when the interrupt IN pipe initialized.
152 *
153 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
154 * @param message The result of the interrupt IN pipe transfer.
155 * @param callbackParam The parameter for this callback. It is same with
156 * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the audio class handle.
157 *
158 * @return A USB error code or kStatus_USB_Success.
159 */
USB_DeviceAudioInterruptIn(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)160 usb_status_t USB_DeviceAudioInterruptIn(usb_device_handle handle,
161 usb_device_endpoint_callback_message_struct_t *message,
162 void *callbackParam)
163 {
164 usb_device_audio_struct_t *audioHandle;
165 usb_status_t error = kStatus_USB_Error;
166
167 /* Get the audio class handle */
168 audioHandle = (usb_device_audio_struct_t *)callbackParam;
169
170 if (NULL == audioHandle)
171 {
172 return kStatus_USB_InvalidHandle;
173 }
174
175 if ((NULL != audioHandle->configStruct) && (NULL != audioHandle->configStruct->classCallback))
176 {
177 /* Notify the application control data sent by calling the audio class callback.
178 classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
179 it is from the second parameter of classInit */
180 error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle,
181 kUSB_DeviceAudioEventControlSendResponse, message);
182 }
183
184 return error;
185 }
186
187 /*!
188 * @brief ISO IN endpoint callback function.
189 *
190 * This callback function is used to notify uplayer the transfser result of a transfer.
191 * This callback pointer is passed when the ISO IN pipe initialized.
192 *
193 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
194 * @param message The result of the ISO IN pipe transfer.
195 * @param callbackParam The parameter for this callback. It is same with
196 * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the audio class handle.
197 *
198 * @return A USB error code or kStatus_USB_Success.
199 */
USB_DeviceAudioIsochronousIn(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)200 usb_status_t USB_DeviceAudioIsochronousIn(usb_device_handle handle,
201 usb_device_endpoint_callback_message_struct_t *message,
202 void *callbackParam)
203 {
204 usb_device_audio_struct_t *audioHandle;
205 usb_status_t status = kStatus_USB_Error;
206
207 /* Get the audio class handle */
208 audioHandle = (usb_device_audio_struct_t *)callbackParam;
209 if (NULL == audioHandle)
210 {
211 return kStatus_USB_InvalidHandle;
212 }
213 audioHandle->streamInPipeBusy = 0U;
214 if ((NULL != audioHandle->configStruct) && (NULL != audioHandle->configStruct->classCallback))
215 {
216 /* Notify the application stream data sent by calling the audio class callback.
217 classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
218 it is from the second parameter of classInit */
219 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle,
220 kUSB_DeviceAudioEventStreamSendResponse, message);
221 }
222
223 return status;
224 }
225
226 /*!
227 * @brief ISO OUT endpoint callback function.
228 *
229 * This callback function is used to notify uplayer the transfser result of a transfer.
230 * This callback pointer is passed when the ISO OUT pipe initialized.
231 *
232 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
233 * @param message The result of the ISO OUT pipe transfer.
234 * @param callbackParam The parameter for this callback. It is same with
235 * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the audio class handle.
236 *
237 * @return A USB error code or kStatus_USB_Success.
238 */
USB_DeviceAudioIsochronousOut(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)239 usb_status_t USB_DeviceAudioIsochronousOut(usb_device_handle handle,
240 usb_device_endpoint_callback_message_struct_t *message,
241 void *callbackParam)
242 {
243 usb_device_audio_struct_t *audioHandle;
244 usb_status_t status = kStatus_USB_Error;
245
246 /* Get the audio class handle */
247 audioHandle = (usb_device_audio_struct_t *)callbackParam;
248 if (NULL == audioHandle)
249 {
250 return kStatus_USB_InvalidHandle;
251 }
252 audioHandle->streamOutPipeBusy = 0U;
253
254 if ((NULL != audioHandle->configStruct) && (NULL != audioHandle->configStruct->classCallback))
255 {
256 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
257 it is from the second parameter of classInit */
258 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle,
259 kUSB_DeviceAudioEventStreamRecvResponse, message);
260 }
261 return status;
262 }
263
264 /*!
265 * @brief Initialize the stream endpoints of the audio class.
266 *
267 * This callback function is used to initialize the stream endpoints of the audio class.
268 *
269 * @param audioHandle The device audio class handle. It equals the value returned from
270 * usb_device_class_config_struct_t::classHandle.
271 *
272 * @return A USB error code or kStatus_USB_Success.
273 */
USB_DeviceAudioStreamEndpointsInit(usb_device_audio_struct_t * audioHandle)274 usb_status_t USB_DeviceAudioStreamEndpointsInit(usb_device_audio_struct_t *audioHandle)
275 {
276 usb_device_interface_list_t *interfaceList;
277 usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL;
278 usb_status_t status = kStatus_USB_Error;
279 uint8_t count;
280 uint8_t index;
281
282 /* Check the configuration is valid or not. */
283 if (0U == audioHandle->configuration)
284 {
285 return status;
286 }
287
288 /* Check the configuration is valid or not. */
289 if (audioHandle->configuration > audioHandle->configStruct->classInfomation->configurations)
290 {
291 return status;
292 }
293
294 if (NULL == audioHandle->configStruct->classInfomation->interfaceList)
295 {
296 return status;
297 }
298
299 /* Get the interface list of the new configuration. */
300 interfaceList = &audioHandle->configStruct->classInfomation->interfaceList[audioHandle->configuration - 1U];
301
302 /* Find stream interface by using the alternate setting of the interface. */
303 for (count = 0U; count < interfaceList->count; count++)
304 {
305 if ((USB_DEVICE_CONFIG_AUDIO_CLASS_CODE == interfaceList->interfaces[count].classCode) &&
306 (USB_DEVICE_AUDIO_STREAM_SUBCLASS == interfaceList->interfaces[count].subclassCode))
307 {
308 for (index = 0; index < interfaceList->interfaces[count].count; index++)
309 {
310 if (interfaceList->interfaces[count].interface[index].alternateSetting == audioHandle->streamAlternate)
311 {
312 interface = &interfaceList->interfaces[count].interface[index];
313 break;
314 }
315 }
316 audioHandle->streamInterfaceNumber = interfaceList->interfaces[count].interfaceNumber;
317 break;
318 }
319 }
320 if (NULL == interface)
321 {
322 return status;
323 }
324 /* Keep new stream interface handle. */
325 audioHandle->streamInterfaceHandle = interface;
326
327 /* Initialize the endpoints of the new interface. */
328 for (count = 0U; count < interface->endpointList.count; count++)
329 {
330 usb_device_endpoint_init_struct_t epInitStruct;
331 usb_device_endpoint_callback_struct_t epCallback;
332 epInitStruct.zlt = 0U;
333 epInitStruct.interval = interface->endpointList.endpoint[count].interval;
334 epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress;
335 epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize;
336 epInitStruct.transferType = interface->endpointList.endpoint[count].transferType;
337
338 if ((USB_ENDPOINT_ISOCHRONOUS == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) &&
339 (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
340 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))
341 {
342 epCallback.callbackFn = USB_DeviceAudioIsochronousIn;
343 }
344 else
345 {
346 epCallback.callbackFn = USB_DeviceAudioIsochronousOut;
347 }
348 epCallback.callbackParam = audioHandle;
349
350 status = USB_DeviceInitEndpoint(audioHandle->handle, &epInitStruct, &epCallback);
351 }
352 return status;
353 }
354
355 /*!
356 * @brief De-initialize the stream endpoints of the audio class.
357 *
358 * This callback function is used to de-initialize the stream endpoints of the audio class.
359 *
360 * @param audioHandle The device audio class handle. It equals the value returned from
361 * usb_device_class_config_struct_t::classHandle.
362 *
363 * @return A USB error code or kStatus_USB_Success.
364 */
USB_DeviceAudioStreamEndpointsDeinit(usb_device_audio_struct_t * audioHandle)365 usb_status_t USB_DeviceAudioStreamEndpointsDeinit(usb_device_audio_struct_t *audioHandle)
366 {
367 usb_status_t status = kStatus_USB_Error;
368 usb_device_endpoint_callback_message_struct_t message;
369 uint8_t count;
370
371 if (NULL == audioHandle->streamInterfaceHandle)
372 {
373 return status;
374 }
375 /* De-initialize all stream endpoints of the interface */
376 for (count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++)
377 {
378 status = USB_DeviceDeinitEndpoint(
379 audioHandle->handle, audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress);
380 }
381
382 for (count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++)
383 {
384 if ((audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress &
385 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
386 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT ==
387 USB_IN)
388 {
389 if (0U != audioHandle->streamInPipeBusy)
390 {
391 message.length = USB_CANCELLED_TRANSFER_LENGTH;
392 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
393 status = USB_DeviceAudioIsochronousIn(audioHandle->handle, &message, audioHandle);
394 #else
395 (void)USB_DeviceAudioIsochronousIn(audioHandle->handle, &message, audioHandle);
396 #endif
397 }
398 }
399 else
400 {
401 if (0U != audioHandle->streamOutPipeBusy)
402 {
403 message.length = USB_CANCELLED_TRANSFER_LENGTH;
404 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
405 status = USB_DeviceAudioIsochronousOut(audioHandle->handle, &message, audioHandle);
406 #else
407 (void)USB_DeviceAudioIsochronousOut(audioHandle->handle, &message, audioHandle);
408 #endif
409 }
410 }
411 }
412
413 audioHandle->streamInterfaceHandle = NULL;
414 return status;
415 }
416
417 /*!
418 * @brief Initialize the control endpoints of the audio class.
419 *
420 * This callback function is used to initialize the control endpoints of the audio class.
421 *
422 * @param audioHandle The device audio class handle. It equals the value returned from
423 * usb_device_class_config_struct_t::classHandle.
424 *
425 * @return A USB error code or kStatus_USB_Success.
426 */
USB_DeviceAudioControlEndpointsInit(usb_device_audio_struct_t * audioHandle)427 usb_status_t USB_DeviceAudioControlEndpointsInit(usb_device_audio_struct_t *audioHandle)
428 {
429 usb_device_interface_list_t *interfaceList;
430 usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL;
431 usb_status_t status = kStatus_USB_Error;
432 uint8_t count;
433 uint8_t index;
434
435 /* Check the configuration is valid or not. */
436 if (0U == audioHandle->configuration)
437 {
438 return status;
439 }
440
441 /* Check the configuration is valid or not. */
442 if (audioHandle->configuration > audioHandle->configStruct->classInfomation->configurations)
443 {
444 return status;
445 }
446
447 if (NULL == audioHandle->configStruct->classInfomation->interfaceList)
448 {
449 return status;
450 }
451
452 /* Get the control interface list of the new configuration. */
453 interfaceList = &audioHandle->configStruct->classInfomation->interfaceList[audioHandle->configuration - 1U];
454
455 /* Find control interface by using the alternate setting of the interface. */
456 for (count = 0U; count < interfaceList->count; count++)
457 {
458 if ((USB_DEVICE_CONFIG_AUDIO_CLASS_CODE == interfaceList->interfaces[count].classCode) &&
459 (USB_DEVICE_AUDIO_CONTROL_SUBCLASS == interfaceList->interfaces[count].subclassCode))
460 {
461 for (index = 0U; index < interfaceList->interfaces[count].count; index++)
462 {
463 if (interfaceList->interfaces[count].interface[index].alternateSetting == audioHandle->controlAlternate)
464 {
465 interface = &interfaceList->interfaces[count].interface[index];
466 break;
467 }
468 }
469 audioHandle->controlInterfaceNumber = interfaceList->interfaces[count].interfaceNumber;
470 break;
471 }
472 }
473 if (NULL == interface)
474 {
475 return status;
476 }
477 /* Keep new control interface handle. */
478 audioHandle->controlInterfaceHandle = interface;
479
480 /* Initialize the control endpoints of the new interface. */
481 for (count = 0U; count < interface->endpointList.count; count++)
482 {
483 usb_device_endpoint_init_struct_t epInitStruct;
484 usb_device_endpoint_callback_struct_t epCallback;
485 epInitStruct.zlt = 0U;
486 epInitStruct.interval = interface->endpointList.endpoint[count].interval;
487 epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress;
488 epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize;
489 epInitStruct.transferType = interface->endpointList.endpoint[count].transferType;
490
491 if ((USB_ENDPOINT_INTERRUPT == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) &&
492 (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
493 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))
494 {
495 epCallback.callbackFn = USB_DeviceAudioInterruptIn;
496 }
497 else
498 {
499 continue;
500 }
501 epCallback.callbackParam = audioHandle;
502
503 status = USB_DeviceInitEndpoint(audioHandle->handle, &epInitStruct, &epCallback);
504 }
505 return status;
506 }
507
508 /*!
509 * @brief De-initialize the control endpoints of the audio class.
510 *
511 * This callback function is used to de-initialize the control endpoints of the audio class.
512 *
513 * @param audioHandle The device audio class handle. It equals the value returned from
514 * usb_device_class_config_struct_t::classHandle.
515 *
516 * @return A USB error code or kStatus_USB_Success.
517 */
USB_DeviceAudioControlEndpointsDeinit(usb_device_audio_struct_t * audioHandle)518 usb_status_t USB_DeviceAudioControlEndpointsDeinit(usb_device_audio_struct_t *audioHandle)
519 {
520 usb_status_t status = kStatus_USB_Error;
521 uint8_t count;
522
523 if (NULL == audioHandle->controlInterfaceHandle)
524 {
525 return status;
526 }
527 /* De-initialize all control endpoints of the interface */
528 for (count = 0U; count < audioHandle->controlInterfaceHandle->endpointList.count; count++)
529 {
530 status = USB_DeviceDeinitEndpoint(
531 audioHandle->handle, audioHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress);
532 }
533 audioHandle->controlInterfaceHandle = NULL;
534 return status;
535 }
536
537 /*!
538 * @brief Handle the audio device GET CUR control feature unit request.
539 *
540 * This callback function provides flexibility to add class and vendor specific requests
541 *
542 * @param audioHandle The device audio class handle. It equals the value returned from
543 * usb_device_class_config_struct_t::classHandle.
544 * @param controlRequest The pointer of the control request structure.
545 *
546 * @return A USB error code or kStatus_USB_Success.
547 */
USB_DeviceAudioGetCurAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)548 usb_status_t USB_DeviceAudioGetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
549 usb_device_control_request_struct_t *controlRequest)
550 {
551 usb_status_t status = kStatus_USB_InvalidRequest;
552 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
553 uint32_t audioCommand = 0U;
554
555 /* Select GET CUR request Control Feature Unit Module */
556 switch (controlSelector)
557 {
558 case USB_DEVICE_AUDIO_FU_MUTE_CONTROL_SELECTOR:
559 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_MUTE_CONTROL;
560 break;
561 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
562 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_VOLUME_CONTROL;
563 break;
564 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
565 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_BASS_CONTROL;
566 break;
567 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
568 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_MID_CONTROL;
569 break;
570 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
571 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_TREBLE_CONTROL;
572 break;
573 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
574 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_GRAPHIC_EQUALIZER_CONTROL;
575 break;
576 case USB_DEVICE_AUDIO_FU_AUTOMATIC_GAIN_CONTROL_SELECTOR:
577 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_AUTOMATIC_GAIN_CONTROL;
578 break;
579 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
580 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_DELAY_CONTROL;
581 break;
582 case USB_DEVICE_AUDIO_FU_BASS_BOOST_CONTROL_SELECTOR:
583 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_BASS_BOOST_CONTROL;
584 break;
585 case USB_DEVICE_AUDIO_FU_LOUDNESS_CONTROL_SELECTOR:
586 audioCommand = USB_DEVICE_AUDIO_FU_GET_CUR_LOUDNESS_CONTROL;
587 break;
588 default:
589 /*no action*/
590 break;
591 }
592 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
593 (NULL != audioHandle->configStruct->classCallback))
594 {
595 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
596 it is from the second parameter of classInit */
597 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
598 }
599
600 return status;
601 }
602
603 /*!
604 * @brief Handle the audio device SET CUR control feature unit request.
605 *
606 * This callback function provides flexibility to add class and vendor specific requests
607 *
608 * @param audioHandle The device audio class handle. It equals the value returned from
609 * usb_device_class_config_struct_t::classHandle.
610 * @param controlRequest The pointer of the control request structure.
611 *
612 * @return A USB error code or kStatus_USB_Success.
613 */
USB_DeviceAudioSetCurAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)614 usb_status_t USB_DeviceAudioSetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
615 usb_device_control_request_struct_t *controlRequest)
616 {
617 usb_status_t status = kStatus_USB_InvalidRequest;
618 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08U) & 0xFFU);
619 uint32_t audioCommand = 0;
620
621 /* Select SET CUR request Control Feature Unit Module */
622 switch (controlSelector)
623 {
624 case USB_DEVICE_AUDIO_FU_MUTE_CONTROL_SELECTOR:
625 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_MUTE_CONTROL;
626 break;
627 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
628 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_VOLUME_CONTROL;
629 break;
630 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
631 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_BASS_CONTROL;
632 break;
633 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
634 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_MID_CONTROL;
635 break;
636 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
637 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_TREBLE_CONTROL;
638 break;
639 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
640 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_GRAPHIC_EQUALIZER_CONTROL;
641 break;
642 case USB_DEVICE_AUDIO_FU_AUTOMATIC_GAIN_CONTROL_SELECTOR:
643 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_AUTOMATIC_GAIN_CONTROL;
644 break;
645 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
646 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_DELAY_CONTROL;
647 break;
648 case USB_DEVICE_AUDIO_FU_BASS_BOOST_CONTROL_SELECTOR:
649 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_BASS_BOOST_CONTROL;
650 break;
651 case USB_DEVICE_AUDIO_FU_LOUDNESS_CONTROL_SELECTOR:
652 audioCommand = USB_DEVICE_AUDIO_FU_SET_CUR_LOUDNESS_CONTROL;
653 break;
654 default:
655 /*no action*/
656 break;
657 }
658 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
659 (NULL != audioHandle->configStruct->classCallback))
660 {
661 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
662 it is from the second parameter of classInit */
663 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
664 }
665 return status;
666 }
667
668 /*!
669 * @brief Handle the audio device GET feature unit request.
670 *
671 * This callback function provides flexibility to add class and vendor specific requests
672 *
673 * @param audioHandle The device audio class handle. It equals the value returned from
674 * usb_device_class_config_struct_t::classHandle.
675 * @param controlRequest The pointer of the control request structure.
676 *
677 * @return A USB error code or kStatus_USB_Success.
678 */
USB_DeviceAudioGetFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)679 usb_status_t USB_DeviceAudioGetFeatureUnit(usb_device_audio_struct_t *audioHandle,
680 usb_device_control_request_struct_t *controlRequest)
681 {
682 usb_status_t status = kStatus_USB_InvalidRequest;
683
684 /* Select GET request Control Feature Unit Module */
685 switch (controlRequest->setup->bRequest)
686 {
687 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
688 case USB_DEVICE_AUDIO_CUR_REQUEST:
689 status = USB_DeviceAudioGetCurAudioFeatureUnit(audioHandle, controlRequest);
690 break;
691 case USB_DEVICE_AUDIO_RANGE_REQUEST:
692 status = USB_DeviceAudioGetRangeAudioFeatureUnit(audioHandle, controlRequest);
693 break;
694 default:
695 /*no action*/
696 break;
697 #else
698 case USB_DEVICE_AUDIO_GET_CUR_REQUEST:
699 status = USB_DeviceAudioGetCurAudioFeatureUnit(audioHandle, controlRequest);
700 break;
701 case USB_DEVICE_AUDIO_GET_MIN_REQUEST:
702 status = USB_DeviceAudioGetMinAudioFeatureUnit(audioHandle, controlRequest);
703 break;
704 case USB_DEVICE_AUDIO_GET_MAX_REQUEST:
705 status = USB_DeviceAudioGetMaxAudioFeatureUnit(audioHandle, controlRequest);
706 break;
707 case USB_DEVICE_AUDIO_GET_RES_REQUEST:
708 status = USB_DeviceAudioGetResAudioFeatureUnit(audioHandle, controlRequest);
709 break;
710 default:
711 /*no action*/
712 break;
713 #endif
714 }
715 return status;
716 }
717
718 /*!
719 * @brief Handle the audio device SET feature unit request.
720 *
721 * This callback function provides flexibility to add class and vendor specific requests
722 *
723 * @param audioHandle The device audio class handle. It equals the value returned from
724 * usb_device_class_config_struct_t::classHandle.
725 * @param controlRequest The pointer of the control request structure.
726 *
727 * @return A USB error code or kStatus_USB_Success.
728 */
USB_DeviceAudioSetFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)729 usb_status_t USB_DeviceAudioSetFeatureUnit(usb_device_audio_struct_t *audioHandle,
730 usb_device_control_request_struct_t *controlRequest)
731 {
732 usb_status_t status = kStatus_USB_InvalidRequest;
733 /* Select SET request Control Feature Unit Module */
734 switch (controlRequest->setup->bRequest)
735 {
736 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
737 case USB_DEVICE_AUDIO_CUR_REQUEST:
738 status = USB_DeviceAudioSetCurAudioFeatureUnit(audioHandle, controlRequest);
739 break;
740 case USB_DEVICE_AUDIO_RANGE_REQUEST:
741 break;
742 default:
743 /*no action*/
744 break;
745 #else
746 case USB_DEVICE_AUDIO_SET_CUR_REQUEST:
747 status = USB_DeviceAudioSetCurAudioFeatureUnit(audioHandle, controlRequest);
748 break;
749 case USB_DEVICE_AUDIO_SET_MIN_REQUEST:
750 status = USB_DeviceAudioSetMinAudioFeatureUnit(audioHandle, controlRequest);
751 break;
752 case USB_DEVICE_AUDIO_SET_MAX_REQUEST:
753 status = USB_DeviceAudioSetMaxAudioFeatureUnit(audioHandle, controlRequest);
754 break;
755 case USB_DEVICE_AUDIO_SET_RES_REQUEST:
756 status = USB_DeviceAudioSetResAudioFeatureUnit(audioHandle, controlRequest);
757 break;
758 default:
759 /*no action*/
760 break;
761 #endif
762 }
763 return status;
764 }
765
766 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
767 /*!
768 * @brief Handle the audio device GET RANGE control feature unit request.
769 *
770 * This callback function provides flexibility to add class and vendor specific requests
771 *
772 * @param audioHandle The device audio class handle. It equals the value returned from
773 * usb_device_class_config_struct_t::classHandle.
774 * @param controlRequest The pointer of the control request structure.
775 *
776 * @return A USB error code or kStatus_USB_Success.
777 */
USB_DeviceAudioGetRangeAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)778 usb_status_t USB_DeviceAudioGetRangeAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
779 usb_device_control_request_struct_t *controlRequest)
780 {
781 usb_status_t status = kStatus_USB_InvalidRequest;
782 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
783 uint32_t audioCommand = 0U;
784
785 /* Select GET RANGE request Control Feature Unit Module */
786 switch (controlSelector)
787 {
788 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
789 audioCommand = USB_DEVICE_AUDIO_FU_GET_RANGE_VOLUME_CONTROL;
790 break;
791 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
792 break;
793 default:
794 /*no action*/
795 break;
796 }
797
798 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
799 (NULL != audioHandle->configStruct->classCallback))
800 {
801 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
802 it is from the second parameter of classInit */
803 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
804 }
805
806 return status;
807 }
808
809 /*!
810 * @brief Handle the audio device GET Clock Source control feature unit request.
811 *
812 * This callback function provides flexibility to add class and vendor specific requests
813 *
814 * @param audioHandle The device audio class handle. It equals the value returned from
815 * usb_device_class_config_struct_t::classHandle.
816 * @param controlRequest The pointer of the control request structure.
817 *
818 * @return A USB error code or kStatus_USB_Success.
819 */
USB_DeviceAudioGetClockSource(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)820 usb_status_t USB_DeviceAudioGetClockSource(usb_device_audio_struct_t *audioHandle,
821 usb_device_control_request_struct_t *controlRequest)
822 {
823 usb_status_t status = kStatus_USB_InvalidRequest;
824 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
825 uint32_t audioCommand = 0;
826 /* Select GET request Control Clock Source Module */
827 switch (controlRequest->setup->bRequest)
828 {
829 case USB_DEVICE_AUDIO_CUR_REQUEST:
830 switch (controlSelector)
831 {
832 case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL_SELECTOR:
833 audioCommand = USB_DEVICE_AUDIO_CS_GET_CUR_SAMPLING_FREQ_CONTROL;
834 break;
835 case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL_SELECTOR:
836 audioCommand = USB_DEVICE_AUDIO_CS_GET_CUR_CLOCK_VALID_CONTROL;
837 break;
838 default:
839 /*no action*/
840 break;
841 }
842 break;
843 case USB_DEVICE_AUDIO_RANGE_REQUEST:
844 switch (controlSelector)
845 {
846 case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL_SELECTOR:
847 audioCommand = USB_DEVICE_AUDIO_CS_GET_RANGE_SAMPLING_FREQ_CONTROL;
848 break;
849 default:
850 /*no action*/
851 break;
852 }
853 break;
854 default:
855 /*no action*/
856 break;
857 }
858
859 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
860 (NULL != audioHandle->configStruct->classCallback))
861 {
862 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
863 it is from the second parameter of classInit */
864 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
865 }
866 return status;
867 }
868
869 /*!
870 * @brief Handle the audio device SET Clock Source control feature unit request.
871 *
872 * This callback function provides flexibility to add class and vendor specific requests
873 *
874 * @param audioHandle The device audio class handle. It equals the value returned from
875 * usb_device_class_config_struct_t::classHandle.
876 * @param controlRequest The pointer of the control request structure.
877 *
878 * @return A USB error code or kStatus_USB_Success.
879 */
USB_DeviceAudioSetClockSource(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)880 usb_status_t USB_DeviceAudioSetClockSource(usb_device_audio_struct_t *audioHandle,
881 usb_device_control_request_struct_t *controlRequest)
882 {
883 usb_status_t status = kStatus_USB_InvalidRequest;
884 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
885 uint32_t audioCommand = 0;
886 /* Select SET request Control Clock Source Module */
887 switch (controlRequest->setup->bRequest)
888 {
889 case USB_DEVICE_AUDIO_CUR_REQUEST:
890 switch (controlSelector)
891 {
892 case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL_SELECTOR:
893 audioCommand = USB_DEVICE_AUDIO_CS_SET_CUR_SAMPLING_FREQ_CONTROL;
894 break;
895 case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL_SELECTOR:
896 audioCommand = USB_DEVICE_AUDIO_CS_SET_CUR_CLOCK_VALID_CONTROL;
897 break;
898 default:
899 /*no action*/
900 break;
901 }
902 break;
903 case USB_DEVICE_AUDIO_RANGE_REQUEST:
904 break;
905 default:
906 /*no action*/
907 break;
908 }
909 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
910 (NULL != audioHandle->configStruct->classCallback))
911 {
912 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
913 it is from the second parameter of classInit */
914 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
915 }
916 return status;
917 }
918
919 #else
920
921 /*!
922 * @brief Handle the audio device set minimum volume/control feature unit request.
923 *
924 * This callback function provides flexibility to add class and vendor specific requests
925 *
926 * @param audioHandle The device audio class handle. It equals the value returned from
927 * usb_device_class_config_struct_t::classHandle.
928 * @param controlRequest The pointer of the control request structure.
929 *
930 * @return A USB error code or kStatus_USB_Success.
931 */
USB_DeviceAudioSetMinAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)932 usb_status_t USB_DeviceAudioSetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
933 usb_device_control_request_struct_t *controlRequest)
934 {
935 usb_status_t status = kStatus_USB_InvalidRequest;
936 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
937 uint32_t audioCommand = 0U;
938
939 /* Select SET MIN request Control Feature Unit Module */
940 switch (controlSelector)
941 {
942 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
943 audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_VOLUME_CONTROL;
944 break;
945 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
946 audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_BASS_CONTROL;
947 break;
948 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
949 audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_MID_CONTROL;
950 break;
951 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
952 audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_TREBLE_CONTROL;
953 break;
954 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
955 audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_GRAPHIC_EQUALIZER_CONTROL;
956 break;
957 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
958 audioCommand = USB_DEVICE_AUDIO_FU_SET_MIN_DELAY_CONTROL;
959 break;
960 default:
961 /*no action*/
962 break;
963 }
964 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
965 (NULL != audioHandle->configStruct->classCallback))
966 {
967 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
968 it is from the second parameter of classInit */
969 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
970 }
971
972 return status;
973 }
974
975 /*!
976 * @brief Handle the audio device maximum volume/control feature unit request.
977 *
978 * This callback function provides flexibility to add class and vendor specific requests
979 *
980 * @param audioHandle The device audio class handle. It equals the value returned from
981 * usb_device_class_config_struct_t::classHandle.
982 * @param controlRequest The pointer of the control request structure.
983 *
984 * @return A USB error code or kStatus_USB_Success.
985 */
USB_DeviceAudioSetMaxAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)986 usb_status_t USB_DeviceAudioSetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
987 usb_device_control_request_struct_t *controlRequest)
988 {
989 usb_status_t status = kStatus_USB_InvalidRequest;
990 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
991 uint32_t audioCommand = 0;
992
993 /* Select SET MAX request Control Feature Unit Module */
994 switch (controlSelector)
995 {
996 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
997 audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_VOLUME_CONTROL;
998 break;
999 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
1000 audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_BASS_CONTROL;
1001 break;
1002 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
1003 audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_MID_CONTROL;
1004 break;
1005 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
1006 audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_TREBLE_CONTROL;
1007 break;
1008 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
1009 audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_GRAPHIC_EQUALIZER_CONTROL;
1010 break;
1011 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
1012 audioCommand = USB_DEVICE_AUDIO_FU_SET_MAX_DELAY_CONTROL;
1013 break;
1014 default:
1015 /*no action*/
1016 break;
1017 }
1018 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1019 (NULL != audioHandle->configStruct->classCallback))
1020 {
1021 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1022 it is from the second parameter of classInit */
1023 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1024 }
1025
1026 return status;
1027 }
1028
1029 /*!
1030 * @brief Handle the audio device set res volume/control feature unit request.
1031 *
1032 * This callback function provides flexibility to add class and vendor specific requests
1033 *
1034 * @param audioHandle The device audio class handle. It equals the value returned from
1035 * usb_device_class_config_struct_t::classHandle.
1036 * @param controlRequest The pointer of the control request structure.
1037 *
1038 * @return A USB error code or kStatus_USB_Success.
1039 */
USB_DeviceAudioSetResAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1040 usb_status_t USB_DeviceAudioSetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
1041 usb_device_control_request_struct_t *controlRequest)
1042 {
1043 usb_status_t status = kStatus_USB_InvalidRequest;
1044 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1045 uint32_t audioCommand = 0;
1046
1047 /* Select SET RES request Control Feature Unit Module */
1048 switch (controlSelector)
1049 {
1050 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
1051 audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_VOLUME_CONTROL;
1052 break;
1053 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
1054 audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_BASS_CONTROL;
1055 break;
1056 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
1057 audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_MID_CONTROL;
1058 break;
1059 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
1060 audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_TREBLE_CONTROL;
1061 break;
1062 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
1063 audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_GRAPHIC_EQUALIZER_CONTROL;
1064 break;
1065 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
1066 audioCommand = USB_DEVICE_AUDIO_FU_SET_RES_DELAY_CONTROL;
1067 break;
1068 default:
1069 /*no action*/
1070 break;
1071 }
1072 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1073 (NULL != audioHandle->configStruct->classCallback))
1074 {
1075 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1076 it is from the second parameter of classInit */
1077 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1078 }
1079 return status;
1080 }
1081
1082 /*!
1083 * @brief Handle the audio device GET MIN control feature unit request.
1084 *
1085 * This callback function provides flexibility to add class and vendor specific requests
1086 *
1087 * @param audioHandle The device audio class handle. It equals the value returned from
1088 * usb_device_class_config_struct_t::classHandle.
1089 * @param controlRequest The pointer of the control request structure.
1090 *
1091 * @return A USB error code or kStatus_USB_Success.
1092 */
USB_DeviceAudioGetMinAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1093 usb_status_t USB_DeviceAudioGetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
1094 usb_device_control_request_struct_t *controlRequest)
1095 {
1096 usb_status_t status = kStatus_USB_InvalidRequest;
1097 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1098 uint32_t audioCommand = 0U;
1099
1100 /* Select GET MIN request Control Feature Unit Module */
1101 switch (controlSelector)
1102 {
1103 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
1104 audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_VOLUME_CONTROL;
1105 break;
1106 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
1107 audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_BASS_CONTROL;
1108 break;
1109 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
1110 audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_MID_CONTROL;
1111 break;
1112 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
1113 audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_TREBLE_CONTROL;
1114 break;
1115 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
1116 audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_GRAPHIC_EQUALIZER_CONTROL;
1117 break;
1118 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
1119 audioCommand = USB_DEVICE_AUDIO_FU_GET_MIN_DELAY_CONTROL;
1120 break;
1121 default:
1122 /* no action*/
1123 break;
1124 }
1125 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1126 (NULL != audioHandle->configStruct->classCallback))
1127 {
1128 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1129 it is from the second parameter of classInit */
1130 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1131 }
1132 return status;
1133 }
1134
1135 /*!
1136 * @brief Handle the audio device GET MAX control feature unit request.
1137 *
1138 * This callback function provides flexibility to add class and vendor specific requests
1139 *
1140 * @param audioHandle The device audio class handle. It equals the value returned from
1141 * usb_device_class_config_struct_t::classHandle.
1142 * @param controlRequest The pointer of the control request structure.
1143 *
1144 * @return A USB error code or kStatus_USB_Success.
1145 */
USB_DeviceAudioGetMaxAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1146 usb_status_t USB_DeviceAudioGetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
1147 usb_device_control_request_struct_t *controlRequest)
1148 {
1149 usb_status_t status = kStatus_USB_InvalidRequest;
1150 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1151 uint32_t audioCommand = 0U;
1152
1153 /* Select GET MAX request Control Feature Unit Module */
1154 switch (controlSelector)
1155 {
1156 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
1157 audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_VOLUME_CONTROL;
1158 break;
1159 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
1160 audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_BASS_CONTROL;
1161 break;
1162 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
1163 audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_MID_CONTROL;
1164 break;
1165 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
1166 audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_TREBLE_CONTROL;
1167 break;
1168 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
1169 audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_GRAPHIC_EQUALIZER_CONTROL;
1170 break;
1171 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
1172 audioCommand = USB_DEVICE_AUDIO_FU_GET_MAX_DELAY_CONTROL;
1173 break;
1174 default:
1175 /*no action*/
1176 break;
1177 }
1178 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1179 (NULL != audioHandle->configStruct->classCallback))
1180 {
1181 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1182 it is from the second parameter of classInit */
1183 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1184 }
1185 return status;
1186 }
1187
1188 /*!
1189 * @brief Handle the audio device GET RES control feature unit request.
1190 *
1191 * This callback function provides flexibility to add class and vendor specific requests
1192 *
1193 * @param audioHandle The device audio class handle. It equals the value returned from
1194 * usb_device_class_config_struct_t::classHandle.
1195 * @param controlRequest The pointer of the control request structure.
1196 *
1197 * @return A USB error code or kStatus_USB_Success.
1198 */
USB_DeviceAudioGetResAudioFeatureUnit(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1199 usb_status_t USB_DeviceAudioGetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle,
1200 usb_device_control_request_struct_t *controlRequest)
1201 {
1202 usb_status_t status = kStatus_USB_InvalidRequest;
1203 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1204 uint32_t audioCommand = 0U;
1205
1206 /* Select GET RES request Control Feature Unit Module */
1207 switch (controlSelector)
1208 {
1209 case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL_SELECTOR:
1210 audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_VOLUME_CONTROL;
1211 break;
1212 case USB_DEVICE_AUDIO_FU_BASS_CONTROL_SELECTOR:
1213 audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_BASS_CONTROL;
1214 break;
1215 case USB_DEVICE_AUDIO_FU_MID_CONTROL_SELECTOR:
1216 audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_MID_CONTROL;
1217 break;
1218 case USB_DEVICE_AUDIO_FU_TREBLE_CONTROL_SELECTOR:
1219 audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_TREBLE_CONTROL;
1220 break;
1221 case USB_DEVICE_AUDIO_FU_GRAPHIC_EQUALIZER_CONTROL_SELECTOR:
1222 audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_GRAPHIC_EQUALIZER_CONTROL;
1223 break;
1224 case USB_DEVICE_AUDIO_FU_DELAY_CONTROL_SELECTOR:
1225 audioCommand = USB_DEVICE_AUDIO_FU_GET_RES_DELAY_CONTROL;
1226 break;
1227 default:
1228 /*no action*/
1229 break;
1230 }
1231 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1232 (NULL != audioHandle->configStruct->classCallback))
1233 {
1234 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1235 it is from the second parameter of classInit*/
1236 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1237 }
1238
1239 return status;
1240 }
1241 #endif /* !USB_DEVICE_CONFIG_AUDIO_CLASS_2_0 */
1242
1243 /*!
1244 * @brief Handle the audio device SET request endpoint.
1245 *
1246 * This callback function provides flexibility to add class and vendor specific requests
1247 *
1248 * @param audioHandle The device audio class handle. It equals the value returned from
1249 * usb_device_class_config_struct_t::classHandle.
1250 * @param controlRequest The pointer of the control request structure.
1251 *
1252 * @return A USB error code or kStatus_USB_Success.
1253 */
USB_DeviceAudioSetRequestEndpoint(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1254 usb_status_t USB_DeviceAudioSetRequestEndpoint(usb_device_audio_struct_t *audioHandle,
1255 usb_device_control_request_struct_t *controlRequest)
1256 {
1257 usb_status_t status = kStatus_USB_InvalidRequest;
1258 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1259 uint32_t audioCommand = 0;
1260
1261 /* Select SET request Control for endpoint */
1262 switch (controlRequest->setup->bRequest)
1263 {
1264 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
1265 case USB_DEVICE_AUDIO_CUR_REQUEST:
1266 switch (controlSelector)
1267 {
1268 case USB_DEVICE_AUDIO_EP_PITCH_CONTROL_SELECTOR_AUDIO20:
1269 audioCommand = USB_DEVICE_AUDIO_EP_SET_CUR_PITCH_CONTROL_AUDIO20;
1270 break;
1271 default:
1272 /*no action*/
1273 break;
1274 }
1275 break;
1276 default:
1277 /*no action*/
1278 break;
1279 #else
1280 case USB_DEVICE_AUDIO_SET_CUR_REQUEST:
1281 switch (controlSelector)
1282 {
1283 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1284 audioCommand = USB_DEVICE_AUDIO_EP_SET_CUR_SAMPLING_FREQ_CONTROL;
1285 break;
1286 case USB_DEVICE_AUDIO_EP_PITCH_CONTROL_SELECTOR:
1287 audioCommand = USB_DEVICE_AUDIO_EP_SET_CUR_PITCH_CONTROL;
1288 break;
1289 default:
1290 /*no action*/
1291 break;
1292 }
1293 break;
1294 case USB_DEVICE_AUDIO_SET_MIN_REQUEST:
1295 switch (controlSelector)
1296 {
1297 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1298 audioCommand = USB_DEVICE_AUDIO_EP_SET_MIN_SAMPLING_FREQ_CONTROL;
1299 break;
1300 default:
1301 /*no action*/
1302 break;
1303 }
1304 break;
1305 case USB_DEVICE_AUDIO_SET_MAX_REQUEST:
1306 switch (controlSelector)
1307 {
1308 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1309 audioCommand = USB_DEVICE_AUDIO_EP_SET_MAX_SAMPLING_FREQ_CONTROL;
1310 break;
1311 default:
1312 /*no action*/
1313 break;
1314 }
1315 break;
1316 case USB_DEVICE_AUDIO_SET_RES_REQUEST:
1317 switch (controlSelector)
1318 {
1319 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1320 audioCommand = USB_DEVICE_AUDIO_EP_SET_RES_SAMPLING_FREQ_CONTROL;
1321 break;
1322 default:
1323 /*no action*/
1324 break;
1325 }
1326 break;
1327
1328 default:
1329 /*no action*/
1330 break;
1331 #endif /* USB_DEVICE_CONFIG_AUDIO_CLASS_2_0 */
1332 }
1333 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1334 (NULL != audioHandle->configStruct->classCallback))
1335 {
1336 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1337 it is from the second parameter of classInit */
1338 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1339 }
1340 return status;
1341 }
1342
1343 /*!
1344 * @brief Handle the audio device GET request endpoint.
1345 *
1346 * This callback function provides flexibility to add class and vendor specific requests
1347 *
1348 * @param audioHandle The device audio class handle. It equals the value returned from
1349 * usb_device_class_config_struct_t::classHandle.
1350 * @param controlRequest The pointer of the control request structure.
1351 *
1352 * @return A USB error code or kStatus_USB_Success.
1353 */
USB_DeviceAudioGetRequestEndpoint(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1354 usb_status_t USB_DeviceAudioGetRequestEndpoint(usb_device_audio_struct_t *audioHandle,
1355 usb_device_control_request_struct_t *controlRequest)
1356 {
1357 usb_status_t status = kStatus_USB_InvalidRequest;
1358 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1359 uint32_t audioCommand = 0;
1360 /* Select GET request Control for endpoint */
1361 switch (controlRequest->setup->bRequest)
1362 {
1363 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
1364 case USB_DEVICE_AUDIO_CUR_REQUEST:
1365 switch (controlSelector)
1366 {
1367 case USB_DEVICE_AUDIO_EP_DATA_OVERRUN_CONTROL_SELECTOR:
1368 audioCommand = USB_DEVICE_AUDIO_EP_GET_CUR_DATA_OVERRUN_CONTROL;
1369 break;
1370 case USB_DEVICE_AUDIO_EP_DATA_UNDERRUN_CONTROL_SELECTOR:
1371 audioCommand = USB_DEVICE_AUDIO_EP_GET_CUR_DATA_UNDERRUN_CONTROL;
1372 break;
1373 default:
1374 /*no action*/
1375 break;
1376 }
1377 break;
1378 default:
1379 /*no action*/
1380 break;
1381 #else
1382 case USB_DEVICE_AUDIO_GET_CUR_REQUEST:
1383 switch (controlSelector)
1384 {
1385 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1386 audioCommand = USB_DEVICE_AUDIO_EP_GET_CUR_SAMPLING_FREQ_CONTROL;
1387 break;
1388 default:
1389 /*no action*/
1390 break;
1391 }
1392 break;
1393 case USB_DEVICE_AUDIO_GET_MIN_REQUEST:
1394 switch (controlSelector)
1395 {
1396 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1397 audioCommand = USB_DEVICE_AUDIO_EP_GET_MIN_SAMPLING_FREQ_CONTROL;
1398 break;
1399 default:
1400 /*no action*/
1401 break;
1402 }
1403 break;
1404 case USB_DEVICE_AUDIO_GET_MAX_REQUEST:
1405 switch (controlSelector)
1406 {
1407 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1408
1409 audioCommand = USB_DEVICE_AUDIO_EP_GET_MAX_SAMPLING_FREQ_CONTROL;
1410 break;
1411 default:
1412 /*no action*/
1413 break;
1414 }
1415 break;
1416 case USB_DEVICE_AUDIO_GET_RES_REQUEST:
1417 switch (controlSelector)
1418 {
1419 case USB_DEVICE_AUDIO_EP_SAMPLING_FREQ_CONTROL_SELECTOR:
1420 audioCommand = USB_DEVICE_AUDIO_EP_GET_RES_SAMPLING_FREQ_CONTROL;
1421
1422 break;
1423 default:
1424 /*no action*/
1425 break;
1426 }
1427 break;
1428 default:
1429 /*no action*/
1430 break;
1431 #endif
1432 }
1433 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1434 (NULL != audioHandle->configStruct->classCallback))
1435 {
1436 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1437 it is from the second parameter of classInit */
1438 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1439 }
1440 return status;
1441 }
1442
1443 /*!
1444 * @brief Handle the audio device GET control terminal request.
1445 *
1446 * This callback function provides flexibility to add class and vendor specific requests
1447 *
1448 * @param audioHandle The device audio class handle. It equals the value returned from
1449 * usb_device_class_config_struct_t::classHandle.
1450 * @param controlRequest The pointer of the control request structure.
1451 *
1452 * @return A USB error code or kStatus_USB_Success.
1453 */
USB_DeviceAudioGetControlTerminal(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest,uint8_t terminal_type)1454 usb_status_t USB_DeviceAudioGetControlTerminal(usb_device_audio_struct_t *audioHandle,
1455 usb_device_control_request_struct_t *controlRequest,
1456 uint8_t terminal_type)
1457 {
1458 usb_status_t status = kStatus_USB_InvalidRequest;
1459 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1460 uint32_t audioCommand = 0;
1461 /* Select GET request Control for endpoint */
1462 switch (controlRequest->setup->bRequest)
1463 {
1464 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
1465 case USB_DEVICE_AUDIO_CUR_REQUEST:
1466 switch (controlSelector)
1467 {
1468 case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
1469 if (USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL == terminal_type)
1470 {
1471 audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_COPY_PROTECT_CONTROL;
1472 }
1473 else
1474 {
1475 /* Input Terminals only support the Get Terminal Copy Protect Control request */
1476 }
1477 break;
1478 case USB_DEVICE_AUDIO_TE_CONNECTOR_CONTROL:
1479 audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_CONNECTOR_CONTROL;
1480 break;
1481 case USB_DEVICE_AUDIO_TE_OVERLOAD_CONTROL:
1482 audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_OVERLOAD_CONTROL;
1483 break;
1484 default:
1485 /*no action*/
1486 break;
1487 }
1488 break;
1489 default:
1490 /*no action*/
1491 break;
1492 #else
1493 case USB_DEVICE_AUDIO_GET_CUR_REQUEST:
1494 switch (controlSelector)
1495 {
1496 case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
1497 if (USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL == terminal_type)
1498 {
1499 audioCommand = USB_DEVICE_AUDIO_TE_GET_CUR_COPY_PROTECT_CONTROL;
1500 }
1501 else
1502 {
1503 /* Input Terminals only support the Get Terminal Copy Protect Control request */
1504 }
1505 break;
1506 default:
1507 /*no action*/
1508 break;
1509 }
1510 break;
1511 default:
1512 /*no action*/
1513 break;
1514 #endif
1515 }
1516
1517 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1518 (NULL != audioHandle->configStruct->classCallback))
1519 {
1520 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1521 it is from the second parameter of classInit */
1522 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1523 }
1524
1525 return status;
1526 }
1527
1528 /*!
1529 * @brief Handle the audio device SET control terminal request.
1530 *
1531 * This callback function provides flexibility to add class and vendor specific requests
1532 *
1533 * @param audioHandle The device audio class handle. It equals the value returned from
1534 * usb_device_class_config_struct_t::classHandle.
1535 * @param controlRequest The pointer of the control request structure.
1536 * @param terminal_type The terminal type:: input terminal or output terminal
1537 *
1538 * @return A USB error code, kStatus_USB_Success or kStatus_USB_InvalidRequest.
1539 */
USB_DeviceAudioSetControlTerminal(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest,uint8_t terminal_type)1540 usb_status_t USB_DeviceAudioSetControlTerminal(usb_device_audio_struct_t *audioHandle,
1541 usb_device_control_request_struct_t *controlRequest,
1542 uint8_t terminal_type)
1543 {
1544 usb_status_t status = kStatus_USB_InvalidRequest;
1545 uint8_t controlSelector = (uint8_t)((controlRequest->setup->wValue >> 0x08) & 0xFFU);
1546 uint32_t audioCommand = 0;
1547 /* Select GET request Control for endpoint */
1548 switch (controlRequest->setup->bRequest)
1549 {
1550 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
1551 case USB_DEVICE_AUDIO_CUR_REQUEST:
1552 switch (controlSelector)
1553 {
1554 case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
1555 if (USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL == terminal_type)
1556 {
1557 audioCommand = USB_DEVICE_AUDIO_TE_SET_CUR_COPY_PROTECT_CONTROL;
1558 }
1559 else
1560 {
1561 /* Output Terminals only support the Set Terminal Copy Protect Control request */
1562 }
1563 break;
1564 default:
1565 /*no action*/
1566 break;
1567 }
1568 break;
1569 default:
1570 /*no action*/
1571 break;
1572 #else
1573 case USB_DEVICE_AUDIO_SET_CUR_REQUEST:
1574 switch (controlSelector)
1575 {
1576 case USB_DEVICE_AUDIO_TE_COPY_PROTECT_CONTROL:
1577 if (USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL == terminal_type)
1578 {
1579 audioCommand = USB_DEVICE_AUDIO_TE_SET_CUR_COPY_PROTECT_CONTROL;
1580 }
1581 else
1582 {
1583 /* Output Terminals only support the Set Terminal Copy Protect Control request */
1584 }
1585 break;
1586 default:
1587 /*no action*/
1588 break;
1589 }
1590 break;
1591 default:
1592 /*no action*/
1593 break;
1594 #endif
1595 }
1596
1597 if ((0U != audioCommand) && (NULL != audioHandle->configStruct) &&
1598 (NULL != audioHandle->configStruct->classCallback))
1599 {
1600 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1601 it is from the second parameter of classInit */
1602 status = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest);
1603 }
1604
1605 return status;
1606 }
1607
1608 /*!
1609 * @brief Handle the audio device set request interface.
1610 *
1611 * This callback function provides flexibility to add class and vendor specific requests
1612 *
1613 * @param audioHandle The device audio class handle. It equals the value returned from
1614 * usb_device_class_config_struct_t::classHandle.
1615 * @param controlRequest The pointer of the control request structure.
1616 *
1617 * @return A USB error code or kStatus_USB_Success.
1618 */
USB_DeviceAudioSetRequestInterface(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1619 usb_status_t USB_DeviceAudioSetRequestInterface(usb_device_audio_struct_t *audioHandle,
1620 usb_device_control_request_struct_t *controlRequest)
1621 {
1622 uint32_t i;
1623 usb_device_audio_entities_struct_t *entity_list;
1624 usb_status_t status = kStatus_USB_Error;
1625 uint8_t entityId = (uint8_t)(controlRequest->setup->wIndex >> 0x08);
1626
1627 entity_list = (usb_device_audio_entities_struct_t *)audioHandle->controlInterfaceHandle->classSpecific;
1628 for (i = 0; i < entity_list->count; i++)
1629 {
1630 if (entityId == entity_list->entity[i].entityId)
1631 {
1632 switch (entity_list->entity[i].entityType)
1633 {
1634 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL:
1635 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL:
1636 /*Select SET Request Control Input Terminal Module */
1637 status = USB_DeviceAudioSetControlTerminal(audioHandle, controlRequest,
1638 entity_list->entity[i].entityType);
1639 break;
1640 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT:
1641 /* Select SET request Control Feature Unit Module */
1642 status = USB_DeviceAudioSetFeatureUnit(audioHandle, controlRequest);
1643 break;
1644 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
1645 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_SOURCE_UNIT:
1646 /* Select SET request Control Clock Source Module */
1647 status = USB_DeviceAudioSetClockSource(audioHandle, controlRequest);
1648 break;
1649 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_SELECTOR_UNIT:
1650 /* Select SET request Control Clock Selector Module */
1651 status = kStatus_USB_InvalidRequest;
1652 break;
1653 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_MULTIPLIER_UNIT:
1654 /* Select SET request Control Clock multiplier Module */
1655 status = kStatus_USB_InvalidRequest;
1656 break;
1657 #endif
1658 default:
1659 status = kStatus_USB_InvalidRequest;
1660 break;
1661 }
1662 }
1663 }
1664 return status;
1665 }
1666
1667 /*!
1668 * @brief Handle the audio device get request interface.
1669 *
1670 * This callback function provides flexibility to add class and vendor specific requests
1671 *
1672 * @param audioHandle The device audio class handle. It equals the value returned from
1673 * usb_device_class_config_struct_t::classHandle.
1674 * @param controlRequest The pointer of the control request structure.
1675 *
1676 * @return A USB error code or kStatus_USB_Success.
1677 */
USB_DeviceAudioGetRequestInterface(usb_device_audio_struct_t * audioHandle,usb_device_control_request_struct_t * controlRequest)1678 usb_status_t USB_DeviceAudioGetRequestInterface(usb_device_audio_struct_t *audioHandle,
1679 usb_device_control_request_struct_t *controlRequest)
1680 {
1681 uint32_t i;
1682 usb_device_audio_entities_struct_t *entity_list;
1683 usb_status_t status = kStatus_USB_Error;
1684 uint8_t entityId = (uint8_t)(controlRequest->setup->wIndex >> 0x08);
1685
1686 entity_list = (usb_device_audio_entities_struct_t *)audioHandle->controlInterfaceHandle->classSpecific;
1687 for (i = 0; i < entity_list->count; i++)
1688 {
1689 if (entityId == entity_list->entity[i].entityId)
1690 {
1691 switch (entity_list->entity[i].entityType)
1692 {
1693 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL:
1694 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL:
1695 status = USB_DeviceAudioGetControlTerminal(audioHandle, controlRequest,
1696 entity_list->entity[i].entityType);
1697 break;
1698 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT:
1699 status = USB_DeviceAudioGetFeatureUnit(audioHandle, controlRequest);
1700 break;
1701 #if (USB_DEVICE_CONFIG_AUDIO_CLASS_2_0)
1702 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_SOURCE_UNIT:
1703 /* Select SET request Control Clock Source Module */
1704 status = USB_DeviceAudioGetClockSource(audioHandle, controlRequest);
1705 break;
1706 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_SELECTOR_UNIT:
1707 /* Select SET request Control Clock Select Module */
1708 status = kStatus_USB_InvalidRequest;
1709 break;
1710 case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_MULTIPLIER_UNIT:
1711 /* Select SET request Control Clock Multiplier Module */
1712 status = kStatus_USB_InvalidRequest;
1713 break;
1714 #endif
1715 default:
1716 status = kStatus_USB_InvalidRequest;
1717 break;
1718 }
1719 }
1720 }
1721 return status;
1722 }
1723
1724 /*!
1725 * @brief Handle the event passed to the audio class.
1726 *
1727 * This function handles the event passed to the audio class.
1728 *
1729 * @param handle The audio class handle, got from the usb_device_class_config_struct_t::classHandle.
1730 * @param event The event codes. Please refer to the enumeration usb_device_class_event_t.
1731 * @param param The param type is determined by the event code.
1732 *
1733 * @return A USB error code or kStatus_USB_Success.
1734 * @retval kStatus_USB_Success Free device handle successfully.
1735 * @retval kStatus_USB_InvalidParameter The device handle not be found.
1736 * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller.
1737 */
USB_DeviceAudioEvent(void * handle,uint32_t event,void * param)1738 usb_status_t USB_DeviceAudioEvent(void *handle, uint32_t event, void *param)
1739 {
1740 usb_device_audio_struct_t *audioHandle;
1741 usb_status_t error = kStatus_USB_Error;
1742 uint16_t interfaceAlternate;
1743 uint8_t *temp8;
1744 uint8_t alternate;
1745 uint32_t count;
1746 usb_device_class_event_t eventCode = (usb_device_class_event_t)event;
1747 if ((NULL == param) || (NULL == handle))
1748 {
1749 return kStatus_USB_InvalidHandle;
1750 }
1751
1752 /* Get the audio class handle. */
1753 audioHandle = (usb_device_audio_struct_t *)handle;
1754
1755 switch (eventCode)
1756 {
1757 case kUSB_DeviceClassEventDeviceReset:
1758 /* Bus reset, clear the configuration. */
1759 audioHandle->configuration = 0U;
1760 audioHandle->streamOutPipeBusy = 0U;
1761 audioHandle->streamInPipeBusy = 0U;
1762 error = kStatus_USB_Success;
1763 break;
1764 case kUSB_DeviceClassEventSetConfiguration:
1765 /* Get the new configuration. */
1766 temp8 = ((uint8_t *)param);
1767 if (NULL == audioHandle->configStruct)
1768 {
1769 break;
1770 }
1771 if (*temp8 == audioHandle->configuration)
1772 {
1773 error = kStatus_USB_Success;
1774 break;
1775 }
1776 /* De-initialize the endpoints when current configuration is none zero. */
1777 if (0U != audioHandle->configuration)
1778 {
1779 error = USB_DeviceAudioControlEndpointsDeinit(audioHandle);
1780 error = USB_DeviceAudioStreamEndpointsDeinit(audioHandle);
1781 }
1782 /* Save new configuration. */
1783 audioHandle->configuration = *temp8;
1784 /* Clear the alternate setting value. */
1785 audioHandle->controlAlternate = 0U;
1786 /* Clear the alternate setting value. */
1787 audioHandle->streamAlternate = 0U;
1788 audioHandle->controlInterfaceHandle = NULL;
1789 audioHandle->streamInterfaceHandle = NULL;
1790 /* Initialize the control endpoints of the new current configuration by using the alternate setting 0. */
1791 error = USB_DeviceAudioControlEndpointsInit(audioHandle);
1792 /* Initialize the stream endpoints of the new current configuration by using the alternate setting 0. */
1793 error = USB_DeviceAudioStreamEndpointsInit(audioHandle);
1794 break;
1795 case kUSB_DeviceClassEventSetInterface:
1796 if (NULL == audioHandle->configStruct)
1797 {
1798 break;
1799 }
1800 /* Get the new alternate setting of the interface */
1801 interfaceAlternate = *((uint16_t *)param);
1802 /* Get the alternate setting value */
1803 alternate = (uint8_t)(interfaceAlternate & 0xFFU);
1804
1805 /* Whether the interface belongs to the class. */
1806 if (audioHandle->controlInterfaceNumber == ((uint8_t)(interfaceAlternate >> 8U)))
1807 {
1808 /* When the interface is control interface. */
1809 /* Only handle new alternate setting. */
1810 if (alternate == audioHandle->controlAlternate)
1811 {
1812 error = kStatus_USB_Success;
1813 break;
1814 }
1815 /* De-initialize old endpoints */
1816 error = USB_DeviceAudioControlEndpointsDeinit(audioHandle);
1817 audioHandle->controlAlternate = alternate;
1818 /* Initialize new endpoints */
1819 error = USB_DeviceAudioControlEndpointsInit(audioHandle);
1820 }
1821 else if (audioHandle->streamInterfaceNumber == ((uint8_t)(interfaceAlternate >> 8U)))
1822 {
1823 /* When the interface is stream interface. */
1824 /* Only handle new alternate setting. */
1825 if (alternate == audioHandle->streamAlternate)
1826 {
1827 error = kStatus_USB_Success;
1828 break;
1829 }
1830 /* De-initialize old endpoints */
1831 error = USB_DeviceAudioStreamEndpointsDeinit(audioHandle);
1832 audioHandle->streamAlternate = alternate;
1833 /* Initialize new endpoints */
1834 error = USB_DeviceAudioStreamEndpointsInit(audioHandle);
1835 }
1836 else
1837 {
1838 /*no action*/
1839 }
1840 break;
1841 case kUSB_DeviceClassEventSetEndpointHalt:
1842 if (NULL == audioHandle->configStruct)
1843 {
1844 break;
1845 }
1846 /* Get the endpoint address */
1847 temp8 = ((uint8_t *)param);
1848 if (NULL != audioHandle->controlInterfaceHandle)
1849 {
1850 for (count = 0U; count < audioHandle->controlInterfaceHandle->endpointList.count; count++)
1851 {
1852 if (*temp8 == audioHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress)
1853 {
1854 /* Only stall the endpoint belongs to control interface of the class */
1855 error = USB_DeviceStallEndpoint(audioHandle->handle, *temp8);
1856 }
1857 }
1858 }
1859 if (NULL != audioHandle->streamInterfaceHandle)
1860 {
1861 for (count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++)
1862 {
1863 if (*temp8 == audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress)
1864 {
1865 /* Only stall the endpoint belongs to stream interface of the class */
1866 error = USB_DeviceStallEndpoint(audioHandle->handle, *temp8);
1867 }
1868 }
1869 }
1870 break;
1871 case kUSB_DeviceClassEventClearEndpointHalt:
1872 if (NULL == audioHandle->configStruct)
1873 {
1874 break;
1875 }
1876 /* Get the endpoint address */
1877 temp8 = ((uint8_t *)param);
1878 if (NULL != audioHandle->controlInterfaceHandle)
1879 {
1880 for (count = 0U; count < audioHandle->controlInterfaceHandle->endpointList.count; count++)
1881 {
1882 if (*temp8 == audioHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress)
1883 {
1884 /* Only un-stall the endpoint belongs to control interface of the class */
1885 error = USB_DeviceUnstallEndpoint(audioHandle->handle, *temp8);
1886 }
1887 }
1888 }
1889 if (NULL != audioHandle->streamInterfaceHandle)
1890 {
1891 for (count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++)
1892 {
1893 if (*temp8 == audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress)
1894 {
1895 /* Only un-stall the endpoint belongs to stream interface of the class */
1896 error = USB_DeviceUnstallEndpoint(audioHandle->handle, *temp8);
1897 }
1898 }
1899 }
1900 break;
1901 case kUSB_DeviceClassEventClassRequest:
1902 {
1903 /* Handle the audio class specific request. */
1904 usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param;
1905 uint8_t interfaceOrEndpoint = (uint8_t)controlRequest->setup->wIndex;
1906
1907 if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) ==
1908 USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
1909 {
1910 if ((NULL == audioHandle->controlInterfaceHandle) || (NULL == audioHandle->streamInterfaceHandle))
1911 {
1912 break; /* return error */
1913 }
1914 for (count = 0U; count < audioHandle->controlInterfaceHandle->endpointList.count; count++)
1915 {
1916 if (interfaceOrEndpoint ==
1917 audioHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress)
1918 {
1919 break;
1920 }
1921 }
1922 if (count == audioHandle->controlInterfaceHandle->endpointList.count)
1923 {
1924 for (count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++)
1925 {
1926 if (interfaceOrEndpoint ==
1927 audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress)
1928 {
1929 break;
1930 }
1931 }
1932 if (count == audioHandle->streamInterfaceHandle->endpointList.count)
1933 {
1934 break; /* return error */
1935 }
1936 }
1937 error = kStatus_USB_InvalidRequest;
1938 switch (controlRequest->setup->bmRequestType)
1939 {
1940 case USB_DEVICE_AUDIO_SET_REQUEST_ENDPOINT:
1941 error = USB_DeviceAudioSetRequestEndpoint(audioHandle, controlRequest);
1942 break;
1943 case USB_DEVICE_AUDIO_GET_REQUEST_ENDPOINT:
1944 error = USB_DeviceAudioGetRequestEndpoint(audioHandle, controlRequest);
1945 break;
1946 default:
1947 /*no action*/
1948 break;
1949 }
1950 }
1951 else if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) ==
1952 USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
1953 {
1954 if (audioHandle->controlInterfaceNumber == interfaceOrEndpoint)
1955 {
1956 error = kStatus_USB_InvalidRequest;
1957 switch (controlRequest->setup->bmRequestType)
1958 {
1959 case USB_DEVICE_AUDIO_SET_REQUEST_INTERFACE:
1960 error = USB_DeviceAudioSetRequestInterface(audioHandle, controlRequest);
1961 break;
1962 case USB_DEVICE_AUDIO_GET_REQUEST_INTERFACE:
1963 error = USB_DeviceAudioGetRequestInterface(audioHandle, controlRequest);
1964 break;
1965 default:
1966 /*no action*/
1967 break;
1968 }
1969 }
1970 }
1971 else
1972 {
1973 /* no action */
1974 }
1975 }
1976 break;
1977 default:
1978 /*no action*/
1979 break;
1980 }
1981 return error;
1982 }
1983
1984 /*!
1985 * @brief Initialize the audio class.
1986 *
1987 * This function is used to initialize the audio class.
1988 *
1989 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
1990 * @param config The class configuration information.
1991 * @param handle It is out parameter, is used to return pointer of the audio class handle to the caller.
1992 *
1993 * @return A USB error code or kStatus_USB_Success.
1994 */
USB_DeviceAudioInit(uint8_t controllerId,usb_device_class_config_struct_t * config,class_handle_t * handle)1995 usb_status_t USB_DeviceAudioInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle)
1996 {
1997 usb_device_audio_struct_t *audioHandle;
1998 usb_status_t error = kStatus_USB_Error;
1999
2000 /* Allocate a audio class handle. */
2001 error = USB_DeviceAudioAllocateHandle(&audioHandle);
2002
2003 if (kStatus_USB_Success != error)
2004 {
2005 return error;
2006 }
2007
2008 /* Get the device handle according to the controller id. */
2009 error = USB_DeviceClassGetDeviceHandle(controllerId, &audioHandle->handle);
2010
2011 if (kStatus_USB_Success != error)
2012 {
2013 return error;
2014 }
2015
2016 if (NULL == audioHandle->handle)
2017 {
2018 return kStatus_USB_InvalidHandle;
2019 }
2020 /* Save the configuration of the class. */
2021 audioHandle->configStruct = config;
2022 /* Clear the configuration value. */
2023 audioHandle->configuration = 0U;
2024 audioHandle->streamAlternate = 0xffU;
2025 audioHandle->controlAlternate = 0xffU;
2026
2027 *handle = (class_handle_t)audioHandle;
2028 return error;
2029 }
2030
2031 /*!
2032 * @brief De-initialize the device audio class.
2033 *
2034 * The function de-initializes the device audio class.
2035 *
2036 * @param handle The ccid class handle got from usb_device_class_config_struct_t::classHandle.
2037 *
2038 * @return A USB error code or kStatus_USB_Success.
2039 */
USB_DeviceAudioDeinit(class_handle_t handle)2040 usb_status_t USB_DeviceAudioDeinit(class_handle_t handle)
2041 {
2042 usb_device_audio_struct_t *audioHandle;
2043 usb_status_t error = kStatus_USB_Error;
2044
2045 audioHandle = (usb_device_audio_struct_t *)handle;
2046
2047 if (NULL == audioHandle)
2048 {
2049 return kStatus_USB_InvalidHandle;
2050 }
2051 error = USB_DeviceAudioStreamEndpointsDeinit(audioHandle);
2052 error = USB_DeviceAudioControlEndpointsDeinit(audioHandle);
2053 (void)USB_DeviceAudioFreeHandle(audioHandle);
2054 return error;
2055 }
2056
2057 /*!
2058 * @brief Send data through a specified endpoint.
2059 *
2060 * The function is used to send data through a specified endpoint.
2061 * The function calls USB_DeviceSendRequest internally.
2062 *
2063 * @param handle The audio class handle got from usb_device_class_config_struct_t::classHandle.
2064 * @param endpointAddress Endpoint index.
2065 * @param buffer The memory address to hold the data need to be sent.
2066 * @param length The data length need to be sent.
2067 *
2068 * @return A USB error code or kStatus_USB_Success.
2069 *
2070 * @note The return value just means if the sending request is successful or not; the transfer done is notified by
2071 * usb_device_audio_stream_in or usb_device_audio_control_in.
2072 * Currently, only one transfer request can be supported for one specific endpoint.
2073 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
2074 * should implement a queue in the application level.
2075 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
2076 * callback).
2077 */
USB_DeviceAudioSend(class_handle_t handle,uint8_t ep,uint8_t * buffer,uint32_t length)2078 usb_status_t USB_DeviceAudioSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
2079 {
2080 usb_device_audio_struct_t *audioHandle;
2081 usb_status_t error = kStatus_USB_Error;
2082
2083 if (NULL == handle)
2084 {
2085 return kStatus_USB_InvalidHandle;
2086 }
2087 audioHandle = (usb_device_audio_struct_t *)handle;
2088
2089 if (0U != audioHandle->streamInPipeBusy)
2090 {
2091 return kStatus_USB_Busy;
2092 }
2093 audioHandle->streamInPipeBusy = 1U;
2094
2095 error = USB_DeviceSendRequest(audioHandle->handle, ep, buffer, length);
2096 if (kStatus_USB_Success != error)
2097 {
2098 audioHandle->streamInPipeBusy = 0U;
2099 }
2100 return error;
2101 }
2102
2103 /*!
2104 * @brief Receive data through a specified endpoint.
2105 *
2106 * The function is used to receive data through a specified endpoint.
2107 * The function calls USB_DeviceRecvRequest internally.
2108 *
2109 * @param handle The audio class handle got from usb_device_class_config_struct_t::classHandle.
2110 * @param endpointAddress Endpoint index.
2111 * @param buffer The memory address to save the received data.
2112 * @param length The data length want to be received.
2113 *
2114 * @return A USB error code or kStatus_USB_Success.
2115 *
2116 * @note The return value just means if the receiving request is successful or not; the transfer done is notified by
2117 * usb_device_audio_stream_out.
2118 * Currently, only one transfer request can be supported for one specific endpoint.
2119 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
2120 * should implement a queue in the application level.
2121 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
2122 * callback).
2123 */
USB_DeviceAudioRecv(class_handle_t handle,uint8_t ep,uint8_t * buffer,uint32_t length)2124 usb_status_t USB_DeviceAudioRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length)
2125 {
2126 usb_device_audio_struct_t *audioHandle;
2127 usb_status_t error = kStatus_USB_Error;
2128
2129 if (NULL == handle)
2130 {
2131 return kStatus_USB_InvalidHandle;
2132 }
2133 audioHandle = (usb_device_audio_struct_t *)handle;
2134
2135 if (0U != audioHandle->streamOutPipeBusy)
2136 {
2137 return kStatus_USB_Busy;
2138 }
2139 audioHandle->streamOutPipeBusy = 1U;
2140
2141 error = USB_DeviceRecvRequest(audioHandle->handle, ep, buffer, length);
2142 if (kStatus_USB_Success != error)
2143 {
2144 audioHandle->streamOutPipeBusy = 0U;
2145 }
2146 return error;
2147 }
2148
2149 #endif
2150