#ifndef _TUSB_FIFO_H_
#define _TUSB_FIFO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "common/tusb_common.h"
#define CFG_FIFO_MUTEX (CFG_TUSB_OS != OPT_OS_NONE)
#if CFG_FIFO_MUTEX
#include "osal/osal.h"
#define tu_fifo_mutex_t osal_mutex_t
#endif
typedef struct
{
uint8_t* buffer ; uint16_t depth ; uint16_t item_size ; bool overwritable ;
uint16_t non_used_index_space ; uint16_t max_pointer_idx ;
volatile uint16_t wr_idx ; volatile uint16_t rd_idx ;
#if CFG_FIFO_MUTEX
tu_fifo_mutex_t mutex_wr;
tu_fifo_mutex_t mutex_rd;
#endif
} tu_fifo_t;
typedef struct
{
uint16_t len_lin ; uint16_t len_wrap ; void * ptr_lin ; void * ptr_wrap ; } tu_fifo_buffer_info_t;
#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
{ \
.buffer = _buffer, \
.depth = _depth, \
.item_size = sizeof(_type), \
.overwritable = _overwritable, \
.non_used_index_space = UINT16_MAX - (2*(_depth)-1), \
.max_pointer_idx = 2*(_depth)-1, \
}
#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
uint8_t _name##_buf[_depth*sizeof(_type)]; \
tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable)
bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
bool tu_fifo_clear(tu_fifo_t *f);
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);
#if CFG_FIFO_MUTEX
TU_ATTR_ALWAYS_INLINE static inline
void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t write_mutex_hdl, tu_fifo_mutex_t read_mutex_hdl)
{
f->mutex_wr = write_mutex_hdl;
f->mutex_rd = read_mutex_hdl;
}
#endif
bool tu_fifo_write (tu_fifo_t* f, void const * p_data);
uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t n);
uint16_t tu_fifo_write_n_const_addr_full_words (tu_fifo_t* f, const void * data, uint16_t n);
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 (tu_fifo_t* f, void * p_buffer);
uint16_t tu_fifo_peek_n (tu_fifo_t* f, void * p_buffer, uint16_t n);
uint16_t tu_fifo_count (tu_fifo_t* f);
uint16_t tu_fifo_remaining (tu_fifo_t* f);
bool tu_fifo_empty (tu_fifo_t* f);
bool tu_fifo_full (tu_fifo_t* f);
bool tu_fifo_overflowed (tu_fifo_t* f);
void tu_fifo_correct_read_pointer (tu_fifo_t* f);
TU_ATTR_ALWAYS_INLINE static inline
uint16_t tu_fifo_depth(tu_fifo_t* f)
{
return f->depth;
}
void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n);
void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n);
void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info);
void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
#ifdef __cplusplus
}
#endif
#endif