summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakimisu <[email protected]>2023-06-21 20:43:35 +0800
committersakimisu <[email protected]>2023-06-21 20:43:35 +0800
commit1c7110bd8627b9ad49935a2310edef02f6d8f619 (patch)
treef49cf8a5ff3e3215265f3f65987c7c1a94af41ef
parent48efbfe5219e19f0cac3cc63a119638e2bbb375a (diff)
refactor audio device class
-rw-r--r--cherryusb_config_template.h8
-rw-r--r--class/audio/usbd_audio.c569
-rw-r--r--class/audio/usbd_audio.h26
-rw-r--r--demo/audio_v1_mic_multichan_template.c24
-rw-r--r--demo/audio_v1_mic_speaker_multichan_template.c55
-rw-r--r--demo/audio_v2_mic_multichan_template.c36
-rw-r--r--demo/audio_v2_mic_speaker_multichan_template.c90
-rw-r--r--demo/audio_v2_speaker_multichan_template.c61
8 files changed, 414 insertions, 455 deletions
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_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];
-};
+struct usbd_audio_priv {
+ struct audio_entity_info *table;
+ uint8_t num;
+ uint16_t uac_version;
+} g_usbd_audio;
-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,210 +78,188 @@ 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;
+ if (subtype == 0x01) {
+ USB_LOG_ERR("Do not find subtype for 0x%02x\r\n", entity_id);
+ return -1;
}
- 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;
+ USB_LOG_DBG("Audio entity_id:%02x, subtype:%02x, cs:%02x\r\n", entity_id, subtype, control_selector);
- if (volume < 0x8000) {
- volume2db = 0.00390625 * volume;
- } else if (volume > 0x8000) {
- volume2db = -0.00390625 * (0xffff - volume + 1);
+ 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;
}
-
- 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, &current_feature_control->volume[ch].vol_current, 2);
- *len = 2;
- break;
-
- case AUDIO_REQUEST_GET_MIN:
- memcpy(*data, &current_feature_control->volume[ch].vol_min, 2);
- *len = 2;
- break;
-
- case AUDIO_REQUEST_GET_MAX:
- memcpy(*data, &current_feature_control->volume[ch].vol_max, 2);
- *len = 2;
- break;
-
- case AUDIO_REQUEST_GET_RES:
- memcpy(*data, &current_feature_control->volume[ch].vol_res, 2);
- *len = 2;
- break;
-
- case AUDIO_REQUEST_SET_RES:
- memcpy(&current_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);
+ } 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 (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;
+ 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;
}
- 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 {
+ } 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 control selector 0x%02x\r\n", control_selector);
- return -1;
- }
+ }
+ break;
- 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;
+ 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(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);
+ 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;
- break;
- default:
- USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
- return -1;
- }
- }
-#endif
- else {
- return -1;
+ 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)
+__WEAK void usbd_audio_set_volume(uint8_t ep, uint8_t ch, int volume)
{
- 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 int usbd_audio_get_volume(uint8_t ep, uint8_t ch)
+{
+ return 0;
}
-__WEAK void usbd_audio_set_volume(uint8_t entity_id, uint8_t ch, float dB)
+__WEAK void usbd_audio_set_mute(uint8_t ep, uint8_t ch, bool mute)
{
}
-__WEAK void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable)
+__WEAK bool usbd_audio_get_mute(uint8_t ep, uint8_t ch)
{
+ return 0;
}
-__WEAK void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq)
+__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;
}
-#endif
-__WEAK void usbd_audio_set_pitch(uint8_t ep, bool enable)
+__WEAK void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table)
{
-} \ 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,15 +178,19 @@ static struct usbd_endpoint audio_in_ep = {
struct usbd_interface intf0;
struct usbd_interface intf1;
-void audio_init()
+struct audio_entity_info audio_entity_table[] = {
+ { .bEntityId = AUDIO_IN_FU_ID,
+ .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
+ .ep = AUDIO_IN_EP },
+};
+
+void audio_v1_init(uint8_t busid)
{
- usbd_desc_register(audio_descriptor);
- usbd_add_interface(usbd_audio_init_intf(&intf0));
- usbd_add_interface(usbd_audio_init_intf(&intf1));
+ 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_audio_add_entity(0x02, AUDIO_CONTROL_FEATURE_UNIT);
-
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()
+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 },
+};
+
+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_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_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE);
- usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT);
-
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()
+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 },
+};
+
+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_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_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE);
- usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT);
-
usbd_initialize();
}
-void audio_test()
+void audio_v2_test(void)
{
- while (1) {
- if (rx_flag) {
- }
+ if (rx_flag) {
}
}