diff --git a/cherryusb_config_template.h b/cherryusb_config_template.h index d1567bff..6728a1fa 100644 --- a/cherryusb_config_template.h +++ b/cherryusb_config_template.h @@ -81,14 +81,6 @@ #define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" #endif -#ifndef CONFIG_USBDEV_AUDIO_VERSION -#define CONFIG_USBDEV_AUDIO_VERSION 0x0100 -#endif - -#ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL -#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8 -#endif - #ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE #define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 128 #endif diff --git a/class/audio/usbd_audio.c b/class/audio/usbd_audio.c index b6b3d274..ad7b4c42 100644 --- a/class/audio/usbd_audio.c +++ b/class/audio/usbd_audio.c @@ -6,109 +6,71 @@ #include "usbd_core.h" #include "usbd_audio.h" -#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200 -struct usbd_audio_volume_info { - uint16_t vol_min; - uint16_t vol_max; - uint16_t vol_res; - uint16_t vol_current; +struct audio_entity_param { + uint32_t wCur; + uint32_t wMin; + uint32_t wMax; + uint32_t wRes; }; -struct usbd_audio_attribute_control { - struct usbd_audio_volume_info volume[CONFIG_USBDEV_AUDIO_MAX_CHANNEL]; - uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL]; - uint8_t automatic_gain[CONFIG_USBDEV_AUDIO_MAX_CHANNEL]; -}; -#else -struct audio_v2_control_range2_param_block_default { - uint16_t wNumSubRanges; - struct - { - uint16_t wMin; - uint16_t wMax; - uint16_t wRes; - } subrange[CONFIG_USBDEV_AUDIO_MAX_CHANNEL]; -} __PACKED; +struct usbd_audio_priv { + struct audio_entity_info *table; + uint8_t num; + uint16_t uac_version; +} g_usbd_audio; -struct usbd_audio_attribute_control { - uint32_t volume_bCUR; - uint32_t mute_bCUR; - struct audio_v2_control_range2_param_block_default volume; - uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL]; -}; -#endif -struct audio_entity_info { - usb_slist_t list; - uint8_t bDescriptorSubtype; - uint8_t bEntityId; - void *priv[2]; -}; - -static usb_slist_t usbd_audio_entity_info_head = USB_SLIST_OBJECT_INIT(usbd_audio_entity_info_head); - -#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200 static int audio_class_endpoint_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { uint8_t control_selector; uint32_t sampling_freq = 0; - uint8_t pitch_enable; uint8_t ep; - if ((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_RECIPIENT_ENDPOINT) { - control_selector = HI_BYTE(setup->wValue); - ep = LO_BYTE(setup->wIndex); + control_selector = HI_BYTE(setup->wValue); + ep = LO_BYTE(setup->wIndex); - switch (setup->bRequest) { - case AUDIO_REQUEST_SET_CUR: - switch (control_selector) { - case AUDIO_EP_CONTROL_SAMPLING_FEQ: - memcpy((uint8_t *)&sampling_freq, *data, *len); - USB_LOG_DBG("Set ep:%02x %d Hz\r\n", ep, (int)sampling_freq); - usbd_audio_set_sampling_freq(0, ep, sampling_freq); - break; - case AUDIO_EP_CONTROL_PITCH: - pitch_enable = (*data)[0]; - usbd_audio_set_pitch(ep, pitch_enable); - break; - default: - USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); - return -1; - } - break; - case AUDIO_REQUEST_GET_CUR: - sampling_freq = 16000; - memcpy(*data, &sampling_freq, 4); - *len = 4; - USB_LOG_DBG("Get ep:%02x %d Hz\r\n", ep, (int)sampling_freq); - break; - default: - USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest); - return -1; - } - } else { - return -1; + switch (control_selector) { + case AUDIO_EP_CONTROL_SAMPLING_FEQ: + switch (setup->bRequest) { + case AUDIO_REQUEST_SET_CUR: + memcpy((uint8_t *)&sampling_freq, *data, *len); + USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); + usbd_audio_set_sampling_freq(ep, sampling_freq); + break; + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + sampling_freq = usbd_audio_get_sampling_freq(ep); + memcpy(*data, &sampling_freq, 3); + USB_LOG_DBG("Get ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); + *len = 3; + break; + } + + break; + default: + USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); + return -1; } return 0; } -#endif static int audio_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { - USB_LOG_DBG("AUDIO Class request: " + USB_LOG_DBG("Audio Class request: " "bRequest 0x%02x\r\n", setup->bRequest); - struct audio_entity_info *current_entity_info = NULL; - struct usbd_audio_attribute_control *current_feature_control = NULL; -#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200 - uint32_t *sampling_freq; -#endif - usb_slist_t *i; uint8_t entity_id; + uint8_t ep; + uint8_t subtype = 0x01; uint8_t control_selector; uint8_t ch; uint8_t mute; uint16_t volume; + int volume_db; + uint32_t sampling_freq = 0; + const char *mute_string[2] = { "off", "on" }; entity_id = HI_BYTE(setup->wIndex); @@ -116,211 +78,189 @@ static int audio_class_interface_request_handler(struct usb_setup_packet *setup, ch = LO_BYTE(setup->wValue); ARG_UNUSED(mute_string); - if (ch > (CONFIG_USBDEV_AUDIO_MAX_CHANNEL - 1)) { - return -2; - } - usb_slist_for_each(i, &usbd_audio_entity_info_head) - { - struct audio_entity_info *tmp_entity_info = usb_slist_entry(i, struct audio_entity_info, list); - if (tmp_entity_info->bEntityId == entity_id) { - current_entity_info = tmp_entity_info; + for (uint8_t i = 0; i < g_usbd_audio.num; i++) { + if (g_usbd_audio.table[i].bEntityId == entity_id) { + subtype = g_usbd_audio.table[i].bDescriptorSubtype; + ep = g_usbd_audio.table[i].ep; break; } } - if (current_entity_info == NULL) { - return -2; - } - - current_feature_control = (struct usbd_audio_attribute_control *)current_entity_info->priv[0]; -#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200 - sampling_freq = (uint32_t *)current_entity_info->priv[1]; -#endif - if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) { -#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200 - float volume2db = 0.0; - - switch (control_selector) { - case AUDIO_FU_CONTROL_MUTE: - switch (setup->bRequest) { - case AUDIO_REQUEST_SET_CUR: - mute = (*data)[0]; - current_feature_control->mute[ch] = mute; - USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]); - usbd_audio_set_mute(entity_id, ch, mute); - break; - case AUDIO_REQUEST_GET_CUR: - (*data)[0] = current_feature_control->mute[ch]; - break; - default: - USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest); - return -1; - } - - break; - case AUDIO_FU_CONTROL_VOLUME: - switch (setup->bRequest) { - case AUDIO_REQUEST_SET_CUR: - volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0])); - current_feature_control->volume[ch].vol_current = volume; - - if (volume < 0x8000) { - volume2db = 0.00390625 * volume; - } else if (volume > 0x8000) { - volume2db = -0.00390625 * (0xffff - volume + 1); - } - - USB_LOG_DBG("Set UnitId:%d ch[%d] %0.4f dB\r\n", entity_id, ch, volume2db); - usbd_audio_set_volume(entity_id, ch, volume2db); - break; - case AUDIO_REQUEST_GET_CUR: - memcpy(*data, ¤t_feature_control->volume[ch].vol_current, 2); - *len = 2; - break; - - case AUDIO_REQUEST_GET_MIN: - memcpy(*data, ¤t_feature_control->volume[ch].vol_min, 2); - *len = 2; - break; - - case AUDIO_REQUEST_GET_MAX: - memcpy(*data, ¤t_feature_control->volume[ch].vol_max, 2); - *len = 2; - break; - - case AUDIO_REQUEST_GET_RES: - memcpy(*data, ¤t_feature_control->volume[ch].vol_res, 2); - *len = 2; - break; - - case AUDIO_REQUEST_SET_RES: - memcpy(¤t_feature_control->volume[ch].vol_res, *data, 2); - *len = 2; - break; - default: - USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest); - return -1; - } - break; - default: - USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); - return -1; - } -#else - switch (setup->bRequest) { - case AUDIO_REQUEST_CUR: - switch (control_selector) { - case AUDIO_FU_CONTROL_MUTE: - if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - (*data)[0] = current_feature_control->mute_bCUR; - *len = 1; - } else { - mute = (*data)[0]; - current_feature_control->mute_bCUR = mute; - USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]); - usbd_audio_set_mute(entity_id, ch, mute); - } - break; - case AUDIO_FU_CONTROL_VOLUME: - if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - (*data)[0] = current_feature_control->volume_bCUR & 0XFF; - (*data)[1] = (current_feature_control->volume_bCUR >> 8) & 0xff; - *len = 2; - } else { - volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0])); - current_feature_control->volume_bCUR = volume; - USB_LOG_DBG("Set UnitId:%d ch[%d] %d dB\r\n", entity_id, ch, volume); - usbd_audio_set_volume(entity_id, ch, volume); - } - break; - default: - USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); - return -1; - } - break; - case AUDIO_REQUEST_RANGE: - switch (control_selector) { - case AUDIO_FU_CONTROL_VOLUME: - if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - *((uint16_t *)(*data + 0)) = current_feature_control->volume.wNumSubRanges; - *((uint16_t *)(*data + 2)) = current_feature_control->volume.subrange[ch].wMin; - *((uint16_t *)(*data + 4)) = current_feature_control->volume.subrange[ch].wMax; - *((uint16_t *)(*data + 6)) = current_feature_control->volume.subrange[ch].wRes; - *len = 8; - } else { - } - break; - default: - USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); - return -1; - } - - break; - default: - USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest); - return -1; - } -#endif - } -#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200 - else if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) { - switch (setup->bRequest) { - case AUDIO_REQUEST_CUR: - switch (control_selector) { - case AUDIO_CS_CONTROL_SAM_FREQ: - if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - memcpy(*data, &sampling_freq[ch], sizeof(uint32_t)); - USB_LOG_DBG("Get ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq[ch]); - *len = 4; - } else { - memcpy(&sampling_freq[ch], *data, setup->wLength); - USB_LOG_DBG("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq[ch]); - usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq[ch]); - } - break; - case AUDIO_CS_CONTROL_CLOCK_VALID: - if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - (*data)[0] = 1; - *len = 1; - } else { - } - break; - default: - USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); - return -1; - } - break; - case AUDIO_REQUEST_RANGE: - switch (control_selector) { - case AUDIO_CS_CONTROL_SAM_FREQ: - if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { - uint8_t *sampling_freq_table = NULL; - uint16_t num; - - usbd_audio_get_sampling_freq_table(entity_id, &sampling_freq_table); - num = (uint16_t)((uint16_t)(sampling_freq_table[1] << 8) | ((uint16_t)sampling_freq_table[0])); - memcpy(*data, sampling_freq_table, (12 * num + 2)); - *len = (12 * num + 2); - USB_LOG_DBG("Get sampling_freq_table entity_id:%d ch[%d] addr:%x\r\n", entity_id, ch, (uint32_t)sampling_freq_table); - } else { - } - break; - default: - USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector); - return -1; - } - - break; - default: - USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest); - return -1; - } - } -#endif - else { + if (subtype == 0x01) { + USB_LOG_ERR("Do not find subtype for 0x%02x\r\n", entity_id); return -1; } + + USB_LOG_DBG("Audio entity_id:%02x, subtype:%02x, cs:%02x\r\n", entity_id, subtype, control_selector); + + switch (subtype) { + case AUDIO_CONTROL_FEATURE_UNIT: + switch (control_selector) { + case AUDIO_FU_CONTROL_MUTE: + if (g_usbd_audio.uac_version < 0x0200) { + switch (setup->bRequest) { + case AUDIO_REQUEST_SET_CUR: + mute = (*data)[0]; + usbd_audio_set_mute(ep, ch, mute); + break; + case AUDIO_REQUEST_GET_CUR: + (*data)[0] = usbd_audio_get_mute(ep, ch); + *len = 1; + break; + default: + USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); + return -1; + } + } else { + switch (setup->bRequest) { + case AUDIO_REQUEST_CUR: + if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { + (*data)[0] = usbd_audio_get_mute(ep, ch); + *len = 1; + } else { + mute = (*data)[0]; + usbd_audio_set_mute(ep, ch, mute); + } + break; + default: + //USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); + return -1; + } + } + break; + case AUDIO_FU_CONTROL_VOLUME: + if (g_usbd_audio.uac_version < 0x0200) { + switch (setup->bRequest) { + case AUDIO_REQUEST_SET_CUR: + memcpy(&volume, *data, *len); + if (volume < 0x8000) { + volume_db = volume / 256; + } else if (volume > 0x8000) { + volume_db = (0xffff - volume + 1) / -256; + } + volume_db += 128; /* 0 ~ 255 */ + USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%04x\r\n", ep, ch, volume); + usbd_audio_set_volume(ep, ch, volume_db); + break; + case AUDIO_REQUEST_GET_CUR: + volume_db = usbd_audio_get_volume(ep, ch); + volume_db -= 128; + if (volume_db >= 0) { + volume = volume_db * 256; + } else { + volume = volume_db * 256 + 0xffff + 1; + } + memcpy(*data, &volume, 2); + *len = 2; + break; + case AUDIO_REQUEST_GET_MIN: + (*data)[0] = 0x00; /* -2560/256 dB */ + (*data)[1] = 0xdb; + *len = 2; + break; + case AUDIO_REQUEST_GET_MAX: + (*data)[0] = 0x00; /* 0 dB */ + (*data)[1] = 0x00; + *len = 2; + break; + case AUDIO_REQUEST_GET_RES: + (*data)[0] = 0x00; /* -256/256 dB */ + (*data)[1] = 0x01; + *len = 2; + break; + default: + USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); + return -1; + } + } else { + switch (setup->bRequest) { + case AUDIO_REQUEST_CUR: + if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { + volume_db = usbd_audio_get_volume(ep, ch); + volume = volume_db; + memcpy(*data, &volume, 2); + *len = 2; + } else { + memcpy(&volume, *data, *len); + volume_db = volume; + USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%02x\r\n", ep, ch, volume); + usbd_audio_set_volume(ep, ch, volume_db); + } + break; + case AUDIO_REQUEST_RANGE: + if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { + *((uint16_t *)(*data + 0)) = 1; + *((uint16_t *)(*data + 2)) = 0; + *((uint16_t *)(*data + 4)) = 100; + *((uint16_t *)(*data + 6)) = 1; + *len = 8; + } else { + } + break; + default: + //USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); + return -1; + } + } + break; + + default: + USB_LOG_WRN("Unhandled Audio Class cs 0x%02x \r\n", control_selector); + return -1; + } + break; + case AUDIO_CONTROL_CLOCK_SOURCE: + switch (control_selector) { + case AUDIO_CS_CONTROL_SAM_FREQ: + switch (setup->bRequest) { + case AUDIO_REQUEST_CUR: + if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { + sampling_freq = usbd_audio_get_sampling_freq(ep); + memcpy(*data, &sampling_freq, 4); + USB_LOG_DBG("Get ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); + *len = 4; + } else { + memcpy(&sampling_freq, *data, setup->wLength); + USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); + usbd_audio_set_sampling_freq(ep, sampling_freq); + } + break; + case AUDIO_REQUEST_RANGE: + if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { + uint8_t *sampling_freq_table = NULL; + uint16_t num; + + usbd_audio_get_sampling_freq_table(ep, &sampling_freq_table); + num = (uint16_t)((uint16_t)(sampling_freq_table[1] << 8) | ((uint16_t)sampling_freq_table[0])); + memcpy(*data, sampling_freq_table, (12 * num + 2)); + *len = (12 * num + 2); + } else { + } + break; + default: + //USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector); + return -1; + } + break; + case AUDIO_CS_CONTROL_CLOCK_VALID: + if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { + (*data)[0] = 1; + *len = 1; + } else { + return -1; + } + break; + + default: + //USB_LOG_WRN("Unhandled Audio Class cs 0x%02x \r\n", control_selector); + return -1; + } + break; + + default: + break; + } return 0; } @@ -333,7 +273,7 @@ static void audio_notify_handler(uint8_t event, void *arg) case USBD_EVENT_SET_INTERFACE: { struct usb_interface_descriptor *intf = (struct usb_interface_descriptor *)arg; - if (intf->bAlternateSetting == 1) { + if (intf->bAlternateSetting) { usbd_audio_open(intf->bInterfaceNumber); } else { usbd_audio_close(intf->bInterfaceNumber); @@ -347,86 +287,57 @@ static void audio_notify_handler(uint8_t event, void *arg) } } -struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf) +struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf, + uint16_t uac_version, + struct audio_entity_info *table, + uint8_t num) { - intf->class_interface_handler = audio_class_interface_request_handler; -#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200 - intf->class_endpoint_handler = audio_class_endpoint_request_handler; -#else - intf->class_endpoint_handler = NULL; -#endif - intf->vendor_handler = NULL; - intf->notify_handler = audio_notify_handler; + if (uac_version < 0x0200) { + intf->class_interface_handler = audio_class_interface_request_handler; + intf->class_endpoint_handler = audio_class_endpoint_request_handler; + intf->vendor_handler = NULL; + intf->notify_handler = audio_notify_handler; + } else { + intf->class_interface_handler = audio_class_interface_request_handler; + intf->class_endpoint_handler = NULL; + intf->vendor_handler = NULL; + intf->notify_handler = audio_notify_handler; + } + + g_usbd_audio.uac_version = uac_version; + g_usbd_audio.table = table; + g_usbd_audio.num = num; return intf; } -void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype) -{ - struct audio_entity_info *entity_info = usb_malloc(sizeof(struct audio_entity_info)); - memset(entity_info, 0, sizeof(struct audio_entity_info)); - entity_info->bEntityId = entity_id; - entity_info->bDescriptorSubtype = bDescriptorSubtype; - - if (bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) { -#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200 - struct usbd_audio_attribute_control *control = usb_malloc(sizeof(struct usbd_audio_attribute_control)); - memset(control, 0, sizeof(struct usbd_audio_attribute_control)); - for (uint8_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) { - control->volume[ch].vol_min = 0xdb00; - control->volume[ch].vol_max = 0x0000; - control->volume[ch].vol_res = 0x0100; - control->volume[ch].vol_current = 0xf600; - control->mute[ch] = 0; - control->automatic_gain[ch] = 0; - } -#else - struct usbd_audio_attribute_control *control = usb_malloc(sizeof(struct usbd_audio_attribute_control)); - memset(control, 0, sizeof(struct usbd_audio_attribute_control)); - for (uint8_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) { - control->volume.wNumSubRanges = 1; - control->volume.subrange[ch].wMin = 0; - control->volume.subrange[ch].wMax = 100; - control->volume.subrange[ch].wRes = 1; - control->mute[ch] = 0; - control->volume_bCUR = 0; - control->mute_bCUR = 0; - } -#endif - entity_info->priv[0] = control; - } else if (bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) { -#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200 - uint32_t *sampling_freq = usb_malloc(sizeof(uint32_t) * CONFIG_USBDEV_AUDIO_MAX_CHANNEL); - for (size_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) { - sampling_freq[ch] = 16000; - } - entity_info->priv[1] = sampling_freq; -#else - entity_info->priv[1] = NULL; -#endif - } - - usb_slist_add_tail(&usbd_audio_entity_info_head, &entity_info->list); -} - -__WEAK void usbd_audio_set_volume(uint8_t entity_id, uint8_t ch, float dB) +__WEAK void usbd_audio_set_volume(uint8_t ep, uint8_t ch, int volume) { } -__WEAK void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable) +__WEAK int usbd_audio_get_volume(uint8_t ep, uint8_t ch) +{ + return 0; +} + +__WEAK void usbd_audio_set_mute(uint8_t ep, uint8_t ch, bool mute) { } -__WEAK void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq) +__WEAK bool usbd_audio_get_mute(uint8_t ep, uint8_t ch) +{ + return 0; +} + +__WEAK void usbd_audio_set_sampling_freq(uint8_t ep, uint32_t sampling_freq) { } -#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200 -__WEAK void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table) +__WEAK uint32_t usbd_audio_get_sampling_freq(uint8_t ep) +{ + return 0; +} + +__WEAK void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table) { } -#endif - -__WEAK void usbd_audio_set_pitch(uint8_t ep, bool enable) -{ -} \ No newline at end of file diff --git a/class/audio/usbd_audio.h b/class/audio/usbd_audio.h index 420e88ce..94fe07f5 100644 --- a/class/audio/usbd_audio.h +++ b/class/audio/usbd_audio.h @@ -12,17 +12,29 @@ extern "C" { #endif +struct audio_entity_info { + uint8_t bDescriptorSubtype; + uint8_t bEntityId; + uint8_t ep; +}; + /* Init audio interface driver */ -struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf); +struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf, + uint16_t uac_version, + struct audio_entity_info *table, + uint8_t num); void usbd_audio_open(uint8_t intf); void usbd_audio_close(uint8_t intf); -void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype); -void usbd_audio_set_volume(uint8_t entity_id, uint8_t ch, float dB); -void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable); -void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq); -void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table); -void usbd_audio_set_pitch(uint8_t ep, bool enable); + +void usbd_audio_set_volume(uint8_t ep, uint8_t ch, int volume); +int usbd_audio_get_volume(uint8_t ep, uint8_t ch); +void usbd_audio_set_mute(uint8_t ep, uint8_t ch, bool mute); +bool usbd_audio_get_mute(uint8_t ep, uint8_t ch); +void usbd_audio_set_sampling_freq(uint8_t ep, uint32_t sampling_freq); +uint32_t usbd_audio_get_sampling_freq(uint8_t ep); + +void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table); #ifdef __cplusplus } diff --git a/demo/audio_v1_mic_multichan_template.c b/demo/audio_v1_mic_multichan_template.c index eee29f4f..7ab10ca6 100644 --- a/demo/audio_v1_mic_multichan_template.c +++ b/demo/audio_v1_mic_multichan_template.c @@ -14,6 +14,8 @@ #define AUDIO_IN_EP 0x81 +#define AUDIO_IN_FU_ID 0x02 + /* AUDIO Class Config */ #define AUDIO_FREQ 16000U @@ -61,13 +63,13 @@ AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \ AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -const uint8_t audio_descriptor[] = { +const uint8_t audio_v1_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01), AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE), - AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, INPUT_CTRL), - AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02), + AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL), + AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID), AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)), /////////////////////////////////////// /// string0 descriptor @@ -176,14 +178,18 @@ static struct usbd_endpoint audio_in_ep = { struct usbd_interface intf0; struct usbd_interface intf1; -void audio_init() -{ - usbd_desc_register(audio_descriptor); - usbd_add_interface(usbd_audio_init_intf(&intf0)); - usbd_add_interface(usbd_audio_init_intf(&intf1)); - usbd_add_endpoint(&audio_in_ep); +struct audio_entity_info audio_entity_table[] = { + { .bEntityId = AUDIO_IN_FU_ID, + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, + .ep = AUDIO_IN_EP }, +}; - usbd_audio_add_entity(0x02, AUDIO_CONTROL_FEATURE_UNIT); +void audio_v1_init(uint8_t busid) +{ + usbd_desc_register(audio_v1_descriptor); + usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0100, audio_entity_table, 1)); + usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0100, audio_entity_table, 1)); + usbd_add_endpoint(&audio_in_ep); usbd_initialize(); } diff --git a/demo/audio_v1_mic_speaker_multichan_template.c b/demo/audio_v1_mic_speaker_multichan_template.c index 2e6ae3bf..eb28fba7 100644 --- a/demo/audio_v1_mic_speaker_multichan_template.c +++ b/demo/audio_v1_mic_speaker_multichan_template.c @@ -15,6 +15,9 @@ #define AUDIO_IN_EP 0x81 #define AUDIO_OUT_EP 0x02 +#define AUDIO_IN_FU_ID 0x02 +#define AUDIO_OUT_FU_ID 0x05 + /* AUDIO Class Config */ #define AUDIO_SPEAKER_FREQ 16000U #define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u @@ -49,7 +52,7 @@ AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \ AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -const uint8_t audio_descriptor[] = { +const uint8_t audio_v1_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01), USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02), @@ -59,9 +62,9 @@ const uint8_t audio_descriptor[] = { AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003), AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00), AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05), - AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,\ + AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)), - AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,\ + AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)), /////////////////////////////////////// /// string0 descriptor @@ -137,8 +140,8 @@ const uint8_t audio_descriptor[] = { 0x00 }; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET]; volatile bool tx_flag = 0; volatile bool rx_flag = 0; @@ -148,7 +151,7 @@ void usbd_audio_open(uint8_t intf) if (intf == 1) { rx_flag = 1; /* setup first out ep read transfer */ - usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET); + usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET); printf("OPEN1\r\n"); } else { tx_flag = 1; @@ -175,7 +178,7 @@ void usbd_configure_done_callback(void) void usbd_audio_out_callback(uint8_t ep, uint32_t nbytes) { USB_LOG_RAW("actual out len:%d\r\n", nbytes); - usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET); + usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET); } void usbd_audio_in_callback(uint8_t ep, uint32_t nbytes) @@ -198,32 +201,36 @@ struct usbd_interface intf0; struct usbd_interface intf1; struct usbd_interface intf2; -void audio_init() +struct audio_entity_info audio_entity_table[] = { + { .bEntityId = AUDIO_IN_FU_ID, + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, + .ep = AUDIO_IN_EP }, + { .bEntityId = AUDIO_OUT_FU_ID, + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, + .ep = AUDIO_OUT_EP }, +}; + +void audio_v1_init(void) { - usbd_desc_register(audio_descriptor); - usbd_add_interface(usbd_audio_init_intf(&intf0)); - usbd_add_interface(usbd_audio_init_intf(&intf1)); - usbd_add_interface(usbd_audio_init_intf(&intf2)); + usbd_desc_register(audio_v1_descriptor); + usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0100, audio_entity_table, 2)); + usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0100, audio_entity_table, 2)); + usbd_add_interface(usbd_audio_init_intf(&intf2, 0x0100, audio_entity_table, 2)); usbd_add_endpoint(&audio_in_ep); usbd_add_endpoint(&audio_out_ep); - usbd_audio_add_entity(0x02, AUDIO_CONTROL_FEATURE_UNIT); - usbd_audio_add_entity(0x05, AUDIO_CONTROL_FEATURE_UNIT); - usbd_initialize(); } -void audio_test() +void audio_v1_test(void) { - while (1) { - if (tx_flag) { - memset(write_buffer, 'a', AUDIO_IN_PACKET); - ep_tx_busy_flag = true; - usbd_ep_start_write(AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET); - while (ep_tx_busy_flag) { - if (tx_flag == false) { - break; - } + if (tx_flag) { + memset(write_buffer, 'a', AUDIO_IN_PACKET); + ep_tx_busy_flag = true; + usbd_ep_start_write(AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET); + while (ep_tx_busy_flag) { + if (tx_flag == false) { + break; } } } diff --git a/demo/audio_v2_mic_multichan_template.c b/demo/audio_v2_mic_multichan_template.c index 9b3a158c..d6533a21 100644 --- a/demo/audio_v2_mic_multichan_template.c +++ b/demo/audio_v2_mic_multichan_template.c @@ -14,6 +14,9 @@ #define AUDIO_IN_EP 0x81 +#define AUDIO_IN_CLOCK_ID 0x01 +#define AUDIO_IN_FU_ID 0x03 + #define AUDIO_FREQ 48000 #define HALF_WORD_BYTES 2 //2 half word (one channel) #define SAMPLE_BITS 16 //16 bit per channel @@ -50,7 +53,6 @@ #define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000)) - #define USB_AUDIO_CONFIG_DESC_SIZ (9 + \ AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \ AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ @@ -65,7 +67,7 @@ AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -const uint8_t audio_descriptor[] = { +const uint8_t audio_v2_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01), USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00), @@ -168,9 +170,9 @@ void usbd_audio_close(uint8_t intf) tx_flag = 0; } -void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table) +void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table) { - if (entity_id == 0x01) { + if (ep == AUDIO_IN_EP) { *sampling_freq_table = (uint8_t *)mic_default_sampling_freq_table; } } @@ -192,23 +194,27 @@ static struct usbd_endpoint audio_in_ep = { struct usbd_interface intf0; struct usbd_interface intf1; -void audio_init() -{ - usbd_desc_register(audio_descriptor); - usbd_add_interface(usbd_audio_init_intf(&intf0)); - usbd_add_interface(usbd_audio_init_intf(&intf1)); - usbd_add_endpoint(&audio_in_ep); +struct audio_entity_info audio_entity_table[] = { + { .bEntityId = AUDIO_IN_CLOCK_ID, + .bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE, + .ep = AUDIO_IN_EP }, + { .bEntityId = AUDIO_IN_FU_ID, + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, + .ep = AUDIO_IN_EP }, +}; - usbd_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE); - usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT); +void audio_v2_init(void) +{ + usbd_desc_register(audio_v2_descriptor); + usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0200, audio_entity_table, 2)); + usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0200, audio_entity_table, 2)); + usbd_add_endpoint(&audio_in_ep); usbd_initialize(); } -void audio_test() +void audio_v2_test(void) { - while (1) { - if (tx_flag) { - } + if (tx_flag) { } } diff --git a/demo/audio_v2_mic_speaker_multichan_template.c b/demo/audio_v2_mic_speaker_multichan_template.c index 62d72f3b..2701d1e8 100644 --- a/demo/audio_v2_mic_speaker_multichan_template.c +++ b/demo/audio_v2_mic_speaker_multichan_template.c @@ -15,6 +15,11 @@ #define AUDIO_OUT_EP 0x02 #define AUDIO_IN_EP 0x81 +#define AUDIO_OUT_CLOCK_ID 0x01 +#define AUDIO_OUT_FU_ID 0x03 +#define AUDIO_IN_CLOCK_ID 0x05 +#define AUDIO_IN_FU_ID 0x07 + #define AUDIO_FREQ 48000 #define HALF_WORD_BYTES 2 //2 half word (one channel) #define SAMPLE_BITS 16 //16 bit per channel @@ -49,36 +54,34 @@ #define INPUT_CH_ENABLE 0x000000ff #endif - #define OUT_CHANNEL_NUM 2 #if OUT_CHANNEL_NUM == 1 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000000 #elif OUT_CHANNEL_NUM == 2 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000003 #elif OUT_CHANNEL_NUM == 3 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000007 #elif OUT_CHANNEL_NUM == 4 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000000f #elif OUT_CHANNEL_NUM == 5 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000001f #elif OUT_CHANNEL_NUM == 6 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000003F #elif OUT_CHANNEL_NUM == 7 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000007f #elif OUT_CHANNEL_NUM == 8 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x000000ff #endif - /* AudioFreq * DataSize (2 bytes) * NumChannels */ #define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000)) #define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000)) @@ -106,7 +109,7 @@ AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -uint8_t audio_descriptor[] = { +uint8_t audio_v2_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01), USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00), @@ -220,7 +223,8 @@ static const uint8_t mic_default_sampling_freq_table[] = { AUDIO_SAMPLE_FREQ_4B(0x00) }; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET]; volatile bool tx_flag = 0; volatile bool rx_flag = 0; @@ -230,7 +234,7 @@ void usbd_audio_open(uint8_t intf) if (intf == 1) { rx_flag = 1; /* setup first out ep read transfer */ - usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET); + usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET); USB_LOG_RAW("OPEN1\r\n"); } else { tx_flag = 1; @@ -248,27 +252,27 @@ void usbd_audio_close(uint8_t intf) } } -void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table) +void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table) { - if (entity_id == 0x01) { + if (ep == AUDIO_OUT_EP) { *sampling_freq_table = (uint8_t *)speaker_default_sampling_freq_table; - } else if (entity_id == 0x05) { + } else if (ep == AUDIO_IN_EP) { *sampling_freq_table = (uint8_t *)mic_default_sampling_freq_table; } else { } } -void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq) +void usbd_audio_set_sampling_freq(uint8_t ep, uint32_t sampling_freq) { uint16_t packet_size = 0; - if (entity_id == 1) { + if (ep == AUDIO_OUT_EP) { packet_size = ((sampling_freq * 2 * OUT_CHANNEL_NUM) / 1000); - audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 11] = packet_size; - audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 10] = packet_size >> 8; - } else if (entity_id == 5) { + audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 11] = packet_size; + audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 10] = packet_size >> 8; + } else if (ep == AUDIO_IN_EP) { packet_size = ((sampling_freq * 2 * IN_CHANNEL_NUM) / 1000); - audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 11] = packet_size; - audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 10] = packet_size >> 8; + audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 11] = packet_size; + audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 10] = packet_size >> 8; } } @@ -278,6 +282,8 @@ void usbd_configure_done_callback(void) void usbd_audio_iso_out_callback(uint8_t ep, uint32_t nbytes) { + USB_LOG_RAW("actual out len:%d\r\n", nbytes); + usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET); } void usbd_audio_iso_in_callback(uint8_t ep, uint32_t nbytes) @@ -298,27 +304,37 @@ struct usbd_interface intf0; struct usbd_interface intf1; struct usbd_interface intf2; -void audio_init() +struct audio_entity_info audio_entity_table[] = { + { .bEntityId = AUDIO_OUT_CLOCK_ID, + .bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE, + .ep = AUDIO_OUT_EP }, + { .bEntityId = AUDIO_OUT_FU_ID, + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, + .ep = AUDIO_OUT_EP }, + { .bEntityId = AUDIO_IN_CLOCK_ID, + .bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE, + .ep = AUDIO_IN_EP }, + { .bEntityId = AUDIO_IN_FU_ID, + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, + .ep = AUDIO_IN_EP }, +}; + +void audio_v2_init(void) { - usbd_desc_register(audio_descriptor); - usbd_add_interface(usbd_audio_init_intf(&intf0)); - usbd_add_interface(usbd_audio_init_intf(&intf1)); - usbd_add_interface(usbd_audio_init_intf(&intf2)); + usbd_desc_register(audio_v2_descriptor); + usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0200, audio_entity_table, 4)); + usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0200, audio_entity_table, 4)); + usbd_add_interface(usbd_audio_init_intf(&intf2, 0x0200, audio_entity_table, 4)); usbd_add_endpoint(&audio_in_ep); usbd_add_endpoint(&audio_out_ep); - usbd_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE); - usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT); - usbd_audio_add_entity(0x05, AUDIO_CONTROL_CLOCK_SOURCE); - usbd_audio_add_entity(0x07, AUDIO_CONTROL_FEATURE_UNIT); - usbd_initialize(); } -void audio_test() +void audio_v2_test(void) { - while (1) { - if (tx_flag) { - } + if (tx_flag) { + } + if (rx_flag) { } } diff --git a/demo/audio_v2_speaker_multichan_template.c b/demo/audio_v2_speaker_multichan_template.c index d2016dea..54ae38ff 100644 --- a/demo/audio_v2_speaker_multichan_template.c +++ b/demo/audio_v2_speaker_multichan_template.c @@ -14,6 +14,9 @@ #define AUDIO_OUT_EP 0x01 +#define AUDIO_OUT_CLOCK_ID 0x01 +#define AUDIO_OUT_FU_ID 0x03 + #define AUDIO_FREQ 48000 #define HALF_WORD_BYTES 2 //2 half word (one channel) #define SAMPLE_BITS 16 //16 bit per channel @@ -23,28 +26,28 @@ #define OUT_CHANNEL_NUM 2 #if OUT_CHANNEL_NUM == 1 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000000 #elif OUT_CHANNEL_NUM == 2 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000003 #elif OUT_CHANNEL_NUM == 3 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x00000007 #elif OUT_CHANNEL_NUM == 4 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000000f #elif OUT_CHANNEL_NUM == 5 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000001f #elif OUT_CHANNEL_NUM == 6 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000003F #elif OUT_CHANNEL_NUM == 7 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x0000007f #elif OUT_CHANNEL_NUM == 8 -#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) +#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL) #define OUTPUT_CH_ENABLE 0x000000ff #endif @@ -64,13 +67,13 @@ AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC) -const uint8_t audio_descriptor[] = { +const uint8_t audio_v2_descriptor[] = { USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01), USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00), - AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03), + AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03), AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000), - AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL), + AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL), AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000), AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL), /////////////////////////////////////// @@ -166,7 +169,7 @@ static const uint8_t default_sampling_freq_table[] = { AUDIO_SAMPLE_FREQ_4B(0x00), }; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET]; volatile bool rx_flag = 0; @@ -174,7 +177,7 @@ void usbd_audio_open(uint8_t intf) { rx_flag = 1; /* setup first out ep read transfer */ - usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET); + usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET); USB_LOG_RAW("OPEN\r\n"); } void usbd_audio_close(uint8_t intf) @@ -183,9 +186,9 @@ void usbd_audio_close(uint8_t intf) rx_flag = 0; } -void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table) +void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table) { - if (entity_id == 0x01) { + if (ep == AUDIO_OUT_EP) { *sampling_freq_table = (uint8_t *)default_sampling_freq_table; } } @@ -196,6 +199,8 @@ void usbd_configure_done_callback(void) void usbd_audio_iso_out_callback(uint8_t ep, uint32_t nbytes) { + USB_LOG_RAW("actual out len:%d\r\n", nbytes); + usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET); } static struct usbd_endpoint audio_out_ep = { @@ -206,23 +211,27 @@ static struct usbd_endpoint audio_out_ep = { struct usbd_interface intf0; struct usbd_interface intf1; -void audio_init() -{ - usbd_desc_register(audio_descriptor); - usbd_add_interface(usbd_audio_init_intf(&intf0)); - usbd_add_interface(usbd_audio_init_intf(&intf1)); - usbd_add_endpoint(&audio_out_ep); +struct audio_entity_info audio_entity_table[] = { + { .bEntityId = AUDIO_OUT_CLOCK_ID, + .bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE, + .ep = AUDIO_OUT_EP }, + { .bEntityId = AUDIO_OUT_FU_ID, + .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT, + .ep = AUDIO_OUT_EP }, +}; - usbd_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE); - usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT); +void audio_v2_init(void) +{ + usbd_desc_register(audio_v2_descriptor); + usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0200, audio_entity_table, 2)); + usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0200, audio_entity_table, 2)); + usbd_add_endpoint(&audio_out_ep); usbd_initialize(); } -void audio_test() +void audio_v2_test(void) { - while (1) { - if (rx_flag) { - } + if (rx_flag) { } }