@@ -314,7 +314,44 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu
314314}
315315
316316//--------------------------------------------------------------------+
317- // Index (free-running and real buffer pointer)
317+ // Helper
318+ //--------------------------------------------------------------------+
319+
320+ // return only the index difference and as such can be used to determine an overflow i.e overflowable count
321+ TU_ATTR_ALWAYS_INLINE static inline
322+ uint16_t _ff_count (uint16_t depth , uint16_t wr_idx , uint16_t rd_idx )
323+ {
324+ // In case we have non-power of two depth we need a further modification
325+ if (wr_idx >= rd_idx )
326+ {
327+ return (uint16_t ) (wr_idx - rd_idx );
328+ } else
329+ {
330+ return (uint16_t ) (2 * depth - (rd_idx - wr_idx ));
331+ }
332+ }
333+
334+ // BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS"
335+ // Only one overflow is allowed for this function to work e.g. if depth = 100, you must not
336+ // write more than 2*depth-1 items in one rush without updating write pointer. Otherwise
337+ // write pointer wraps and you pointer states are messed up. This can only happen if you
338+ // use DMAs, write functions do not allow such an error.
339+ TU_ATTR_ALWAYS_INLINE static inline
340+ bool _ff_overflowed (uint16_t depth , uint16_t wr_idx , uint16_t rd_idx )
341+ {
342+ return _ff_count (depth , wr_idx , rd_idx ) > depth ;
343+ }
344+
345+ // return remaining slot in fifo
346+ TU_ATTR_ALWAYS_INLINE static inline
347+ uint16_t _ff_remaining (uint16_t depth , uint16_t wr_idx , uint16_t rd_idx )
348+ {
349+ uint16_t const count = _ff_count (depth , wr_idx , rd_idx );
350+ return (depth > count ) ? (depth - count ) : 0 ;
351+ }
352+
353+ //--------------------------------------------------------------------+
354+ // Index Helper
318355//--------------------------------------------------------------------+
319356
320357// Advance an absolute index
@@ -334,6 +371,7 @@ static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset)
334371 return new_idx ;
335372}
336373
374+ #if 0 // not used but
337375// Backward an absolute index
338376static uint16_t backward_index (uint16_t depth , uint16_t idx , uint16_t offset )
339377{
@@ -349,6 +387,7 @@ static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset)
349387
350388 return new_idx ;
351389}
390+ #endif
352391
353392// index to pointer, simply an modulo with minus.
354393TU_ATTR_ALWAYS_INLINE static inline
@@ -359,45 +398,24 @@ uint16_t idx2ptr(uint16_t depth, uint16_t idx)
359398 return idx ;
360399}
361400
362- // return only the index difference and as such can be used to determine an overflow i.e overflowable count
401+ // Works on local copies of w
402+ // When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms
403+ // an full fifo i.e _ff_count() = depth
363404TU_ATTR_ALWAYS_INLINE static inline
364- uint16_t _ff_count ( uint16_t depth , uint16_t wr_idx , uint16_t rd_idx )
405+ uint16_t _ff_correct_read_index ( tu_fifo_t * f , uint16_t wr_idx )
365406{
366- // In case we have non-power of two depth we need a further modification
367- if (wr_idx >= rd_idx )
407+ uint16_t rd_idx ;
408+ if ( wr_idx >= f -> depth )
368409 {
369- return ( uint16_t ) ( wr_idx - rd_idx ) ;
370- } else
410+ rd_idx = wr_idx - f -> depth ;
411+ }else
371412 {
372- return ( uint16_t ) ( 2 * depth - ( rd_idx - wr_idx )) ;
413+ rd_idx = wr_idx + f -> depth ;
373414 }
374- }
375415
376- // BE AWARE - THIS FUNCTION MIGHT NOT GIVE A CORRECT ANSWERE IN CASE WRITE POINTER "OVERFLOWS"
377- // Only one overflow is allowed for this function to work e.g. if depth = 100, you must not
378- // write more than 2*depth-1 items in one rush without updating write pointer. Otherwise
379- // write pointer wraps and you pointer states are messed up. This can only happen if you
380- // use DMAs, write functions do not allow such an error.
381- TU_ATTR_ALWAYS_INLINE static inline
382- bool _ff_overflowed (uint16_t depth , uint16_t wr_idx , uint16_t rd_idx )
383- {
384- return _ff_count (depth , wr_idx , rd_idx ) > depth ;
385- }
416+ f -> rd_idx = rd_idx ;
386417
387- // return remaining slot in fifo
388- TU_ATTR_ALWAYS_INLINE static inline
389- uint16_t _ff_remaining (uint16_t depth , uint16_t wr_idx , uint16_t rd_idx )
390- {
391- uint16_t const count = _ff_count (depth , wr_idx , rd_idx );
392- return (depth > count ) ? (depth - count ) : 0 ;
393- }
394-
395- // Works on local copies of w
396- // For more details see _tu_fifo_overflow()!
397- TU_ATTR_ALWAYS_INLINE static inline
398- void _tu_fifo_correct_read_pointer (tu_fifo_t * f , uint16_t wr_idx )
399- {
400- f -> rd_idx = backward_index (f -> depth , wr_idx , f -> depth );
418+ return rd_idx ;
401419}
402420
403421// Works on local copies of w and r
@@ -407,14 +425,14 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16
407425 uint16_t cnt = _ff_count (f -> depth , wr_idx , rd_idx );
408426
409427 // Check overflow and correct if required
410- if (cnt > f -> depth )
428+ if ( cnt > f -> depth )
411429 {
412- _tu_fifo_correct_read_pointer (f , wr_idx );
430+ rd_idx = _ff_correct_read_index (f , wr_idx );
413431 cnt = f -> depth ;
414432 }
415433
416434 // Skip beginning of buffer
417- if (cnt == 0 ) return false;
435+ if ( cnt == 0 ) return false;
418436
419437 uint16_t rd_ptr = idx2ptr (f -> depth , rd_idx );
420438
@@ -431,18 +449,17 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1
431449 uint16_t cnt = _ff_count (f -> depth , wr_idx , rd_idx );
432450
433451 // Check overflow and correct if required
434- if (cnt > f -> depth )
452+ if ( cnt > f -> depth )
435453 {
436- _tu_fifo_correct_read_pointer (f , wr_idx );
437- rd_idx = f -> rd_idx ;
454+ rd_idx = _ff_correct_read_index (f , wr_idx );
438455 cnt = f -> depth ;
439456 }
440457
441458 // Skip beginning of buffer
442- if (cnt == 0 ) return 0 ;
459+ if ( cnt == 0 ) return 0 ;
443460
444461 // Check if we can read something at and after offset - if too less is available we read what remains
445- if (cnt < n ) n = cnt ;
462+ if ( cnt < n ) n = cnt ;
446463
447464 uint16_t rd_ptr = idx2ptr (f -> depth , rd_idx );
448465
@@ -662,7 +679,7 @@ bool tu_fifo_overflowed(tu_fifo_t* f)
662679void tu_fifo_correct_read_pointer (tu_fifo_t * f )
663680{
664681 _ff_lock (f -> mutex_rd );
665- _tu_fifo_correct_read_pointer (f , f -> wr_idx );
682+ _ff_correct_read_index (f , f -> wr_idx );
666683 _ff_unlock (f -> mutex_rd );
667684}
668685
@@ -963,10 +980,9 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
963980 if (cnt > f -> depth )
964981 {
965982 _ff_lock (f -> mutex_rd );
966- _tu_fifo_correct_read_pointer (f , wr_idx );
983+ rd_idx = _ff_correct_read_index (f , wr_idx );
967984 _ff_unlock (f -> mutex_rd );
968985
969- rd_idx = f -> rd_idx ;
970986 cnt = f -> depth ;
971987 }
972988
@@ -988,7 +1004,8 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
9881004 info -> ptr_lin = & f -> buffer [rd_ptr ];
9891005
9901006 // Check if there is a wrap around necessary
991- if (wr_ptr > rd_ptr ) {
1007+ if (wr_ptr > rd_ptr )
1008+ {
9921009 // Non wrapping case
9931010 info -> len_lin = cnt ;
9941011
0 commit comments