From 8f72c97f7b0fa14badbc36497fba2c6d21cb59d0 Mon Sep 17 00:00:00 2001 From: Reinhard Panhuber Date: Fri, 30 Apr 2021 12:59:12 +0200 Subject: [PATCH] Change read infos to pointer type --- src/class/audio/audio_device.c | 50 ++++++++++--------- src/common/tusb_fifo.c | 88 +++++++++++++++++----------------- src/common/tusb_fifo.h | 6 +-- 3 files changed, 76 insertions(+), 68 deletions(-) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 8615b246..f19f8f6f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -650,23 +650,26 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u uint8_t * src; uint8_t * dst_end; - tu_fifo_linear_wr_info info; + tu_fifo_buffer_info_t info; for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) { - src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; - info = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, nBytesPerFFToRead); + tu_fifo_get_write_info(&audio->rx_supp_ff[cnt_ff], &info, nBytesPerFFToRead); - dst_end = info.ptr_lin + info.len_lin; - src = audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, info.ptr_lin, dst_end, src, n_ff_used); - - // Handle wrapped part of FIFO - if (info.len_wrap != 0) + if (info.len_lin != 0) { - dst_end = info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, info.ptr_wrap, dst_end, src, n_ff_used); + src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; + dst_end = info.ptr_lin + info.len_lin; + src = audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, info.ptr_lin, dst_end, src, n_ff_used); + + // Handle wrapped part of FIFO + if (info.len_wrap != 0) + { + dst_end = info.ptr_wrap + info.len_wrap; + audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, 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); } // Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it @@ -976,25 +979,28 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi uint8_t * dst; uint8_t * src_end; - tu_fifo_linear_wr_info info; + tu_fifo_buffer_info_t info; 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]; - info = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, nBytesPerFFToSend); + tu_fifo_get_read_info(&audio->tx_supp_ff[cnt_ff], &info, nBytesPerFFToSend); - src_end = info.ptr_lin + info.len_lin; - dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_lin, src_end, dst, n_ff_used); - - // Handle wrapped part of FIFO - if (info.len_wrap != 0) + if (info.ptr_lin != 0) { - src_end = info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_wrap, src_end, dst, n_ff_used); - } + src_end = info.ptr_lin + info.len_lin; + dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_lin, src_end, dst, n_ff_used); - tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); + // Handle wrapped part of FIFO + if (info.len_wrap != 0) + { + src_end = info.ptr_wrap + info.len_wrap; + audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, 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); + } } return nBytesPerFFToSend * n_ff_used; diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 75dae090..1c408488 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -883,7 +883,7 @@ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) /******************************************************************************/ /*! - @brief Get linear read info + @brief Get read info Returns the length and pointer from which bytes can be read in a linear manner. This is of major interest for DMA transmissions. If returned length is zero the @@ -895,24 +895,18 @@ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) wrapped part! @param[in] f Pointer to FIFO - @param[in] offset - Number of ITEMS to ignore before start writing - @param[out] **ptr - Pointer to start writing to - @param[in] n - Number of ITEMS to read from buffer - @return len - Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid + @param[out] *info + Pointer to struct which holds the desired infos */ /******************************************************************************/ -tu_fifo_linear_wr_info tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n) +void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t n) { // Operate on temporary values in case they change in between uint16_t w = f->wr_idx, r = f->rd_idx; uint16_t cnt = _tu_fifo_count(f, w, r); - // Check overflow and correct if required + // Check overflow and correct if required - may happen in case a DMA wrote too fast if (cnt > f->depth) { _ff_lock(f->mutex_rd); @@ -922,36 +916,40 @@ tu_fifo_linear_wr_info tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offse cnt = f->depth; } - tu_fifo_linear_wr_info info = {0,0,NULL,NULL}; - // Skip beginning of buffer - if (cnt == 0 || offset >= cnt) return info; + if (cnt == 0) + { + info->len_lin = 0; + info->len_wrap = 0; + info->ptr_lin = NULL; + info->ptr_wrap = NULL; + return; + } - // Check if we can read something at and after offset - if too less is available we read what remains - cnt -= offset; if (cnt < n) n = cnt; // Get relative pointers - w = get_relative_pointer(f, w, 0); - r = get_relative_pointer(f, r, offset); + w = get_relative_pointer(f, w,0); + r = get_relative_pointer(f, r,0); // Copy pointer to buffer to start reading from - info.ptr_lin = &f->buffer[r]; - info.ptr_wrap = f->buffer; + info->ptr_lin = &f->buffer[r]; // Check if there is a wrap around necessary if (w > r) { // Non wrapping case - info.len_lin = tu_min16(n, w - r); // Limit to required length - info.len_wrap = 0; + info->len_lin = tu_min16(n, w - r); // Limit to required length + info->len_wrap = 0; + info->ptr_wrap = NULL; } else { - info.len_lin = tu_min16(n, f->depth - r); // Also the case if FIFO was full - info.len_wrap = n-info.len_lin; // n was already limited to what is available + info->len_lin = tu_min16(n, f->depth - r); // Also the case if FIFO was full + info->len_wrap = n-info->len_lin; + info->ptr_wrap = f->buffer; } - return info; + return; } /******************************************************************************/ @@ -967,22 +965,18 @@ tu_fifo_linear_wr_info tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offse time to get a pointer to the wrapped part! @param[in] f Pointer to FIFO - @param[in] offset - Number of ITEMS to ignore before start writing - @param[out] **ptr - Pointer to start writing to + @param[out] *info + Pointer to struct which holds the desired infos @param[in] n Number of ITEMS to write into buffer - @return len - Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid */ /******************************************************************************/ -tu_fifo_linear_wr_info tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n) +void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t n) { uint16_t w = f->wr_idx, r = f->rd_idx; uint16_t free = _tu_fifo_remaining(f, w, r); - tu_fifo_linear_wr_info info = {0,0,NULL,NULL}; + // We need n here because we must enforce the read and write pointers to be not more separated than 2*depth! if (!f->overwritable) { @@ -1002,27 +996,35 @@ tu_fifo_linear_wr_info tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offs } // Check if there is room to write to - if (free == 0 || offset >= free) return info; + if (free == 0) + { + info->len_lin = 0; + info->len_wrap = 0; + info->ptr_lin = NULL; + info->ptr_wrap = NULL; + return; + } // Get relative pointers - w = get_relative_pointer(f, w, offset); - r = get_relative_pointer(f, r, 0); + w = get_relative_pointer(f, w,0); + r = get_relative_pointer(f, r,0); // Copy pointer to buffer to start writing to - info.ptr_lin = &f->buffer[w]; - info.ptr_wrap = f->buffer; // Always start of buffer + info->ptr_lin = &f->buffer[w]; if (w < r) { // Non wrapping case - info.len_lin = tu_min16(n, r-w); // Limit to required length - info.len_wrap = 0; + info->len_lin = tu_min16(n, r-w); // Limit to required length + info->len_wrap = 0; + info->ptr_wrap = NULL; } else { - info.len_lin = tu_min16(n, f->depth - w); // Limit to required length - info.len_wrap = n-info.len_lin; // Remaining length - n already was limited to free or FIFO depth + info->len_lin = tu_min16(n, f->depth - w); // Limit to required length + info->len_wrap = n-info->len_lin; // Remaining length - n already was limited to free or FIFO depth + info->ptr_wrap = f->buffer; // Always start of buffer } - return info; + return; } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index c23f2572..797a5e72 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -86,7 +86,7 @@ typedef struct uint16_t len_wrap ; ///< wrapped length in item size void * ptr_lin ; ///< linear part start pointer void * ptr_wrap ; ///< wrapped part start pointer -} tu_fifo_linear_wr_info; +} tu_fifo_buffer_info_t; #define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ { \ @@ -144,8 +144,8 @@ void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n); // tu_fifo_advance_read_pointer()/tu_fifo_advance_write_pointer and conduct a second read/write operation // TODO - update comments -tu_fifo_linear_wr_info tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n); -tu_fifo_linear_wr_info tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n); +void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t n); +void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t n); static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) {