56 return ft->bNrChannels;
83 *byte_cnt = ft->bSubframeSize;
85 return ft->bBitResolution;
91uint32_t srate_to_u32(uint8_t *srate)
93 return (srate[2] << 16) | (srate[1] << 8) | srate[0];
117 int max_cnt, uint8_t *type)
130 *type = ft->bSamFreqType;
137 srate_list[0] = srate_to_u32(&ft->tSamFreq[0][0]);
138 srate_list[1] = srate_to_u32(&ft->tSamFreq[1][0]);
142 for (i = 0; i < *type; i++)
143 srate_list[i] = srate_to_u32(&ft->tSamFreq[i][0]);
172 uint8_t bmRequestType;
173 uint8_t tSampleFreq[3];
185 tSampleFreq[0] = *srate & 0xff;
186 tSampleFreq[1] = (*srate >> 8) & 0xff;
187 tSampleFreq[2] = (*srate >> 16) & 0xff;
190 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_EP;
192 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_EP;
195 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
196 (SAMPLING_FREQ_CONTROL << 8),
197 ep->bEndpointAddress,
207 *srate = srate_to_u32(tSampleFreq);
242 uint8_t bmRequestType;
253 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
255 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
258 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
259 (MUTE_CONTROL << 8) | chn,
260 (bUnitID << 8) | (uac->
acif.
iface->if_num),
325 uint8_t bmRequestType;
336 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
338 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
341 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
342 (VOLUME_CONTROL << 8) | chn,
343 (bUnitID << 8) | (uac->
acif.
iface->if_num),
387 uint8_t bmRequestType;
398 bmRequestType = REQ_TYPE_IN | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
400 bmRequestType = REQ_TYPE_OUT | REQ_TYPE_CLASS_DEV | REQ_TYPE_TO_IFACE;
403 ret = usbh_ctrl_xfer(uac->
udev, bmRequestType, req,
404 (AUTOMATIC_GAIN_CONTROL << 8) | chn,
405 (bUnitID << 8) | (uac->
acif.
iface->if_num),
431int usbh_uac_find_max_alt(IFACE_T *iface, uint8_t dir, uint8_t attr, uint8_t *bAlternateSetting)
435 uint16_t wMaxPacketSize = 0;
437 for (i = 0; i < iface->num_alt; i++)
439 for (j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
441 ep = &(iface->alt[i].ep[j]);
443 if (((ep->bEndpointAddress & EP_ADDR_DIR_MASK) != dir) ||
444 ((ep->bmAttributes & EP_ATTR_TT_MASK) != attr))
447 if (ep->wMaxPacketSize > wMaxPacketSize)
450 *bAlternateSetting = i;
451 wMaxPacketSize = ep->wMaxPacketSize;
455 if (wMaxPacketSize == 0)
472int usbh_uac_find_best_alt(IFACE_T *iface, uint8_t dir, uint8_t attr,
int pkt_sz, uint8_t *bAlternateSetting)
476 uint16_t wMaxPacketSize = 0xFFFF;
478 for (i = 0; i < iface->num_alt; i++)
480 for (j = 0; j < iface->alt[i].ifd->bNumEndpoints; j++)
482 ep = &(iface->alt[i].ep[j]);
484 if (((ep->bEndpointAddress & EP_ADDR_DIR_MASK) != dir) ||
485 ((ep->bmAttributes & EP_ATTR_TT_MASK) != attr))
488 if ((ep->wMaxPacketSize >= pkt_sz) && (ep->wMaxPacketSize < wMaxPacketSize))
491 *bAlternateSetting = i;
492 wMaxPacketSize = ep->wMaxPacketSize;
496 if (wMaxPacketSize == 0xFFFF)
498 UAC_DBGMSG(
"Audio interface %d cannot find endpoint with wMaxPacketSize >= %d!\n", iface->if_num, pkt_sz);
505static void iso_in_irq(UTR_T *utr)
511 if (!uac || !uac->
udev)
519 utr->bIsoNewSched = 0;
521 for (i = 0; i < IF_PER_UTR; i++)
523 if (utr->iso_status[i] == 0)
526 uac->
func_au_in(uac, utr->iso_buff[i], utr->iso_xlen[i]);
530 UAC_DBGMSG(
"Iso %d err - %d\n", i, utr->iso_status[i]);
532 utr->bIsoNewSched = 1;
534 utr->iso_xlen[i] = utr->ep->wMaxPacketSize;
538 ret = usbh_iso_xfer(utr);
540 UAC_DBGMSG(
"usbh_iso_xfer failed!\n");
556 UDEV_T *udev = uac->
udev;
563 uint8_t bAlternateSetting;
575 if (usbh_uac_find_max_alt(iface, EP_ADDR_DIR_IN, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
580 ret = usbh_set_interface(iface, bAlternateSetting);
583 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
587 ret = uac_parse_streaming_interface(uac, iface, bAlternateSetting);
595 aif = asif->
iface->aif;
596 for (i = 0; i < aif->ifd->bNumEndpoints; i++)
600 if (((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_IN) &&
601 ((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO))
604 UAC_DBGMSG(
"Audio in endpoint 0x%x found, size: %d\n", ep->bEndpointAddress, ep->wMaxPacketSize);
613 UAC_DBGMSG(
"Activated isochronous-in endpoint =>");
614 usbh_dump_ep_info(ep);
622 asif->
utr[i] = alloc_utr(udev);
630 buff = (uint8_t *)usbh_alloc_mem(ep->wMaxPacketSize * IF_PER_UTR *
NUM_UTR);
641 utr->buff = buff + (ep->wMaxPacketSize * IF_PER_UTR * i);
642 utr->data_len = ep->wMaxPacketSize * IF_PER_UTR;
643 for (j = 0; j < IF_PER_UTR; j++)
645 utr->iso_xlen[j] = ep->wMaxPacketSize;
646 utr->iso_buff[j] = utr->buff + (ep->wMaxPacketSize * j);
654 asif->
utr[0]->bIsoNewSched = 1;
661 utr->func = iso_in_irq;
662 ret = usbh_iso_xfer(utr);
665 UAC_DBGMSG(
"Error - failed to start UTR %d isochronous-in transfer (%d)", i, ret);
670 uac->
state = UAC_STATE_RUNNING;
679 usbh_quit_utr(asif->
utr[i]);
685 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
690 free_utr(asif->
utr[i]);
711 if (uac->
state != UAC_STATE_DISCONNECTING)
713 ret = usbh_set_interface(asif->
iface, 0);
716 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", asif->
iface->if_num, 0, ret);
723 usbh_quit_utr(asif->
utr[i]);
728 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
733 free_utr(asif->
utr[i]);
737 if (uac->
state != UAC_STATE_DISCONNECTING)
741 uac->
state = UAC_STATE_READY;
751static void iso_out_irq(UTR_T *utr)
757 if (!uac || !uac->
udev)
765 utr->bIsoNewSched = 0;
767 for (i = 0; i < IF_PER_UTR; i++)
769 if (utr->iso_status[i] != 0)
773 utr->bIsoNewSched = 1;
775 utr->iso_xlen[i] = uac->
func_au_out(uac, utr->iso_buff[i], utr->ep->wMaxPacketSize);
779 ret = usbh_iso_xfer(utr);
781 UAC_DBGMSG(
"usbh_iso_xfer failed!\n");
798 UDEV_T *udev = uac->
udev;
805 uint8_t bAlternateSetting;
808 if (!uac || !func || !iface)
817 if (usbh_uac_find_max_alt(iface, EP_ADDR_DIR_OUT, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
822 ret = usbh_set_interface(iface, bAlternateSetting);
825 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
829 ret = uac_parse_streaming_interface(uac, iface, bAlternateSetting);
837 aif = asif->
iface->aif;
838 for (i = 0; i < aif->ifd->bNumEndpoints; i++)
842 if (((ep->bEndpointAddress & EP_ADDR_DIR_MASK) == EP_ADDR_DIR_OUT) &&
843 ((ep->bmAttributes & EP_ATTR_TT_MASK) == EP_ATTR_TT_ISO))
846 UAC_DBGMSG(
"Audio in endpoint 0x%x found, size: %d\n", ep->bEndpointAddress, ep->wMaxPacketSize);
855 UAC_DBGMSG(
"Activated isochronous-out endpoint =>");
856 usbh_dump_ep_info(ep);
864 asif->
utr[i] = alloc_utr(udev);
872 buff = (uint8_t *)usbh_alloc_mem(ep->wMaxPacketSize * IF_PER_UTR *
NUM_UTR);
882 asif->
utr[i]->buff = buff + (ep->wMaxPacketSize * IF_PER_UTR * i);
883 asif->
utr[i]->data_len = ep->wMaxPacketSize * IF_PER_UTR;
890 asif->
utr[0]->bIsoNewSched = 1;
897 utr->func = iso_out_irq;
899 for (j = 0; j < IF_PER_UTR; j++)
901 utr->iso_buff[j] = utr->buff + (ep->wMaxPacketSize * j);
902 utr->iso_xlen[j] = uac->
func_au_out(uac, utr->iso_buff[j], ep->wMaxPacketSize);
905 ret = usbh_iso_xfer(utr);
908 UAC_DBGMSG(
"Error - failed to start UTR %d isochronous-in transfer (%d)", i, ret);
913 uac->
state = UAC_STATE_RUNNING;
922 usbh_quit_utr(asif->
utr[i]);
928 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
933 free_utr(asif->
utr[i]);
952 if (uac->
state != UAC_STATE_DISCONNECTING)
954 ret = usbh_set_interface(asif->
iface, 0);
957 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", asif->
iface->if_num, 0, ret);
964 usbh_quit_utr(asif->
utr[i]);
969 usbh_free_mem(asif->
utr[0]->buff, asif->
utr[0]->data_len *
NUM_UTR);
974 free_utr(asif->
utr[i]);
978 if (uac->
state != UAC_STATE_DISCONNECTING)
982 uac->
state = UAC_STATE_READY;
1000 uint8_t bAlternateSetting;
1010 if (usbh_uac_find_max_alt(iface, EP_ADDR_DIR_IN, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
1013 ret = usbh_set_interface(iface, bAlternateSetting);
1016 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
1028 if (usbh_uac_find_max_alt(iface, EP_ADDR_DIR_OUT, EP_ATTR_TT_ISO, &bAlternateSetting) != 0)
1031 ret = usbh_set_interface(iface, bAlternateSetting);
1034 UAC_ERRMSG(
"Failed to set interface %d, %d! (%d)\n", iface->if_num, bAlternateSetting, ret);
NuMicro peripheral access layer header file.
#define NULL
NULL pointer.
#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)
M480 MCU USB Host Audio Class header file.
USB Host library header file.
USB Host library exported header file.
USB Host UAC class driver header file.