diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 1c4084882..323bb6270 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -348,9 +348,9 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) } // get relative from absolute pointer -static uint16_t get_relative_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) +static uint16_t get_relative_pointer(tu_fifo_t* f, uint16_t p) { - return _ff_mod(advance_pointer(f, p, offset), f->depth); + return _ff_mod(p, f->depth); } // Works on local copies of w and r - return only the difference and as such can be used to determine an overflow @@ -396,7 +396,7 @@ static inline void _tu_fifo_correct_read_pointer(tu_fifo_t* f, uint16_t wAbs) // Works on local copies of w and r // Must be protected by mutexes since in case of an overflow read pointer gets modified -static bool _tu_fifo_peek_at(tu_fifo_t* f, uint16_t offset, void * p_buffer, uint16_t wAbs, uint16_t rAbs) +static bool _tu_fifo_peek_at(tu_fifo_t* f, void * p_buffer, uint16_t wAbs, uint16_t rAbs) { uint16_t cnt = _tu_fifo_count(f, wAbs, rAbs); @@ -408,9 +408,9 @@ static bool _tu_fifo_peek_at(tu_fifo_t* f, uint16_t offset, void * p_buffer, uin } // Skip beginning of buffer - if (cnt == 0 || offset >= cnt) return false; + if (cnt == 0) return false; - uint16_t rRel = get_relative_pointer(f, rAbs, offset); + uint16_t rRel = get_relative_pointer(f, rAbs); // Peek data _ff_pull(f, p_buffer, rRel); @@ -420,7 +420,7 @@ static bool _tu_fifo_peek_at(tu_fifo_t* f, uint16_t offset, void * p_buffer, uin // Works on local copies of w and r // Must be protected by mutexes since in case of an overflow read pointer gets modified -static uint16_t _tu_fifo_peek_at_n(tu_fifo_t* f, uint16_t offset, void * p_buffer, uint16_t n, uint16_t wAbs, uint16_t rAbs, tu_fifo_copy_mode_t copy_mode) +static uint16_t _tu_fifo_peek_at_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wAbs, uint16_t rAbs, tu_fifo_copy_mode_t copy_mode) { uint16_t cnt = _tu_fifo_count(f, wAbs, rAbs); @@ -433,13 +433,12 @@ static uint16_t _tu_fifo_peek_at_n(tu_fifo_t* f, uint16_t offset, void * p_buffe } // Skip beginning of buffer - if (cnt == 0 || offset >= cnt) return 0; + if (cnt == 0) return 0; // 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; - uint16_t rRel = get_relative_pointer(f, rAbs, offset); + uint16_t rRel = get_relative_pointer(f, rAbs); // Peek data _ff_pull_n(f, p_buffer, n, rRel, copy_mode); @@ -479,7 +478,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu w = r; } - uint16_t wRel = get_relative_pointer(f, w, 0); + uint16_t wRel = get_relative_pointer(f, w); // Write data _ff_push_n(f, buf8, n, wRel, copy_mode); @@ -497,7 +496,7 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo _ff_lock(f->mutex_rd); // Peek the data - n = _tu_fifo_peek_at_n(f, 0, buffer, n, f->wr_idx, f->rd_idx, copy_mode); // f->rd_idx might get modified in case of an overflow so we can not use a local variable + n = _tu_fifo_peek_at_n(f, buffer, n, f->wr_idx, f->rd_idx, copy_mode); // f->rd_idx might get modified in case of an overflow so we can not use a local variable // Advance read pointer f->rd_idx = advance_pointer(f, f->rd_idx, n); @@ -635,7 +634,7 @@ bool tu_fifo_read(tu_fifo_t* f, void * buffer) _ff_lock(f->mutex_rd); // Peek the data - bool ret = _tu_fifo_peek_at(f, 0, buffer, f->wr_idx, f->rd_idx); // f->rd_idx might get modified in case of an overflow so we can not use a local variable + bool ret = _tu_fifo_peek_at(f, buffer, f->wr_idx, f->rd_idx); // f->rd_idx might get modified in case of an overflow so we can not use a local variable // Advance pointer f->rd_idx = advance_pointer(f, f->rd_idx, ret); @@ -685,10 +684,10 @@ uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint1 @returns TRUE if the queue is not empty */ /******************************************************************************/ -bool tu_fifo_peek_at(tu_fifo_t* f, uint16_t offset, void * p_buffer) +bool tu_fifo_peek_at(tu_fifo_t* f, void * p_buffer) { _ff_lock(f->mutex_rd); - bool ret = _tu_fifo_peek_at(f, offset, p_buffer, f->wr_idx, f->rd_idx); + bool ret = _tu_fifo_peek_at(f, p_buffer, f->wr_idx, f->rd_idx); _ff_unlock(f->mutex_rd); return ret; } @@ -700,8 +699,6 @@ bool tu_fifo_peek_at(tu_fifo_t* f, uint16_t offset, void * p_buffer) @param[in] f Pointer to the FIFO buffer to manipulate - @param[in] offset - Position to read from in the FIFO buffer with respect to read pointer @param[in] p_buffer Pointer to the place holder for data read from the buffer @param[in] n @@ -710,10 +707,10 @@ bool tu_fifo_peek_at(tu_fifo_t* f, uint16_t offset, void * p_buffer) @returns Number of bytes written to p_buffer */ /******************************************************************************/ -uint16_t tu_fifo_peek_at_n(tu_fifo_t* f, uint16_t offset, void * p_buffer, uint16_t n) +uint16_t tu_fifo_peek_at_n(tu_fifo_t* f, void * p_buffer, uint16_t n) { _ff_lock(f->mutex_rd); - bool ret = _tu_fifo_peek_at_n(f, offset, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC); + bool ret = _tu_fifo_peek_at_n(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC); _ff_unlock(f->mutex_rd); return ret; } @@ -742,7 +739,7 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data) if ( _tu_fifo_full(f, w, f->rd_idx) && !f->overwritable ) return false; - uint16_t wRel = get_relative_pointer(f, w, 0); + uint16_t wRel = get_relative_pointer(f, w); // Write data _ff_push(f, data, wRel); @@ -929,8 +926,8 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t n if (cnt < n) n = cnt; // Get relative pointers - w = get_relative_pointer(f, w,0); - r = get_relative_pointer(f, r,0); + w = get_relative_pointer(f, w); + r = get_relative_pointer(f, r); // Copy pointer to buffer to start reading from info->ptr_lin = &f->buffer[r]; @@ -976,27 +973,7 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t uint16_t w = f->wr_idx, r = f->rd_idx; uint16_t free = _tu_fifo_remaining(f, w, r); - // We need n here because we must enforce the read and write pointers to be not more separated than 2*depth! - - if (!f->overwritable) - { - // Not overwritable limit up to full - n = tu_min16(n, free); - } - else if (n >= f->depth) - { - // If overwrite is allowed it must be less than or equal to 2 x buffer length, otherwise the overflow can not be resolved by the read functions - if(n > 2*f->depth) return info; - - n = f->depth; - // We start writing at the read pointer's position since we fill the complete - // buffer and we do not want to modify the read pointer within a write function! - // This would end up in a race condition with read functions! - w = r; - } - - // Check if there is room to write to - if (free == 0) + if (free == 0 || n > 2*f->depth) // If overwrite is allowed it must be less than or equal to 2 x buffer length, otherwise the overflow can not be resolved by the read functions { info->len_lin = 0; info->len_wrap = 0; @@ -1005,9 +982,25 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t return; } + + // We need n here because we must enforce the read and write pointers to be not more separated than 2*depth! + if (!f->overwritable) + { + // Not overwritable limit up to full + n = tu_min16(n, free); + } + else if (n >= f->depth) + { + n = f->depth; + // We start writing at the read pointer's position since we fill the complete + // buffer and we do not want to modify the read pointer within a write function! + // This would end up in a race condition with read functions! + w = r; + } + // Get relative pointers - w = get_relative_pointer(f, w,0); - r = get_relative_pointer(f, r,0); + w = get_relative_pointer(f, w); + r = get_relative_pointer(f, r); // Copy pointer to buffer to start writing to info->ptr_lin = &f->buffer[w]; diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 797a5e728..fffe87bce 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -123,8 +123,8 @@ bool tu_fifo_read (tu_fifo_t* f, void * p_buffer); uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t n); uint16_t tu_fifo_read_n_const_addr_full_words (tu_fifo_t* f, void * buffer, uint16_t n); -bool tu_fifo_peek_at (tu_fifo_t* f, uint16_t pos, void * p_buffer); -uint16_t tu_fifo_peek_at_n (tu_fifo_t* f, uint16_t pos, void * p_buffer, uint16_t n); +bool tu_fifo_peek_at (tu_fifo_t* f, void * p_buffer); +uint16_t tu_fifo_peek_at_n (tu_fifo_t* f, void * p_buffer, uint16_t n); uint16_t tu_fifo_count (tu_fifo_t* f); bool tu_fifo_empty (tu_fifo_t* f); @@ -149,7 +149,7 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info, uint16_t static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) { - return tu_fifo_peek_at(f, 0, p_buffer); + return tu_fifo_peek_at(f, p_buffer); } static inline uint16_t tu_fifo_depth(tu_fifo_t* f)