54 return ft->bNrChannels;
81 *byte_cnt = ft->bSubframeSize;
83 return ft->bBitResolution;
89uint32_t srate_to_u32(uint8_t *srate)
91 return (srate[2] << 16) | (srate[1] << 8) | srate[0];
115 int max_cnt, uint8_t *type)
128 *type = ft->bSamFreqType;
135 srate_list[0] = srate_to_u32(&ft->tSamFreq[0][0]);
136 srate_list[1] = srate_to_u32(&ft->tSamFreq[1][0]);
140 for(i = 0; i < *type; i++)
141 srate_list[i] = srate_to_u32(&ft->tSamFreq[i][0]);
170 uint8_t bmRequestType;
171 uint8_t tSampleFreq[3];
183 tSampleFreq[0] = *srate & 0xff;
184 tSampleFreq[1] = (*srate >> 8) & 0xff;
185 tSampleFreq[2] = (*srate >> 16) & 0xff;
188 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_EP;
190 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_EP;
193 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
194 (SAMPLING_FREQ_CONTROL << 8),
195 ep->bEndpointAddress,
205 *srate = srate_to_u32(tSampleFreq);
240 uint8_t bmRequestType;
251 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
253 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
256 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
257 (MUTE_CONTROL << 8) | chn,
258 (bUnitID << 8) | (uac->
acif.
iface->if_num),
323 uint8_t bmRequestType;
334 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
336 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
339 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
340 (VOLUME_CONTROL << 8) | chn,
341 (bUnitID << 8) | (uac->
acif.
iface->if_num),
385 uint8_t bmRequestType;
396 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
398 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
401 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
402 (AUTOMATIC_GAIN_CONTROL << 8) | chn,
403 (bUnitID << 8) | (uac->
acif.
iface->if_num),
429int usbh_uac_find_max_alt(IFACE_T *iface, uint8_t dir, uint8_t attr, uint8_t *bAlternateSetting)
433 uint16_t wMaxPacketSize = 0;
435 for(i = 0; i < iface->num_alt; i++)
437 for(j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
439 ep = &(iface->alt[i].ep[j]);
441 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) != dir) ||
442 ((ep->bmAttributes & EP_ATTR_TT_MASK) != attr))
445 if(ep->wMaxPacketSize > wMaxPacketSize)
448 *bAlternateSetting = i;
449 wMaxPacketSize = ep->wMaxPacketSize;
453 if(wMaxPacketSize == 0)
470int usbh_uac_find_best_alt(IFACE_T *iface, uint8_t dir, uint8_t attr,
int pkt_sz, uint8_t *bAlternateSetting)
474 uint16_t wMaxPacketSize = 0xFFFF;
476 for(i = 0; i < iface->num_alt; i++)
478 for(j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
480 ep = &(iface->alt[i].ep[j]);
482 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) != dir) ||
483 ((ep->bmAttributes & EP_ATTR_TT_MASK) != attr))
486 if((ep->wMaxPacketSize >= pkt_sz) && (ep->wMaxPacketSize < wMaxPacketSize))
489 *bAlternateSetting = i;
490 wMaxPacketSize = ep->wMaxPacketSize;
494 if(wMaxPacketSize == 0xFFFF)
496 UAC_DBGMSG(
"Audio interface %d cannot find endpoint with wMaxPacketSize >= %d!\n", iface->if_num, pkt_sz);
503static void iso_in_irq(UTR_T *utr)
509 if(!uac || !uac->
udev)
517 utr->bIsoNewSched = 0;
519 for(i = 0; i < IF_PER_UTR; i++)
521 if(utr->iso_status[i] == 0)
524 uac->
func_au_in(uac, utr->iso_buff[i], utr->iso_xlen[i]);
528 UAC_DBGMSG(
"Iso %d err - %d\n", i, utr->iso_status[i]);
530 utr->bIsoNewSched = 1;
532 utr->iso_xlen[i] = utr->ep->wMaxPacketSize;
536 ret = usbh_iso_xfer(utr);
538 UAC_DBGMSG(
"usbh_iso_xfer failed!\n");
554 UDEV_T *udev = uac->
udev;
561 uint8_t bAlternateSetting;
573 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_IN, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
578 ret = usbh_set_interface(iface, bAlternateSetting);
581 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
585 ret = uac_parse_streaming_interface(uac, iface, bAlternateSetting);
593 aif = asif->
iface->aif;
594 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
598 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN) &&
599 ((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO))
602 UAC_DBGMSG(
"Audio in endpoint 0x%x found, size: %d\n", ep->bEndpointAddress, ep->wMaxPacketSize);
611 UAC_DBGMSG(
"Activated isochronous-in endpoint =>");
612 usbh_dump_ep_info(ep);
620 asif->
utr[i] = alloc_utr(udev);
628 buff = (uint8_t *)usbh_alloc_mem(ep->wMaxPacketSize * IF_PER_UTR *
NUM_UTR);
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++)
643 utr->iso_xlen[j] = ep->wMaxPacketSize;
644 utr->iso_buff[j] = utr->buff + (ep->wMaxPacketSize * j);
652 asif->
utr[0]->bIsoNewSched = 1;
659 utr->func = iso_in_irq;
660 ret = usbh_iso_xfer(utr);
663 UAC_DBGMSG(
"Error - failed to start UTR %d isochronous-in transfer (%d)", i, ret);
668 uac->
state = UAC_STATE_RUNNING;
677 usbh_quit_utr(asif->
utr[i]);
683 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
688 free_utr(asif->
utr[i]);
709 if(uac->
state != UAC_STATE_DISCONNECTING)
711 ret = usbh_set_interface(asif->
iface, 0);
714 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", asif->
iface->if_num, 0, ret);
721 usbh_quit_utr(asif->
utr[i]);
726 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
731 free_utr(asif->
utr[i]);
735 if(uac->
state != UAC_STATE_DISCONNECTING)
739 uac->
state = UAC_STATE_READY;
749static void iso_out_irq(UTR_T *utr)
755 if(!uac || !uac->
udev)
763 utr->bIsoNewSched = 0;
765 for(i = 0; i < IF_PER_UTR; i++)
767 if(utr->iso_status[i] != 0)
771 utr->bIsoNewSched = 1;
773 utr->iso_xlen[i] = uac->
func_au_out(uac, utr->iso_buff[i], utr->ep->wMaxPacketSize);
777 ret = usbh_iso_xfer(utr);
779 UAC_DBGMSG(
"usbh_iso_xfer failed!\n");
796 UDEV_T *udev = uac->
udev;
803 uint8_t bAlternateSetting;
806 if(!uac || !func || !iface)
815 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_OUT, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
820 ret = usbh_set_interface(iface, bAlternateSetting);
823 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
827 ret = uac_parse_streaming_interface(uac, iface, bAlternateSetting);
835 aif = asif->
iface->aif;
836 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
840 if(((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_OUT) &&
841 ((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO))
844 UAC_DBGMSG(
"Audio in endpoint 0x%x found, size: %d\n", ep->bEndpointAddress, ep->wMaxPacketSize);
853 UAC_DBGMSG(
"Activated isochronous-out endpoint =>");
854 usbh_dump_ep_info(ep);
862 asif->
utr[i] = alloc_utr(udev);
870 buff = (uint8_t *)usbh_alloc_mem(ep->wMaxPacketSize * IF_PER_UTR *
NUM_UTR);
880 asif->
utr[i]->buff = buff + (ep->wMaxPacketSize * IF_PER_UTR * i);
881 asif->
utr[i]->data_len = ep->wMaxPacketSize * IF_PER_UTR;
888 asif->
utr[0]->bIsoNewSched = 1;
895 utr->func = iso_out_irq;
897 for(j = 0; j < IF_PER_UTR; j++)
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);
903 ret = usbh_iso_xfer(utr);
906 UAC_DBGMSG(
"Error - failed to start UTR %d isochronous-in transfer (%d)", i, ret);
911 uac->
state = UAC_STATE_RUNNING;
920 usbh_quit_utr(asif->
utr[i]);
926 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
931 free_utr(asif->
utr[i]);
950 if(uac->
state != UAC_STATE_DISCONNECTING)
952 ret = usbh_set_interface(asif->
iface, 0);
955 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", asif->
iface->if_num, 0, ret);
962 usbh_quit_utr(asif->
utr[i]);
967 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
972 free_utr(asif->
utr[i]);
976 if(uac->
state != UAC_STATE_DISCONNECTING)
980 uac->
state = UAC_STATE_READY;
998 uint8_t bAlternateSetting;
1008 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_IN, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
1011 ret = usbh_set_interface(iface, bAlternateSetting);
1014 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
1026 if(usbh_uac_find_max_alt(iface, EP_ADDR_DIR_OUT, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
1029 ret = usbh_set_interface(iface, bAlternateSetting);
1032 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
NuMicro peripheral access layer header file.
#define USBH_ERR_NOT_ACCESS0
#define UAC_RET_FUNC_NOT_FOUND
#define UAC_RET_DEV_NOT_FOUND
#define UAC_RET_DEV_NOT_SUPPORTED
#define USBH_ERR_NOT_FOUND
#define USBH_ERR_NOT_ACCESS1
#define USBH_ERR_MEMORY_OUT
#define UAC_RET_OUT_OF_MEMORY
#define UAC_RET_IS_STREAMING
int usbh_uac_stop_audio_out(struct uac_dev_t *audev)
Stop UAC device audio out data stream.
int usbh_uac_sampling_rate_control(struct uac_dev_t *audev, uint8_t target, uint8_t req, uint32_t *srate)
Set sampling rate frequency.
int usbh_uac_get_channel_number(struct uac_dev_t *audev, uint8_t target)
Obtain Audio Class device's channel number.
int usbh_uac_stop_audio_in(struct uac_dev_t *audev)
Stop UAC device audio in data stream.
int usbh_uac_open(struct uac_dev_t *audev)
Open an connected UAC device.
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.
int usbh_uac_start_audio_out(struct uac_dev_t *uac, UAC_CB_FUNC *func)
Start to transmit audio data to UAC device. (Speaker)
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..
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.
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.
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.
int usbh_uac_start_audio_in(struct uac_dev_t *uac, UAC_CB_FUNC *func)
Start to receive audio data from UAC device. (Microphone)
UAC_CB_FUNC * func_au_out
int() UAC_CB_FUNC(struct uac_dev_t *dev, uint8_t *data, int len)
USB Host Audio Class header file.
USB Host library header file.
USB Host library exported header file.
USB Host UAC class driver header file.