M471M/R1/S BSP V3.01.000
The Board Support Package for M4521
uac_core.c
Go to the documentation of this file.
1/**************************************************************************/
8#include <stdio.h>
9#include <string.h>
10
11#include "NuMicro.h"
12
13#include "usb.h"
14#include "usbh_lib.h"
15#include "usbh_uac.h"
16#include "uac.h"
17
18
42int usbh_uac_get_channel_number(UAC_DEV_T *uac, uint8_t target)
43{
44 AS_FT1_T *ft;
45
46 if(target == UAC_SPEAKER)
47 ft = uac->asif_out.ft;
48 else
49 ft = uac->asif_in.ft;
50
51 if(!ft)
53
54 return ft->bNrChannels;
55}
56
57
69int usbh_uac_get_bit_resolution(UAC_DEV_T *uac, uint8_t target, uint8_t *byte_cnt)
70{
71 AS_FT1_T *ft;
72
73 if(target == UAC_SPEAKER)
74 ft = uac->asif_out.ft;
75 else
76 ft = uac->asif_in.ft;
77
78 if(!ft)
80
81 *byte_cnt = ft->bSubframeSize;
82
83 return ft->bBitResolution;
84}
85
86
88
89uint32_t srate_to_u32(uint8_t *srate)
90{
91 return (srate[2] << 16) | (srate[1] << 8) | srate[0];
92}
93
95
96
114int usbh_uac_get_sampling_rate(UAC_DEV_T *uac, uint8_t target, uint32_t *srate_list,
115 int max_cnt, uint8_t *type)
116{
117 AS_FT1_T *ft;
118 int i;
119
120 if(target == UAC_SPEAKER)
121 ft = uac->asif_out.ft;
122 else
123 ft = uac->asif_in.ft;
124
125 if(!ft)
127
128 *type = ft->bSamFreqType;
129
130 if(*type == 0)
131 {
132 if(max_cnt < 2)
134
135 srate_list[0] = srate_to_u32(&ft->tSamFreq[0][0]);
136 srate_list[1] = srate_to_u32(&ft->tSamFreq[1][0]);
137 }
138 else
139 {
140 for(i = 0; i < *type; i++)
141 srate_list[i] = srate_to_u32(&ft->tSamFreq[i][0]);
142 }
143 return 0;
144}
145
146
167int usbh_uac_sampling_rate_control(UAC_DEV_T *uac, uint8_t target, uint8_t req, uint32_t *srate)
168{
169 EP_INFO_T *ep;
170 uint8_t bmRequestType;
171 uint8_t tSampleFreq[3];
172 uint32_t xfer_len;
173 int ret;
174
175 if(target == UAC_SPEAKER)
176 ep = uac->asif_out.ep;
177 else
178 ep = uac->asif_in.ep;
179
180 if(ep == NULL)
182
183 tSampleFreq[0] = *srate & 0xff;
184 tSampleFreq[1] = (*srate >> 8) & 0xff;
185 tSampleFreq[2] = (*srate >> 16) & 0xff;
186
187 if(req & 0x80)
188 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_EP;
189 else
190 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_EP;
191
192 /* Audio Class Request - Endpoint Control Requests (5.2.3.2) */
193 ret = usbh_ctrl_xfer(uac->udev, bmRequestType, req,
194 (SAMPLING_FREQ_CONTROL << 8), /* wValue - Control Selector (CS) */
195 ep->bEndpointAddress, /* wIndex - endpoint */
196 3, /* wLength - parameter block length */
197 tSampleFreq, /* parameter block */
198 &xfer_len, UAC_REQ_TIMEOUT);
199 if(ret < 0)
200 return ret;
201
202 if(xfer_len != 3)
203 return UAC_RET_DATA_LEN;
204
205 *srate = srate_to_u32(tSampleFreq);
206 return 0;
207}
208
209
238int usbh_uac_mute_control(UAC_DEV_T *uac, uint8_t target, uint8_t req, uint16_t chn, uint8_t *mute)
239{
240 uint8_t bmRequestType;
241 uint8_t bUnitID;
242 uint32_t xfer_len;
243 int ret;
244
245 if(target == UAC_MICROPHONE)
246 bUnitID = uac->acif.mic_fuid;
247 else
248 bUnitID = uac->acif.speaker_fuid;
249
250 if(req & 0x80)
251 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
252 else
253 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
254
255 /* Audio Class Request - Feature Unit Control Request (5.2.2.4) */
256 ret = usbh_ctrl_xfer(uac->udev, bmRequestType, req,
257 (MUTE_CONTROL << 8) | chn, /* wValue - Control Selector (CS) */
258 (bUnitID << 8) | (uac->acif.iface->if_num), /* wIndex - unit ID and interface number */
259 1, /* wLength - parameter block length */
260 mute, /* parameter block */
261 &xfer_len, UAC_REQ_TIMEOUT);
262 if(ret < 0)
263 return ret;
264
265 if(xfer_len != 1)
266 return UAC_RET_DATA_LEN;
267
268 return 0;
269}
270
271
321int usbh_uac_vol_control(UAC_DEV_T *uac, uint8_t target, uint8_t req, uint16_t chn, uint16_t *volume)
322{
323 uint8_t bmRequestType;
324 uint8_t bUnitID;
325 uint32_t xfer_len;
326 int ret;
327
328 if(target == UAC_MICROPHONE)
329 bUnitID = uac->acif.mic_fuid;
330 else
331 bUnitID = uac->acif.speaker_fuid;
332
333 if(req & 0x80)
334 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
335 else
336 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
337
338 /* Audio Class Request - Feature Unit Control Request (5.2.2.4) */
339 ret = usbh_ctrl_xfer(uac->udev, bmRequestType, req,
340 (VOLUME_CONTROL << 8) | chn,/* wValue - Control Selector (CS) */
341 (bUnitID << 8) | (uac->acif.iface->if_num), /* wIndex - unit ID and interface number */
342 2, /* wLength - parameter block length */
343 (uint8_t *)volume, /* parameter block */
344 &xfer_len, UAC_REQ_TIMEOUT);
345 if(ret < 0)
346 return ret;
347
348 if(xfer_len != 2)
349 return UAC_RET_DATA_LEN;
350
351 return 0;
352}
353
354
383int usbh_uac_auto_gain_control(UAC_DEV_T *uac, uint8_t target, uint8_t req, uint16_t chn, uint8_t *bAGC)
384{
385 uint8_t bmRequestType;
386 uint8_t bUnitID;
387 uint32_t xfer_len;
388 int ret;
389
390 if(target == UAC_MICROPHONE)
391 bUnitID = uac->acif.mic_fuid;
392 else
393 bUnitID = uac->acif.speaker_fuid;
394
395 if(req & 0x80)
396 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
397 else
398 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
399
400 /* Audio Class Request - Feature Unit Control Request (5.2.2.4) */
401 ret = usbh_ctrl_xfer(uac->udev, bmRequestType, req,
402 (AUTOMATIC_GAIN_CONTROL << 8) | chn, /* wValue - Control Selector (CS) */
403 (bUnitID << 8) | (uac->acif.iface->if_num), /* wIndex - unit ID and interface number */
404 1, /* wLength - parameter block length */
405 bAGC, /* parameter block */
406 &xfer_len, UAC_REQ_TIMEOUT);
407 if(ret < 0)
408 return ret;
409
410 if(xfer_len != 1)
411 return UAC_RET_DATA_LEN;
412
413 return 0;
414}
415
416
418
429int usbh_uac_find_max_alt(IFACE_T *iface, uint8_t dir, uint8_t attr, uint8_t *bAlternateSetting)
430{
431 EP_INFO_T *ep;
432 uint8_t i, j;
433 uint16_t wMaxPacketSize = 0;
434
435 for(i = 0; i < iface->num_alt; i++)
436 {
437 for(j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
438 {
439 ep = &(iface->alt[i].ep[j]); /* get endpoint */
440
441 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) != dir) ||
442 ((ep->bmAttributes & EP_ATTR_TT_MASK) != attr))
443 continue; /* not interested endpoint */
444
445 if(ep->wMaxPacketSize > wMaxPacketSize)
446 {
447 /* a better candidate endpoint found */
448 *bAlternateSetting = i;
449 wMaxPacketSize = ep->wMaxPacketSize;
450 }
451 }
452 }
453 if(wMaxPacketSize == 0)
454 return USBH_ERR_NOT_FOUND;
455
456 return 0;
457}
458
470int usbh_uac_find_best_alt(IFACE_T *iface, uint8_t dir, uint8_t attr, int pkt_sz, uint8_t *bAlternateSetting)
471{
472 EP_INFO_T *ep;
473 uint8_t i, j;
474 uint16_t wMaxPacketSize = 0xFFFF;
475
476 for(i = 0; i < iface->num_alt; i++)
477 {
478 for(j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
479 {
480 ep = &(iface->alt[i].ep[j]); /* get endpoint */
481
482 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) != dir) ||
483 ((ep->bmAttributes & EP_ATTR_TT_MASK) != attr))
484 continue; /* not interested endpoint */
485
486 if((ep->wMaxPacketSize >= pkt_sz) && (ep->wMaxPacketSize < wMaxPacketSize))
487 {
488 /* a better candidate endpoint found */
489 *bAlternateSetting = i;
490 wMaxPacketSize = ep->wMaxPacketSize;
491 }
492 }
493 }
494 if(wMaxPacketSize == 0xFFFF)
495 {
496 UAC_DBGMSG("Audio interface %d cannot find endpoint with wMaxPacketSize >= %d!\n", iface->if_num, pkt_sz);
497 return USBH_ERR_NOT_FOUND;
498 }
499 return 0;
500}
501
502
503static void iso_in_irq(UTR_T *utr)
504{
505 UAC_DEV_T *uac = (UAC_DEV_T *)utr->context;
506 int i, ret;
507
508 /* We don't want to do anything if we are about to be removed! */
509 if(!uac || !uac->udev)
510 return;
511
512 if(uac->asif_in.flag_streaming == 0)
513 return;
514
515 //UAC_DBGMSG("SF=%d, 0x%x\n", utr->iso_sf, (int)utr);
516
517 utr->bIsoNewSched = 0;
518
519 for(i = 0; i < IF_PER_UTR; i++)
520 {
521 if(utr->iso_status[i] == 0)
522 {
523 if((uac->func_au_in != NULL) && (utr->iso_xlen[i] > 0))
524 uac->func_au_in(uac, utr->iso_buff[i], utr->iso_xlen[i]);
525 }
526 else
527 {
528 UAC_DBGMSG("Iso %d err - %d\n", i, utr->iso_status[i]);
529 if((utr->iso_status[i] == USBH_ERR_NOT_ACCESS0) || (utr->iso_status[i] == USBH_ERR_NOT_ACCESS1))
530 utr->bIsoNewSched = 1;
531 }
532 utr->iso_xlen[i] = utr->ep->wMaxPacketSize;
533 }
534
535 /* schedule the following isochronous transfers */
536 ret = usbh_iso_xfer(utr);
537 if(ret < 0)
538 UAC_DBGMSG("usbh_iso_xfer failed!\n");
539}
540
542
543
553{
554 UDEV_T *udev = uac->udev;
555 AS_IF_T *asif = &uac->asif_in;
556 IFACE_T *iface = uac->asif_in.iface;
557 ALT_IFACE_T *aif;
558 EP_INFO_T *ep;
559 UTR_T *utr;
560 uint8_t *buff;
561 uint8_t bAlternateSetting;
562 int i, j, ret;
563
564 if(!uac || !iface)
566
567 if(asif->flag_streaming)
569
570 /*------------------------------------------------------------------------------------*/
571 /* Select the maximum packet size alternative interface */
572 /*------------------------------------------------------------------------------------*/
573 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_IN, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
575
576 uac->func_au_in = func;
577
578 ret = usbh_set_interface(iface, bAlternateSetting);
579 if(ret < 0)
580 {
581 UAC_ERRMSG("Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
582 return ret;
583 }
584
585 ret = uac_parse_streaming_interface(uac, iface, bAlternateSetting);
586 if(ret < 0)
587 return ret;
588
589 /*------------------------------------------------------------------------------------*/
590 /* Find the endpoint */
591 /*------------------------------------------------------------------------------------*/
592 asif->ep = NULL;
593 aif = asif->iface->aif;
594 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
595 {
596 ep = &(aif->ep[i]);
597
598 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN) &&
599 ((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO))
600 {
601 asif->ep = ep;
602 UAC_DBGMSG("Audio in endpoint 0x%x found, size: %d\n", ep->bEndpointAddress, ep->wMaxPacketSize);
603 break;
604 }
605 }
606 if(asif->ep == NULL)
608 ep = asif->ep;
609
610#ifdef UAC_DEBUG
611 UAC_DBGMSG("Activated isochronous-in endpoint =>");
612 usbh_dump_ep_info(ep);
613#endif
614
615 /*------------------------------------------------------------------------------------*/
616 /* Allocate isochronous in buffer */
617 /*------------------------------------------------------------------------------------*/
618 for(i = 0; i < NUM_UTR; i++) /* allocate UTRs */
619 {
620 asif->utr[i] = alloc_utr(udev); /* allocate UTR */
621 if(asif->utr[i] == NULL)
622 {
623 ret = USBH_ERR_MEMORY_OUT; /* memory allocate failed */
624 goto err_out; /* abort */
625 }
626 }
627
628 buff = (uint8_t *)usbh_alloc_mem(ep->wMaxPacketSize * IF_PER_UTR * NUM_UTR);
629 if(buff == NULL)
630 {
631 ret = USBH_ERR_MEMORY_OUT; /* memory allocate failed */
632 goto err_out; /* abort */
633 }
634
635 for(i = 0; i < NUM_UTR; i++) /* dispatch buffers */
636 {
637 /* divide buffer equally */
638 utr = asif->utr[i];
639 utr->buff = buff + (ep->wMaxPacketSize * IF_PER_UTR * i);
640 utr->data_len = ep->wMaxPacketSize * IF_PER_UTR;
641 for(j = 0; j < IF_PER_UTR; j++)
642 {
643 utr->iso_xlen[j] = ep->wMaxPacketSize;
644 utr->iso_buff[j] = utr->buff + (ep->wMaxPacketSize * j);
645 }
646 }
647
648 /*------------------------------------------------------------------------------------*/
649 /* Start UTRs */
650 /*------------------------------------------------------------------------------------*/
651
652 asif->utr[0]->bIsoNewSched = 1;
653
654 for(i = 0; i < NUM_UTR; i++)
655 {
656 utr = asif->utr[i];
657 utr->context = uac;
658 utr->ep = ep;
659 utr->func = iso_in_irq;
660 ret = usbh_iso_xfer(utr);
661 if(ret < 0)
662 {
663 UAC_DBGMSG("Error - failed to start UTR %d isochronous-in transfer (%d)", i, ret);
664 goto err_out;
665 }
666 }
667 asif->flag_streaming = 1;
668 uac->state = UAC_STATE_RUNNING;
669
670 return UAC_RET_OK;
671
672err_out:
673
674 for(i = 0; i < NUM_UTR; i++) /* quit all UTRs */
675 {
676 if(asif->utr[i])
677 usbh_quit_utr(asif->utr[i]);
678 }
679 asif->flag_streaming = 0;
680 /* free USB transfer buffer */
681 if((asif->utr[0] != NULL) &&
682 (asif->utr[0]->buff != NULL))
683 usbh_free_mem(asif->utr[0]->buff, asif->utr[0]->data_len * NUM_UTR);
684
685 for(i = 0; i < NUM_UTR; i++) /* free all UTRs */
686 {
687 if(asif->utr[i])
688 free_utr(asif->utr[i]);
689 asif->utr[i] = NULL;
690 }
691 return ret;
692}
693
702{
703 AS_IF_T *asif = &uac->asif_in;
704 int i, ret;
705
706 asif->flag_streaming = 0;
707
708 /* Set interface alternative settings */
709 if(uac->state != UAC_STATE_DISCONNECTING)
710 {
711 ret = usbh_set_interface(asif->iface, 0);
712 if(ret < 0)
713 {
714 UAC_ERRMSG("Failed to set interface %d, %d! (%d)\n", asif->iface->if_num, 0, ret);
715 }
716 }
717
718 for(i = 0; i < NUM_UTR; i++) /* stop all UTRs */
719 {
720 if(asif->utr[i])
721 usbh_quit_utr(asif->utr[i]);
722 }
723
724 if((asif->utr[0] != NULL) &&
725 (asif->utr[0]->buff != NULL)) /* free audio buffer */
726 usbh_free_mem(asif->utr[0]->buff, asif->utr[0]->data_len * NUM_UTR);
727
728 for(i = 0; i < NUM_UTR; i++) /* free all UTRs */
729 {
730 if(asif->utr[i])
731 free_utr(asif->utr[i]);
732 asif->utr[i] = NULL;
733 }
734
735 if(uac->state != UAC_STATE_DISCONNECTING)
736 {
737 if((uac->asif_out.iface == NULL) || (uac->asif_out.flag_streaming == 0))
738 {
739 uac->state = UAC_STATE_READY;
740 }
741 }
742
743 return UAC_RET_OK;
744}
745
746
748
749static void iso_out_irq(UTR_T *utr)
750{
751 UAC_DEV_T *uac = (UAC_DEV_T *)utr->context;
752 int i, ret;
753
754 /* We don't want to do anything if we are about to be removed! */
755 if(!uac || !uac->udev)
756 return;
757
758 if(uac->asif_out.flag_streaming == 0)
759 return;
760
761 //UAC_DBGMSG("SF=%d, 0x%x\n", utr->iso_sf, (int)utr);
762
763 utr->bIsoNewSched = 0;
764
765 for(i = 0; i < IF_PER_UTR; i++)
766 {
767 if(utr->iso_status[i] != 0)
768 {
769 // UAC_DBGMSG("Iso %d err - %d\n", i, utr->iso_status[i]);
770 if((utr->iso_status[i] == USBH_ERR_NOT_ACCESS0) || (utr->iso_status[i] == USBH_ERR_NOT_ACCESS1))
771 utr->bIsoNewSched = 1;
772 }
773 utr->iso_xlen[i] = uac->func_au_out(uac, utr->iso_buff[i], utr->ep->wMaxPacketSize);
774 }
775
776 /* schedule the following isochronous transfers */
777 ret = usbh_iso_xfer(utr);
778 if(ret < 0)
779 UAC_DBGMSG("usbh_iso_xfer failed!\n");
780}
781
783
784
795{
796 UDEV_T *udev = uac->udev;
797 AS_IF_T *asif = &uac->asif_out;
798 IFACE_T *iface = uac->asif_out.iface;
799 ALT_IFACE_T *aif;
800 EP_INFO_T *ep;
801 UTR_T *utr;
802 uint8_t *buff;
803 uint8_t bAlternateSetting;
804 int i, j, ret;
805
806 if(!uac || !func || !iface)
808
809 if(asif->flag_streaming)
811
812 /*------------------------------------------------------------------------------------*/
813 /* Select the maximum packet size alternative interface */
814 /*------------------------------------------------------------------------------------*/
815 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_OUT, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
817
818 uac->func_au_out = func;
819
820 ret = usbh_set_interface(iface, bAlternateSetting);
821 if(ret < 0)
822 {
823 UAC_ERRMSG("Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
824 return ret;
825 }
826
827 ret = uac_parse_streaming_interface(uac, iface, bAlternateSetting);
828 if(ret < 0)
829 return ret;
830
831 /*------------------------------------------------------------------------------------*/
832 /* Find the endpoint */
833 /*------------------------------------------------------------------------------------*/
834 asif->ep = NULL;
835 aif = asif->iface->aif;
836 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
837 {
838 ep = &(aif->ep[i]);
839
840 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_OUT) &&
841 ((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO))
842 {
843 asif->ep = ep;
844 UAC_DBGMSG("Audio in endpoint 0x%x found, size: %d\n", ep->bEndpointAddress, ep->wMaxPacketSize);
845 break;
846 }
847 }
848 if(asif->ep == NULL)
850 ep = asif->ep;
851
852#ifdef UAC_DEBUG
853 UAC_DBGMSG("Activated isochronous-out endpoint =>");
854 usbh_dump_ep_info(ep);
855#endif
856
857 /*------------------------------------------------------------------------------------*/
858 /* Allocate isochronous in buffer */
859 /*------------------------------------------------------------------------------------*/
860 for(i = 0; i < NUM_UTR; i++) /* allocate UTRs */
861 {
862 asif->utr[i] = alloc_utr(udev); /* allocate UTR */
863 if(asif->utr[i] == NULL)
864 {
865 ret = USBH_ERR_MEMORY_OUT; /* memory allocate failed */
866 goto err_out; /* abort */
867 }
868 }
869
870 buff = (uint8_t *)usbh_alloc_mem(ep->wMaxPacketSize * IF_PER_UTR * NUM_UTR);
871 if(buff == NULL)
872 {
873 ret = USBH_ERR_MEMORY_OUT; /* memory allocate failed */
874 goto err_out; /* abort */
875 }
876
877 for(i = 0; i < NUM_UTR; i++) /* dispatch buffers */
878 {
879 /* divide buffer equally */
880 asif->utr[i]->buff = buff + (ep->wMaxPacketSize * IF_PER_UTR * i);
881 asif->utr[i]->data_len = ep->wMaxPacketSize * IF_PER_UTR;
882 }
883
884 /*------------------------------------------------------------------------------------*/
885 /* Start UTRs */
886 /*------------------------------------------------------------------------------------*/
887
888 asif->utr[0]->bIsoNewSched = 1;
889
890 for(i = 0; i < NUM_UTR; i++)
891 {
892 utr = asif->utr[i];
893 utr->context = uac;
894 utr->ep = ep;
895 utr->func = iso_out_irq;
896
897 for(j = 0; j < IF_PER_UTR; j++) /* get audio out data from user */
898 {
899 utr->iso_buff[j] = utr->buff + (ep->wMaxPacketSize * j);
900 utr->iso_xlen[j] = uac->func_au_out(uac, utr->iso_buff[j], ep->wMaxPacketSize);
901 }
902
903 ret = usbh_iso_xfer(utr);
904 if(ret < 0)
905 {
906 UAC_DBGMSG("Error - failed to start UTR %d isochronous-in transfer (%d)", i, ret);
907 goto err_out;
908 }
909 }
910 asif->flag_streaming = 1;
911 uac->state = UAC_STATE_RUNNING;
912
913 return UAC_RET_OK;
914
915err_out:
916
917 for(i = 0; i < NUM_UTR; i++) /* quit all UTRs */
918 {
919 if(asif->utr[i])
920 usbh_quit_utr(asif->utr[i]);
921 }
922 asif->flag_streaming = 0;
923
924 if((asif->utr[0] != NULL) && /* free USB transfer buffer */
925 (asif->utr[0]->buff != NULL))
926 usbh_free_mem(asif->utr[0]->buff, asif->utr[0]->data_len * NUM_UTR);
927
928 for(i = 0; i < NUM_UTR; i++) /* free all UTRs */
929 {
930 if(asif->utr[i])
931 free_utr(asif->utr[i]);
932 asif->utr[i] = NULL;
933 }
934 return ret;
935}
936
945{
946 AS_IF_T *asif = &uac->asif_out;
947 int i, ret;
948
949 /* Set interface alternative settings */
950 if(uac->state != UAC_STATE_DISCONNECTING)
951 {
952 ret = usbh_set_interface(asif->iface, 0);
953 if(ret < 0)
954 {
955 UAC_ERRMSG("Failed to set interface %d, %d! (%d)\n", asif->iface->if_num, 0, ret);
956 }
957 }
958
959 for(i = 0; i < NUM_UTR; i++) /* stop all UTRs */
960 {
961 if(asif->utr[i])
962 usbh_quit_utr(asif->utr[i]);
963 }
964
965 if((asif->utr[0] != NULL) &&
966 (asif->utr[0]->buff != NULL)) /* free audio buffer */
967 usbh_free_mem(asif->utr[0]->buff, asif->utr[0]->data_len * NUM_UTR);
968
969 for(i = 0; i < NUM_UTR; i++) /* free all UTRs */
970 {
971 if(asif->utr[i])
972 free_utr(asif->utr[i]);
973 asif->utr[i] = NULL;
974 }
975
976 if(uac->state != UAC_STATE_DISCONNECTING)
977 {
978 if((uac->asif_in.iface == NULL) || (uac->asif_in.flag_streaming == 0))
979 {
980 uac->state = UAC_STATE_READY;
981 }
982 }
983 asif->flag_streaming = 0;
984
985 return UAC_RET_OK;
986}
987
996{
997 IFACE_T *iface;
998 uint8_t bAlternateSetting;
999 int ret;
1000
1001 /*------------------------------------------------------------------------------------*/
1002 /* Select the maximum packet size alternative interface */
1003 /*------------------------------------------------------------------------------------*/
1004 iface = uac->asif_in.iface;
1005
1006 if(iface != NULL)
1007 {
1008 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_IN, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
1010
1011 ret = usbh_set_interface(iface, bAlternateSetting);
1012 if(ret < 0)
1013 {
1014 UAC_ERRMSG("Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
1015 return ret;
1016 }
1017 }
1018
1019 /*------------------------------------------------------------------------------------*/
1020 /* Select the maximum packet size alternative interface */
1021 /*------------------------------------------------------------------------------------*/
1022 iface = uac->asif_out.iface;
1023
1024 if(iface != NULL)
1025 {
1026 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_OUT, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
1028
1029 ret = usbh_set_interface(iface, bAlternateSetting);
1030 if(ret < 0)
1031 {
1032 UAC_ERRMSG("Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
1033 return ret;
1034 }
1035 }
1036 return 0;
1037}
1038 /* end of group USBH_EXPORTED_FUNCTIONS */
1040 /* end of group USBH_Library */
1042 /* end of group LIBRARY */
1044
1045/*** (C) COPYRIGHT 2020 Nuvoton Technology Corp. ***/
1046
NuMicro peripheral access layer header file.
#define NULL
Definition: M471M_R1_S.h:13908
#define UAC_MICROPHONE
Definition: usbh_uac.h:35
#define USBH_ERR_NOT_ACCESS0
Definition: usbh_lib.h:67
#define UAC_SPEAKER
Definition: usbh_uac.h:34
#define UAC_RET_FUNC_NOT_FOUND
Definition: usbh_lib.h:97
#define UAC_RET_DEV_NOT_FOUND
Definition: usbh_lib.h:96
#define UAC_RET_DEV_NOT_SUPPORTED
Definition: usbh_lib.h:103
#define NUM_UTR
Definition: usbh_uac.h:31
#define USBH_ERR_NOT_FOUND
Definition: usbh_lib.h:38
#define USBH_ERR_NOT_ACCESS1
Definition: usbh_lib.h:68
#define UAC_REQ_TIMEOUT
Definition: usbh_uac.h:32
#define USBH_ERR_MEMORY_OUT
Definition: usbh_lib.h:31
#define UAC_RET_OUT_OF_MEMORY
Definition: usbh_lib.h:101
#define UAC_RET_OK
Definition: usbh_lib.h:95
#define UAC_RET_DATA_LEN
Definition: usbh_lib.h:99
#define UAC_RET_IS_STREAMING
Definition: usbh_lib.h:105
int usbh_uac_stop_audio_out(struct uac_dev_t *audev)
Stop UAC device audio out data stream.
Definition: uac_core.c:944
int usbh_uac_sampling_rate_control(struct uac_dev_t *audev, uint8_t target, uint8_t req, uint32_t *srate)
Set sampling rate frequency.
Definition: uac_core.c:167
int usbh_uac_get_channel_number(struct uac_dev_t *audev, uint8_t target)
Obtain Audio Class device's channel number.
Definition: uac_core.c:42
int usbh_uac_stop_audio_in(struct uac_dev_t *audev)
Stop UAC device audio in data stream.
Definition: uac_core.c:701
int usbh_uac_open(struct uac_dev_t *audev)
Open an connected UAC device.
Definition: uac_core.c:995
int usbh_uac_vol_control(struct uac_dev_t *audev, uint8_t target, uint8_t req, uint16_t chn, uint16_t *volume)
Audio Class device volume control.
Definition: uac_core.c:321
int usbh_uac_start_audio_out(struct uac_dev_t *uac, UAC_CB_FUNC *func)
Start to transmit audio data to UAC device. (Speaker)
Definition: uac_core.c:794
int usbh_uac_get_bit_resolution(struct uac_dev_t *audev, uint8_t target, uint8_t *byte_cnt)
Obtain Audio Class device subframe bit resolution..
Definition: uac_core.c:69
int usbh_uac_auto_gain_control(struct uac_dev_t *audev, uint8_t target, uint8_t req, uint16_t chn, uint8_t *bAGC)
Audio Class device automatic gain control.
Definition: uac_core.c:383
int usbh_uac_get_sampling_rate(struct uac_dev_t *audev, uint8_t target, uint32_t *srate_list, int max_cnt, uint8_t *type)
Get a list of sampling rate frequencies supported by the UAC device.
Definition: uac_core.c:114
int usbh_uac_mute_control(struct uac_dev_t *audev, uint8_t target, uint8_t req, uint16_t chn, uint8_t *mute)
Control Audio Class device mute on/off.
Definition: uac_core.c:238
int usbh_uac_start_audio_in(struct uac_dev_t *uac, UAC_CB_FUNC *func)
Start to receive audio data from UAC device. (Microphone)
Definition: uac_core.c:552
UAC_CB_FUNC * func_au_out
Definition: usbh_uac.h:112
EP_INFO_T * ep
Definition: usbh_uac.h:92
UTR_T * utr[NUM_UTR]
Definition: usbh_uac.h:93
uint8_t mic_fuid
Definition: usbh_uac.h:82
UAC_STATE_E state
Definition: usbh_uac.h:114
IFACE_T * iface
Definition: usbh_uac.h:80
AC_IF_T acif
Definition: usbh_uac.h:108
IFACE_T * iface
Definition: usbh_uac.h:91
AS_IF_T asif_in
Definition: usbh_uac.h:109
uint8_t speaker_fuid
Definition: usbh_uac.h:84
uint8_t flag_streaming
Definition: usbh_uac.h:99
UAC_CB_FUNC * func_au_in
Definition: usbh_uac.h:111
UDEV_T * udev
Definition: usbh_uac.h:107
AS_FT1_T * ft
Definition: usbh_uac.h:97
AS_IF_T asif_out
Definition: usbh_uac.h:110
int() UAC_CB_FUNC(struct uac_dev_t *dev, uint8_t *data, int len)
Definition: usbh_lib.h:126
USB Host Audio Class header file.
USB Host library header file.
USB Host library exported header file.
USB Host UAC class driver header file.