mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-09 18:44:31 +00:00
minimize tu_fifo size to 16
- remove non_used_index_space - packed overwritable with item_size
This commit is contained in:
parent
9c73c1a532
commit
2a1b81e3c5
@ -68,22 +68,19 @@ typedef enum
|
|||||||
|
|
||||||
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable)
|
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable)
|
||||||
{
|
{
|
||||||
if (depth > 0x8000) return false; // Maximum depth is 2^15 items
|
// Limit index space to 2*depth - this allows for a fast "modulo" calculation
|
||||||
|
// but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable
|
||||||
|
// only if overflow happens once (important for unsupervised DMA applications)
|
||||||
|
if (depth > 0x8000) return false;
|
||||||
|
|
||||||
_ff_lock(f->mutex_wr);
|
_ff_lock(f->mutex_wr);
|
||||||
_ff_lock(f->mutex_rd);
|
_ff_lock(f->mutex_rd);
|
||||||
|
|
||||||
f->buffer = (uint8_t*) buffer;
|
f->buffer = (uint8_t*) buffer;
|
||||||
f->depth = depth;
|
f->depth = depth;
|
||||||
f->item_size = item_size;
|
f->item_size = (uint16_t) (item_size & 0x7FFF);
|
||||||
f->overwritable = overwritable;
|
f->overwritable = overwritable;
|
||||||
|
|
||||||
// Limit index space to 2*depth - this allows for a fast "modulo" calculation
|
|
||||||
// but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable
|
|
||||||
// only if overflow happens once (important for unsupervised DMA applications)
|
|
||||||
//f->max_pointer_idx = (uint16_t) (2*depth - 1);
|
|
||||||
f->non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1));
|
|
||||||
|
|
||||||
f->rd_idx = f->wr_idx = 0;
|
f->rd_idx = f->wr_idx = 0;
|
||||||
|
|
||||||
_ff_unlock(f->mutex_wr);
|
_ff_unlock(f->mutex_wr);
|
||||||
@ -331,7 +328,8 @@ static uint16_t advance_pointer(tu_fifo_t* f, uint16_t idx, uint16_t offset)
|
|||||||
uint16_t next_p = (uint16_t) (idx + offset);
|
uint16_t next_p = (uint16_t) (idx + offset);
|
||||||
if ( (idx > next_p) || (next_p >= 2*f->depth) )
|
if ( (idx > next_p) || (next_p >= 2*f->depth) )
|
||||||
{
|
{
|
||||||
next_p = (uint16_t) (next_p + f->non_used_index_space);
|
uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1));
|
||||||
|
next_p = (uint16_t) (next_p + non_used_index_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
return next_p;
|
return next_p;
|
||||||
@ -346,7 +344,8 @@ static uint16_t backward_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset)
|
|||||||
uint16_t new_p = (uint16_t) (p - offset);
|
uint16_t new_p = (uint16_t) (p - offset);
|
||||||
if ( (p < new_p) || (new_p >= 2*f->depth) )
|
if ( (p < new_p) || (new_p >= 2*f->depth) )
|
||||||
{
|
{
|
||||||
new_p = (uint16_t) (new_p - f->non_used_index_space);
|
uint16_t const non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1));
|
||||||
|
new_p = (uint16_t) (new_p - non_used_index_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_p;
|
return new_p;
|
||||||
@ -363,13 +362,15 @@ static inline uint16_t idx2ptr(uint16_t idx, uint16_t depth)
|
|||||||
// Works on local copies of w and r - return only the difference and as such can be used to determine an overflow
|
// Works on local copies of w and r - return only the difference and as such can be used to determine an overflow
|
||||||
static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx)
|
static inline uint16_t _tu_fifo_count(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx)
|
||||||
{
|
{
|
||||||
uint16_t cnt = (uint16_t) (wr_idx-rd_idx);
|
uint16_t cnt;
|
||||||
|
|
||||||
// In case we have non-power of two depth we need a further modification
|
// In case we have non-power of two depth we need a further modification
|
||||||
if (rd_idx > wr_idx)
|
if (wr_idx >= rd_idx)
|
||||||
{
|
{
|
||||||
// 2*f->depth - (rd_idx - wr_idx);
|
cnt = (uint16_t) (wr_idx - rd_idx);
|
||||||
cnt = (uint16_t) (cnt - f->non_used_index_space);
|
} else
|
||||||
|
{
|
||||||
|
cnt = (uint16_t) (2*f->depth - (rd_idx - wr_idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
@ -395,7 +396,7 @@ static inline bool _tu_fifo_full(tu_fifo_t* f, uint16_t wAbs, uint16_t rAbs)
|
|||||||
// use DMAs, write functions do not allow such an error.
|
// use DMAs, write functions do not allow such an error.
|
||||||
static inline bool _tu_fifo_overflowed(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx)
|
static inline bool _tu_fifo_overflowed(tu_fifo_t* f, uint16_t wr_idx, uint16_t rd_idx)
|
||||||
{
|
{
|
||||||
return (_tu_fifo_count(f, wr_idx, rd_idx) > f->depth);
|
return _tu_fifo_count(f, wr_idx, rd_idx) > f->depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Works on local copies of w
|
// Works on local copies of w
|
||||||
@ -868,8 +869,6 @@ bool tu_fifo_clear(tu_fifo_t *f)
|
|||||||
_ff_lock(f->mutex_rd);
|
_ff_lock(f->mutex_rd);
|
||||||
|
|
||||||
f->rd_idx = f->wr_idx = 0;
|
f->rd_idx = f->wr_idx = 0;
|
||||||
//f->max_pointer_idx = (uint16_t) (2*f->depth-1);
|
|
||||||
f->non_used_index_space = (uint16_t) (UINT16_MAX - (2*f->depth-1));
|
|
||||||
|
|
||||||
_ff_unlock(f->mutex_wr);
|
_ff_unlock(f->mutex_wr);
|
||||||
_ff_unlock(f->mutex_rd);
|
_ff_unlock(f->mutex_rd);
|
||||||
|
@ -69,8 +69,8 @@ extern "C" {
|
|||||||
* | 0 | 1 | W | 3 | 4 | R |
|
* | 0 | 1 | W | 3 | 4 | R |
|
||||||
*
|
*
|
||||||
* - Number of items in the fifo can be determined in either cases:
|
* - Number of items in the fifo can be determined in either cases:
|
||||||
* - case W > R: Count = W - R
|
* - case W >= R: Count = W - R
|
||||||
* - case W < R: Count = 2*depth - (R - W)
|
* - case W < R: Count = 2*depth - (R - W)
|
||||||
*
|
*
|
||||||
* In non-overwritable mode, computed Count (in above 2 cases) is at most equal to depth.
|
* In non-overwritable mode, computed Count (in above 2 cases) is at most equal to depth.
|
||||||
* However, in over-writable mode, write index can be repeatedly increased and count can be
|
* However, in over-writable mode, write index can be repeatedly increased and count can be
|
||||||
@ -82,10 +82,10 @@ extern "C" {
|
|||||||
* -------------------------
|
* -------------------------
|
||||||
* | R | 1 | 2 | 3 | W | 5 |
|
* | R | 1 | 2 | 3 | W | 5 |
|
||||||
*
|
*
|
||||||
* - Double Overflowed i.e index is out of allowed range [0,2*depth) e.g:
|
* - Double Overflowed i.e index is out of allowed range [0,2*depth)
|
||||||
|
* This occurs when we continue to write after 1st overflowed to 2nd overflowed. e.g:
|
||||||
* write(3), write(1), write(2)
|
* write(3), write(1), write(2)
|
||||||
* Continue to write after overflowed to 2nd overflowed.
|
* This must be prevented since it will cause unrecoverable state, in above example
|
||||||
* We must prevent 2nd overflowed since it will cause incorrect computed of count, in above example
|
|
||||||
* if not handled the fifo will be empty instead of continue-to-be full. Since we must not modify
|
* if not handled the fifo will be empty instead of continue-to-be full. Since we must not modify
|
||||||
* read index in write() function, which cause race condition. We will re-position write index so that
|
* read index in write() function, which cause race condition. We will re-position write index so that
|
||||||
* after data is written it is a full fifo i.e W = depth - R
|
* after data is written it is a full fifo i.e W = depth - R
|
||||||
@ -106,17 +106,16 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t* buffer ; ///< buffer pointer
|
uint8_t* buffer ; // buffer pointer
|
||||||
uint16_t depth ; ///< max items
|
uint16_t depth ; // max items
|
||||||
uint16_t item_size ; ///< size of each item
|
|
||||||
|
|
||||||
bool overwritable ;
|
struct TU_ATTR_PACKED {
|
||||||
|
uint16_t item_size : 15; // size of each item
|
||||||
|
bool overwritable : 1 ; // ovwerwritable when full
|
||||||
|
};
|
||||||
|
|
||||||
uint16_t non_used_index_space ; ///< required for non-power-of-two buffer length
|
volatile uint16_t wr_idx ; // write index
|
||||||
//uint16_t max_pointer_idx ; ///< maximum absolute pointer index
|
volatile uint16_t rd_idx ; // read index
|
||||||
|
|
||||||
volatile uint16_t wr_idx ; ///< write index
|
|
||||||
volatile uint16_t rd_idx ; ///< read index
|
|
||||||
|
|
||||||
#if OSAL_MUTEX_REQUIRED
|
#if OSAL_MUTEX_REQUIRED
|
||||||
osal_mutex_t mutex_wr;
|
osal_mutex_t mutex_wr;
|
||||||
@ -133,13 +132,12 @@ typedef struct
|
|||||||
void * ptr_wrap ; ///< wrapped part start pointer
|
void * ptr_wrap ; ///< wrapped part start pointer
|
||||||
} tu_fifo_buffer_info_t;
|
} tu_fifo_buffer_info_t;
|
||||||
|
|
||||||
#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
|
#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
|
||||||
{ \
|
{ \
|
||||||
.buffer = _buffer, \
|
.buffer = _buffer, \
|
||||||
.depth = _depth, \
|
.depth = _depth, \
|
||||||
.item_size = sizeof(_type), \
|
.item_size = sizeof(_type), \
|
||||||
.overwritable = _overwritable, \
|
.overwritable = _overwritable, \
|
||||||
.non_used_index_space = (uint16_t)(UINT16_MAX - (2*(_depth)-1)), \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
|
#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
|
||||||
|
@ -388,6 +388,8 @@ bool tud_init (uint8_t rhport)
|
|||||||
|
|
||||||
TU_LOG(USBD_DBG, "USBD init on controller %u\r\n", rhport);
|
TU_LOG(USBD_DBG, "USBD init on controller %u\r\n", rhport);
|
||||||
TU_LOG_INT(USBD_DBG, sizeof(usbd_device_t));
|
TU_LOG_INT(USBD_DBG, sizeof(usbd_device_t));
|
||||||
|
TU_LOG_INT(USBD_DBG, sizeof(tu_fifo_t));
|
||||||
|
TU_LOG_INT(USBD_DBG, sizeof(tu_edpt_stream_t));
|
||||||
|
|
||||||
tu_varclr(&_usbd_dev);
|
tu_varclr(&_usbd_dev);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user