diff --git a/class/audio/usbd_audio.c b/class/audio/usbd_audio.c index 96a352ce..df177220 100644 --- a/class/audio/usbd_audio.c +++ b/class/audio/usbd_audio.c @@ -109,8 +109,8 @@ static int audio_custom_request_handler(struct usb_setup_packet *setup, uint8_t switch (control_selector) { case AUDIO_EP_CONTROL_SAMPLING_FEQ: memcpy((uint8_t *)&sampling_freq, *data, *len); - USB_LOG_INFO("Set ep %02x %d Hz\r\n", ep, (int)sampling_freq); - usbd_audio_set_sampling_freq(ep, sampling_freq); + USB_LOG_INFO("Set ep:%02x %d Hz\r\n", ep, (int)sampling_freq); + usbd_audio_set_sampling_freq(0, ep, sampling_freq); return 0; case AUDIO_EP_CONTROL_PITCH: pitch_enable = (*data)[0]; @@ -179,8 +179,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * case AUDIO_REQUEST_SET_CUR: mute = (*data)[0]; current_control->mute[ch] = mute; - USB_LOG_INFO("Set ch[%d] mute %s\r\n", ch, mute_string[mute]); - usbd_audio_set_mute(ch, mute); + USB_LOG_INFO("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_control->mute[ch]; @@ -203,8 +203,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * volume2db = -0.00390625 * (0xffff - volume + 1); } - USB_LOG_INFO("Set ch[%d] %0.4f dB\r\n", ch, volume2db); - usbd_audio_set_volume(ch, volume2db); + USB_LOG_INFO("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_control->volume[ch].vol_current, 2); @@ -244,8 +244,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * *len = 1; } else { mute = (*data)[0]; - USB_LOG_INFO("Set ch[%d] mute %s\r\n", ch, mute_string[mute]); - usbd_audio_set_mute(ch, mute); + USB_LOG_INFO("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: @@ -256,8 +256,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * } else { volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0])); current_control->volume_bCUR = volume; - USB_LOG_INFO("Set ch[%d] %d dB\r\n", ch, volume); - usbd_audio_set_volume(ch, volume); + USB_LOG_INFO("Set UnitId:%d ch[%d] %d dB\r\n", entity_id, ch, volume); + usbd_audio_set_volume(entity_id, ch, volume); } break; default: @@ -303,8 +303,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * uint32_t sampling_freq; memcpy(&sampling_freq, *data, setup->wLength); current_control->sampling_freq[ch] = sampling_freq; - USB_LOG_INFO("Set ch[%d] %d Hz\r\n", ch, (int)sampling_freq); - usbd_audio_set_sampling_freq(ch, sampling_freq); + USB_LOG_INFO("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq); + usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq); } break; case AUDIO_CS_CONTROL_CLOCK_VALID: @@ -326,7 +326,7 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t * uint8_t *sampling_freq_table = NULL; uint16_t num; - usbd_audio_get_sampling_freq_table(&sampling_freq_table); + 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])); *data = sampling_freq_table; *len = (12 * num + 2); @@ -397,14 +397,14 @@ void usbd_audio_add_interface(usbd_class_t *devclass, usbd_interface_t *intf) void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype) { - struct audio_entity_info *entity_info = malloc(sizeof(struct audio_entity_info)); + 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 = malloc(sizeof(struct usbd_audio_attribute_control)); + 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; @@ -435,19 +435,19 @@ void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype) usb_slist_add_tail(&usbd_audio_entity_info_head, &entity_info->list); } -__WEAK void usbd_audio_set_volume(uint8_t ch, float dB) +__WEAK void usbd_audio_set_volume(uint8_t entity_id, uint8_t ch, float dB) { } -__WEAK void usbd_audio_set_mute(uint8_t ch, uint8_t enable) +__WEAK void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable) { } -__WEAK void usbd_audio_set_sampling_freq(uint8_t ep_ch, uint32_t sampling_freq) +__WEAK void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq) { } -__WEAK void usbd_audio_get_sampling_freq_table(uint8_t **sampling_freq_table) +__WEAK void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table) { *sampling_freq_table = (uint8_t *)default_sampling_freq_table; } diff --git a/class/audio/usbd_audio.h b/class/audio/usbd_audio.h index 42a4614d..2735db26 100644 --- a/class/audio/usbd_audio.h +++ b/class/audio/usbd_audio.h @@ -34,10 +34,10 @@ void usbd_audio_add_interface(usbd_class_t *devclass, usbd_interface_t *intf); 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 ch, float dB); -void usbd_audio_set_mute(uint8_t ch, uint8_t enable); -void usbd_audio_set_sampling_freq(uint8_t ep_ch, uint32_t sampling_freq); -void usbd_audio_get_sampling_freq_table(uint8_t **sampling_freq_table); +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_sof_callback(void); diff --git a/demo/audio_v2_mic_dualchan_template.c b/demo/audio_v2_mic_dualchan_template.c index 9f6bf8c7..4abe8c7b 100644 --- a/demo/audio_v2_mic_dualchan_template.c +++ b/demo/audio_v2_mic_dualchan_template.c @@ -15,14 +15,11 @@ #define AUDIO_IN_EP 0x01 #define AUDIO_FREQ 96000 -/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */ -/* 16bit(2 Bytes) 双声道(Mono:2) */ - -#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * 2 * 2) / 1000)) - #define HALF_WORD_BYTES 2 //2 half word (one channel) #define SAMPLE_BITS 16 //16 bit per channel +#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * 2 * HALF_WORD_BYTES) / 1000)) + #define CHANNEL_NUM 2 #define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME) diff --git a/demo/audio_v2_mic_speaker_multichan_template.c b/demo/audio_v2_mic_speaker_multichan_template.c new file mode 100644 index 00000000..6b292907 --- /dev/null +++ b/demo/audio_v2_mic_speaker_multichan_template.c @@ -0,0 +1,210 @@ +#include "usbd_core.h" +#include "usbd_audio.h" + +#define USBD_VID 0xffff +#define USBD_PID 0xffff +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +#ifdef CONFIG_USB_HS +#define EP_INTERVAL 0x04 +#else +#define EP_INTERVAL 0x01 +#endif + +#define AUDIO_OUT_EP 0x02 +#define AUDIO_IN_EP 0x81 + +#define AUDIO_FREQ 96000 +#define HALF_WORD_BYTES 2 //2 half word (one channel) +#define SAMPLE_BITS 16 //16 bit per channel + +#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * 2 * HALF_WORD_BYTES) / 1000)) +#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * 2 * HALF_WORD_BYTES) / 1000)) + +#if 1 +#define OUT_CHANNEL_NUM 2 +#define IN_CHANNEL_NUM 2 +#define INPUT_CTRL DBVAL(BMCONTROL),DBVAL(BMCONTROL) +#define INPUT_CH_ENABLE 0x00000003 +#else +#define OUT_CHANNEL_NUM 2 +#define IN_CHANNEL_NUM 6 +#define INPUT_CTRL DBVAL(BMCONTROL),DBVAL(BMCONTROL),DBVAL(BMCONTROL),DBVAL(BMCONTROL),DBVAL(BMCONTROL),DBVAL(BMCONTROL) +#define INPUT_CH_ENABLE 0x0000001F +#endif + +#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME) + +#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \ + AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_AS_DESCRIPTOR_INIT_LEN + \ + AUDIO_V2_AS_DESCRIPTOR_INIT_LEN) + +#define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \ + AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \ + AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \ + AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC) + +const uint8_t audio_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), + AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03), + AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, 0x00000003, 0x0000), + AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, DBVAL(BMCONTROL), DBVAL(BMCONTROL)), + AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000), + AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03), + AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000), + AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL), + AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000), + AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, 0x00000003, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL), + AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, AUDIO_IN_PACKET, EP_INTERVAL), + /////////////////////////////////////// + /// string0 descriptor + /////////////////////////////////////// + USB_LANGID_INIT(USBD_LANGID_STRING), + /////////////////////////////////////// + /// string1 descriptor + /////////////////////////////////////// + 0x14, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'C', 0x00, /* wcChar0 */ + 'h', 0x00, /* wcChar1 */ + 'e', 0x00, /* wcChar2 */ + 'r', 0x00, /* wcChar3 */ + 'r', 0x00, /* wcChar4 */ + 'y', 0x00, /* wcChar5 */ + 'U', 0x00, /* wcChar6 */ + 'S', 0x00, /* wcChar7 */ + 'B', 0x00, /* wcChar8 */ + /////////////////////////////////////// + /// string2 descriptor + /////////////////////////////////////// + 0x26, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'C', 0x00, /* wcChar0 */ + 'h', 0x00, /* wcChar1 */ + 'e', 0x00, /* wcChar2 */ + 'r', 0x00, /* wcChar3 */ + 'r', 0x00, /* wcChar4 */ + 'y', 0x00, /* wcChar5 */ + 'U', 0x00, /* wcChar6 */ + 'S', 0x00, /* wcChar7 */ + 'B', 0x00, /* wcChar8 */ + ' ', 0x00, /* wcChar9 */ + 'U', 0x00, /* wcChar10 */ + 'A', 0x00, /* wcChar11 */ + 'C', 0x00, /* wcChar12 */ + ' ', 0x00, /* wcChar13 */ + 'D', 0x00, /* wcChar14 */ + 'E', 0x00, /* wcChar15 */ + 'M', 0x00, /* wcChar16 */ + 'O', 0x00, /* wcChar17 */ + /////////////////////////////////////// + /// string3 descriptor + /////////////////////////////////////// + 0x16, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + '2', 0x00, /* wcChar0 */ + '0', 0x00, /* wcChar1 */ + '2', 0x00, /* wcChar2 */ + '1', 0x00, /* wcChar3 */ + '0', 0x00, /* wcChar4 */ + '3', 0x00, /* wcChar5 */ + '1', 0x00, /* wcChar6 */ + '0', 0x00, /* wcChar7 */ + '0', 0x00, /* wcChar8 */ + '5', 0x00, /* wcChar9 */ +#ifdef CONFIG_USB_HS + /////////////////////////////////////// + /// device qualifier descriptor + /////////////////////////////////////// + 0x0a, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +#endif + 0x00 +}; + +volatile bool tx_flag = 0; +volatile bool rx_flag = 0; + +void usbd_audio_open(uint8_t intf) +{ + if (intf == 1) { + rx_flag = 1; + MSG("OPEN1\r\n"); + } else { + tx_flag = 1; + MSG("OPEN2\r\n"); + } +} +void usbd_audio_close(uint8_t intf) +{ + if (intf == 1) { + rx_flag = 1; + MSG("CLOSE1\r\n"); + } else { + tx_flag = 0; + MSG("CLOSE2\r\n"); + } +} + +static usbd_class_t audio_class; +static usbd_interface_t audio_control_intf; +static usbd_interface_t audio_stream_intf; + +void usbd_audio_iso_callback(uint8_t ep) +{ +} + +static usbd_endpoint_t audio_in_ep = { + .ep_cb = usbd_audio_iso_callback, + .ep_addr = AUDIO_IN_EP +}; + +void audio_init() +{ + usbd_desc_register(audio_descriptor); + usbd_audio_add_interface(&audio_class, &audio_control_intf); + usbd_audio_add_interface(&audio_class, &audio_stream_intf); + usbd_audio_add_interface(&audio_class, &audio_stream_intf2); + usbd_interface_add_endpoint(&audio_stream_intf, &audio_out_ep); + usbd_interface_add_endpoint(&audio_stream_intf2, &audio_in_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() +{ + while (1) { + if (tx_flag) { + } + } +} diff --git a/demo/audio_v2_speaker_dualchan_template.c b/demo/audio_v2_speaker_dualchan_template.c index 0013603b..1b35690f 100644 --- a/demo/audio_v2_speaker_dualchan_template.c +++ b/demo/audio_v2_speaker_dualchan_template.c @@ -15,14 +15,11 @@ #define AUDIO_OUT_EP 0x01 #define AUDIO_FREQ 96000 -/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */ -/* 16bit(2 Bytes) 双声道(Mono:2) */ - -#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * 2 * 2) / 1000)) - #define HALF_WORD_BYTES 2 //2 half word (one channel) #define SAMPLE_BITS 16 //16 bit per channel +#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * 2 * HALF_WORD_BYTES) / 1000)) + #define CHANNEL_NUM 2 #define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)