@@ -314,7 +314,44 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rel, tu
314
314
}
315
315
316
316
//--------------------------------------------------------------------+
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
318
355
//--------------------------------------------------------------------+
319
356
320
357
// Advance an absolute index
@@ -334,6 +371,7 @@ static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset)
334
371
return new_idx ;
335
372
}
336
373
374
+ #if 0 // not used but
337
375
// Backward an absolute index
338
376
static uint16_t backward_index (uint16_t depth , uint16_t idx , uint16_t offset )
339
377
{
@@ -349,6 +387,7 @@ static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset)
349
387
350
388
return new_idx ;
351
389
}
390
+ #endif
352
391
353
392
// index to pointer, simply an modulo with minus.
354
393
TU_ATTR_ALWAYS_INLINE static inline
@@ -359,45 +398,24 @@ uint16_t idx2ptr(uint16_t depth, uint16_t idx)
359
398
return idx ;
360
399
}
361
400
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
363
404
TU_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 )
365
406
{
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 )
368
409
{
369
- return ( uint16_t ) ( wr_idx - rd_idx ) ;
370
- } else
410
+ rd_idx = wr_idx - f -> depth ;
411
+ }else
371
412
{
372
- return ( uint16_t ) ( 2 * depth - ( rd_idx - wr_idx )) ;
413
+ rd_idx = wr_idx + f -> depth ;
373
414
}
374
- }
375
415
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 ;
386
417
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 ;
401
419
}
402
420
403
421
// 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
407
425
uint16_t cnt = _ff_count (f -> depth , wr_idx , rd_idx );
408
426
409
427
// Check overflow and correct if required
410
- if (cnt > f -> depth )
428
+ if ( cnt > f -> depth )
411
429
{
412
- _tu_fifo_correct_read_pointer (f , wr_idx );
430
+ rd_idx = _ff_correct_read_index (f , wr_idx );
413
431
cnt = f -> depth ;
414
432
}
415
433
416
434
// Skip beginning of buffer
417
- if (cnt == 0 ) return false;
435
+ if ( cnt == 0 ) return false;
418
436
419
437
uint16_t rd_ptr = idx2ptr (f -> depth , rd_idx );
420
438
@@ -431,18 +449,17 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1
431
449
uint16_t cnt = _ff_count (f -> depth , wr_idx , rd_idx );
432
450
433
451
// Check overflow and correct if required
434
- if (cnt > f -> depth )
452
+ if ( cnt > f -> depth )
435
453
{
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 );
438
455
cnt = f -> depth ;
439
456
}
440
457
441
458
// Skip beginning of buffer
442
- if (cnt == 0 ) return 0 ;
459
+ if ( cnt == 0 ) return 0 ;
443
460
444
461
// 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 ;
446
463
447
464
uint16_t rd_ptr = idx2ptr (f -> depth , rd_idx );
448
465
@@ -662,7 +679,7 @@ bool tu_fifo_overflowed(tu_fifo_t* f)
662
679
void tu_fifo_correct_read_pointer (tu_fifo_t * f )
663
680
{
664
681
_ff_lock (f -> mutex_rd );
665
- _tu_fifo_correct_read_pointer (f , f -> wr_idx );
682
+ _ff_correct_read_index (f , f -> wr_idx );
666
683
_ff_unlock (f -> mutex_rd );
667
684
}
668
685
@@ -963,10 +980,9 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
963
980
if (cnt > f -> depth )
964
981
{
965
982
_ff_lock (f -> mutex_rd );
966
- _tu_fifo_correct_read_pointer (f , wr_idx );
983
+ rd_idx = _ff_correct_read_index (f , wr_idx );
967
984
_ff_unlock (f -> mutex_rd );
968
985
969
- rd_idx = f -> rd_idx ;
970
986
cnt = f -> depth ;
971
987
}
972
988
@@ -988,7 +1004,8 @@ void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
988
1004
info -> ptr_lin = & f -> buffer [rd_ptr ];
989
1005
990
1006
// Check if there is a wrap around necessary
991
- if (wr_ptr > rd_ptr ) {
1007
+ if (wr_ptr > rd_ptr )
1008
+ {
992
1009
// Non wrapping case
993
1010
info -> len_lin = cnt ;
994
1011
0 commit comments