Merge pull request #2725

UAC2: Fix memclr on driver reset.
This commit is contained in:
Ha Thach 2024-07-19 12:21:36 +07:00 committed by GitHub
commit 7706e6f5d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -304,19 +304,6 @@ typedef struct
uint16_t desc_length; // Length of audio function descriptor uint16_t desc_length; // Length of audio function descriptor
// Buffer for control requests
uint8_t * ctrl_buf;
uint8_t ctrl_buf_sz;
// Current active alternate settings
uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP!
// EP Transfer buffers and FIFOs
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
#if !CFG_TUD_AUDIO_ENABLE_DECODING
tu_fifo_t ep_out_ff;
#endif
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
struct { struct {
CFG_TUSB_MEM_ALIGN uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). CFG_TUSB_MEM_ALIGN uint32_t value; // Feedback value for asynchronous mode (in 16.16 format).
@ -346,17 +333,6 @@ typedef struct
} feedback; } feedback;
#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT
#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING
tu_fifo_t ep_in_ff;
#endif
// Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74)
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6];
#endif
// Decoding parameters - parameters are set when alternate AS interface is set by host // Decoding parameters - parameters are set when alternate AS interface is set by host
// Coding is currently only supported for EP. Software coding corresponding to AS interfaces without EPs are not supported currently. // Coding is currently only supported for EP. Software coding corresponding to AS interfaces without EPs are not supported currently.
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
@ -365,8 +341,7 @@ typedef struct
#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING
audio_data_format_type_I_t format_type_I_rx; audio_data_format_type_I_t format_type_I_rx;
uint8_t n_bytes_per_sampe_rx; uint8_t n_bytes_per_sample_rx;
uint8_t n_channels_per_ff_rx;
uint8_t n_ff_used_rx; uint8_t n_ff_used_rx;
#endif #endif
#endif #endif
@ -382,26 +357,57 @@ typedef struct
#if CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL) #if CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL)
audio_format_type_t format_type_tx; audio_format_type_t format_type_tx;
uint8_t n_channels_tx; uint8_t n_channels_tx;
uint8_t n_bytes_per_sampe_tx; uint8_t n_bytes_per_sample_tx;
#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING
audio_data_format_type_I_t format_type_I_tx; audio_data_format_type_I_t format_type_I_tx;
uint8_t n_channels_per_ff_tx;
uint8_t n_ff_used_tx; uint8_t n_ff_used_tx;
#endif #endif
#endif #endif
// Buffer for control requests
uint8_t * ctrl_buf;
uint8_t ctrl_buf_sz;
// Current active alternate settings
uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP!
// EP Transfer buffers and FIFOs
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
#if !CFG_TUD_AUDIO_ENABLE_DECODING
tu_fifo_t ep_out_ff;
#endif
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT
#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING
tu_fifo_t ep_in_ff;
#endif
// Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74)
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6];
#endif
// Support FIFOs for software encoding and decoding // Support FIFOs for software encoding and decoding
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
tu_fifo_t * rx_supp_ff; tu_fifo_t * rx_supp_ff;
uint8_t n_rx_supp_ff; uint8_t n_rx_supp_ff;
uint16_t rx_supp_ff_sz_max; uint16_t rx_supp_ff_sz_max;
#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING
uint8_t n_channels_per_ff_rx;
#endif
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING
tu_fifo_t * tx_supp_ff; tu_fifo_t * tx_supp_ff;
uint8_t n_tx_supp_ff; uint8_t n_tx_supp_ff;
uint16_t tx_supp_ff_sz_max; uint16_t tx_supp_ff_sz_max;
#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING
uint8_t n_channels_per_ff_tx;
#endif
#endif #endif
// Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR the support FIFOs are used // Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR the support FIFOs are used
@ -707,16 +713,16 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u
if (info.len_lin != 0) if (info.len_lin != 0)
{ {
info.len_lin = tu_min16(nBytesPerFFToRead, info.len_lin); info.len_lin = tu_min16(nBytesPerFFToRead, info.len_lin);
src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sample_rx];
dst_end = info.ptr_lin + info.len_lin; dst_end = info.ptr_lin + info.len_lin;
src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_lin, dst_end, src, n_ff_used); src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_lin, dst_end, src, n_ff_used);
// Handle wrapped part of FIFO // Handle wrapped part of FIFO
info.len_wrap = tu_min16(nBytesPerFFToRead - info.len_lin, info.len_wrap); info.len_wrap = tu_min16(nBytesPerFFToRead - info.len_lin, info.len_wrap);
if (info.len_wrap != 0) if (info.len_wrap != 0)
{ {
dst_end = info.ptr_wrap + info.len_wrap; dst_end = info.ptr_wrap + info.len_wrap;
audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_wrap, dst_end, src, n_ff_used); audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_wrap, dst_end, src, n_ff_used);
} }
tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap);
} }
@ -1024,7 +1030,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
// Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT! // Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT!
nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, audio->ep_in_sz / n_ff_used); nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, audio->ep_in_sz / n_ff_used);
// Round to full number of samples (flooring) // Round to full number of samples (flooring)
uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx; uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx;
nBytesPerFFToSend = (nBytesPerFFToSend / nSlotSize) * nSlotSize; nBytesPerFFToSend = (nBytesPerFFToSend / nSlotSize) * nSlotSize;
#endif #endif
@ -1036,7 +1042,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++)
{ {
dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx]; dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sample_tx];
tu_fifo_get_read_info(&audio->tx_supp_ff[cnt_ff], &info); tu_fifo_get_read_info(&audio->tx_supp_ff[cnt_ff], &info);
@ -1044,7 +1050,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
{ {
info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length
src_end = (uint8_t *)info.ptr_lin + info.len_lin; src_end = (uint8_t *)info.ptr_lin + info.len_lin;
dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_lin, src_end, dst, n_ff_used); dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_lin, src_end, dst, n_ff_used);
// Limit up to desired length // Limit up to desired length
info.len_wrap = tu_min16(nBytesPerFFToSend - info.len_lin, info.len_wrap); info.len_wrap = tu_min16(nBytesPerFFToSend - info.len_lin, info.len_wrap);
@ -1053,7 +1059,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
if (info.len_wrap != 0) if (info.len_wrap != 0)
{ {
src_end = (uint8_t *)info.ptr_wrap + info.len_wrap; src_end = (uint8_t *)info.ptr_wrap + info.len_wrap;
audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_wrap, src_end, dst, n_ff_used); audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_wrap, src_end, dst, n_ff_used);
} }
tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap);
@ -1782,8 +1788,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
// Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap
#if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING #if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING
const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)) const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx))
* (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)); * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx));
for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++)
{ {
tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true);
@ -1813,7 +1819,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
// Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap
#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING
const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sampe_rx) * audio->n_bytes_per_sampe_rx; const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sample_rx) * audio->n_bytes_per_sample_rx;
for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++)
{ {
tu_fifo_config(&audio->rx_supp_ff[cnt], audio->rx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); tu_fifo_config(&audio->rx_supp_ff[cnt], audio->rx_supp_ff[cnt].buffer, active_fifo_depth, 1, true);
@ -2587,14 +2593,14 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const *
#if CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_EP_IN
if (as_itf == audio->ep_in_as_intf_num) if (as_itf == audio->ep_in_as_intf_num)
{ {
audio->n_bytes_per_sampe_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; audio->n_bytes_per_sample_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize;
} }
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
if (as_itf == audio->ep_out_as_intf_num) if (as_itf == audio->ep_out_as_intf_num)
{ {
audio->n_bytes_per_sampe_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; audio->n_bytes_per_sample_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize;
} }
#endif #endif
} }
@ -2613,7 +2619,7 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio)
{ {
TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I); TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I);
TU_VERIFY(audio->n_channels_tx); TU_VERIFY(audio->n_channels_tx);
TU_VERIFY(audio->n_bytes_per_sampe_tx); TU_VERIFY(audio->n_bytes_per_sample_tx);
TU_VERIFY(audio->interval_tx); TU_VERIFY(audio->interval_tx);
TU_VERIFY(audio->sample_rate_tx); TU_VERIFY(audio->sample_rate_tx);
@ -2622,9 +2628,9 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio)
const uint16_t sample_normimal = (uint16_t)(audio->sample_rate_tx * interval / ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); const uint16_t sample_normimal = (uint16_t)(audio->sample_rate_tx * interval / ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000));
const uint16_t sample_reminder = (uint16_t)(audio->sample_rate_tx * interval % ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); const uint16_t sample_reminder = (uint16_t)(audio->sample_rate_tx * interval % ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000));
const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx);
const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sample_tx);
const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx);
// Endpoint size must larger than packet size // Endpoint size must larger than packet size
TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz); TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz);