mirror of
https://github.com/nqtronix/fifofast.git
synced 2026-09-25 11:08:47 +08:00
[snapshot 0.3.0] _fff_remove is now proven to work... [+3]
... because I totaly forgot to test it properly in last snapshot [change] _fff_remove re-written and _fff_remove_lite variant added [new] tests for _fff_remove added [new] test for _fff_peek idx overflow added
This commit is contained in:
+26
-51
@@ -42,11 +42,13 @@
|
||||
|
||||
// version numbering is based on "Semantic Versioning 2.0.0" (semver.org)
|
||||
#define FIFOFAST_VERSION_MAJOR 0
|
||||
#define FIFOFAST_VERSION_MINOR 2
|
||||
#define FIFOFAST_VERSION_PATCH 2
|
||||
#define FIFOFAST_VERSION_MINOR 3
|
||||
#define FIFOFAST_VERSION_PATCH 0
|
||||
#define FIFOFAST_VERSION_SUFFIX
|
||||
#define FIFOFAST_VERSION_META
|
||||
|
||||
// For all development versions (0.x.x) the minor version is increased whenever a function was renamed
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Check requirements
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -224,59 +226,37 @@ struct _fff__name_structp8(_id) _id = \
|
||||
// _id: C conform identifier
|
||||
#define _fff_reset(_id) do{_id.read=0; _id.write=0; _id.level=0;} while (0)
|
||||
|
||||
|
||||
// TODO: remove is broken, reason unknown; details:
|
||||
// _fff_remove(_id, amount) should have the same effect as while(amount){_fff_read(_id);amount--}
|
||||
|
||||
|
||||
// removes a certain number of elements or less, if not enough elements are available.
|
||||
// This function is especially useful after data has been used by _fff_peek(...)
|
||||
// NOTE: This macro can only delete up to _fff_depth(_id)-1 elements! Workaround: Call twice or use
|
||||
// _fff_reset(_id) instead.
|
||||
// _id: C conform identifier
|
||||
// amount: Amount of elements which will be removed; must be 0 <= amount <= _fff_depth(_id);
|
||||
// #define _fff_remove_broken(_id, amount) \
|
||||
// do{ \
|
||||
// uint8_t _amount = (amount); \
|
||||
// if(_fff_is_full(_id)) \
|
||||
// { \
|
||||
// _id.min_w++; \
|
||||
// _amount--; \
|
||||
// } \
|
||||
// if(_fff_mem_mask(_id)-_id.min_w > (_amount)) /*flush if equal*/ \
|
||||
// { \
|
||||
// _id.min_w += _amount; \
|
||||
// _id.read = _fff_wrap(_id, (_id.read+(_amount+1))); \
|
||||
// } \
|
||||
// else \
|
||||
// _fff_reset(_id); \
|
||||
// }while(0)
|
||||
|
||||
|
||||
// amount: Amount of elements which will be removed
|
||||
#define _fff_remove(_id, amount) \
|
||||
do{ \
|
||||
for (uint8_t _idx = amount; _idx > 0; _idx--) \
|
||||
{_fff_read(_id);} \
|
||||
if(amount > 0) \
|
||||
{ \
|
||||
typeof(_id.level) _amount = (typeof(_id.level))amount; \
|
||||
if(amount > _id.level) \
|
||||
_amount = _id.level; \
|
||||
_fff_remove_lite(_id, _amount); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
|
||||
#define _fff_remove_fast(_id, amount) \
|
||||
// removes a certain number of elements. The user must ensure that the given amount of elements can
|
||||
// be removed; 0 and _fff_depth(_id) are invallid amounts! If you require argument checking use
|
||||
// _fff_remove().
|
||||
// This function is especially useful after data has been used by _fff_peek(...)
|
||||
// _id: C conform identifier
|
||||
// amount: Amount of elements which will be removed; must be 1 <= amount <= _fff_mem_level(_id);
|
||||
#define _fff_remove_lite(_id, amount) \
|
||||
do{ \
|
||||
if(!_fff_is_full) \
|
||||
{ \
|
||||
if (_id.amount >= _id.level) \
|
||||
{ \
|
||||
_id.level = 0; \
|
||||
_id.read = _id.write; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_id.level -= amount; \
|
||||
_id.read = _fff_wrap(_id, _id.read+amount) \
|
||||
} \
|
||||
} \
|
||||
if(!_fff_is_full(_id)) \
|
||||
_id.level -= amount; \
|
||||
else \
|
||||
{ \
|
||||
_id.level -= (amount-1) \
|
||||
_id.read = _fff_wrap(_id, _id.read+amount) \
|
||||
} \
|
||||
_id.level -= (amount-1); \
|
||||
_id.read = _fff_wrap(_id, _id.read+amount); \
|
||||
}while(0)
|
||||
|
||||
|
||||
@@ -341,11 +321,6 @@ do{ \
|
||||
_fff_write_lite(_id, newdata); \
|
||||
}while(0)
|
||||
|
||||
// #define _fff_write_bulk(_id, cnt, pointer)
|
||||
// do{
|
||||
//
|
||||
//
|
||||
// }while(0);
|
||||
|
||||
// adds an element to the fifo, but does not write any data to it. instead, a pointer to the data
|
||||
// section is returned. The caller may write up to _fff_data_size(_id) bytes to this location.
|
||||
|
||||
+123
-1
@@ -46,6 +46,7 @@ int main(void)
|
||||
volatile uint8_t dbg1 = 0;
|
||||
volatile uint8_t dbg2 = 0;
|
||||
volatile uint8_t dbg3 = 0;
|
||||
volatile uint8_t dbg4 = 0;
|
||||
|
||||
// for "_fff_read...()" macros only
|
||||
volatile uint8_t dbg_read0 = 0;
|
||||
@@ -138,6 +139,9 @@ int main(void)
|
||||
dbg2 = _fff_peek(fifo_uint8, 2); // = 0x55
|
||||
dbg3 = _fff_peek(fifo_uint8, 3); // = 0x76
|
||||
|
||||
// demonstrate "out of bounds" safety
|
||||
dbg4 = _fff_peek(fifo_uint8, 4); // = 0x53
|
||||
|
||||
dbg_mem_depth = _fff_mem_depth(fifo_uint8); // = 4 (constant)
|
||||
dbg_mem_mask = _fff_mem_mask(fifo_uint8); // = 3 (= 0b11, constant)
|
||||
dbg_mem_level = _fff_mem_level(fifo_uint8); // = 3 (see macro description)
|
||||
@@ -151,7 +155,6 @@ int main(void)
|
||||
// Test Cases READ
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: level decremented wrongly if fifo is full
|
||||
// read 2 values with the fast '_lite' variant (we know we have written at least to entries)
|
||||
dbg_read0 = _fff_read_lite(fifo_uint8); // = 0x53
|
||||
dbg_read1 = _fff_read_lite(fifo_uint8); // = 0x74
|
||||
@@ -260,6 +263,125 @@ int main(void)
|
||||
asm volatile ("nop"); // easy breakpoint
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Test Case REMOVE_LITE
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// fill with any data (macros have been prooven o work before)
|
||||
_fff_write_lite(fifo_uint8, 0x23);
|
||||
_fff_write_lite(fifo_uint8, 0x24);
|
||||
_fff_write_lite(fifo_uint8, 0x25);
|
||||
_fff_write_lite(fifo_uint8, 0x26);
|
||||
// fifo is now full
|
||||
|
||||
// _remove 2 (Test case: fifo full before macro)
|
||||
_fff_remove_lite(fifo_uint8, 2);
|
||||
|
||||
dbg0 = _fff_peek(fifo_uint8, 0); // = 0x25
|
||||
dbg1 = _fff_peek(fifo_uint8, 1); // = 0x26
|
||||
dbg2 = _fff_peek(fifo_uint8, 2); // = 0x23 (empty)
|
||||
dbg3 = _fff_peek(fifo_uint8, 3); // = 0x24 (empty)
|
||||
|
||||
dbg_mem_depth = _fff_mem_depth(fifo_uint8); // = 4 (constant)
|
||||
dbg_mem_mask = _fff_mem_mask(fifo_uint8); // = 3 (= 0b11, constant)
|
||||
dbg_mem_level = _fff_mem_level(fifo_uint8); // = 2 (see macro description)
|
||||
dbg_mem_free = _fff_mem_free(fifo_uint8); // = 1 (see macro description)
|
||||
dbg_is_empty = _fff_is_empty(fifo_uint8); // = 0 (= false)
|
||||
dbg_is_full = _fff_is_full(fifo_uint8); // = 0 (= false)
|
||||
asm volatile ("nop"); // easy breakpoint
|
||||
|
||||
// _remove 1 (Test case: fifo not full before and not empty after macro)
|
||||
_fff_remove_lite(fifo_uint8, 1);
|
||||
|
||||
dbg0 = _fff_peek(fifo_uint8, 0); // = 0x26
|
||||
dbg1 = _fff_peek(fifo_uint8, 1); // = 0x23 (empty)
|
||||
dbg2 = _fff_peek(fifo_uint8, 2); // = 0x24 (empty)
|
||||
dbg3 = _fff_peek(fifo_uint8, 3); // = 0x25 (empty)
|
||||
|
||||
dbg_mem_depth = _fff_mem_depth(fifo_uint8); // = 4 (constant)
|
||||
dbg_mem_mask = _fff_mem_mask(fifo_uint8); // = 3 (= 0b11, constant)
|
||||
dbg_mem_level = _fff_mem_level(fifo_uint8); // = 1 (see macro description)
|
||||
dbg_mem_free = _fff_mem_free(fifo_uint8); // = 2 (see macro description)
|
||||
dbg_is_empty = _fff_is_empty(fifo_uint8); // = 0 (= false)
|
||||
dbg_is_full = _fff_is_full(fifo_uint8); // = 0 (= false)
|
||||
asm volatile ("nop"); // easy breakpoint
|
||||
|
||||
// _remove 1 (Test case: fifo empty after macro)
|
||||
_fff_remove_lite(fifo_uint8, 1);
|
||||
|
||||
dbg0 = _fff_peek(fifo_uint8, 0); // = 0x23 (empty)
|
||||
dbg1 = _fff_peek(fifo_uint8, 1); // = 0x24 (empty)
|
||||
dbg2 = _fff_peek(fifo_uint8, 2); // = 0x25 (empty)
|
||||
dbg3 = _fff_peek(fifo_uint8, 3); // = 0x26 (empty)
|
||||
|
||||
dbg_mem_depth = _fff_mem_depth(fifo_uint8); // = 4 (constant)
|
||||
dbg_mem_mask = _fff_mem_mask(fifo_uint8); // = 3 (= 0b11, constant)
|
||||
dbg_mem_level = _fff_mem_level(fifo_uint8); // = 0 (see macro description)
|
||||
dbg_mem_free = _fff_mem_free(fifo_uint8); // = 3 (see macro description)
|
||||
dbg_is_empty = _fff_is_empty(fifo_uint8); // != 0 (= true, note that the actually value is NOT guaranteed to be '1'!)
|
||||
dbg_is_full = _fff_is_full(fifo_uint8); // = 0 (= false)
|
||||
asm volatile ("nop"); // easy breakpoint
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Test Case REMOVE_LITE
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// fill with any data (macros have been prooven o work before)
|
||||
_fff_write_lite(fifo_uint8, 0x13);
|
||||
_fff_write_lite(fifo_uint8, 0x14);
|
||||
_fff_write_lite(fifo_uint8, 0x15);
|
||||
_fff_write_lite(fifo_uint8, 0x16);
|
||||
// fifo is now full
|
||||
|
||||
// _remove 0 (Test case: amount <= 0 elements)
|
||||
_fff_remove(fifo_uint8, 0);
|
||||
|
||||
dbg0 = _fff_peek(fifo_uint8, 0); // = 0x13
|
||||
dbg1 = _fff_peek(fifo_uint8, 1); // = 0x14
|
||||
dbg2 = _fff_peek(fifo_uint8, 2); // = 0x15
|
||||
dbg3 = _fff_peek(fifo_uint8, 3); // = 0x16
|
||||
|
||||
dbg_mem_depth = _fff_mem_depth(fifo_uint8); // = 4 (constant)
|
||||
dbg_mem_mask = _fff_mem_mask(fifo_uint8); // = 3 (= 0b11, constant)
|
||||
dbg_mem_level = _fff_mem_level(fifo_uint8); // = 0 (see macro description)
|
||||
dbg_mem_free = _fff_mem_free(fifo_uint8); // = 3 (see macro description)
|
||||
dbg_is_empty = _fff_is_empty(fifo_uint8); // = 0 (= false)
|
||||
dbg_is_full = _fff_is_full(fifo_uint8); // != 0 (= true, note that the actually value is NOT guaranteed to be '1'!)
|
||||
asm volatile ("nop"); // easy breakpoint
|
||||
|
||||
// _remove 4 (Test case: amount > _fff_mem_level() w/ fifo full)
|
||||
_fff_remove(fifo_uint8, 4);
|
||||
|
||||
dbg0 = _fff_peek(fifo_uint8, 0); // = 0x16
|
||||
dbg1 = _fff_peek(fifo_uint8, 1); // = 0x13 (empty)
|
||||
dbg2 = _fff_peek(fifo_uint8, 2); // = 0x14 (empty)
|
||||
dbg3 = _fff_peek(fifo_uint8, 3); // = 0x15 (empty)
|
||||
|
||||
dbg_mem_depth = _fff_mem_depth(fifo_uint8); // = 4 (constant)
|
||||
dbg_mem_mask = _fff_mem_mask(fifo_uint8); // = 3 (= 0b11, constant)
|
||||
dbg_mem_level = _fff_mem_level(fifo_uint8); // = 1 (see macro description)
|
||||
dbg_mem_free = _fff_mem_free(fifo_uint8); // = 2 (see macro description)
|
||||
dbg_is_empty = _fff_is_empty(fifo_uint8); // = 0 (= false)
|
||||
dbg_is_full = _fff_is_full(fifo_uint8); // = 0 (= false)
|
||||
asm volatile ("nop"); // easy breakpoint
|
||||
|
||||
// _remove 4 (Test case: amount > _fff_mem_level() w/ fifo not full)
|
||||
_fff_remove(fifo_uint8, 4);
|
||||
|
||||
dbg0 = _fff_peek(fifo_uint8, 0); // = 0x13 (empty)
|
||||
dbg1 = _fff_peek(fifo_uint8, 1); // = 0x14 (empty)
|
||||
dbg2 = _fff_peek(fifo_uint8, 2); // = 0x15 (empty)
|
||||
dbg3 = _fff_peek(fifo_uint8, 3); // = 0x16 (empty)
|
||||
|
||||
dbg_mem_depth = _fff_mem_depth(fifo_uint8); // = 4 (constant)
|
||||
dbg_mem_mask = _fff_mem_mask(fifo_uint8); // = 3 (= 0b11, constant)
|
||||
dbg_mem_level = _fff_mem_level(fifo_uint8); // = 0 (see macro description)
|
||||
dbg_mem_free = _fff_mem_free(fifo_uint8); // = 3 (see macro description)
|
||||
dbg_is_empty = _fff_is_empty(fifo_uint8); // != 0 (= true, note that the actually value is NOT guaranteed to be '1'!)
|
||||
dbg_is_full = _fff_is_full(fifo_uint8); // = 0 (= false)
|
||||
asm volatile ("nop"); // easy breakpoint
|
||||
|
||||
// End simulation
|
||||
while (1) asm volatile ("nop");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user