STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
usbh_audio.c
Go to the documentation of this file.
1 
39 /* Includes ------------------------------------------------------------------*/
40 #include "usbh_audio.h"
41 
97 static USBH_StatusTypeDef USBH_AUDIO_InterfaceInit (USBH_HandleTypeDef *phost);
98 static USBH_StatusTypeDef USBH_AUDIO_InterfaceDeInit (USBH_HandleTypeDef *phost);
99 static USBH_StatusTypeDef USBH_AUDIO_Process(USBH_HandleTypeDef *phost);
100 static USBH_StatusTypeDef USBH_AUDIO_SOFProcess(USBH_HandleTypeDef *phost);
101 static USBH_StatusTypeDef USBH_AUDIO_ClassRequest(USBH_HandleTypeDef *phost);
102 static USBH_StatusTypeDef USBH_AUDIO_CSRequest(USBH_HandleTypeDef *phost,
103  uint8_t feature,
104  uint8_t channel);
105 
106 static USBH_StatusTypeDef USBH_AUDIO_HandleCSRequest(USBH_HandleTypeDef *phost);
107 
108 static USBH_StatusTypeDef USBH_AUDIO_FindAudioStreamingIN(USBH_HandleTypeDef *phost);
109 static USBH_StatusTypeDef USBH_AUDIO_FindAudioStreamingOUT(USBH_HandleTypeDef *phost);
110 static USBH_StatusTypeDef USBH_AUDIO_FindHIDControl(USBH_HandleTypeDef *phost);
111 static USBH_StatusTypeDef USBH_AUDIO_ParseCSDescriptors(USBH_HandleTypeDef *phost);
112 
113 static USBH_StatusTypeDef USBH_AUDIO_BuildHeadphonePath(USBH_HandleTypeDef *phost);
114 static USBH_StatusTypeDef USBH_AUDIO_BuildMicrophonePath(USBH_HandleTypeDef *phost);
115 int32_t USBH_AUDIO_FindLinkedUnitIN(USBH_HandleTypeDef *phost, uint8_t UnitID);
116 int32_t USBH_AUDIO_FindLinkedUnitOUT(USBH_HandleTypeDef *phost, uint8_t UnitID);
117 
118 
119 
120 static USBH_StatusTypeDef ParseCSDescriptors(AUDIO_ClassSpecificDescTypedef *class_desc,
121  uint8_t ac_subclass,
122  uint8_t *pdesc);
123 
124 
125 static USBH_StatusTypeDef USBH_AUDIO_Transmit (USBH_HandleTypeDef *phost);
126 
127 
128 static USBH_StatusTypeDef USBH_AC_SetCur(USBH_HandleTypeDef *phost,
129  uint8_t subtype,
130  uint8_t feature,
131  uint8_t controlSelector,
132  uint8_t channel,
133  uint16_t length);
134 
135 static USBH_StatusTypeDef USBH_AC_GetCur(USBH_HandleTypeDef *phost,
136  uint8_t subtype,
137  uint8_t feature,
138  uint8_t controlSelector,
139  uint8_t channel,
140  uint16_t length);
141 
142 static USBH_StatusTypeDef USBH_AC_GetMin(USBH_HandleTypeDef *phost,
143  uint8_t subtype,
144  uint8_t feature,
145  uint8_t controlSelector,
146  uint8_t channel,
147  uint16_t length);
148 
149 static USBH_StatusTypeDef USBH_AC_GetMax(USBH_HandleTypeDef *phost,
150  uint8_t subtype,
151  uint8_t feature,
152  uint8_t controlSelector,
153  uint8_t channel,
154  uint16_t length);
155 
156 static USBH_StatusTypeDef USBH_AC_GetRes(USBH_HandleTypeDef *phost,
157  uint8_t subtype,
158  uint8_t feature,
159  uint8_t controlSelector,
160  uint8_t channel,
161  uint16_t length);
162 
163 static USBH_StatusTypeDef USBH_AUDIO_SetEndpointControls(USBH_HandleTypeDef *phost,
164  uint8_t Ep,
165  uint8_t *buff);
166 
167 static USBH_StatusTypeDef AUDIO_SetVolume (USBH_HandleTypeDef *phost, uint8_t feature, uint8_t channel, uint16_t volume);
168 
169 static USBH_StatusTypeDef USBH_AUDIO_InputStream (USBH_HandleTypeDef *phost);
170 static USBH_StatusTypeDef USBH_AUDIO_OutputStream (USBH_HandleTypeDef *phost);
171 static USBH_StatusTypeDef USBH_AUDIO_Control (USBH_HandleTypeDef *phost);
172 static USBH_StatusTypeDef USBH_AUDIO_SetControlAttribute (USBH_HandleTypeDef *phost, uint8_t attrib);
173 static int32_t USBH_AUDIO_FindLinkedUnit(USBH_HandleTypeDef *phost, uint8_t UnitID);
174 
176 {
177  "AUDIO",
178  AC_CLASS,
179  USBH_AUDIO_InterfaceInit,
180  USBH_AUDIO_InterfaceDeInit,
181  USBH_AUDIO_ClassRequest,
182  USBH_AUDIO_Process,
183  USBH_AUDIO_SOFProcess,
184  NULL,
185 };
186 
201 static USBH_StatusTypeDef USBH_AUDIO_InterfaceInit (USBH_HandleTypeDef *phost)
202 {
203  USBH_StatusTypeDef status = USBH_FAIL ;
204  USBH_StatusTypeDef out_status, in_status ;
205  AUDIO_HandleTypeDef *AUDIO_Handle;
206  uint8_t interface, index;
207  uint16_t ep_size_out = 0;
208  uint16_t ep_size_in = 0;
209 
210  interface = USBH_FindInterface(phost, AC_CLASS, USB_SUBCLASS_AUDIOCONTROL, 0x00);
211 
212  if(interface == 0xFF) /* Not Valid Interface */
213  {
214  USBH_DbgLog ("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
215  status = USBH_FAIL;
216  }
217  else
218  {
219 
220 
221  phost->pActiveClass->pData = (AUDIO_HandleTypeDef *)USBH_malloc (sizeof(AUDIO_HandleTypeDef));
222  AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
223  USBH_memset(AUDIO_Handle, 0, sizeof(AUDIO_HandleTypeDef));
224 
225 
226  /* 1st Step: Find Audio Interfaces */
227  out_status = USBH_AUDIO_FindAudioStreamingIN (phost);
228 
229  in_status = USBH_AUDIO_FindAudioStreamingOUT(phost);
230 
231  if((out_status == USBH_FAIL) && (in_status == USBH_FAIL))
232  {
233  USBH_DbgLog ("%s class configuration not supported.", phost->pActiveClass->Name);
234  }
235  else
236  {
237  /* 2nd Step: Select Audio Streaming Interfaces with largest endpoint size : default behavior*/
238  for (index = 0; index < AUDIO_MAX_AUDIO_STD_INTERFACE; index ++)
239  {
240  if( AUDIO_Handle->stream_out[index].valid == 1)
241  {
242  if(ep_size_out < AUDIO_Handle->stream_out[index].EpSize)
243  {
244  ep_size_out = AUDIO_Handle->stream_out[index].EpSize;
245  AUDIO_Handle->headphone.interface = AUDIO_Handle->stream_out[index].interface;
246  AUDIO_Handle->headphone.AltSettings = AUDIO_Handle->stream_out[index].AltSettings;
247  AUDIO_Handle->headphone.Ep = AUDIO_Handle->stream_out[index].Ep;
248  AUDIO_Handle->headphone.EpSize = AUDIO_Handle->stream_out[index].EpSize;
249  AUDIO_Handle->headphone.Poll = AUDIO_Handle->stream_out[index].Poll;
250  AUDIO_Handle->headphone.supported = 1;
251  }
252  }
253 
254  if( AUDIO_Handle->stream_in[index].valid == 1)
255  {
256  if(ep_size_in < AUDIO_Handle->stream_in[index].EpSize)
257  {
258  ep_size_in = AUDIO_Handle->stream_in[index].EpSize;
259  AUDIO_Handle->microphone.interface = AUDIO_Handle->stream_in[index].interface;
260  AUDIO_Handle->microphone.AltSettings = AUDIO_Handle->stream_in[index].AltSettings;
261  AUDIO_Handle->microphone.Ep = AUDIO_Handle->stream_in[index].Ep;
262  AUDIO_Handle->microphone.EpSize = AUDIO_Handle->stream_in[index].EpSize;
263  AUDIO_Handle->microphone.Poll = AUDIO_Handle->stream_out[index].Poll;
264  AUDIO_Handle->microphone.supported = 1;
265  }
266  }
267  }
268 
269  if(USBH_AUDIO_FindHIDControl(phost) == USBH_OK)
270  {
271  AUDIO_Handle->control.supported = 1;
272  }
273 
274  /* 3rd Step: Find and Parse Audio interfaces */
275  USBH_AUDIO_ParseCSDescriptors (phost);
276 
277 
278  /* 4th Step: Open the Audio streaming pipes*/
279  if(AUDIO_Handle->headphone.supported == 1)
280  {
281  USBH_AUDIO_BuildHeadphonePath (phost);
282 
283  AUDIO_Handle->headphone.Pipe = USBH_AllocPipe(phost, AUDIO_Handle->headphone.Ep);
284 
285  /* Open pipe for IN endpoint */
286  USBH_OpenPipe (phost,
287  AUDIO_Handle->headphone.Pipe,
288  AUDIO_Handle->headphone.Ep,
289  phost->device.address,
290  phost->device.speed,
292  AUDIO_Handle->headphone.EpSize);
293 
294  USBH_LL_SetToggle (phost, AUDIO_Handle->headphone.Pipe, 0);
295 
296  }
297 
298  if(AUDIO_Handle->microphone.supported == 1)
299  {
300  USBH_AUDIO_BuildMicrophonePath (phost);
301  AUDIO_Handle->microphone.Pipe = USBH_AllocPipe(phost, AUDIO_Handle->microphone.Ep);
302 
303  /* Open pipe for IN endpoint */
304  USBH_OpenPipe (phost,
305  AUDIO_Handle->microphone.Pipe,
306  AUDIO_Handle->microphone.Ep,
307  phost->device.address,
308  phost->device.speed,
310  AUDIO_Handle->microphone.EpSize);
311 
312  USBH_LL_SetToggle (phost, AUDIO_Handle->microphone.Pipe, 0);
313  }
314 
315  if(AUDIO_Handle->control.supported == 1)
316  {
317  AUDIO_Handle->control.Pipe = USBH_AllocPipe(phost, AUDIO_Handle->control.Ep);
318 
319  /* Open pipe for IN endpoint */
320  USBH_OpenPipe (phost,
321  AUDIO_Handle->control.Pipe,
322  AUDIO_Handle->control.Ep,
323  phost->device.address,
324  phost->device.speed,
326  AUDIO_Handle->control.EpSize);
327 
328  USBH_LL_SetToggle (phost, AUDIO_Handle->control.Pipe, 0);
329 
330  }
331 
332  AUDIO_Handle->req_state = AUDIO_REQ_INIT;
333  AUDIO_Handle->control_state = AUDIO_CONTROL_INIT;
334 
335  status = USBH_OK;
336  }
337  }
338  return status;
339 }
340 
341 
342 
349 USBH_StatusTypeDef USBH_AUDIO_InterfaceDeInit (USBH_HandleTypeDef *phost)
350 {
351  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
352 
353  if(AUDIO_Handle->microphone.Pipe != 0x00)
354  {
355  USBH_ClosePipe (phost, AUDIO_Handle->microphone.Pipe);
356  USBH_FreePipe (phost, AUDIO_Handle->microphone.Pipe);
357  AUDIO_Handle->microphone.Pipe = 0; /* Reset the pipe as Free */
358  }
359 
360  if( AUDIO_Handle->headphone.Pipe != 0x00)
361  {
362  USBH_ClosePipe(phost, AUDIO_Handle->headphone.Pipe);
363  USBH_FreePipe (phost, AUDIO_Handle->headphone.Pipe);
364  AUDIO_Handle->headphone.Pipe = 0; /* Reset the pipe as Free */
365  }
366 
367  if( AUDIO_Handle->control.Pipe != 0x00)
368  {
369  USBH_ClosePipe(phost, AUDIO_Handle->control.Pipe);
370  USBH_FreePipe (phost, AUDIO_Handle->control.Pipe);
371  AUDIO_Handle->control.Pipe = 0; /* Reset the pipe as Free */
372  }
373 
374  if(phost->pActiveClass->pData)
375  {
376  USBH_free (phost->pActiveClass->pData);
377  phost->pActiveClass->pData = 0;
378  }
379  return USBH_OK ;
380 }
381 
389 static USBH_StatusTypeDef USBH_AUDIO_ClassRequest(USBH_HandleTypeDef *phost)
390 {
391  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
392  USBH_StatusTypeDef status = USBH_BUSY;
393  USBH_StatusTypeDef req_status = USBH_BUSY;
394 
395  /* Switch AUDIO REQ state machine */
396  switch (AUDIO_Handle->req_state)
397  {
398  case AUDIO_REQ_INIT:
400  if(AUDIO_Handle->microphone.supported == 1)
401  {
402  req_status = USBH_SetInterface(phost,
403  AUDIO_Handle->microphone.interface,
404  0);
405 
406  if(req_status == USBH_OK)
407  {
409  }
410 
411  }
412  else
413  {
415 #if (USBH_USE_OS == 1)
416  osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
417 #endif
418  }
419  break;
420 
422  if(AUDIO_Handle->headphone.supported == 1)
423  {
424  req_status = USBH_SetInterface(phost,
425  AUDIO_Handle->headphone.interface,
426  0);
427 
428  if(req_status == USBH_OK)
429  {
430  AUDIO_Handle->req_state = AUDIO_REQ_CS_REQUESTS;
431  AUDIO_Handle->cs_req_state = AUDIO_REQ_GET_VOLUME;
432 
433  AUDIO_Handle->temp_feature = AUDIO_Handle->headphone.asociated_feature;
434  AUDIO_Handle->temp_channels = AUDIO_Handle->headphone.asociated_channels;
435  }
436  }
437  else
438  {
439  AUDIO_Handle->req_state = AUDIO_REQ_CS_REQUESTS;
440  AUDIO_Handle->cs_req_state = AUDIO_REQ_GET_VOLUME;
441 #if (USBH_USE_OS == 1)
442  osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
443 #endif
444  }
445  break;
446 
448  if(USBH_AUDIO_HandleCSRequest (phost) == USBH_OK)
449  {
450  AUDIO_Handle->req_state = AUDIO_REQ_SET_IN_INTERFACE;
451  }
452  break;
453 
455  if(AUDIO_Handle->microphone.supported == 1)
456  {
457  req_status = USBH_SetInterface(phost,
458  AUDIO_Handle->microphone.interface,
459  AUDIO_Handle->microphone.AltSettings);
460 
461  if(req_status == USBH_OK)
462  {
463  AUDIO_Handle->req_state = AUDIO_REQ_SET_OUT_INTERFACE;
464  }
465  }
466  else
467  {
468  AUDIO_Handle->req_state = AUDIO_REQ_SET_OUT_INTERFACE;
469 #if (USBH_USE_OS == 1)
470  osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
471 #endif
472  }
473  break;
475  if(AUDIO_Handle->headphone.supported == 1)
476  {
477  req_status = USBH_SetInterface(phost,
478  AUDIO_Handle->headphone.interface,
479  AUDIO_Handle->headphone.AltSettings);
480 
481  if(req_status == USBH_OK)
482  {
483  AUDIO_Handle->req_state = AUDIO_REQ_IDLE;
484  }
485 
486  }
487  else
488  {
489  AUDIO_Handle->req_state = AUDIO_REQ_IDLE;
490 #if (USBH_USE_OS == 1)
491  osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
492 #endif
493  }
494  break;
495  case AUDIO_REQ_IDLE:
496  AUDIO_Handle->play_state = AUDIO_PLAYBACK_INIT;
497  phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
498  status = USBH_OK;
499 #if (USBH_USE_OS == 1)
500  osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
501 #endif
502  default:
503  break;
504  }
505  return status;
506 }
507 
515 static USBH_StatusTypeDef USBH_AUDIO_CSRequest(USBH_HandleTypeDef *phost, uint8_t feature, uint8_t channel)
516 {
517  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
518  USBH_StatusTypeDef status = USBH_BUSY;
519  USBH_StatusTypeDef req_status = USBH_BUSY;
520 
521  /* Switch AUDIO REQ state machine */
522  switch (AUDIO_Handle->cs_req_state)
523  {
525  req_status = USBH_AC_GetCur(phost,
526  UAC_FEATURE_UNIT, /* subtype */
527  feature, /* feature */
528  VOLUME_CONTROL, /* Selector */
529  channel, /* channel */
530  0x02); /* length */
531  if(req_status != USBH_BUSY)
532  {
533  AUDIO_Handle->cs_req_state = AUDIO_REQ_GET_MIN_VOLUME;
534  AUDIO_Handle->headphone.attribute.volume = LE16(&(AUDIO_Handle->mem[0]));
535  }
536  break;
537 
539  req_status = USBH_AC_GetMin(phost,
540  UAC_FEATURE_UNIT, /* subtype */
541  feature, /* feature */
542  VOLUME_CONTROL, /* Selector */
543  channel, /* channel */
544  0x02); /* length */
545  if(req_status != USBH_BUSY)
546  {
547  AUDIO_Handle->cs_req_state = AUDIO_REQ_GET_MAX_VOLUME;
548  AUDIO_Handle->headphone.attribute.volumeMin = LE16(&AUDIO_Handle->mem[0]);
549  }
550  break;
551 
553  req_status = USBH_AC_GetMax(phost,
554  UAC_FEATURE_UNIT, /* subtype */
555  feature, /* feature */
556  VOLUME_CONTROL, /* Selector */
557  channel, /* channel */
558  0x02); /* length */
559  if(req_status != USBH_BUSY)
560  {
561  AUDIO_Handle->cs_req_state = AUDIO_REQ_GET_RESOLUTION;
562  AUDIO_Handle->headphone.attribute.volumeMax = LE16(&AUDIO_Handle->mem[0]);
563 
564  if (AUDIO_Handle->headphone.attribute.volumeMax < AUDIO_Handle->headphone.attribute.volumeMin)
565  {
566  AUDIO_Handle->headphone.attribute.volumeMax = 0xFF00;
567  }
568  }
569  break;
570 
572  req_status = USBH_AC_GetRes(phost,
573  UAC_FEATURE_UNIT, /* subtype */
574  feature, /* feature */
575  VOLUME_CONTROL, /* Selector */
576  channel, /* channel */
577  0x02); /* length */
578  if(req_status != USBH_BUSY)
579  {
580  AUDIO_Handle->cs_req_state = AUDIO_REQ_CS_IDLE;
581  AUDIO_Handle->headphone.attribute.resolution = LE16(&AUDIO_Handle->mem[0]);
582  }
583  break;
584 
585 
586  case AUDIO_REQ_CS_IDLE:
587  status = USBH_OK;
588  default:
589  break;
590  }
591  return status;
592 }
593 
601 static USBH_StatusTypeDef USBH_AUDIO_HandleCSRequest(USBH_HandleTypeDef *phost)
602 {
603 
604  USBH_StatusTypeDef status = USBH_BUSY;
605  USBH_StatusTypeDef cs_status = USBH_BUSY;
606  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
607 
608  cs_status = USBH_AUDIO_CSRequest(phost,
609  AUDIO_Handle->temp_feature,
610  AUDIO_Handle->temp_channels);
611 
612  if(cs_status != USBH_BUSY)
613  {
614 
615  if(AUDIO_Handle->temp_channels == 1)
616  {
617  AUDIO_Handle->temp_feature = AUDIO_Handle->headphone.asociated_feature;
618  AUDIO_Handle->temp_channels = 0;
619  status = USBH_OK;
620  }
621  else
622  {
623  AUDIO_Handle->temp_channels--;
624  }
625  AUDIO_Handle->cs_req_state = AUDIO_REQ_GET_VOLUME;
626 #if (USBH_USE_OS == 1)
627  osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
628 #endif
629  }
630 
631  return status;
632 }
633 
640 static USBH_StatusTypeDef USBH_AUDIO_Process (USBH_HandleTypeDef *phost)
641 {
642  USBH_StatusTypeDef status = USBH_BUSY;
643  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
644 
645  if(AUDIO_Handle->headphone.supported == 1)
646  {
647  USBH_AUDIO_OutputStream (phost);
648  }
649 
650  if(AUDIO_Handle->microphone.supported == 1)
651  {
652  USBH_AUDIO_InputStream (phost);
653  }
654 
655  return status;
656 }
657 
664 static USBH_StatusTypeDef USBH_AUDIO_SOFProcess (USBH_HandleTypeDef *phost)
665 {
666  return USBH_OK;
667 }
673 static USBH_StatusTypeDef USBH_AUDIO_FindAudioStreamingIN(USBH_HandleTypeDef *phost)
674 {
675  uint8_t interface, alt_settings;
676  USBH_StatusTypeDef status = USBH_FAIL ;
677  AUDIO_HandleTypeDef *AUDIO_Handle;
678 
679  AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
680 
681  /* Look For AUDIOSTREAMING IN interface */
682  alt_settings = 0;
683  for (interface = 0; interface < USBH_MAX_NUM_INTERFACES ; interface ++ )
684  {
685  if((phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass == AC_CLASS)&&
687  {
688  if((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80)&&
689  (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize > 0))
690  {
691  AUDIO_Handle->stream_in[alt_settings].Ep = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
692  AUDIO_Handle->stream_in[alt_settings].EpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
693  AUDIO_Handle->stream_in[alt_settings].interface = phost->device.CfgDesc.Itf_Desc[interface].bInterfaceNumber;
694  AUDIO_Handle->stream_in[alt_settings].AltSettings = phost->device.CfgDesc.Itf_Desc[interface].bAlternateSetting;
695  AUDIO_Handle->stream_in[alt_settings].Poll = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bInterval;
696  AUDIO_Handle->stream_in[alt_settings].valid = 1;
697  alt_settings++;
698  }
699  }
700  }
701 
702  if(alt_settings > 0)
703  {
704  status = USBH_OK;
705  }
706 
707  return status;
708 }
709 
715 static USBH_StatusTypeDef USBH_AUDIO_FindAudioStreamingOUT(USBH_HandleTypeDef *phost)
716 {
717  uint8_t interface, alt_settings;
718  USBH_StatusTypeDef status = USBH_FAIL ;
719  AUDIO_HandleTypeDef *AUDIO_Handle;
720 
721  AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
722 
723  /* Look For AUDIOSTREAMING IN interface */
724  alt_settings = 0;
725  for (interface = 0; interface < USBH_MAX_NUM_INTERFACES ; interface ++ )
726  {
727  if((phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass == AC_CLASS)&&
729  {
730  if(((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80) == 0x00)&&
731  (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize > 0))
732  {
733  AUDIO_Handle->stream_out[alt_settings].Ep = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
734  AUDIO_Handle->stream_out[alt_settings].EpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
735  AUDIO_Handle->stream_out[alt_settings].interface = phost->device.CfgDesc.Itf_Desc[interface].bInterfaceNumber;
736  AUDIO_Handle->stream_out[alt_settings].AltSettings = phost->device.CfgDesc.Itf_Desc[interface].bAlternateSetting;
737  AUDIO_Handle->stream_out[alt_settings].Poll = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bInterval;
738  AUDIO_Handle->stream_out[alt_settings].valid = 1;
739  alt_settings++;
740  }
741  }
742  }
743 
744  if(alt_settings > 0)
745  {
746  status = USBH_OK;
747  }
748 
749  return status;
750 }
751 
757 static USBH_StatusTypeDef USBH_AUDIO_FindHIDControl(USBH_HandleTypeDef *phost)
758 {
759  uint8_t interface;
760  USBH_StatusTypeDef status = USBH_FAIL ;
761  AUDIO_HandleTypeDef *AUDIO_Handle;
762 
763  AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
764 
765  /* Look For AUDIOCONTROL interface */
766  interface = USBH_FindInterface(phost, AC_CLASS, USB_SUBCLASS_AUDIOCONTROL, 0xFF);
767  if(interface != 0xFF)
768  {
769  for (interface = 0; interface < USBH_MAX_NUM_INTERFACES ; interface ++ )
770  {
771  if((phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass == 0x03)&& /*HID*/
772  (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize > 0))
773  {
774  if((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80) == 0x80)
775  {
776  AUDIO_Handle->control.Ep = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress;
777  AUDIO_Handle->control.EpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
778  AUDIO_Handle->control.interface = phost->device.CfgDesc.Itf_Desc[interface].bInterfaceNumber;
779  AUDIO_Handle->control.Poll = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bInterval;
780  AUDIO_Handle->control.supported = 1;
781  status = USBH_OK;
782  break;
783  }
784  }
785  }
786  }
787  return status;
788 }
789 
795 static USBH_StatusTypeDef USBH_AUDIO_ParseCSDescriptors(USBH_HandleTypeDef *phost)
796 {
797  USBH_DescHeader_t *pdesc ;
798  uint16_t ptr;
799  int8_t itf_index = 0;
800  int8_t itf_number = 0;
801  int8_t alt_setting;
802  AUDIO_HandleTypeDef *AUDIO_Handle;
803 
804  AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
805  pdesc = (USBH_DescHeader_t *)(phost->device.CfgDesc_Raw);
806  ptr = USB_LEN_CFG_DESC;
807 
808  AUDIO_Handle->class_desc.FeatureUnitNum = 0;
809  AUDIO_Handle->class_desc.InputTerminalNum = 0;
810  AUDIO_Handle->class_desc.OutputTerminalNum = 0;
811  AUDIO_Handle->class_desc.ASNum = 0;
812 
813  while(ptr < phost->device.CfgDesc.wTotalLength)
814  {
815  pdesc = USBH_GetNextDesc((uint8_t*) pdesc, &ptr);
816 
817  switch (pdesc->bDescriptorType)
818  {
819 
821  itf_number = *((uint8_t *)pdesc + 2);
822  alt_setting = *((uint8_t *)pdesc + 3);
823  itf_index = USBH_FindInterfaceIndex (phost, itf_number, alt_setting);
824  break;
825 
827  if(itf_number <= phost->device.CfgDesc.bNumInterfaces)
828  {
829 
830  ParseCSDescriptors(&AUDIO_Handle->class_desc,
831  phost->device.CfgDesc.Itf_Desc[itf_index].bInterfaceSubClass,
832  (uint8_t *)pdesc);
833  }
834  break;
835 
836  default:
837  break;
838  }
839  }
840  return USBH_OK;
841 }
842 
848 static USBH_StatusTypeDef ParseCSDescriptors(AUDIO_ClassSpecificDescTypedef *class_desc,
849  uint8_t ac_subclass,
850  uint8_t *pdesc)
851 {
852  if(ac_subclass == USB_SUBCLASS_AUDIOCONTROL)
853  {
854  switch(pdesc[2])
855  {
856  case UAC_HEADER:
857  class_desc->cs_desc.HeaderDesc = (AUDIO_HeaderDescTypeDef *)pdesc;
858  break;
859 
860  case UAC_INPUT_TERMINAL:
861  class_desc->cs_desc.InputTerminalDesc[class_desc->InputTerminalNum++] = (AUDIO_ITDescTypeDef*) pdesc;
862  break;
863 
864  case UAC_OUTPUT_TERMINAL:
865  class_desc->cs_desc.OutputTerminalDesc[class_desc->OutputTerminalNum++] = (AUDIO_OTDescTypeDef*) pdesc;
866  break;
867 
868  case UAC_FEATURE_UNIT:
869  class_desc->cs_desc.FeatureUnitDesc[class_desc->FeatureUnitNum++] = (AUDIO_FeatureDescTypeDef*) pdesc;
870  break;
871 
872  case UAC_SELECTOR_UNIT:
873  class_desc->cs_desc.SelectorUnitDesc[class_desc->SelectorUnitNum++] = (AUDIO_SelectorDescTypeDef*) pdesc;
874  break;
875 
876  case UAC_MIXER_UNIT:
877  class_desc->cs_desc.MixerUnitDesc[class_desc->MixerUnitNum++] = (AUDIO_MixerDescTypeDef*) pdesc;
878  break;
879 
880  default:
881  break;
882  }
883  }
884  else if(ac_subclass == USB_SUBCLASS_AUDIOSTREAMING)
885  {
886  switch(pdesc[2])
887  {
888  case UAC_AS_GENERAL:
889  class_desc->as_desc[class_desc->ASNum].GeneralDesc = (AUDIO_ASGeneralDescTypeDef*) pdesc;
890  break;
891  case UAC_FORMAT_TYPE:
892  class_desc->as_desc[class_desc->ASNum++].FormatTypeDesc = (AUDIO_ASFormatTypeDescTypeDef*) pdesc;
893  break;
894  default:
895  break;
896  }
897  }
898 
899  return USBH_OK;
900 }
901 
902 
909 static int32_t USBH_AUDIO_FindLinkedUnit(USBH_HandleTypeDef *phost, uint8_t UnitID)
910 {
911  uint8_t Index;
912  AUDIO_HandleTypeDef *AUDIO_Handle;
913 
914  AUDIO_Handle = (AUDIO_HandleTypeDef *) phost->pActiveClass->pData;
915 
916  /* Find Feature Unit */
917  for(Index = 0; Index < AUDIO_Handle->class_desc.FeatureUnitNum; Index ++)
918  {
919  if(AUDIO_Handle->class_desc.cs_desc.FeatureUnitDesc[Index]->bSourceID == UnitID)
920  {
921  UnitID = AUDIO_Handle->class_desc.cs_desc.FeatureUnitDesc[Index]->bUnitID;
922 
923  return ((UnitID << 16) | (UAC_FEATURE_UNIT << 8) | Index);
924  }
925  }
926 
927  /* Find Mixer Unit */
928  for(Index = 0; Index < AUDIO_Handle->class_desc.MixerUnitNum; Index ++)
929  {
930  if((AUDIO_Handle->class_desc.cs_desc.MixerUnitDesc[Index]->bSourceID0 == UnitID)||
931  (AUDIO_Handle->class_desc.cs_desc.MixerUnitDesc[Index]->bSourceID1 == UnitID))
932  {
933  UnitID = AUDIO_Handle->class_desc.cs_desc.MixerUnitDesc[Index]->bUnitID;
934 
935  return ((UnitID << 16) | (UAC_MIXER_UNIT << 8) | Index);
936  }
937  }
938 
939 
940  /* Find Selector Unit */
941  for(Index = 0; Index < AUDIO_Handle->class_desc.SelectorUnitNum; Index ++)
942  {
943  if(AUDIO_Handle->class_desc.cs_desc.SelectorUnitDesc[Index]->bSourceID0 == UnitID)
944  {
945  UnitID = AUDIO_Handle->class_desc.cs_desc.SelectorUnitDesc[Index]->bUnitID;
946 
947  return ((UnitID << 16) | (UAC_SELECTOR_UNIT << 8) | Index);
948  }
949  }
950 
951 
952  /* Find OT Unit */
953  for(Index = 0; Index < AUDIO_Handle->class_desc.OutputTerminalNum; Index ++)
954  {
955  if(AUDIO_Handle->class_desc.cs_desc.OutputTerminalDesc[Index]->bSourceID == UnitID)
956  {
957  UnitID = AUDIO_Handle->class_desc.cs_desc.OutputTerminalDesc[Index]->bTerminalID;
958 
959  return ((UnitID << 16) | (UAC_OUTPUT_TERMINAL << 8) | Index);
960  }
961  }
962 
963  /* No associated Unit found */
964  return -1;
965 }
966 
972 USBH_StatusTypeDef USBH_AUDIO_BuildMicrophonePath(USBH_HandleTypeDef *phost)
973 {
974  uint8_t UnitID = 0, Type, Index;
975  uint32_t value;
976  uint8_t terminalIndex;
977  AUDIO_HandleTypeDef *AUDIO_Handle;
978 
979  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
980 
981  /*Find microphone IT*/
982  for(terminalIndex = 0; terminalIndex < AUDIO_Handle->class_desc.InputTerminalNum; terminalIndex++)
983  {
984  if(LE16(AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[terminalIndex]->wTerminalType) == 0x201)
985  {
986  UnitID = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[terminalIndex]->bTerminalID;
987  AUDIO_Handle->microphone.asociated_channels = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[terminalIndex]->bNrChannels;
988  break;
989  }
990  }
991 
992  do
993  {
994  value = USBH_AUDIO_FindLinkedUnit(phost, UnitID);
995  Index = value & 0xFF;
996  Type = (value >> 8) & 0xFF;
997  UnitID = (value >> 16) & 0xFF;
998 
999  switch (Type)
1000  {
1001  case UAC_FEATURE_UNIT:
1002  AUDIO_Handle->microphone.asociated_feature = Index;
1003  break;
1004 
1005  case UAC_MIXER_UNIT:
1006  AUDIO_Handle->microphone.asociated_mixer = Index;
1007  break;
1008 
1009  case UAC_SELECTOR_UNIT:
1010  AUDIO_Handle->microphone.asociated_selector = Index;
1011  break;
1012 
1013  case UAC_OUTPUT_TERMINAL:
1014  AUDIO_Handle->microphone.asociated_terminal = Index;
1015  break;
1016  }
1017  }
1018  while ((Type != UAC_OUTPUT_TERMINAL) && (value > 0));
1019 
1020 
1021 
1022  return USBH_OK;
1023 }
1024 
1030 USBH_StatusTypeDef USBH_AUDIO_BuildHeadphonePath(USBH_HandleTypeDef *phost)
1031 {
1032  uint8_t UnitID = 0, Type, Index;
1033  uint32_t value;
1034  uint8_t terminalIndex;
1035  AUDIO_HandleTypeDef *AUDIO_Handle;
1036 
1037  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1038 
1039  /* Find association between audio streaming and microphone */
1040  for(terminalIndex = 0; terminalIndex < AUDIO_Handle->class_desc.InputTerminalNum; terminalIndex++)
1041  {
1042  if(LE16(AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[terminalIndex]->wTerminalType) == 0x101)
1043  {
1044  UnitID = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[terminalIndex]->bTerminalID;
1045  AUDIO_Handle->headphone.asociated_channels = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[terminalIndex]->bNrChannels;
1046  break;
1047  }
1048  }
1049 
1050  for(Index = 0; Index < AUDIO_Handle->class_desc.ASNum; Index++)
1051  {
1052  if(AUDIO_Handle->class_desc.as_desc[Index].GeneralDesc->bTerminalLink == UnitID)
1053  {
1054  AUDIO_Handle->headphone.asociated_as = Index;
1055  break;
1056  }
1057  }
1058 
1059  do
1060  {
1061  value = USBH_AUDIO_FindLinkedUnit(phost, UnitID);
1062  Index = value & 0xFF;
1063  Type = (value >> 8) & 0xFF;
1064  UnitID = (value >> 16) & 0xFF;
1065 
1066  switch (Type)
1067  {
1068  case UAC_FEATURE_UNIT:
1069  AUDIO_Handle->headphone.asociated_feature = Index;
1070  break;
1071 
1072  case UAC_MIXER_UNIT:
1073  AUDIO_Handle->headphone.asociated_mixer = Index;
1074  break;
1075 
1076  case UAC_SELECTOR_UNIT:
1077  AUDIO_Handle->headphone.asociated_selector = Index;
1078  break;
1079 
1080  case UAC_OUTPUT_TERMINAL:
1081  AUDIO_Handle->headphone.asociated_terminal = Index;
1082  if(LE16(AUDIO_Handle->class_desc.cs_desc.OutputTerminalDesc[Index]->wTerminalType) != 0x103)
1083  {
1084  return USBH_OK;
1085  }
1086  break;
1087  }
1088  }
1089  while ((Type != UAC_OUTPUT_TERMINAL) && (value > 0));
1090 
1091  return USBH_FAIL;
1092 }
1093 
1094 
1105 static USBH_StatusTypeDef USBH_AC_SetCur(USBH_HandleTypeDef *phost,
1106  uint8_t subtype,
1107  uint8_t feature,
1108  uint8_t controlSelector,
1109  uint8_t channel,
1110  uint16_t length)
1111 {
1112  uint16_t wValue,wIndex,wLength;
1113  uint8_t UnitID,InterfaceNum;
1114  AUDIO_HandleTypeDef *AUDIO_Handle;
1115  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1116 
1117  switch(subtype)
1118  {
1119  case UAC_INPUT_TERMINAL:
1120  UnitID = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[0]->bTerminalID;
1121  InterfaceNum = 0; /*Always zero Control Interface */
1122  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1123  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1124  AUDIO_Handle->mem[0] = 0x00;
1125 
1126  wLength = 1;
1127  break;
1128  case UAC_FEATURE_UNIT:
1129  UnitID = AUDIO_Handle->class_desc.cs_desc.FeatureUnitDesc[feature]->bUnitID;
1130  InterfaceNum = 0; /*Always zero Control Interface */
1131  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1132  /*holds the CS(control selector ) and CN (channel number)*/
1133  wValue = (controlSelector << 8) | channel;
1134  wLength = length;
1135  break;
1136  }
1137 
1139  USB_REQ_TYPE_CLASS;
1140 
1141  phost->Control.setup.b.bRequest = UAC_SET_CUR;
1142  phost->Control.setup.b.wValue.w = wValue;
1143  phost->Control.setup.b.wIndex.w = wIndex;
1144  phost->Control.setup.b.wLength.w = wLength;
1145 
1146  return(USBH_CtlReq(phost, (uint8_t *)(AUDIO_Handle->mem) , wLength ));
1147 
1148 }
1149 
1160 static USBH_StatusTypeDef USBH_AC_GetCur(USBH_HandleTypeDef *phost,
1161  uint8_t subtype,
1162  uint8_t feature,
1163  uint8_t controlSelector,
1164  uint8_t channel,
1165  uint16_t length)
1166 {
1167  uint16_t wValue = 0, wIndex = 0,wLength = 0;
1168  uint8_t UnitID = 0, InterfaceNum = 0;
1169  AUDIO_HandleTypeDef *AUDIO_Handle;
1170  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1171 
1172  switch(subtype)
1173  {
1174  case UAC_INPUT_TERMINAL:
1175  UnitID = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[0]->bTerminalID;
1176  InterfaceNum = 0; /*Always zero Control Interface */
1177  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1178  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1179  AUDIO_Handle->mem[0] = 0x00;
1180 
1181  wLength = 1;
1182  break;
1183  case UAC_FEATURE_UNIT:
1184  UnitID = AUDIO_Handle->class_desc.cs_desc.FeatureUnitDesc[feature]->bUnitID;
1185  InterfaceNum = 0; /*Always zero Control Interface */
1186  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1187  /*holds the CS(control selector ) and CN (channel number)*/
1188  wValue = (controlSelector << 8) | channel;
1189  wLength = length;
1190  break;
1191 
1192  case UAC_OUTPUT_TERMINAL:
1193  UnitID = AUDIO_Handle->class_desc.cs_desc.OutputTerminalDesc[0]->bTerminalID;
1194  InterfaceNum = 0; /*Always zero Control Interface */
1195  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1196  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1197  wLength = 1;
1198  break;
1199  }
1200 
1202  USB_REQ_TYPE_CLASS;
1203 
1204  phost->Control.setup.b.bRequest = UAC_GET_CUR;
1205  phost->Control.setup.b.wValue.w = wValue;
1206  phost->Control.setup.b.wIndex.w = wIndex;
1207  phost->Control.setup.b.wLength.w = wLength;
1208 
1209  return(USBH_CtlReq(phost, (uint8_t *)(AUDIO_Handle->mem) , wLength ));
1210 
1211 }
1212 
1213 
1224 static USBH_StatusTypeDef USBH_AC_GetMax(USBH_HandleTypeDef *phost,
1225  uint8_t subtype,
1226  uint8_t feature,
1227  uint8_t controlSelector,
1228  uint8_t channel,
1229  uint16_t length)
1230 {
1231  uint16_t wValue = 0, wIndex = 0, wLength = 0;
1232  uint8_t UnitID = 0, InterfaceNum = 0;
1233  AUDIO_HandleTypeDef *AUDIO_Handle;
1234  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1235 
1236  switch(subtype)
1237  {
1238  case UAC_INPUT_TERMINAL:
1239  UnitID = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[0]->bTerminalID;
1240  InterfaceNum = 0; /*Always zero Control Interface */
1241  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1242  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1243  AUDIO_Handle->mem[0] = 0x00;
1244 
1245  wLength = 1;
1246  break;
1247  case UAC_FEATURE_UNIT:
1248  UnitID = AUDIO_Handle->class_desc.cs_desc.FeatureUnitDesc[feature]->bUnitID;
1249  InterfaceNum = 0; /*Always zero Control Interface */
1250  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1251  /*holds the CS(control selector ) and CN (channel number)*/
1252  wValue = (controlSelector << 8) | channel;
1253  wLength = length;
1254  break;
1255 
1256  case UAC_OUTPUT_TERMINAL:
1257  UnitID = AUDIO_Handle->class_desc.cs_desc.OutputTerminalDesc[0]->bTerminalID;
1258  InterfaceNum = 0; /*Always zero Control Interface */
1259  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1260  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1261  wLength = 1;
1262  break;
1263  }
1264 
1266  USB_REQ_TYPE_CLASS;
1267 
1268  phost->Control.setup.b.bRequest = UAC_GET_MAX;
1269  phost->Control.setup.b.wValue.w = wValue;
1270  phost->Control.setup.b.wIndex.w = wIndex;
1271  phost->Control.setup.b.wLength.w = wLength;
1272 
1273  return(USBH_CtlReq(phost, (uint8_t *)(AUDIO_Handle->mem) , wLength ));
1274 
1275 }
1276 
1277 
1278 
1289 static USBH_StatusTypeDef USBH_AC_GetRes(USBH_HandleTypeDef *phost,
1290  uint8_t subtype,
1291  uint8_t feature,
1292  uint8_t controlSelector,
1293  uint8_t channel,
1294  uint16_t length)
1295 {
1296  uint16_t wValue = 0, wIndex = 0, wLength = 0;
1297  uint8_t UnitID = 0, InterfaceNum = 0;
1298  AUDIO_HandleTypeDef *AUDIO_Handle;
1299  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1300 
1301  switch(subtype)
1302  {
1303  case UAC_INPUT_TERMINAL:
1304  UnitID = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[0]->bTerminalID;
1305  InterfaceNum = 0; /*Always zero Control Interface */
1306  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1307  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1308  AUDIO_Handle->mem[0] = 0x00;
1309 
1310  wLength = 1;
1311  break;
1312  case UAC_FEATURE_UNIT:
1313  UnitID = AUDIO_Handle->class_desc.cs_desc.FeatureUnitDesc[feature]->bUnitID;
1314  InterfaceNum = 0; /*Always zero Control Interface */
1315  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1316  /*holds the CS(control selector ) and CN (channel number)*/
1317  wValue = (controlSelector << 8) | channel;
1318  wLength = length;
1319  break;
1320 
1321  case UAC_OUTPUT_TERMINAL:
1322  UnitID = AUDIO_Handle->class_desc.cs_desc.OutputTerminalDesc[0]->bTerminalID;
1323  InterfaceNum = 0; /*Always zero Control Interface */
1324  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1325  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1326  wLength = 1;
1327  break;
1328  }
1329 
1331  USB_REQ_TYPE_CLASS;
1332 
1333  phost->Control.setup.b.bRequest = UAC_GET_RES;
1334  phost->Control.setup.b.wValue.w = wValue;
1335  phost->Control.setup.b.wIndex.w = wIndex;
1336  phost->Control.setup.b.wLength.w = wLength;
1337 
1338  return(USBH_CtlReq(phost, (uint8_t *)(AUDIO_Handle->mem) , wLength ));
1339 
1340 }
1341 
1352 static USBH_StatusTypeDef USBH_AC_GetMin(USBH_HandleTypeDef *phost,
1353  uint8_t subtype,
1354  uint8_t feature,
1355  uint8_t controlSelector,
1356  uint8_t channel,
1357  uint16_t length)
1358 {
1359  uint16_t wValue = 0, wIndex = 0, wLength = 0;
1360  uint8_t UnitID = 0, InterfaceNum = 0;
1361  AUDIO_HandleTypeDef *AUDIO_Handle;
1362  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1363 
1364  switch(subtype)
1365  {
1366  case UAC_INPUT_TERMINAL:
1367  UnitID = AUDIO_Handle->class_desc.cs_desc.InputTerminalDesc[0]->bTerminalID;
1368  InterfaceNum = 0; /*Always zero Control Interface */
1369  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1370  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1371  AUDIO_Handle->mem[0] = 0x00;
1372 
1373  wLength = 1;
1374  break;
1375  case UAC_FEATURE_UNIT:
1376  UnitID = AUDIO_Handle->class_desc.cs_desc.FeatureUnitDesc[feature]->bUnitID;
1377  InterfaceNum = 0; /*Always zero Control Interface */
1378  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1379  /*holds the CS(control selector ) and CN (channel number)*/
1380  wValue = (controlSelector << 8) | channel;
1381  wLength = length;
1382  break;
1383 
1384  case UAC_OUTPUT_TERMINAL:
1385  UnitID = AUDIO_Handle->class_desc.cs_desc.OutputTerminalDesc[0]->bTerminalID;
1386  InterfaceNum = 0; /*Always zero Control Interface */
1387  wIndex = ( UnitID << 8 ) | InterfaceNum ;
1388  wValue = (COPY_PROTECT_CONTROL << 8 ) ;
1389  wLength = 1;
1390  break;
1391  }
1392 
1394  USB_REQ_TYPE_CLASS;
1395 
1396  phost->Control.setup.b.bRequest = UAC_GET_MIN;
1397  phost->Control.setup.b.wValue.w = wValue;
1398  phost->Control.setup.b.wIndex.w = wIndex;
1399  phost->Control.setup.b.wLength.w = wLength;
1400 
1401  return(USBH_CtlReq(phost, (uint8_t *)(AUDIO_Handle->mem) , wLength ));
1402 
1403 }
1404 
1412 static USBH_StatusTypeDef USBH_AUDIO_SetEndpointControls(USBH_HandleTypeDef *phost,
1413  uint8_t Ep,
1414  uint8_t *buff)
1415 {
1416  uint16_t wValue, wIndex, wLength;
1417 
1418 
1419  wValue = SAMPLING_FREQ_CONTROL << 8;
1420  wIndex = Ep;
1421  wLength = 3; /*length of the frequency parameter*/
1422 
1424  USB_REQ_TYPE_CLASS;
1425 
1426  phost->Control.setup.b.bRequest = UAC_SET_CUR;
1427  phost->Control.setup.b.wValue.w = wValue;
1428  phost->Control.setup.b.wIndex.w = wIndex;
1429  phost->Control.setup.b.wLength.w = wLength;
1430 
1431  return(USBH_CtlReq(phost, (uint8_t *)buff, wLength ));
1432 
1433 }
1434 
1440 static USBH_StatusTypeDef USBH_AUDIO_InputStream (USBH_HandleTypeDef *phost)
1441 {
1442  USBH_StatusTypeDef status = USBH_BUSY ;
1443 
1444  return status;
1445 }
1446 
1452 static USBH_StatusTypeDef USBH_AUDIO_Control (USBH_HandleTypeDef *phost)
1453 {
1454  USBH_StatusTypeDef status = USBH_BUSY ;
1455  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1456  uint16_t attribute = 0;
1457 
1458 
1459  switch(AUDIO_Handle->control_state)
1460  {
1461  case AUDIO_CONTROL_INIT:
1462  if((phost->Timer & 1) == 0)
1463  {
1464  AUDIO_Handle->control.timer = phost->Timer;
1466  (uint8_t *)(AUDIO_Handle->mem),
1467  AUDIO_Handle->control.EpSize,
1468  AUDIO_Handle->control.Pipe);
1469 
1470  AUDIO_Handle->temp_feature = AUDIO_Handle->headphone.asociated_feature;
1471  AUDIO_Handle->temp_channels = AUDIO_Handle->headphone.asociated_channels;
1472 
1473  AUDIO_Handle->control_state = AUDIO_CONTROL_CHANGE ;
1474  }
1475  break;
1476  case AUDIO_CONTROL_CHANGE:
1477  if(USBH_LL_GetURBState(phost , AUDIO_Handle->control.Pipe) == USBH_URB_DONE)
1478  {
1479  attribute = LE16(&AUDIO_Handle->mem[0]);
1480  if(USBH_AUDIO_SetControlAttribute (phost, attribute) == USBH_BUSY)
1481  {
1482  break;
1483  }
1484  }
1485 
1486  if(( phost->Timer - AUDIO_Handle->control.timer) >= AUDIO_Handle->control.Poll)
1487  {
1488  AUDIO_Handle->control.timer = phost->Timer;
1489 
1491  (uint8_t *)(AUDIO_Handle->mem),
1492  AUDIO_Handle->control.EpSize,
1493  AUDIO_Handle->control.Pipe);
1494 
1495  }
1496  break;
1497 
1499  if( USBH_AUDIO_SetControlAttribute (phost, 1) == USBH_OK)
1500  {
1501  AUDIO_Handle->control_state = AUDIO_CONTROL_INIT;
1502  status = USBH_OK;
1503  }
1504  break;
1505 
1507  if( USBH_AUDIO_SetControlAttribute (phost, 2) == USBH_OK)
1508  {
1509  AUDIO_Handle->control_state = AUDIO_CONTROL_INIT;
1510  status = USBH_OK;
1511  }
1512  break;
1513 
1514  case AUDIO_CONTROL_IDLE:
1515  default:
1516  break;
1517  }
1518 
1519  return status;
1520 }
1521 
1527 static USBH_StatusTypeDef USBH_AUDIO_OutputStream (USBH_HandleTypeDef *phost)
1528 {
1529  USBH_StatusTypeDef status = USBH_BUSY ;
1530  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1531  uint8_t *buff;
1532 
1533 
1534  switch(AUDIO_Handle->play_state)
1535  {
1536  case AUDIO_PLAYBACK_INIT:
1537 
1538  if( AUDIO_Handle->class_desc.as_desc[AUDIO_Handle->headphone.asociated_as].FormatTypeDesc->bSamFreqType == 0)
1539  {
1540  AUDIO_Handle->play_state = AUDIO_PLAYBACK_SET_EP_FREQ;
1541  }
1542  else
1543  {
1544  AUDIO_Handle->play_state = AUDIO_PLAYBACK_SET_EP;
1545  }
1546 #if (USBH_USE_OS == 1)
1547  osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
1548 #endif
1549  break;
1550 
1552 
1553  buff = (uint8_t*)AUDIO_Handle->class_desc.as_desc[AUDIO_Handle->headphone.asociated_as].FormatTypeDesc->tSamFreq[0];
1554 
1555  status = USBH_AUDIO_SetEndpointControls(phost, AUDIO_Handle->headphone.Ep, buff);
1556  if(status == USBH_OK)
1557  {
1558  AUDIO_Handle->play_state = AUDIO_PLAYBACK_IDLE;
1559  }
1560  break;
1561 
1562  case AUDIO_PLAYBACK_SET_EP:
1563  buff = (uint8_t *)&AUDIO_Handle->headphone.frequency;
1564  status = USBH_AUDIO_SetEndpointControls(phost,AUDIO_Handle->headphone.Ep, buff);
1565  if(status == USBH_OK)
1566  {
1567  AUDIO_Handle->play_state = AUDIO_PLAYBACK_IDLE;
1568  USBH_AUDIO_FrequencySet(phost);
1569  }
1570  break;
1571  case AUDIO_PLAYBACK_IDLE:
1572 #if (USBH_USE_OS == 1)
1573  osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
1574 #endif
1575  status = USBH_OK;
1576  break;
1577 
1578  case AUDIO_PLAYBACK_PLAY:
1579  USBH_AUDIO_Transmit(phost);
1580  status = USBH_OK;
1581  break;
1582 
1583  default:
1584  break;
1585  }
1586 
1587  return status;
1588 }
1589 
1595 static USBH_StatusTypeDef USBH_AUDIO_Transmit (USBH_HandleTypeDef *phost)
1596 {
1597  USBH_StatusTypeDef status = USBH_BUSY ;
1598  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1599 
1600  switch(AUDIO_Handle->processing_state)
1601  {
1602  case AUDIO_DATA_START_OUT:
1603  /* Sync with start of Even Frame */
1604  if((phost->Timer & 1) == 0)
1605  {
1606  AUDIO_Handle->headphone.timer = phost->Timer;
1607  AUDIO_Handle->processing_state = AUDIO_DATA_OUT;
1608  USBH_IsocSendData(phost,
1609  AUDIO_Handle->headphone.buf,
1610  AUDIO_Handle->headphone.frame_length,
1611  AUDIO_Handle->headphone.Pipe);
1612 
1613  AUDIO_Handle->headphone.partial_ptr = AUDIO_Handle->headphone.frame_length;
1614  AUDIO_Handle->headphone.global_ptr = AUDIO_Handle->headphone.frame_length;
1615  AUDIO_Handle->headphone.cbuf = AUDIO_Handle->headphone.buf;
1616  }
1617  else
1618  {
1619 #if (USBH_USE_OS == 1)
1620  osDelay(1);
1621  osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
1622 #endif
1623  }
1624  break;
1625 
1626  case AUDIO_DATA_OUT:
1627  if((USBH_LL_GetURBState(phost , AUDIO_Handle->headphone.Pipe) == USBH_URB_DONE)&&
1628  (( phost->Timer - AUDIO_Handle->headphone.timer) >= AUDIO_Handle->headphone.Poll))
1629  {
1630  AUDIO_Handle->headphone.timer = phost->Timer;
1631 
1632  if(AUDIO_Handle->control.supported == 1)
1633  {
1634  USBH_AUDIO_Control (phost);
1635  }
1636 
1637  if(AUDIO_Handle->headphone.global_ptr <= AUDIO_Handle->headphone.total_length)
1638  {
1639  USBH_IsocSendData(phost,
1640  AUDIO_Handle->headphone.cbuf,
1641  AUDIO_Handle->headphone.frame_length,
1642  AUDIO_Handle->headphone.Pipe);
1643 
1644  AUDIO_Handle->headphone.cbuf += AUDIO_Handle->headphone.frame_length;
1645  AUDIO_Handle->headphone.partial_ptr += AUDIO_Handle->headphone.frame_length;
1646  AUDIO_Handle->headphone.global_ptr += AUDIO_Handle->headphone.frame_length;
1647  }
1648  else
1649  {
1650  AUDIO_Handle->headphone.partial_ptr = 0xFFFFFFFF;
1651  AUDIO_Handle->play_state = AUDIO_PLAYBACK_IDLE;
1653  }
1654  }
1655  break;
1656  }
1657  return status;
1658 }
1659 
1670  uint16_t SampleRate,
1671  uint8_t NbrChannels,
1672  uint8_t BitPerSample)
1673 {
1675  AUDIO_HandleTypeDef *AUDIO_Handle;
1676  uint8_t index;
1677  uint8_t change_freq = FALSE;
1678  uint32_t freq_min, freq_max;
1679  uint8_t num_supported_freq;
1680 
1681  if(phost->gState == HOST_CLASS)
1682  {
1683  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1684  if(AUDIO_Handle->play_state == AUDIO_PLAYBACK_IDLE)
1685  {
1686 
1687  if(AUDIO_Handle->class_desc.as_desc[AUDIO_Handle->headphone.asociated_as].FormatTypeDesc->bSamFreqType == 0)
1688  {
1689  freq_min = LE24(AUDIO_Handle->class_desc.as_desc[AUDIO_Handle->headphone.asociated_as].FormatTypeDesc->tSamFreq[0]);
1690  freq_max = LE24(AUDIO_Handle->class_desc.as_desc[AUDIO_Handle->headphone.asociated_as].FormatTypeDesc->tSamFreq[1]);
1691 
1692  if(( SampleRate >= freq_min)&& (SampleRate <= freq_max))
1693  {
1694  change_freq = TRUE;
1695  }
1696  }
1697  else
1698  {
1699 
1700  num_supported_freq = (AUDIO_Handle->class_desc.as_desc[AUDIO_Handle->headphone.asociated_as].FormatTypeDesc->bLength - 8)/3;
1701 
1702 
1703  for(index = 0; index < num_supported_freq; index++)
1704  {
1705  if(SampleRate == LE24(AUDIO_Handle->class_desc.as_desc[AUDIO_Handle->headphone.asociated_as].FormatTypeDesc->tSamFreq[index]))
1706  {
1707  change_freq = TRUE;
1708  break;
1709  }
1710  }
1711  }
1712 
1713  if(change_freq == TRUE)
1714  {
1715  AUDIO_Handle->headphone.frequency = SampleRate;
1716  AUDIO_Handle->headphone.frame_length = (SampleRate * BitPerSample * NbrChannels) / 8000;
1717  AUDIO_Handle->play_state = AUDIO_PLAYBACK_SET_EP;
1718  Status = USBH_OK;
1719 
1720  }
1721  }
1722  }
1723  return Status;
1724 }
1725 
1734 USBH_StatusTypeDef USBH_AUDIO_Play (USBH_HandleTypeDef *phost, uint8_t *buf, uint32_t length)
1735 {
1737  AUDIO_HandleTypeDef *AUDIO_Handle;
1738 
1739  if(phost->gState == HOST_CLASS)
1740  {
1741  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1742  if(AUDIO_Handle->play_state == AUDIO_PLAYBACK_IDLE)
1743  {
1744  AUDIO_Handle->headphone.buf = buf;
1745  AUDIO_Handle->headphone.total_length = length;
1746  AUDIO_Handle->play_state = AUDIO_PLAYBACK_PLAY;
1747  AUDIO_Handle->control_state = AUDIO_CONTROL_INIT;
1748  AUDIO_Handle->processing_state = AUDIO_DATA_START_OUT;
1749  Status = USBH_OK;
1750 #if (USBH_USE_OS == 1)
1751  osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
1752 #endif
1753  }
1754  }
1755  return Status;
1756 }
1757 
1765 {
1767  Status = USBH_AUDIO_Suspend(phost);
1768  return Status;
1769 }
1770 
1778 {
1780  AUDIO_HandleTypeDef *AUDIO_Handle;
1781 
1782  if(phost->gState == HOST_CLASS)
1783  {
1784  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1785  if(AUDIO_Handle->play_state == AUDIO_PLAYBACK_PLAY)
1786  {
1787  AUDIO_Handle->control_state = AUDIO_CONTROL_IDLE;
1788  AUDIO_Handle->play_state = AUDIO_PLAYBACK_IDLE;
1789  Status = USBH_OK;
1790  }
1791  }
1792  return Status;
1793 }
1801 {
1803  AUDIO_HandleTypeDef *AUDIO_Handle;
1804 
1805  if(phost->gState == HOST_CLASS)
1806  {
1807  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1808  if(AUDIO_Handle->play_state == AUDIO_PLAYBACK_IDLE)
1809  {
1810  AUDIO_Handle->control_state = AUDIO_CONTROL_INIT;
1811  AUDIO_Handle->play_state = AUDIO_PLAYBACK_PLAY;
1812  }
1813  }
1814  return Status;
1815 }
1823 {
1824  AUDIO_HandleTypeDef *AUDIO_Handle;
1825 
1826  if(phost->gState == HOST_CLASS)
1827  {
1828  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1829  if(AUDIO_Handle->play_state == AUDIO_PLAYBACK_PLAY)
1830  {
1831  return AUDIO_Handle->headphone.partial_ptr;
1832  }
1833  }
1834  return -1;
1835 }
1836 
1845 {
1847  AUDIO_HandleTypeDef *AUDIO_Handle;
1848 
1849  if(phost->gState == HOST_CLASS)
1850  {
1851  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1852  if(AUDIO_Handle->play_state == AUDIO_PLAYBACK_PLAY)
1853  {
1854  if(AUDIO_Handle->headphone.buf <= buf)
1855  {
1856  AUDIO_Handle->headphone.cbuf = buf;
1857  if ( AUDIO_Handle->headphone.buf == buf)
1858  {
1859  AUDIO_Handle->headphone.partial_ptr = 0;
1860  }
1861  Status = USBH_OK;
1862  }
1863  }
1864  }
1865  return Status;
1866 }
1867 
1875 static USBH_StatusTypeDef USBH_AUDIO_SetControlAttribute (USBH_HandleTypeDef *phost, uint8_t attrib)
1876 {
1877  USBH_StatusTypeDef status = USBH_BUSY ;
1878  AUDIO_HandleTypeDef *AUDIO_Handle;
1879 
1880 
1881  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1882 
1883  switch (attrib)
1884  {
1885  case 0x01:
1886  AUDIO_Handle->headphone.attribute.volume += AUDIO_Handle->headphone.attribute.resolution;
1887  break;
1888 
1889  case 0x02:
1890  AUDIO_Handle->headphone.attribute.volume -= AUDIO_Handle->headphone.attribute.resolution;
1891  break;
1892 
1893  }
1894 
1895  if(AUDIO_Handle->headphone.attribute.volume > AUDIO_Handle->headphone.attribute.volumeMax)
1896  {
1897  AUDIO_Handle->headphone.attribute.volume =AUDIO_Handle->headphone.attribute.volumeMax;
1898  }
1899 
1900  if(AUDIO_Handle->headphone.attribute.volume < AUDIO_Handle->headphone.attribute.volumeMin)
1901  {
1902  AUDIO_Handle->headphone.attribute.volume =AUDIO_Handle->headphone.attribute.volumeMin;
1903  }
1904 
1905  if(AUDIO_SetVolume (phost,
1906  AUDIO_Handle->temp_feature,
1907  AUDIO_Handle->temp_channels,
1908  AUDIO_Handle->headphone.attribute.volume) != USBH_BUSY)
1909  {
1910 
1911  if(AUDIO_Handle->temp_channels == 1)
1912  {
1913  AUDIO_Handle->temp_feature = AUDIO_Handle->headphone.asociated_feature;
1914  AUDIO_Handle->temp_channels = AUDIO_Handle->headphone.asociated_channels;
1915  status = USBH_OK;
1916  }
1917  else
1918  {
1919  AUDIO_Handle->temp_channels--;
1920  }
1921  AUDIO_Handle->cs_req_state = AUDIO_REQ_GET_VOLUME;
1922  }
1923 
1924 
1925  return status;
1926 }
1927 
1928 
1937 {
1938  AUDIO_HandleTypeDef *AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1939 
1940  if((volume_ctl == VOLUME_UP) || (volume_ctl == VOLUME_DOWN))
1941  {
1942  if(phost->gState == HOST_CLASS)
1943  {
1944  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1945  if(AUDIO_Handle->play_state == AUDIO_PLAYBACK_PLAY)
1946  {
1947  AUDIO_Handle->control_state = (volume_ctl == VOLUME_UP)? AUDIO_CONTROL_VOLUME_UP : AUDIO_CONTROL_VOLUME_DOWN;
1948  return USBH_OK;
1949  }
1950  }
1951  }
1952  return USBH_FAIL;
1953 }
1963 static USBH_StatusTypeDef AUDIO_SetVolume (USBH_HandleTypeDef *phost, uint8_t feature, uint8_t channel, uint16_t volume)
1964 {
1965  USBH_StatusTypeDef status = USBH_BUSY ;
1966  AUDIO_HandleTypeDef *AUDIO_Handle;
1967 
1968 
1969  AUDIO_Handle = (AUDIO_HandleTypeDef*) phost->pActiveClass->pData;
1970 
1971  AUDIO_Handle->mem[0] = volume;
1972 
1973  status = USBH_AC_SetCur(phost,
1975  feature,
1977  channel,
1978  2);
1979 
1980  return status;
1981 }
1982 
1989 {
1990 
1991 }
1992 
1999 {
2000 
2001 }
2024 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
#define VOLUME_CONTROL
Definition: usbh_audio.h:469
#define UAC_GET_MIN
Definition: usbh_audio.h:505
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost, uint8_t *buff, uint8_t length, uint8_t hc_num)
USBH_InterruptReceiveData Receives the Device Response to the Interrupt IN token. ...
Definition: usbh_ioreq.c:244
#define UAC_FORMAT_TYPE
Definition: usbh_audio.h:486
#define UAC_GET_CUR
Definition: usbh_audio.h:503
#define USB_H2D
Definition: usbh_def.h:108
AUDIO_PlayStateTypeDef play_state
Definition: usbh_audio.h:414
USB_Setup_TypeDef setup
Definition: usbh_def.h:412
uint8_t temp_feature
Definition: usbh_audio.h:426
#define UAC_MIXER_UNIT
Definition: usbh_audio.h:455
AUDIO_VolumeCtrlTypeDef
Definition: usbh_audio.h:123
#define USB_SUBCLASS_AUDIOCONTROL
Definition: usbh_audio.h:444
#define USBH_memset
AUDIO_ControlStateTypeDef control_state
Definition: usbh_audio.h:415
#define USB_SUBCLASS_AUDIOSTREAMING
Definition: usbh_audio.h:445
USBH_DeviceTypeDef device
Definition: usbh_def.h:456
#define UAC_AS_GENERAL
Definition: usbh_audio.h:485
USBH_StatusTypeDef USBH_OpenPipe(USBH_HandleTypeDef *phost, uint8_t ch_num, uint8_t epnum, uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
USBH_Open_Pipe Open a pipe.
Definition: usbh_pipes.c:93
#define USB_D2H
Definition: usbh_def.h:109
__IO uint32_t Timer
Definition: usbh_def.h:461
#define UAC_GET_MAX
Definition: usbh_audio.h:507
uint8_t wTerminalType[2]
Definition: usbh_audio.h:311
uint8_t wTerminalType[2]
Definition: usbh_audio.h:327
uint8_t USBH_AllocPipe(USBH_HandleTypeDef *phost, uint8_t ep_addr)
USBH_Alloc_Pipe Allocate a new Pipe.
Definition: usbh_pipes.c:138
uint16_t_uint8_t wValue
Definition: usbh_def.h:223
uint8_t bInterfaceClass
Definition: usbh_def.h:277
#define UAC_HEADER
Definition: usbh_audio.h:452
#define USB_EP_TYPE_INTR
Definition: usbh_def.h:173
AUDIO_ControlAttributeTypeDef attribute
Definition: usbh_audio.h:219
#define HOST_USER_CLASS_ACTIVE
Definition: usbh_core.h:65
uint8_t tSamFreq[AUDIO_MAX_SAMFREQ_NBR][3]
Definition: usbh_audio.h:278
#define USB_REQ_RECIPIENT_ENDPOINT
Definition: usbd_def.h:80
uint8_t bEndpointAddress
Definition: usbh_def.h:263
AUDIO_OTDescTypeDef * OutputTerminalDesc[AUDIO_MAX_NUM_OUT_TERMINAL]
Definition: usbh_audio.h:386
USBH_StatusTypeDef USBH_AUDIO_SetVolume(USBH_HandleTypeDef *phost, AUDIO_VolumeCtrlTypeDef volume_ctl)
USBH_AUDIO_SetVolume Set Volume.
Definition: usbh_audio.c:1936
USBH_StatusTypeDef USBH_AUDIO_Stop(USBH_HandleTypeDef *phost)
USBH_AUDIO_Pause Stop the playback process.
Definition: usbh_audio.c:1764
USBH_StatusTypeDef USBH_FreePipe(USBH_HandleTypeDef *phost, uint8_t idx)
USBH_Free_Pipe Free the USB Pipe.
Definition: usbh_pipes.c:158
uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol)
USBH_FindInterface Find the interface index for a specific class.
Definition: usbh_core.c:274
int32_t USBH_AUDIO_FindLinkedUnitIN(USBH_HandleTypeDef *phost, uint8_t UnitID)
void(* pUser)(struct _USBH_HandleTypeDef *pHandle, uint8_t id)
Definition: usbh_def.h:464
uint16_t_uint8_t wLength
Definition: usbh_def.h:225
USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES]
Definition: usbh_def.h:296
uint16_t mem[8]
Definition: usbh_audio.h:425
AUDIO_ClassSpecificDescTypedef class_desc
Definition: usbh_audio.h:420
USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost, uint8_t ep_num, uint8_t altSetting)
USBH_SetInterface The command sets the Interface value to the connected device.
Definition: usbh_ctlreq.c:283
AUDIO_SelectorDescTypeDef * SelectorUnitDesc[AUDIO_MAX_NUM_SELECTOR_UNIT]
Definition: usbh_audio.h:389
USBH_CfgDescTypeDef CfgDesc
Definition: usbh_def.h:430
#define USB_REQ_RECIPIENT_INTERFACE
Definition: usbd_def.h:79
#define UAC_OUTPUT_TERMINAL
Definition: usbh_audio.h:454
AUDIO_ITDescTypeDef * InputTerminalDesc[AUDIO_MAX_NUM_IN_TERMINAL]
Definition: usbh_audio.h:385
int32_t USBH_AUDIO_FindLinkedUnitOUT(USBH_HandleTypeDef *phost, uint8_t UnitID)
#define NULL
Definition: usbd_def.h:53
This file contains all the prototypes for the usbh_audio.c.
uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings)
USBH_FindInterfaceIndex Find the interface index for a specific class interface and alternate setting...
Definition: usbh_core.c:306
USBH_ClassTypeDef AUDIO_Class
Definition: usbh_audio.c:175
USBH_CtrlTypeDef Control
Definition: usbh_def.h:455
AUDIO_InterfaceStreamPropTypeDef microphone
Definition: usbh_audio.h:423
#define USBH_MAX_NUM_INTERFACES
uint8_t bInterfaceNumber
Definition: usbh_def.h:274
USBH_StatusTypeDef USBH_CtlReq(USBH_HandleTypeDef *phost, uint8_t *buff, uint16_t length)
USBH_CtlReq USBH_CtlReq sends a control request and provide the status after completion of the reques...
Definition: usbh_ctlreq.c:531
AUDIO_STREAMING_OUT_HandleTypeDef stream_out[AUDIO_MAX_AUDIO_STD_INTERFACE]
Definition: usbh_audio.h:419
USBH_StatusTypeDef USBH_AUDIO_Resume(USBH_HandleTypeDef *phost)
USBH_AUDIO_Resume Resume the playback process.
Definition: usbh_audio.c:1800
#define FALSE
Definition: usbh_def.h:57
AUDIO_InterfaceStreamPropTypeDef headphone
Definition: usbh_audio.h:422
#define COPY_PROTECT_CONTROL
Definition: usbh_audio.h:481
#define SAMPLING_FREQ_CONTROL
Definition: usbh_audio.h:463
#define USBH_malloc
#define LE16(addr)
Definition: usbh_def.h:69
USBH_StatusTypeDef USBH_AUDIO_Play(USBH_HandleTypeDef *phost, uint8_t *buf, uint32_t length)
USBH_AUDIO_Play Start playback process.
Definition: usbh_audio.c:1734
#define USB_DESC_TYPE_INTERFACE
Definition: usbd_def.h:98
AUDIO_FeatureDescTypeDef * FeatureUnitDesc[AUDIO_MAX_NUM_FEATURE_UNIT]
Definition: usbh_audio.h:387
uint8_t temp_channels
Definition: usbh_audio.h:427
#define UAC_SET_CUR
Definition: usbh_audio.h:502
USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS]
Definition: usbh_def.h:281
#define UAC_GET_RES
Definition: usbh_audio.h:509
#define LE24(addr)
Definition: usbh_def.h:89
#define AUDIO_MAX_AUDIO_STD_INTERFACE
Definition: usbh_audio.h:238
AUDIO_InterfaceControlPropTypeDef control
Definition: usbh_audio.h:424
uint8_t bDescriptorType
Definition: usbh_def.h:233
uint16_t wMaxPacketSize
Definition: usbh_def.h:265
uint8_t bInterfaceSubClass
Definition: usbh_def.h:278
#define UAC_SELECTOR_UNIT
Definition: usbh_audio.h:456
AUDIO_MixerDescTypeDef * MixerUnitDesc[AUDIO_MAX_NUM_MIXER_UNIT]
Definition: usbh_audio.h:388
uint8_t bAlternateSetting
Definition: usbh_def.h:275
uint16_t w
Definition: usbh_def.h:204
#define UAC_INPUT_TERMINAL
Definition: usbh_audio.h:453
USBH_DescHeader_t * USBH_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
USBH_GetNextDesc This function return the next descriptor header.
Definition: usbh_ctlreq.c:509
#define TRUE
Definition: usbh_def.h:61
USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, uint8_t, uint8_t)
USBH_LL_SetToggle Set toggle for a pipe.
USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, uint8_t)
USBH_LL_GetURBState Get a URB state from the low level driver.
AUDIO_CSReqStateTypeDef cs_req_state
Definition: usbh_audio.h:413
AUDIO_ProcessingTypeDef processing_state
Definition: usbh_audio.h:416
#define USB_EP_TYPE_ISOC
Definition: usbh_def.h:171
AUDIO_STREAMING_IN_HandleTypeDef stream_in[AUDIO_MAX_AUDIO_STD_INTERFACE]
Definition: usbh_audio.h:418
#define USB_LEN_CFG_DESC
Definition: usbd_def.h:59
AUDIO_HeaderDescTypeDef * HeaderDesc
Definition: usbh_audio.h:384
USBH_StatusTypeDef
Definition: usbh_def.h:302
#define USBH_DbgLog(...)
__IO HOST_StateTypeDef gState
Definition: usbh_def.h:452
AUDIO_ACDescTypeDef cs_desc
Definition: usbh_audio.h:397
#define USB_DESC_TYPE_CS_INTERFACE
Definition: usbh_audio.h:448
__weak void USBH_AUDIO_FrequencySet(USBH_HandleTypeDef *phost)
The function informs user that Settings have been changed.
Definition: usbh_audio.c:1988
__weak void USBH_AUDIO_BufferEmptyCallback(USBH_HandleTypeDef *phost)
The function informs user that User data are processed.
Definition: usbh_audio.c:1998
USBH_StatusTypeDef USBH_AUDIO_Suspend(USBH_HandleTypeDef *phost)
USBH_AUDIO_Suspend Suspend the playback process.
Definition: usbh_audio.c:1777
AUDIO_ASGeneralDescTypeDef * GeneralDesc
Definition: usbh_audio.h:285
osStatus osMessagePut(osMessageQId queue_id, uint32_t info, uint32_t millisec)
Put a Message to a Queue.
Definition: cmsis_os.c:951
USBH_StatusTypeDef USBH_AUDIO_ChangeOutBuffer(USBH_HandleTypeDef *phost, uint8_t *buf)
USBH_AUDIO_ChangeOutBuffer Change audio data buffer address.
Definition: usbh_audio.c:1844
AUDIO_ReqStateTypeDef req_state
Definition: usbh_audio.h:412
osStatus osDelay(uint32_t millisec)
Wait for Timeout (Time Delay)
Definition: cmsis_os.c:305
#define AC_CLASS
Definition: usbh_audio.h:441
AUDIO_ASDescTypeDef as_desc[AUDIO_MAX_STREAMING_INTERFACE]
Definition: usbh_audio.h:398
USBH_ClassTypeDef * pActiveClass
Definition: usbh_def.h:458
#define USBH_free
#define UAC_FEATURE_UNIT
Definition: usbh_audio.h:457
int32_t USBH_AUDIO_GetOutOffset(USBH_HandleTypeDef *phost)
USBH_AUDIO_GetOutOffset return the current buffer pointer for OUT process.
Definition: usbh_audio.c:1822
uint16_t_uint8_t wIndex
Definition: usbh_def.h:224
struct _USB_Setup::_SetupPkt_Struc b
USBH_StatusTypeDef USBH_AUDIO_SetFrequency(USBH_HandleTypeDef *phost, uint16_t SampleRate, uint8_t NbrChannels, uint8_t BitPerSample)
USBH_AUDIO_SetFrequency Set Audio sampling parameters.
Definition: usbh_audio.c:1669
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost, uint8_t *buff, uint32_t length, uint8_t hc_num)
USBH_IsocSendData Sends the data on Isochronous OUT Endpoint.
Definition: usbh_ioreq.c:323
AUDIO_ASFormatTypeDescTypeDef * FormatTypeDesc
Definition: usbh_audio.h:286
USBH_StatusTypeDef USBH_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe_num)
USBH_ClosePipe Close a pipe.
Definition: usbh_pipes.c:121