diff options
| -rw-r--r-- | src/class/audio/audio_host.c | 31 | ||||
| -rw-r--r-- | test/unit-test/test/host/audio/test_audio_host.c | 29 |
2 files changed, 50 insertions, 10 deletions
diff --git a/src/class/audio/audio_host.c b/src/class/audio/audio_host.c index c73e9f225..5c7ce5f8e 100644 --- a/src/class/audio/audio_host.c +++ b/src/class/audio/audio_host.c @@ -1297,15 +1297,28 @@ static const uint8_t *audioh_parse_as(audioh_interface_t *p_audio, const audioh_ break; } - const uint8_t usage = desc_endpoint->bmAttributes.usage; - const bool implicit_feedback = - usage == (TUSB_ISO_EP_ATT_IMPLICIT_FB >> 4) && tu_edpt_dir(desc_endpoint->bEndpointAddress) == TUSB_DIR_IN; - const bool explicit_feedback = - tu_edpt_dir(desc_endpoint->bEndpointAddress) == TUSB_DIR_IN && - (usage == (TUSB_ISO_EP_ATT_EXPLICIT_FB >> 4) || - (usage == (TUSB_ISO_EP_ATT_DATA >> 4) && desc_endpoint->bmAttributes.sync == TUSB_ISO_EP_ATT_NO_SYNC)); + bool is_data_ep = false; + bool is_explicit_feedback = false; + switch (p_audio->protocol) { + #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC1 + case AUDIO_INT_PROTOCOL_CODE_V1: + is_data_ep = desc_endpoint->bmAttributes.sync != TUSB_ISO_EP_ATT_NO_SYNC; + is_explicit_feedback = tu_edpt_dir(desc_endpoint->bEndpointAddress) == TUSB_DIR_IN && !is_data_ep; + break; + #endif + #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 + case AUDIO_INT_PROTOCOL_CODE_V2: + is_data_ep = desc_endpoint->bmAttributes.usage == (TUSB_ISO_EP_ATT_DATA >> 4) || + desc_endpoint->bmAttributes.usage == (TUSB_ISO_EP_ATT_IMPLICIT_FB >> 4); + is_explicit_feedback = tu_edpt_dir(desc_endpoint->bEndpointAddress) == TUSB_DIR_IN && + desc_endpoint->bmAttributes.usage == (TUSB_ISO_EP_ATT_EXPLICIT_FB >> 4); + break; + #endif + default: + break; + } - if (explicit_feedback) { + if (is_explicit_feedback) { const uint16_t fb_ep_size = tu_edpt_packet_size(desc_endpoint); if (has_feedback_ep || (fb_ep_size != 3 && fb_ep_size != 4)) { TU_LOG_DRV(" AUDIO AS itf %u alt %u: invalid/extra feedback ep %02x ignored\r\n", itf_num, alt, @@ -1325,7 +1338,7 @@ static const uint8_t *audioh_parse_as(audioh_interface_t *p_audio, const audioh_ break; } - if (usage == (TUSB_ISO_EP_ATT_DATA >> 4) || implicit_feedback) { + if (is_data_ep) { if (has_data_ep) { TU_LOG_DRV(" AUDIO AS itf %u alt %u: extra data ep %02x ignored\r\n", itf_num, alt, desc_endpoint->bEndpointAddress); diff --git a/test/unit-test/test/host/audio/test_audio_host.c b/test/unit-test/test/host/audio/test_audio_host.c index aa2f70f9b..9f8957984 100644 --- a/test/unit-test/test/host/audio/test_audio_host.c +++ b/test/unit-test/test/host/audio/test_audio_host.c @@ -295,6 +295,9 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) { #define TEST_UAC2_FORMAT(_bytes, _bits) \ 6, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE, AUDIO20_FORMAT_TYPE_I, _bytes, _bits +#define TEST_UAC2_DATA_EP(_ep, _attr, _size, _interval) \ + 7, TUSB_DESC_ENDPOINT, _ep, (TUSB_XFER_ISOCHRONOUS | (_attr)), U16_TO_U8S_LE(_size), _interval + #define TEST_UAC2_CS_DATA_EP \ 8, TUSB_DESC_CS_ENDPOINT, AUDIO20_CS_EP_SUBTYPE_GENERAL, AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, 0, \ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, U16_TO_U8S_LE(0) @@ -430,6 +433,19 @@ static const uint8_t uac2_duplex_shared_clock[] = { TEST_UAC2_CS_DATA_EP, }; +static const uint8_t uac2_capture_no_sync_data[] = { + TEST_UAC2_AC_HEADER(46), + TEST_UAC2_CLOCK_SOURCE(PLAYBACK_CLOCK, AUDIO20_CTRL_RW << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), + TEST_UAC2_INPUT_TERM(CAPTURE_INPUT_TERM, AUDIO_TERM_TYPE_IN_GENERIC_MIC, PLAYBACK_CLOCK, 1), + TEST_UAC2_OUTPUT_TERM(CAPTURE_OUTPUT_TERM, AUDIO_TERM_TYPE_USB_STREAMING, CAPTURE_INPUT_TERM, PLAYBACK_CLOCK), + TEST_UAC2_AS_ALT0, + TEST_UAC2_AS_INTERFACE(1, 1), + TEST_UAC2_AS_GENERAL(CAPTURE_OUTPUT_TERM, 1), + TEST_UAC2_FORMAT(2, 16), + TEST_UAC2_DATA_EP(0x81, TUSB_ISO_EP_ATT_DATA, 96, 1), + TEST_UAC2_CS_DATA_EP, +}; + static const uint8_t playback_with_implicit_feedback[] = { TEST_UAC1_AC_HEADER_2, TEST_UAC1_INPUT_TERM(PLAYBACK_INPUT_TERM, AUDIO_TERM_TYPE_USB_STREAMING, 2), @@ -446,7 +462,7 @@ static const uint8_t playback_with_implicit_feedback[] = { TEST_UAC1_AS_INTERFACE_NUM(AUDIO_AS_IN_ITF, 1, 1), TEST_UAC1_AS_GENERAL(CAPTURE_OUTPUT_TERM), TEST_UAC1_FORMAT(1, 2, 16, 48000), - TEST_UAC1_DATA_EP(0x81, TUSB_ISO_EP_ATT_IMPLICIT_FB, 96, 1), + TEST_UAC1_DATA_EP(0x81, TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_IMPLICIT_FB, 96, 1), TEST_UAC1_CS_DATA_EP, }; @@ -1101,6 +1117,17 @@ void test_audio_host_treats_implicit_feedback_as_audio_in_endpoint(void) { TEST_ASSERT_EQUAL(TUH_AUDIO_STREAM_CAPTURE, tuh_audio_stream_direction(0, 1)); } +void test_audio_host_uac2_treats_no_sync_data_usage_as_audio_in_endpoint(void) { + open_descriptors(uac2_capture_no_sync_data, sizeof(uac2_capture_no_sync_data)); + TEST_ASSERT_TRUE(audioh_set_config(AUDIO_DEV_ADDR, AUDIO_AC_ITF)); + complete_uac2_clock_range(44100, 48000); + + TEST_ASSERT_TRUE(tuh_audio_mounted(0)); + TEST_ASSERT_EQUAL_UINT8(1, tuh_audio_stream_count(0)); + TEST_ASSERT_EQUAL(TUH_AUDIO_STREAM_CAPTURE, tuh_audio_stream_direction(0, 0)); + TEST_ASSERT_EQUAL_UINT8(2, tuh_audio_config_count(0, 0)); +} + void test_audio_host_ignores_second_data_endpoint_in_same_as_interface(void) { open_descriptors(playback_with_extra_data_endpoint, sizeof(playback_with_extra_data_endpoint)); |
