M480 BSP  V3.05.001
The Board Support Package for M480 Series
uac_parser.c
Go to the documentation of this file.
1 /**************************************************************************/
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include "NuMicro.h"
14 
15 #include "usb.h"
16 #include "usbh_lib.h"
17 #include "usbh_uac.h"
18 #include "uac.h"
19 
21 
22 static int uac_parse_ac_interface(UAC_DEV_T *uac, uint8_t *bptr)
23 {
24  AC_IT_T *ac_itd;
25  AC_OT_T *ac_otd;
26 
27  UAC_DBGMSG("Parse AC - [%d] [0x%x] [0x%x]\n", ((CS_HDR_T *)bptr)->bLength, ((CS_HDR_T *)bptr)->bDescriptorType, ((CS_HDR_T *)bptr)->bDescriptorSubtype);
28 
29  switch (((CS_HDR_T *)bptr)->bDescriptorSubtype)
30  {
31  case AC_DESCRIPTOR_UNDEFINED: /* Not interested, discard it... */
32  UAC_DBGMSG("AC: AC_DESCRIPTOR_UNDEFINED\n");
33  break;
34 
35  case HEADER:
36  /* Not interested, discard it... */
37  UAC_DBGMSG("AC: HEADER\n");
38  break;
39 
40  case INPUT_TERMINAL:
41  ac_itd = (AC_IT_T *)bptr;
42  UAC_DBGMSG("AC: INPUT_TERMINAL\n");
43  if (ac_itd->wTerminalType == UAC_TT_USB_STREAMING)
44  {
45  UAC_DBGMSG("USB streaming terminal found, ID=0x%x\n", ac_itd->bTerminalID);
46  }
47  else if ((ac_itd->wTerminalType & 0x200) == 0x200)
48  {
49  UAC_DBGMSG("MICROPHONE input terminal found, ID=0x%x\n", ac_itd->bTerminalID);
50  uac->acif.mic_id = ac_itd->bTerminalID;
51  }
52  else
53  {
54  UAC_DBGMSG("Unsupported INPUT TERMINAL, ignore it!\n");
55  }
56  UAC_DBGMSG(" bTerminalID: 0%x\n", ac_itd->bTerminalID);
57  UAC_DBGMSG(" wTerminalType: 0%x\n", ac_itd->wTerminalType);
58  UAC_DBGMSG(" bAssocTerminal: 0%x\n", ac_itd->bAssocTerminal);
59  UAC_DBGMSG(" bNrChannels: 0%x\n", ac_itd->bNrChannels);
60  UAC_DBGMSG(" wChannelConfig: 0%x\n", ac_itd->wChannelConfig);
61  break;
62 
63  case OUTPUT_TERMINAL:
64  ac_otd = (AC_OT_T *)bptr;
65  UAC_DBGMSG("AC: OUTPUT_TERMINAL\n");
66  if (ac_otd->wTerminalType == UAC_TT_USB_STREAMING)
67  {
68  UAC_DBGMSG("USB streaming terminal found, ID=0x%x\n", ac_otd->bTerminalID);
69  }
70  else if ((ac_otd->wTerminalType & 0x300) == 0x300)
71  {
72  UAC_DBGMSG("SPEAKER output terminal found, ID=0x%x\n", ac_otd->bTerminalID);
73  uac->acif.speaker_id = ac_otd->bTerminalID;
74  uac->acif.speaker_fuid = ac_otd->bSourceID;
75  }
76  else
77  {
78  UAC_DBGMSG("Unsupported OUTPUT TERMINAL, ignore it!\n");
79  }
80  UAC_DBGMSG(" bTerminalID: 0%x\n", ac_otd->bTerminalID);
81  UAC_DBGMSG(" wTerminalType: 0%x\n", ac_otd->wTerminalType);
82  UAC_DBGMSG(" bAssocTerminal: 0%x\n", ac_otd->bAssocTerminal);
83  UAC_DBGMSG(" bSourceID: 0%x\n", ac_otd->bSourceID);
84  break;
85 
86  case MIXER_UNIT:
87 #ifdef UAC_DEBUG
88  UAC_DBGMSG("AC: MIXER_UNIT\n");
89  UAC_DBGMSG(" bUnitID: 0%x\n", ((AC_MXR_T *)bptr)->bUnitID);
90  UAC_DBGMSG(" bNrInPins: 0%x\n", ((AC_MXR_T *)bptr)->bNrInPins);
91 #endif
92  break;
93 
94  case SELECTOR_UNIT:
95 #ifdef UAC_DEBUG
96  UAC_DBGMSG("AC: SELECTOR_UNIT\n");
97  UAC_DBGMSG(" bUnitID: 0%x\n", ((AC_SU_T *)bptr)->bUnitID);
98  UAC_DBGMSG(" bNrInPins: 0%x\n", ((AC_SU_T *)bptr)->bNrInPins);
99 #endif
100  break;
101 
102  case FEATURE_UNIT:
103 
104 #ifdef UAC_DEBUG
105  UAC_DBGMSG("AC: FEATURE_UNIT\n");
106  UAC_DBGMSG(" bUnitID: 0%x\n", ((AC_FU_T *)bptr)->bUnitID);
107  UAC_DBGMSG(" bSourceID: 0%x\n", ((AC_FU_T *)bptr)->bSourceID);
108  UAC_DBGMSG(" bControlSize: 0%x\n", ((AC_FU_T *)bptr)->bControlSize);
109 #endif
110  break;
111 
112  case PROCESSING_UNIT:
113 #ifdef UAC_DEBUG
114  UAC_DBGMSG("AC: PROCESSING_UNIT\n");
115  UAC_DBGMSG(" bUnitID: 0%x\n", ((AC_PU_T *)bptr)->bUnitID);
116  UAC_DBGMSG(" wProcessType: 0%x\n", ((AC_PU_T *)bptr)->wProcessType);
117  UAC_DBGMSG(" bNrInPins: 0%x\n", ((AC_PU_T *)bptr)->bNrInPins);
118 #endif
119  break;
120 
121  case EXTENSION_UNIT:
122  UAC_DBGMSG("AC: EXTENSION_UNIT\n");
123  break;
124 
125  default:
126  UAC_ERRMSG("uac_parse_ac_interface - unrecognized bDescriptorSubtype 0x%x!\n", ((CS_HDR_T *)bptr)->bDescriptorSubtype);
127  return UAC_RET_PARSER;
128  }
129  return 0;
130 }
131 
132 static int uac_set_microphone_feature_unit(UAC_DEV_T *uac)
133 {
134  DESC_CONF_T *config;
135  AC_FU_T *hdr;
136  uint8_t *bptr;
137  uint8_t bTerminalID = uac->acif.mic_id;
138  int size;
139 
140  bptr = uac->udev->cfd_buff;
141  config = (DESC_CONF_T *)bptr;
142 
143  /* step over configuration descriptor */
144  bptr += config->bLength;
145  size = config->wTotalLength - config->bLength;
146 
147  /*------------------------------------------------------------------------------------*/
148  /* Find the Terminal Descriptor */
149  /*------------------------------------------------------------------------------------*/
150  while (size >= sizeof(DESC_IF_T))
151  {
152  hdr = (AC_FU_T *)bptr;
153 
154  if ((hdr->bDescriptorType == CS_INTERFACE) && (hdr->bDescriptorSubtype == FEATURE_UNIT) &&
155  (hdr->bSourceID == bTerminalID))
156  {
157  uac->acif.mic_fuid = hdr->bUnitID;
158  return 0;
159  }
160 
161  if (hdr->bLength == 0)
162  return UAC_RET_PARSER; /* prevent infinite loop */
163 
164  bptr += hdr->bLength;
165  size -= hdr->bLength;
166  }
167  return UAC_RET_PARSER; /* not found */
168 }
169 
178 int uac_parse_control_interface(UAC_DEV_T *uac, IFACE_T *iface)
179 {
180  DESC_CONF_T *config;
181  DESC_IF_T *ifd;
182  int if_num;
183  uint8_t *bptr;
184  int size, ret;
185 
186  if_num = iface->if_num; /* interface number of AC interface */
187 
188  UAC_DBGMSG("UAC parsing audio control (AC) interface %d...\n", if_num);
189 
190  memset(&uac->acif, 0, sizeof(uac->acif)); /* clear AC information */
191  uac->acif.iface = iface;
192 
193  bptr = uac->udev->cfd_buff;
194  config = (DESC_CONF_T *)bptr;
195 
196  /* step over configuration descriptor */
197  bptr += config->bLength;
198  size = config->wTotalLength - config->bLength;
199 
200  /*------------------------------------------------------------------------------------*/
201  /* Find the Standard AC Interface Descriptor */
202  /*------------------------------------------------------------------------------------*/
203  while (size >= sizeof(DESC_IF_T))
204  {
205  ifd = (DESC_IF_T *)bptr;
206 
207  if ((ifd->bDescriptorType == USB_DT_INTERFACE) && (ifd->bInterfaceNumber == if_num) &&
208  (ifd->bInterfaceClass == USB_CLASS_AUDIO) && (ifd->bInterfaceSubClass == SUBCLS_AUDIOCONTROL))
209  break;
210 
211  if (ifd->bLength == 0)
212  return UAC_RET_PARSER; /* prevent infinite loop */
213 
214  bptr += ifd->bLength;
215  size -= ifd->bLength;
216  }
217 
218  if (size < sizeof(DESC_IF_T)) /* cannot find the Standard AC descriptor */
219  {
220  UAC_ERRMSG("UAC_RET_PARSER! - AC standard not found!\n");
221  return UAC_RET_PARSER;
222  }
223 
224  bptr += ifd->bLength;
225  size -= ifd->bLength;
226 
227  /*------------------------------------------------------------------------------------*/
228  /* Walk though all Class-Specific AC Interface Descriptor (4.3.2) */
229  /*------------------------------------------------------------------------------------*/
230  while (size > sizeof(DESC_HDR_T))
231  {
232  ifd = (DESC_IF_T *)bptr;
233 
234  if (ifd->bDescriptorType != CS_INTERFACE)
235  break;
236 
237  ret = uac_parse_ac_interface(uac, bptr);
238  if (ret < 0)
239  {
240  UAC_ERRMSG("UAC_RET_PARSER! - parsing CS\n");
241  return UAC_RET_PARSER;
242  }
243 
244  if (ifd->bLength == 0)
245  return UAC_RET_PARSER; /* prevent infinite loop */
246 
247  bptr += ifd->bLength;
248  size -= ifd->bLength;
249  }
250 
251  uac_set_microphone_feature_unit(uac);
252 
253  UAC_DBGMSG(" Microphone Input Terminal ID: 0x%x\n", uac->acif.mic_id);
254  UAC_DBGMSG(" Microphone Feature Unit ID: 0x%x\n", uac->acif.mic_fuid);
255  UAC_DBGMSG(" Speaker Output Terminal ID: 0x%x\n", uac->acif.speaker_id);
256  UAC_DBGMSG(" Speaker Feature Unit ID: 0x%x\n", uac->acif.speaker_fuid);
257 
258  return 0;
259 }
260 
261 static int uac_parse_as_interface(AS_IF_T *asif, uint8_t *bptr)
262 {
263  ALT_IFACE_T *aif = asif->iface->aif;
264  int i;
265 
266  if (((CS_HDR_T *)bptr)->bDescriptorType == USB_DT_ENDPOINT)
267  {
268  for (i = 0; i < aif->ifd->bNumEndpoints; i++)
269  {
270  if (aif->ep[i].bEndpointAddress == ((DESC_EP_T *)bptr)->bEndpointAddress)
271  {
272  asif->ep = &(asif->iface->aif->ep[i]);
273  break;
274  }
275  }
276  if (i >= aif->ifd->bNumEndpoints)
277  {
278  UAC_ERRMSG("Endpoint 0x%x parsing error!\n", ((DESC_EP_T *)bptr)->bEndpointAddress);
279  return UAC_RET_PARSER;
280  }
281  return 0;
282  }
283 
284  if (((CS_HDR_T *)bptr)->bDescriptorType == CS_ENDPOINT)
285  {
286  asif->cs_epd = (CS_EP_T *)bptr;
287  return 0;
288  }
289 
290  switch (((CS_HDR_T *)bptr)->bDescriptorSubtype)
291  {
292  case AS_DESCRIPTOR_UNDEFINED:
293  UAC_DBGMSG("AS: AS_DESCRIPTOR_UNDEFINED\n");
294  break;
295 
296  case AS_GENERAL:
297  asif->as_gen = (AS_GEN_T *)bptr;
298  UAC_DBGMSG("AS: AS_GENERAL\n");
299  UAC_DBGMSG(" bTerminalLink: 0%x\n", asif->as_gen->bTerminalLink);
300  UAC_DBGMSG(" wFormatTag: 0%x\n", asif->as_gen->wFormatTag);
301  break;
302 
303  case FORMAT_TYPE:
304  asif->ft = (AS_FT1_T *)bptr;
305  UAC_DBGMSG("AS: FORMAT_TYPE\n");
306  break;
307 
308  case FORMAT_SPECIFIC:
309  UAC_DBGMSG("AS: FORMAT_SPECIFIC\n");
310  break;
311 
312  default:
313  UAC_ERRMSG("uac_parse_as_interface - unrecognized bDescriptorSubtype 0x%x!\n", ((CS_HDR_T *)bptr)->bDescriptorSubtype);
314  return UAC_RET_PARSER;
315  }
316 
317  return 0;
318 }
319 
320 static int iface_have_iso_in_ep(IFACE_T *iface)
321 {
322  int i, j;
323  EP_INFO_T *ep;
324 
325  for (i = 0; i < iface->num_alt; i++)
326  {
327  for (j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
328  {
329  ep = &(iface->alt[i].ep[j]);
330  if (ep != NULL)
331  {
332  if (((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO) &&
333  ((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN))
334  return 1;
335  }
336  }
337  }
338  return 0;
339 }
340 
341 static int iface_have_iso_out_ep(IFACE_T *iface)
342 {
343  int i, j;
344  EP_INFO_T *ep;
345 
346  for (i = 0; i < iface->num_alt; i++)
347  {
348  for (j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
349  {
350  ep = &(iface->alt[i].ep[j]);
351  if (ep != NULL)
352  {
353  if (((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO) &&
354  ((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_OUT))
355  return 1;
356  }
357  }
358  }
359  return 0;
360 }
361 
362 static void * uac_find_terminal(UAC_DEV_T *uac, uint8_t bTerminalID)
363 {
364  DESC_CONF_T *config;
365  AC_OT_T *hdr;
366  uint8_t *bptr;
367  int size;
368 
369  bptr = uac->udev->cfd_buff;
370  config = (DESC_CONF_T *)bptr;
371 
372  /* step over configuration descriptor */
373  bptr += config->bLength;
374  size = config->wTotalLength - config->bLength;
375 
376  /*------------------------------------------------------------------------------------*/
377  /* Find the Terminal Descriptor */
378  /*------------------------------------------------------------------------------------*/
379  while (size >= sizeof(DESC_IF_T))
380  {
381  hdr = (AC_OT_T *)bptr;
382 
383  if ((hdr->bDescriptorType == CS_INTERFACE) &&
384  ((hdr->bDescriptorSubtype == INPUT_TERMINAL) || (hdr->bDescriptorSubtype == OUTPUT_TERMINAL)) &&
385  (hdr->bTerminalID == bTerminalID))
386  return (void *)hdr;
387 
388  if (hdr->bLength == 0)
389  return NULL; /* prevent infinite loop */
390 
391  bptr += hdr->bLength;
392  size -= hdr->bLength;
393  }
394  return NULL; /* not found */
395 }
396 
397 #if 0
398 static void * uac_find_feature_unit(UAC_DEV_T *uac, uint8_t bUnitID)
399 {
400  DESC_CONF_T *config;
401  AC_FU_T *hdr;
402  uint8_t *bptr;
403  int size;
404 
405  bptr = uac->udev->cfd_buff;
406  config = (DESC_CONF_T *)bptr;
407 
408  /* step over configuration descriptor */
409  bptr += config->bLength;
410  size = config->wTotalLength - config->bLength;
411 
412  /*------------------------------------------------------------------------------------*/
413  /* Find the Terminal Descriptor */
414  /*------------------------------------------------------------------------------------*/
415  while (size >= sizeof(DESC_IF_T))
416  {
417  hdr = (AC_FU_T *)bptr;
418 
419  if ((hdr->bDescriptorType == CS_INTERFACE) && (hdr->bDescriptorSubtype == FEATURE_UNIT) &&
420  (hdr->bUnitID == bUnitID))
421  return (void *)hdr;
422 
423  if (hdr->bLength == 0)
424  return NULL; /* prevent infinite loop */
425 
426  bptr += hdr->bLength;
427  size -= hdr->bLength;
428  }
429  return NULL; /* not found */
430 }
431 #endif
432 
442 int uac_parse_streaming_interface(UAC_DEV_T *uac, IFACE_T *iface, uint8_t bAlternateSetting)
443 {
444  DESC_CONF_T *config;
445  DESC_IF_T *ifd;
446  AS_IF_T asif;
447  int if_num;
448  uint8_t *bptr;
449  int size, ret;
450 
451  if_num = iface->if_num; /* interface number of AC interface */
452 
453  UAC_DBGMSG("UAC parsing audio stream (AS) interface %d, alt %d...\n", if_num, bAlternateSetting);
454 
455  memset(&asif, 0, sizeof(asif)); /* clear AS information */
456  asif.iface = iface;
457 
458  bptr = uac->udev->cfd_buff;
459  config = (DESC_CONF_T *)bptr;
460 
461  /* step over configuration descriptor */
462  bptr += config->bLength;
463  size = config->wTotalLength - config->bLength;
464 
465  /*------------------------------------------------------------------------------------*/
466  /* Find the Standard AS Interface Descriptor */
467  /*------------------------------------------------------------------------------------*/
468  while (size >= sizeof(DESC_IF_T))
469  {
470  ifd = (DESC_IF_T *)bptr;
471 
472  if ((ifd->bDescriptorType == USB_DT_INTERFACE) &&
473  (ifd->bInterfaceNumber == if_num) && (ifd->bAlternateSetting == bAlternateSetting) &&
474  (ifd->bInterfaceClass == USB_CLASS_AUDIO) && (ifd->bInterfaceSubClass == SUBCLS_AUDIOSTREAMING))
475  break;
476 
477  if (ifd->bLength == 0)
478  return UAC_RET_PARSER; /* prevent infinite loop */
479 
480  bptr += ifd->bLength;
481  size -= ifd->bLength;
482  }
483 
484  if (size < sizeof(DESC_IF_T)) /* cannot find the Standard AC descriptor */
485  {
486  UAC_ERRMSG("UAC_RET_PARSER! - AC standard not found!\n");
487  return UAC_RET_PARSER;
488  }
489 
490  if (ifd->bNumEndpoints == 0)
491  {
492  UAC_DBGMSG("This alternative interface is an idle interface.\n");
493  return 0;
494  }
495 
496  bptr += ifd->bLength;
497  size -= ifd->bLength;
498 
499  /*------------------------------------------------------------------------------------*/
500  /* Walk though all Class-Specific AS Interface Descriptor (4.5.2) */
501  /*------------------------------------------------------------------------------------*/
502  while (size > sizeof(DESC_HDR_T))
503  {
504  ifd = (DESC_IF_T *)bptr;
505 
506  //UAC_DBGMSG("Parse AS - [%d] [0x%x] [0x%x]\n", ((CS_HDR_T *)bptr)->bLength, ((CS_HDR_T *)bptr)->bDescriptorType, ((CS_HDR_T *)bptr)->bDescriptorSubtype);
507 
508  if ((ifd->bDescriptorType != CS_INTERFACE) &&
509  (ifd->bDescriptorType != USB_DT_ENDPOINT) &&
510  (ifd->bDescriptorType != CS_ENDPOINT))
511  break;
512 
513 
514  ret = uac_parse_as_interface(&asif, bptr);
515  if (ret < 0)
516  {
517  UAC_ERRMSG("UAC_RET_PARSER! - parsing CS\n");
518  return UAC_RET_PARSER;
519  }
520 
521  if (ifd->bLength == 0)
522  return UAC_RET_PARSER; /* prevent infinite loop */
523 
524  bptr += ifd->bLength;
525  size -= ifd->bLength;
526  }
527 
528  if (asif.as_gen == NULL)
529  {
530  UAC_ERRMSG("UAC_RET_PARSER! - AS_GEN not found!\n");
531  return UAC_RET_PARSER;
532  }
533 
534  if (iface_have_iso_in_ep(iface))
535  {
536  /* Find microphone's output terminal by AS_GEN's bTerminalLink */
537  asif.ot = (AC_OT_T *)uac_find_terminal(uac, asif.as_gen->bTerminalLink);
538  if (asif.ot)
539  {
540  UAC_DBGMSG("Audio in Terminal ID: 0%x\n", asif.ot->bTerminalID);
541  UAC_DBGMSG(" bDescriptorSubtype: 0%x\n", asif.ot->bDescriptorSubtype);
542  UAC_DBGMSG(" wTerminalType: 0%x\n", asif.ot->wTerminalType);
543  UAC_DBGMSG(" bAssocTerminal: 0%x\n", asif.ot->bAssocTerminal);
544  UAC_DBGMSG(" bSourceID: 0%x\n", asif.ot->bSourceID);
545  }
546  else
547  {
548  UAC_ERRMSG("Cannot find audio in Output Terminal %d!\n", asif.as_gen->bTerminalLink);
549  }
550  memcpy(&uac->asif_in, &asif, sizeof(asif));
551  }
552  else if (iface_have_iso_out_ep(iface))
553  {
554  asif.it = (AC_IT_T *)uac_find_terminal(uac, asif.as_gen->bTerminalLink);
555  if (asif.it)
556  {
557  UAC_DBGMSG("Audio out Terminal ID: 0%x\n", asif.it->bTerminalID);
558  UAC_DBGMSG(" bDescriptorSubtype: 0%x\n", asif.it->bDescriptorSubtype);
559  UAC_DBGMSG(" wTerminalType: 0%x\n", asif.it->wTerminalType);
560  UAC_DBGMSG(" bAssocTerminal: 0%x\n", asif.it->bAssocTerminal);
561  }
562  else
563  {
564  UAC_ERRMSG("Cannot find audio in Output Terminal %d!\n", asif.as_gen->bTerminalLink);
565  }
566  memcpy(&uac->asif_out, &asif, sizeof(asif));
567  }
568  else
569  {
570  UAC_ERRMSG("Interface cannot find iso endpoints!\n");
571  return UAC_RET_PARSER;
572  }
573 
574  UAC_DBGMSG("\n\nAudio stream interface parsing done =>\n");
575  UAC_DBGMSG(" Interface: %d, Alt: %d (iface = 0x%x)\n", if_num, bAlternateSetting, asif.iface);
576  if (asif.ep)
577  UAC_DBGMSG(" Endpoint: 0x%x, wMaxPacketSize: %d\n", asif.ep->bEndpointAddress, asif.ep->wMaxPacketSize);
578  UAC_DBGMSG(" as_gen: %s\n", (asif.as_gen == NULL) ? "Not Found" : "OK");
579  UAC_DBGMSG(" it: %s\n", (asif.it == NULL) ? "Not Found" : "OK");
580  UAC_DBGMSG(" ot: %s\n", (asif.ot == NULL) ? "Not Found" : "OK");
581  UAC_DBGMSG(" ft: %s\n", (asif.ft == NULL) ? "Not Found" : "OK");
582  UAC_DBGMSG(" cs_epd: %s\n", (asif.cs_epd == NULL) ? "Not Found" : "OK");
583 
584  return 0;
585 }
586 
587 
589 
590 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
591 
USB Host UAC class driver header file.
uint8_t mic_id
Definition: usbh_uac.h:83
AS_FT1_T * ft
Definition: usbh_uac.h:100
NuMicro peripheral access layer header file.
IFACE_T * iface
Definition: usbh_uac.h:82
M480 MCU USB Host Audio Class header file.
USB Host library exported header file.
AS_IF_T asif_in
Definition: usbh_uac.h:113
CS_EP_T * cs_epd
Definition: usbh_uac.h:101
AS_GEN_T * as_gen
Definition: usbh_uac.h:97
AS_IF_T asif_out
Definition: usbh_uac.h:114
UDEV_T * udev
Definition: usbh_uac.h:111
uint8_t speaker_fuid
Definition: usbh_uac.h:86
AC_OT_T * ot
Definition: usbh_uac.h:99
IFACE_T * iface
Definition: usbh_uac.h:94
AC_IT_T * it
Definition: usbh_uac.h:98
USB Host library header file.
#define UAC_RET_PARSER
Definition: usbh_lib.h:105
#define NULL
NULL pointer.
Definition: M480.h:604
uint8_t mic_fuid
Definition: usbh_uac.h:84
AC_IF_T acif
Definition: usbh_uac.h:112
uint8_t speaker_id
Definition: usbh_uac.h:85
EP_INFO_T * ep
Definition: usbh_uac.h:95