Fix audiod_get_AS_interface_index in audio class.
Enhance uac2_headset example with multiple sample rates. Add macro to calculate EP size.
This commit is contained in:
		| @@ -34,9 +34,11 @@ | ||||
| // MACRO CONSTANT TYPEDEF PROTOTYPES | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| #ifndef AUDIO_SAMPLE_RATE | ||||
| #define AUDIO_SAMPLE_RATE     48000 | ||||
| #endif | ||||
| // List of supported sample rates | ||||
| const uint32_t sample_rates[]       = {44100, 48000, 88200, 96000}; | ||||
| uint32_t       current_sample_rate  = 44100; | ||||
|  | ||||
| #define N_SAMPLE_RATES  (sizeof(sample_rates) / 4) | ||||
|  | ||||
| /* Blink pattern | ||||
|  * - 25 ms   : streaming data | ||||
| @@ -166,24 +168,30 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t | ||||
| { | ||||
|   TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); | ||||
|  | ||||
|   // Example supports only single frequency, same value will be used for current value and range | ||||
|   if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) | ||||
|   { | ||||
|     if (request->bRequest == AUDIO_CS_REQ_CUR) | ||||
|     { | ||||
|       TU_LOG2("Clock get current freq %u\r\n", AUDIO_SAMPLE_RATE); | ||||
|       TU_LOG1("Clock get current freq %u\r\n", current_sample_rate); | ||||
|  | ||||
|       audio_control_cur_4_t curf = { tu_htole32(AUDIO_SAMPLE_RATE) }; | ||||
|       audio_control_cur_4_t curf = { tu_htole32(current_sample_rate) }; | ||||
|       return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); | ||||
|     } | ||||
|     else if (request->bRequest == AUDIO_CS_REQ_RANGE) | ||||
|     { | ||||
|       audio_control_range_4_n_t(1) rangef = | ||||
|       audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = | ||||
|       { | ||||
|         .wNumSubRanges = tu_htole16(1), | ||||
|         .subrange[0] = { tu_htole32(AUDIO_SAMPLE_RATE), tu_htole32(AUDIO_SAMPLE_RATE), 0} | ||||
|         .wNumSubRanges = tu_htole16(N_SAMPLE_RATES) | ||||
|       }; | ||||
|       TU_LOG2("Clock get freq range (%d, %d, %d)\r\n", (int)rangef.subrange[0].bMin, (int)rangef.subrange[0].bMax, (int)rangef.subrange[0].bRes); | ||||
|       TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); | ||||
|       for(uint8_t i = 0; i < N_SAMPLE_RATES; i++) | ||||
|       { | ||||
|         rangef.subrange[i].bMin = sample_rates[i]; | ||||
|         rangef.subrange[i].bMax = sample_rates[i]; | ||||
|         rangef.subrange[i].bRes = 0; | ||||
|         TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes); | ||||
|       } | ||||
|        | ||||
|       return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef)); | ||||
|     } | ||||
|   } | ||||
| @@ -191,7 +199,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t | ||||
|            request->bRequest == AUDIO_CS_REQ_CUR) | ||||
|   { | ||||
|     audio_control_cur_1_t cur_valid = { .bCur = 1 }; | ||||
|     TU_LOG2("Clock get is valid %u\r\n", cur_valid.bCur); | ||||
|     TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); | ||||
|     return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid)); | ||||
|   } | ||||
|   TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n", | ||||
| @@ -199,6 +207,32 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| // Helper for clock set requests | ||||
| static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) | ||||
| { | ||||
|   (void)rhport; | ||||
|  | ||||
|   TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); | ||||
|   TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); | ||||
|  | ||||
|   if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) | ||||
|   { | ||||
|     TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); | ||||
|  | ||||
|     current_sample_rate = ((audio_control_cur_4_t *)buf)->bCur; | ||||
|  | ||||
|     TU_LOG1("Clock set current freq: %d\r\n", current_sample_rate); | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n", | ||||
|             request->bEntityID, request->bControlSelector, request->bRequest); | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Helper for feature unit get requests | ||||
| static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) | ||||
| { | ||||
| @@ -207,7 +241,7 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req | ||||
|   if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) | ||||
|   { | ||||
|     audio_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] }; | ||||
|     TU_LOG2("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); | ||||
|     TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); | ||||
|     return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); | ||||
|   } | ||||
|   else if (UAC2_ENTITY_SPK_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME) | ||||
| @@ -218,14 +252,14 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req | ||||
|         .wNumSubRanges = tu_htole16(1), | ||||
|         .subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) } | ||||
|       }; | ||||
|       TU_LOG2("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, | ||||
|       TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, | ||||
|               range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); | ||||
|       return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol)); | ||||
|     } | ||||
|     else if (request->bRequest == AUDIO_CS_REQ_CUR) | ||||
|     { | ||||
|       audio_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) }; | ||||
|       TU_LOG2("Get channel %u volume %u dB\r\n", request->bChannelNumber, cur_vol.bCur); | ||||
|       TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); | ||||
|       return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol)); | ||||
|     } | ||||
|   } | ||||
| @@ -249,7 +283,7 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req | ||||
|  | ||||
|     mute[request->bChannelNumber] = ((audio_control_cur_1_t *)buf)->bCur; | ||||
|  | ||||
|     TU_LOG2("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); | ||||
|     TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
| @@ -259,7 +293,7 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req | ||||
|  | ||||
|     volume[request->bChannelNumber] = ((audio_control_cur_2_t const *)buf)->bCur; | ||||
|  | ||||
|     TU_LOG2("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); | ||||
|     TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
| @@ -299,7 +333,8 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p | ||||
|  | ||||
|   if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) | ||||
|     return tud_audio_feature_unit_set_request(rhport, request, buf); | ||||
|  | ||||
|   if (request->bEntityID == UAC2_ENTITY_CLOCK) | ||||
|     return tud_audio_clock_set_request(rhport, request, buf); | ||||
|   TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", | ||||
|           request->bEntityID, request->bControlSelector, request->bRequest); | ||||
|  | ||||
|   | ||||
| @@ -93,13 +93,12 @@ extern "C" { | ||||
| //-------------------------------------------------------------------- | ||||
| // AUDIO CLASS DRIVER CONFIGURATION | ||||
| //-------------------------------------------------------------------- | ||||
| #define CFG_TUD_AUDIO_IN_PATH                     (CFG_TUD_AUDIO) | ||||
| #define CFG_TUD_AUDIO_OUT_PATH                    (CFG_TUD_AUDIO) | ||||
|  | ||||
| //#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN                       220       // This equals TUD_AUDIO_HEADSET_STEREO_DESC_LEN, however, including it from usb_descriptors.h is not possible due to some strange include hassle | ||||
| #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN                       TUD_AUDIO_HEADSET_STEREO_DESC_LEN | ||||
|  | ||||
| // Audio format type I specifications | ||||
| #define CFG_TUD_AUDIO_FUNC_1_N_MAX_SAMPLE_RATE              96000 | ||||
| #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX                  1 | ||||
| #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX          2 | ||||
| #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX                  2 | ||||
| @@ -108,18 +107,18 @@ extern "C" { | ||||
|  | ||||
| // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) | ||||
| #define CFG_TUD_AUDIO_ENABLE_EP_IN                1 | ||||
| #define CFG_TUD_AUDIO_EP_SZ_IN                    (CFG_TUD_AUDIO_IN_PATH * (48 + 1) * (CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX) * (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)) // 48 Samples (48 kHz) x 2 Bytes/Sample x n Channels | ||||
| #define CFG_TUD_AUDIO_EP_SZ_IN                    TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_N_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) // 48 Samples (48 kHz) x 2 Bytes/Sample x n Channels | ||||
| #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ      CFG_TUD_AUDIO_EP_SZ_IN | ||||
| #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX         CFG_TUD_AUDIO_EP_SZ_IN                  // Maximum EP IN size for all AS alternate settings used | ||||
|  | ||||
| // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) | ||||
| #define CFG_TUD_AUDIO_ENABLE_EP_OUT               1 | ||||
| #define CFG_TUD_AUDIO_EP_OUT_SZ                   (CFG_TUD_AUDIO_OUT_PATH * ((48 + CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * (CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX) * (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX))) // N Samples (N kHz) x 2 Bytes/Sample x n Channels | ||||
| #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ     CFG_TUD_AUDIO_EP_OUT_SZ*3 | ||||
| #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX        CFG_TUD_AUDIO_EP_OUT_SZ                 // Maximum EP IN size for all AS alternate settings used | ||||
| #define CFG_TUD_AUDIO_EP_SZ_OUT                   TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_N_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) // N Samples (N kHz) x 2 Bytes/Sample x n Channels | ||||
| #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ     CFG_TUD_AUDIO_EP_SZ_OUT*3 | ||||
| #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX        CFG_TUD_AUDIO_EP_SZ_OUT                 // Maximum EP IN size for all AS alternate settings used | ||||
|  | ||||
| // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) | ||||
| #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 	          1 | ||||
| #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 	          2 | ||||
|  | ||||
| // Size of control request buffer | ||||
| #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ	64 | ||||
|   | ||||
| @@ -93,7 +93,7 @@ uint8_t const desc_configuration[] = | ||||
|     TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), | ||||
|  | ||||
|     // Interface number, string index, EP Out & EP In address, EP size | ||||
|     TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, 2, 16, EPNUM_AUDIO, CFG_TUD_AUDIO_EP_OUT_SZ, EPNUM_AUDIO | 0x80, CFG_TUD_AUDIO_EP_SZ_IN) | ||||
|     TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, 2, 16, EPNUM_AUDIO, CFG_TUD_AUDIO_EP_SZ_OUT, EPNUM_AUDIO | 0x80, CFG_TUD_AUDIO_EP_SZ_IN) | ||||
| }; | ||||
|  | ||||
| // Invoked when received GET CONFIGURATION DESCRIPTOR | ||||
|   | ||||
| @@ -77,7 +77,7 @@ enum | ||||
|     /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ | ||||
|     TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ | ||||
|     /* Clock Source Descriptor(4.7.2.1) */\ | ||||
|     TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 5, /*_assocTerm*/ 0x00,  /*_stridx*/ 0x00),    \ | ||||
|     TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00,  /*_stridx*/ 0x00),    \ | ||||
|     /* Input Terminal Descriptor(4.7.2.4) */\ | ||||
|     TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ | ||||
|     /* Feature Unit Descriptor(4.7.2.8) */\ | ||||
| @@ -99,21 +99,21 @@ enum | ||||
|     /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ | ||||
|     TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ | ||||
|     /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ | ||||
|     TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01),\ | ||||
|     TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ | ||||
|     /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ | ||||
|     TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ | ||||
|     /* Standard AS Interface Descriptor(4.9.1) */\ | ||||
|     /* Interface 2, Alternate 0 - default alternate setting with 0 bandwidth */\ | ||||
|     TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x04),\ | ||||
|     /* Standard AS Interface Descriptor(4.9.1) */\ | ||||
|     /* Interface 1, Alternate 1 - alternate interface for data streaming */\ | ||||
|     /* Interface 2, Alternate 1 - alternate interface for data streaming */\ | ||||
|     TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ | ||||
|     /* Class-Specific AS Interface Descriptor(4.9.2) */\ | ||||
|     TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ | ||||
|     /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ | ||||
|     TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ | ||||
|     /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ | ||||
|     TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epinsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01),\ | ||||
|     TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epinsize, /*_interval*/ 0x01),\ | ||||
|     /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ | ||||
|     TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)\ | ||||
|  | ||||
|   | ||||
| @@ -1997,15 +1997,17 @@ static bool audiod_get_AS_interface_index(uint8_t itf, audiod_function_t * audio | ||||
|     while (p_desc < p_desc_end) | ||||
|     { | ||||
|       // We assume the number of alternate settings is increasing thus we return the index of alternate setting zero! | ||||
|       if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf) | ||||
|       if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) | ||||
|       { | ||||
|         *idxItf = tmp; | ||||
|         *pp_desc_int = p_desc; | ||||
|         return true; | ||||
|         if (((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf) | ||||
|         { | ||||
|           *idxItf = tmp; | ||||
|           *pp_desc_int = p_desc; | ||||
|           return true; | ||||
|         } | ||||
|         // Increase index, bytes read, and pointer | ||||
|         tmp++; | ||||
|       } | ||||
|  | ||||
|       // Increase index, bytes read, and pointer | ||||
|       tmp++; | ||||
|       p_desc = tu_desc_next(p_desc); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -542,6 +542,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb | ||||
|   /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ | ||||
|   TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ 1)\ | ||||
|  | ||||
| //   Calculate wMaxPacketSize of Endpoints | ||||
| #define TUD_AUDIO_EP_SIZE(_maxFrequency, _nBytesPerSample, _nChannels) \ | ||||
|     ((((_maxFrequency + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 7999 : 999)) / ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 8000 : 1000)) + 1) * _nBytesPerSample * _nChannels) | ||||
|  | ||||
|  | ||||
| //------------- TUD_USBTMC/USB488 -------------// | ||||
| #define TUD_USBTMC_APP_CLASS    (TUSB_CLASS_APPLICATION_SPECIFIC) | ||||
| #define TUD_USBTMC_APP_SUBCLASS 0x03u | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 MasterPhi
					MasterPhi