35#if defined(__ICCARM__)
36#pragma diag_suppress = Pa082
39#if OSAL_MUTEX_REQUIRED
53#define _ff_lock(_mutex)
54#define _ff_unlock(_mutex)
65#ifdef TUP_MEM_CONST_ADDR
75 if (depth > 0x8000)
return false;
82 f->item_size = (uint16_t) (item_size & 0x7FFF);
83 f->overwritable = overwritable;
97#ifdef TUP_MEM_CONST_ADDR
103 volatile const uint32_t * reg_rx = (
volatile const uint32_t *) app_buf;
106 uint16_t full_words = len >> 2;
114 uint8_t
const bytes_rem = len & 0x03;
117 uint32_t tmp32 = *reg_rx;
118 memcpy(ff_buf, &tmp32, bytes_rem);
126 volatile uint32_t * reg_tx = (
volatile uint32_t *) app_buf;
129 uint16_t full_words = len >> 2;
137 uint8_t
const bytes_rem = len & 0x03;
141 memcpy(&tmp32, ff_buf, bytes_rem);
151 memcpy(f->
buffer + (rel * f->item_size), app_buf, f->item_size);
157 uint16_t
const lin_count = f->
depth - wr_ptr;
158 uint16_t
const wrap_count = n - lin_count;
160 uint16_t lin_bytes = lin_count * f->item_size;
161 uint16_t wrap_bytes = wrap_count * f->item_size;
164 uint8_t* ff_buf = f->
buffer + (wr_ptr * f->item_size);
172 memcpy(ff_buf, app_buf, n*f->item_size);
179 memcpy(ff_buf, app_buf, lin_bytes);
183 memcpy(f->
buffer, ((uint8_t
const*) app_buf) + lin_bytes, wrap_bytes);
186#ifdef TUP_MEM_CONST_ADDR
199 uint16_t nLin_4n_bytes = lin_bytes & 0xFFFC;
201 ff_buf += nLin_4n_bytes;
204 uint8_t rem = lin_bytes & 0x03;
207 volatile const uint32_t * rx_fifo = (
volatile const uint32_t *) app_buf;
209 uint8_t remrem = (uint8_t)
tu_min16(wrap_bytes, 4-rem);
210 wrap_bytes -= remrem;
212 uint32_t tmp32 = *rx_fifo;
213 uint8_t * src_u8 = ((uint8_t *) &tmp32);
216 while(rem--) *ff_buf++ = *src_u8++;
220 while(remrem--) *ff_buf++ = *src_u8++;
239 memcpy(app_buf, f->
buffer + (rel * f->item_size), f->item_size);
245 uint16_t
const lin_count = f->
depth - rd_ptr;
246 uint16_t
const wrap_count = n - lin_count;
248 uint16_t lin_bytes = lin_count * f->item_size;
249 uint16_t wrap_bytes = wrap_count * f->item_size;
252 uint8_t* ff_buf = f->
buffer + (rd_ptr * f->item_size);
257 if ( n <= lin_count )
260 memcpy(app_buf, ff_buf, n*f->item_size);
267 memcpy(app_buf, ff_buf, lin_bytes);
270 memcpy((uint8_t*) app_buf + lin_bytes, f->
buffer, wrap_bytes);
273#ifdef TUP_MEM_CONST_ADDR
275 if ( n <= lin_count )
285 uint16_t lin_4n_bytes = lin_bytes & 0xFFFC;
287 ff_buf += lin_4n_bytes;
290 uint8_t rem = lin_bytes & 0x03;
293 volatile uint32_t * reg_tx = (
volatile uint32_t *) app_buf;
295 uint8_t remrem = (uint8_t)
tu_min16(wrap_bytes, 4-rem);
296 wrap_bytes -= remrem;
299 uint8_t * dst_u8 = (uint8_t *)&tmp32;
302 while(rem--) *dst_u8++ = *ff_buf++;
306 while(remrem--) *dst_u8++ = *ff_buf++;
329TU_ATTR_ALWAYS_INLINE
static inline
330uint16_t
_ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx)
333 if (wr_idx >= rd_idx)
335 return (uint16_t) (wr_idx - rd_idx);
338 return (uint16_t) (2*depth - (rd_idx - wr_idx));
343TU_ATTR_ALWAYS_INLINE
static inline
346 uint16_t
const count =
_ff_count(depth, wr_idx, rd_idx);
347 return (depth > count) ? (depth - count) : 0;
361 uint16_t new_idx = (uint16_t) (idx +
offset);
362 if ( (idx > new_idx) || (new_idx >= 2*depth) )
364 uint16_t
const non_used_index_space = (uint16_t) (UINT16_MAX - (2*depth-1));
365 new_idx = (uint16_t) (new_idx + non_used_index_space);
378 uint16_t new_idx = (uint16_t) (idx -
offset);
379 if ( (idx < new_idx) || (new_idx >= 2*depth) )
381 uint16_t
const non_used_index_space = (uint16_t) (UINT16_MAX - (2*depth-1));
382 new_idx = (uint16_t) (new_idx - non_used_index_space);
390TU_ATTR_ALWAYS_INLINE
static inline
394 while ( idx >= depth ) idx -= depth;
401TU_ATTR_ALWAYS_INLINE
static inline
405 if ( wr_idx >= f->
depth )
407 rd_idx = wr_idx - f->
depth;
410 rd_idx = wr_idx + f->
depth;
425 if ( cnt == 0 )
return false;
428 if ( cnt > f->
depth )
449 if ( cnt == 0 )
return 0;
452 if ( cnt > f->
depth )
459 if ( cnt < n ) n = cnt;
464 _ff_pull_n(f, p_buffer, n, rd_ptr, copy_mode);
471 if ( n == 0 )
return 0;
475 uint16_t wr_idx = f->
wr_idx;
476 uint16_t rd_idx = f->
rd_idx;
478 uint8_t
const* buf8 = (uint8_t
const*)
data;
480 TU_LOG(TU_FIFO_DBG,
"rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ",
483 if ( !f->overwritable )
500 buf8 += (n - f->
depth) * f->item_size;
514 uint16_t
const overflowable_count =
_ff_count(f->
depth, wr_idx, rd_idx);
515 if (overflowable_count + n >= 2*f->
depth)
540 TU_LOG(TU_FIFO_DBG,
"actual_n = %u, wr_ptr = %u", n, wr_ptr);
548 TU_LOG(TU_FIFO_DBG,
"\tnew_wr = %u\r\n", f->
wr_idx);
735#ifdef TUP_MEM_CONST_ADDR
824 uint16_t
const wr_idx = f->
wr_idx;
866#ifdef TUP_MEM_CONST_ADDR
924 f->overwritable = overwritable;
992 uint16_t wr_idx = f->
wr_idx;
993 uint16_t rd_idx = f->
rd_idx;
1012 info->ptr_lin = NULL;
1013 info->ptr_wrap = NULL;
1025 if (wr_ptr > rd_ptr)
1028 info->len_lin = cnt;
1031 info->ptr_wrap = NULL;
1037 info->len_wrap = cnt -
info->len_lin;
1059 uint16_t wr_idx = f->
wr_idx;
1060 uint16_t rd_idx = f->
rd_idx;
1067 info->ptr_lin = NULL;
1068 info->ptr_wrap = NULL;
1079 if (wr_ptr < rd_ptr)
1082 info->len_lin = rd_ptr-wr_ptr;
1084 info->ptr_wrap = NULL;
1089 info->len_wrap = remain -
info->len_lin;
static TU_ATTR_ALWAYS_INLINE bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
static TU_ATTR_ALWAYS_INLINE bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
SemaphoreHandle_t osal_mutex_t
static void * memcpy(void *dst, const void *src, size_t n)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_min16(uint16_t x, uint16_t y)
static TU_ATTR_ALWAYS_INLINE void tu_unaligned_write32(void *mem, uint32_t value)
static TU_ATTR_ALWAYS_INLINE uint32_t tu_unaligned_read32(const void *mem)
static uint16_t _tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n, tu_fifo_copy_mode_t copy_mode)
bool tu_fifo_overflowed(tu_fifo_t *f)
Check if overflow happened.
uint16_t tu_fifo_count(tu_fifo_t *f)
Get number of items in FIFO.
void tu_fifo_correct_read_pointer(tu_fifo_t *f)
uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t *f, const void *data, uint16_t n)
This function will write n elements into the array index specified by the write pointer and increment...
static TU_ATTR_ALWAYS_INLINE void _ff_lock(osal_mutex_t mutex)
static TU_ATTR_ALWAYS_INLINE uint16_t _ff_correct_read_index(tu_fifo_t *f, uint16_t wr_idx)
static void _ff_push_const_addr(uint8_t *ff_buf, const void *app_buf, uint16_t len)
void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
Get linear write info.
static uint16_t _tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, tu_fifo_copy_mode_t copy_mode)
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable)
static void _ff_pull_n(tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_copy_mode_t copy_mode)
static bool _tu_fifo_peek(tu_fifo_t *f, void *p_buffer, uint16_t wr_idx, uint16_t rd_idx)
bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable)
Change the fifo mode to overwritable or not overwritable.
uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n)
This function will write n elements into the array index specified by the write pointer and increment...
uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n)
Read n items without removing it from the FIFO This function checks for an overflow and corrects read...
bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer)
Read one item without removing it from the FIFO. This function checks for an overflow and corrects re...
static void _ff_pull(tu_fifo_t *f, void *app_buf, uint16_t rel)
static TU_ATTR_ALWAYS_INLINE uint16_t idx2ptr(uint16_t depth, uint16_t idx)
static uint16_t backward_index(uint16_t depth, uint16_t idx, uint16_t offset)
void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n)
Advance write pointer - intended to be used in combination with DMA. It is possible to fill the FIFO ...
uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t *f, void *buffer, uint16_t n)
This function will read n elements from the array index specified by the read pointer and increment t...
bool tu_fifo_full(tu_fifo_t *f)
Check if FIFO is full.
uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n)
This function will read n elements from the array index specified by the read pointer and increment t...
void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n)
Advance read pointer - intended to be used in combination with DMA. It is possible to read from the F...
static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset)
bool tu_fifo_read(tu_fifo_t *f, void *buffer)
Read one element out of the buffer.
bool tu_fifo_empty(tu_fifo_t *f)
Check if FIFO is empty.
static void _ff_push_n(tu_fifo_t *f, void const *app_buf, uint16_t n, uint16_t wr_ptr, tu_fifo_copy_mode_t copy_mode)
bool tu_fifo_write(tu_fifo_t *f, const void *data)
Write one element into the buffer.
static uint16_t _tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_copy_mode_t copy_mode)
static void _ff_push(tu_fifo_t *f, void const *app_buf, uint16_t rel)
tu_fifo_copy_mode_t
Write modes intended to allow special read and write functions to be able to copy data to and from US...
@ TU_FIFO_COPY_INC
Copy from/to an increasing source/destination address - default mode.
@ TU_FIFO_COPY_CST_FULL_WORDS
Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardwa...
static TU_ATTR_ALWAYS_INLINE void _ff_unlock(osal_mutex_t mutex)
uint16_t tu_fifo_remaining(tu_fifo_t *f)
Get remaining space in FIFO.
void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
Get read info.
static TU_ATTR_ALWAYS_INLINE uint16_t _ff_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx)
static void _ff_pull_const_addr(void *app_buf, const uint8_t *ff_buf, uint16_t len)
static TU_ATTR_ALWAYS_INLINE uint16_t _ff_remaining(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx)
bool tu_fifo_clear(tu_fifo_t *f)
Clear the fifo read and write pointers.