28
28
#include "osal/osal.h"
29
29
#include "tusb_fifo.h"
30
30
31
+ #define TU_FIFO_DBG 0
32
+
31
33
// Suppress IAR warning
32
34
// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
33
35
#if defined(__ICCARM__ )
34
36
#pragma diag_suppress = Pa082
35
37
#endif
36
38
37
- #define TU_FIFO_DBG 0
38
-
39
- // implement mutex lock and unlock
40
- #if CFG_FIFO_MUTEX
39
+ #if OSAL_MUTEX_REQUIRED
41
40
42
41
static inline void _ff_lock (osal_mutex_t mutex )
43
42
{
@@ -80,8 +79,8 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si
80
79
f -> depth = depth ;
81
80
f -> item_size = (uint16_t ) (item_size & 0x7FFF );
82
81
f -> overwritable = overwritable ;
83
-
84
- f -> rd_idx = f -> wr_idx = 0 ;
82
+ f -> rd_idx = 0 ;
83
+ f -> wr_idx = 0 ;
85
84
86
85
_ff_unlock (f -> mutex_wr );
87
86
_ff_unlock (f -> mutex_rd );
@@ -142,13 +141,13 @@ static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t
142
141
}
143
142
}
144
143
145
- // send one item to FIFO WITHOUT updating write pointer
144
+ // send one item to fifo WITHOUT updating write pointer
146
145
static inline void _ff_push (tu_fifo_t * f , void const * app_buf , uint16_t rel )
147
146
{
148
147
memcpy (f -> buffer + (rel * f -> item_size ), app_buf , f -> item_size );
149
148
}
150
149
151
- // send n items to FIFO WITHOUT updating write pointer
150
+ // send n items to fifo WITHOUT updating write pointer
152
151
static void _ff_push_n (tu_fifo_t * f , void const * app_buf , uint16_t n , uint16_t rel , tu_fifo_copy_mode_t copy_mode )
153
152
{
154
153
uint16_t const nLin = f -> depth - rel ;
@@ -227,13 +226,13 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t
227
226
}
228
227
}
229
228
230
- // get one item from FIFO WITHOUT updating read pointer
229
+ // get one item from fifo WITHOUT updating read pointer
231
230
static inline void _ff_pull (tu_fifo_t * f , void * app_buf , uint16_t rel )
232
231
{
233
232
memcpy (app_buf , f -> buffer + (rel * f -> item_size ), f -> item_size );
234
233
}
235
234
236
- // get n items from FIFO WITHOUT updating read pointer
235
+ // get n items from fifo WITHOUT updating read pointer
237
236
static void _ff_pull_n (tu_fifo_t * f , void * app_buf , uint16_t n , uint16_t rel , tu_fifo_copy_mode_t copy_mode )
238
237
{
239
238
uint16_t const nLin = f -> depth - rel ;
@@ -475,14 +474,14 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu
475
474
uint16_t rd_idx = f -> rd_idx ;
476
475
477
476
uint8_t const * buf8 = (uint8_t const * ) data ;
478
- uint16_t overflowable_count = _tu_fifo_count (f , wr_idx , rd_idx );
479
- uint16_t const remain = _tu_fifo_remaining (f , wr_idx , rd_idx );
480
477
481
- TU_LOG (TU_FIFO_DBG , "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: " , rd_idx , wr_idx , _tu_fifo_count (f , wr_idx , rd_idx ), remain , n );
478
+ TU_LOG (TU_FIFO_DBG , "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: " ,
479
+ rd_idx , wr_idx , _tu_fifo_count (f , wr_idx , rd_idx ), _tu_fifo_remaining (f , wr_idx , rd_idx ), n );
482
480
483
481
if ( !f -> overwritable )
484
482
{
485
483
// limit up to full
484
+ uint16_t const remain = _tu_fifo_remaining (f , wr_idx , rd_idx );
486
485
n = tu_min16 (n , remain );
487
486
}
488
487
else
@@ -508,23 +507,27 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu
508
507
// We start writing at the read pointer's position since we fill the whole buffer
509
508
wr_idx = rd_idx ;
510
509
}
511
- else if (overflowable_count + n >= 2 * f -> depth )
512
- {
513
- // Double overflowed
514
- // Index is bigger than the allowed range [0,2*depth)
515
- // re-position write index to have a full fifo after pushed
516
- wr_idx = advance_pointer (f , rd_idx , f -> depth - n );
517
-
518
- // TODO we should also shift out n bytes from read index since we avoid changing rd index !!
519
- // However memmove() is expensive due to actual copying + wrapping consideration.
520
- // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory
521
- // currently deliberately not implemented --> result in incorrect data read back
522
- }else
510
+ else
523
511
{
524
- // normal + single overflowed:
525
- // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read()
526
- // Therefore we just increase write index
527
- // we will correct (re-position) read index later on in fifo_read() function
512
+ uint16_t const overflowable_count = _tu_fifo_count (f , wr_idx , rd_idx );
513
+ if (overflowable_count + n >= 2 * f -> depth )
514
+ {
515
+ // Double overflowed
516
+ // Index is bigger than the allowed range [0,2*depth)
517
+ // re-position write index to have a full fifo after pushed
518
+ wr_idx = advance_pointer (f , rd_idx , f -> depth - n );
519
+
520
+ // TODO we should also shift out n bytes from read index since we avoid changing rd index !!
521
+ // However memmove() is expensive due to actual copying + wrapping consideration.
522
+ // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory
523
+ // currently deliberately not implemented --> result in incorrect data read back
524
+ }else
525
+ {
526
+ // normal + single overflowed:
527
+ // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read()
528
+ // Therefore we just increase write index
529
+ // we will correct (re-position) read index later on in fifo_read() function
530
+ }
528
531
}
529
532
}
530
533
@@ -868,7 +871,8 @@ bool tu_fifo_clear(tu_fifo_t *f)
868
871
_ff_lock (f -> mutex_wr );
869
872
_ff_lock (f -> mutex_rd );
870
873
871
- f -> rd_idx = f -> wr_idx = 0 ;
874
+ f -> rd_idx = 0 ;
875
+ f -> wr_idx = 0 ;
872
876
873
877
_ff_unlock (f -> mutex_wr );
874
878
_ff_unlock (f -> mutex_rd );
@@ -1031,9 +1035,9 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
1031
1035
1032
1036
if (remain == 0 )
1033
1037
{
1034
- info -> len_lin = 0 ;
1038
+ info -> len_lin = 0 ;
1035
1039
info -> len_wrap = 0 ;
1036
- info -> ptr_lin = NULL ;
1040
+ info -> ptr_lin = NULL ;
1037
1041
info -> ptr_wrap = NULL ;
1038
1042
return ;
1039
1043
}
0 commit comments