[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:
nqtronix
2018-10-03 13:58:16 +02:00
parent 6e323ce62a
commit 24dad3d100
2 changed files with 149 additions and 52 deletions
+26 -51
View File
@@ -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
View File
@@ -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");
}