Multi purpose buffer module.

Multipurpose ringbuffer

Since there weren't any ringbuffers available on the internet optimized for 32-Bit ARM operation without unix-calls and dynamic memory... I created one.

This module is a fixed ringbuffer, it does not allocate any memory, it can work as FIFO or LIFO or any other exotic mode depending on your imagination. With a fixed 32Bit element size it is optimized for 32 bit arm processors. Any smaller value will have overhead, any larger value will require a double entry. (not recommended)

I hope you can use it.

Information

This is not a C++ class, it is a C Module. It does work object oriented, however you cannot work on the object, you work with the object.

Import programxIFO_example

Small example for xIFO

Files at this revision

API Documentation at this revision

Comitter:
jeroen3
Date:
Fri Apr 04 21:36:55 2014 +0000
Parent:
1:5f59aa9b86ed
Commit message:
major revision, now supports multiple C formats and Templates C++

Changed in this revision

xIFO.c Show diff for this revision Revisions of this file
xIFO.cpp Show annotated file Show diff for this revision Revisions of this file
xIFO.h Show annotated file Show diff for this revision Revisions of this file
--- a/xIFO.c	Mon Oct 28 19:20:00 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,287 +0,0 @@
-
- /**
- * @file    xifo.c
- * @brief   xifo circular buffer
- * @details xifo supplies object oriented circular buffer with 32 bit size elements. \n
- *                     To use either as FIFO (First In First Out) or as FILO (First In Last Out)
- *
- * @Author    Jeroen Lodder
- * @Date        April 2013
- * @version 2
- *
- * @{
- */
-#include "xIFO.h"
-
-/**
- * @brief   Initialise buffer object structure.
- *
- * @note    Does not clear memory pool.
- *
- * @param[in] c   Pointer to @p xifo_t object used for configuration.
- * @param[in] s   Number of elements buffer can hold (size).
- * @param[in] sp  Start of pre-allocated memory pool.
- */
-void xifo_init(xifo_t *c, uint32_t s, uint32_t *sp){
-    c->startpool        = sp;
-    c->endpool          = &sp[s-1];
-    c->size             = s;
-    c->full             = 0;
-    c->elementcount     = 0;
-    c->read             = sp;
-    c->write            = sp;
-}
-
-/**
- * @brief   Clear buffer contents
- *
- * @note    Must be used on initialised buffer object.
- *
- * @param[in] c   Pointer to @p xifo_t object.
- */
-void xifo_clear(xifo_t *c){
-    c->ptemp = c->startpool;
-    while(c->ptemp <= c->endpool){
-        *c->ptemp++ = 0;        
-    }
-}
-
-/**
- * @brief   Read from buffer (lr) Least Recent oriented (fifo)
- *
- * @note    Buffer state will be preserved
- *
- * @warning    Consider this opertaion as atomic!
- *
- * @details Read n elements from the oldest element to the most recent.
- *                    As for index[0] the least recently added element is returned.
- *                    And for index[elementcount] the most recent element is returned.
- *                    This makes it possible to peek in fifo.
- *
- * @param[in] c           Pointer to @p xifo_t used for configuration.
- * @param[in] index   Index relative from least recent
- *
- * @return    Contents of element or 0 if failed (element can hold 0)
- */
-uint32_t xifo_read_lr(xifo_t *c, uint32_t index){
-    /* Verify there is valid data to read */
-    if(index+1 > c->elementcount){
-        return 0;    /* Nothing to read there */
-    }
-    /* Calculate index of oldest element */
-    index = (c->elementcount-1) - index;
-    /* Set pointer */
-    c->ptemp = (c->read) - index;
-    if(c->ptemp < c->startpool){
-        /* We exceeded pool boundaries */
-        /* Calculate overshoot (startpool - indexptr) and subtract from end */
-        /* Since one element of overshoot results in end - 1 you would miss the last value */
-        c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp);
-    }
-    /* Read most recent */
-    return *c->ptemp;
-}
-
-/**
- * @brief   Read from buffer (mr) Most Recent oriented (filo)
- *
- * @note    Buffer state will be preserved
- *
- * @warning    Consider this opertaion as atomic!
- *
- * @details Read n elements back in time.
- *                    As for index[0] the most recently added element is returned.
- *                    And for index[elementcount] the oldest element is returned.
- *                    This makes it possible to keep history. For DSP application.
- *
- * @param[in] c           Pointer to @p xifo_t used for configuration.
- * @param[in] index   Index relative from most recent
- *
- * @return    Contents of element or 0 if failed (element can hold 0)
- */
-uint32_t xifo_read_mr(xifo_t *c, uint32_t index){
-    /* Verify there is valid data to read */
-    if(index+1 > c->elementcount){
-        return 0;    /* Nothing to read there */
-    }
-    /* Set pointer */
-    c->ptemp = (c->read) - index;
-    /* Validate pointer */
-    if(c->ptemp < c->startpool){
-        /* We exceeded pool boundaries */
-        /* Calculate overshoot (startpool - indexptr) and subtract from end */
-        /* Since one element of overshoot results in end - 1 you would miss the last value */
-        c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp);
-    }
-    /* Read most recent */
-    return *c->ptemp;
-}
-
-/**
- * @brief   Pop (mr) most recent from buffer (filo)
- *
- * @note    Buffer state will be altered
- *
- * @warning    Consider this opertaion as atomic!
- *
- * @details Read and remove the most recently added from the buffer.
- *                     Using this results in a stack type of buffer.
- *
- * @param[in] c           Pointer to @p xifo_t used for configuration.
- *
- * @return    Contents of element or 0 if failed (element can hold 0)
- */
-uint32_t xifo_pop_mr(xifo_t *c){
-    /* Verify there is valid data read */
-    if(c->elementcount == 0){
-        return 0;    /* Nothing to read there */
-    }
-    /* Read */
-    c->temp = *c->read;
-    /* Empty */
-    *c->read = 0;
-    /* Most recent element read, return write pointer */
-    c->write = c->read;
-    /* Decrement read pointer */
-    c->read--;
-    /* Validate pointer */
-    if( c->read < c->startpool ){
-        /* We exceeded pool boundaries */
-        c->read = c->endpool;
-    }
-    /* Reduce elementcount */
-    c->elementcount--;
-    if(c->elementcount < c->size)
-        c->full = 0;
-    return c->temp;
-}
-
-/**
- * @brief   Pop (lr) least recent from buffer (fifo)
- *
- * @note    Buffer state will be altered
- *
- * @warning    Consider this opertaion as atomic!
- *
- * @details Read and remove the least recently added from the buffer.
- *                     Using this results in a fifo type of buffer.
- *
- * @param[in] c    Pointer to @p xifo_t used for configuration.
- *
- * @return    Contents of element or 0 if failed (element can hold 0)
- */
-uint32_t xifo_pop_lr(xifo_t *c){    
-    /* Verify there is valid data read */
-    if(c->elementcount == 0){
-        return 0;    /* Nothing to read there */
-    }
-    /* Derive least recent buffer element */
-    c->ptemp = c->read+1 - c->elementcount;
-    /* Validate pointer */
-    if(c->ptemp < c->startpool){
-        /* We exceeded pool boundaries */
-        /* Calculate overshoot (startpool - indexptr) and subtract from end */
-        /* Since one element of overshoot results in end - 1 you would miss the last value */
-        c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp);
-    }
-    /* Read oldest buffer element */
-    { /* block with temporary variable to prevent stack use */
-        register uint32_t element;
-        /* Read to temp register */
-        element = *c->ptemp;
-        /* Empty */
-        *c->ptemp = 0;
-        /* Clear temp register */
-        c->temp = element;
-    }
-    /* Reduce elementcount */
-    c->elementcount--;
-    /* Check full flag */
-    if(c->elementcount < c->size)
-        c->full = 0;
-    return c->temp;
-}
-
-/**
- * @brief   Write to buffer
- *
- * @note    Readpointer is automatically set to the last added element.
- *
- * @warning    Consider this opertaion as atomic!
- *                    
- * @details Adds a value to the buffer.
- *                    Automatically overwrites oldest elements when full.
- *
- * @param[in] c            Pointer to @p xifo_t used for configuration.
- * @param[in] data    Data to add to buffer
- *
- * @return    Number of free buffer elements
- */
-uint32_t xifo_write(xifo_t *c, uint32_t data){    
-    /* Write data */
-    *c->write = data;
-    /* Update read pointer to most recent element */
-    c->read = c->write;
-    /* Write pointer increment */
-    c->write += 1;
-    /* Validate pointer */
-    if( c->write > c->endpool){
-          /* We exceeded pool boundaries */
-            c->write = c->startpool;
-    }
-    /* Update elementcount */
-    c->elementcount++;
-    /* Verify full */
-    if( c->elementcount >= c->size ){
-        c->full = 1;
-        c->elementcount = c->size;
-    }
-    /* return free elements count */
-    return c->size - c->elementcount;
-}
-
-/**
- * @brief   Get buffer size
- *
- * @param[in] c    Pointer to @p xifo_t used for configuration.
- *
- * @return    Size of memory pool in elements
- */
-uint32_t xifo_get_size(xifo_t *c){
-    return c->size;
-}
-
-/**
- * @brief   Get number of used elements
- *
- * @param[in] c    Pointer to @p xifo_t used for configuration.
- *
- * @return    Number of used buffer elements
- */
-uint32_t xifo_get_used(xifo_t *c){
-    return c->elementcount;
-}
-
-/**
-* @brief   Get number of free elements
-*
-* @param[in] c    Pointer to @p xifo_t used for configuration.
-*
-* @return    Number of free elements
-*/
-uint32_t xifo_get_free(xifo_t *c){
-    return c->size - c->elementcount;
-}
-
-/**
- * @brief   Get full flag
- *
- * @param[in] c    Pointer to @p xifo_t used for configuration.
- *
- * @return    1 if full
- */
-uint32_t xifo_get_full(xifo_t *c){
-    return c->full;
-}
-
-/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xIFO.cpp	Fri Apr 04 21:36:55 2014 +0000
@@ -0,0 +1,1142 @@
+/**
+ * @file    xifo.c
+ * @brief   xifo circular buffer with <t>/8/16/32/64 bit elements
+ * @details xifo supplies object oriented circular buffer with 8 bit size elements. \n
+ *          To use either as FIFO (First In First Out) or as FILO (First In Last Out)
+ *          You might want to rename this file is you are using a C compiler.
+ *
+ * @Author  Jeroen Lodder
+ * @Date    March 2014
+ * @version 3
+ * 
+ * Copyright (c) 2014 Jeroen Lodder
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * @{
+ */
+#include "xIFO.h"
+
+#if xIFO_USE_64BIT == TRUE
+/**
+ * @brief   Initialize buffer object structure.
+ *
+ * @note    Does not clear memory pool.
+ *
+ * @param[in] c   Pointer to @p xifo64_t object used for configuration.
+ * @param[in] s   Number of elements buffer can hold (size).
+ * @param[in] sp  Start of pre-allocated memory pool.
+ */
+void xifo64_init(xifo64_t *c, uint32_t s, uint64_t *sp){
+    c->startpool        = sp;
+    c->size             = s;
+    c->endpool          = &sp[--s];
+    c->full             = 0;
+    c->count            = 0;
+    c->read             = sp;
+    c->write            = sp;
+}
+
+/**
+ * @brief   Clear buffer memory pool
+ *
+ * @note    Must be used on initialised buffer object.
+ *
+ * @param[in] c   Pointer to @p xifo64_t object.
+ */
+void xifo64_clear(xifo64_t *c){
+    register uint64_t *ptemp = c->startpool;
+    register uint32_t i = c->size;
+    while(i--){
+
+        *ptemp++ = 0;
+    }
+}
+
+/**
+ * @brief   Read from buffer (lr) Least Recent oriented (fifo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements from the oldest element to the most recent.
+ *                  As for index[0] the least recently added element is returned.
+ *                  And for index[count] the most recent element is returned.
+ *                  This makes it possible to peek in fifo.
+ *
+ * @param[in] c         Pointer to @p xifo64_t used for configuration.
+ * @param[in] index   Index relative from least recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint64_t xifo64_read_lr(xifo64_t *c, uint32_t index){
+    register uint64_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Calculate index of oldest element */
+    index = (c->count-1) - index;
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Read from buffer (mr) Most Recent oriented (filo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements back in time.
+ *                  As for index[0] the most recently added element is returned.
+ *                  And for index[count] the oldest element is returned.
+ *                  This makes it possible to keep history. For DSP application.
+ *
+ * @param[in] c         Pointer to @p xifo64_t used for configuration.
+ * @param[in] index   Index relative from most recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint64_t xifo64_read_mr(xifo64_t *c, uint32_t index){
+    register uint64_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Pop (mr) most recent from buffer (filo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the most recently added from the buffer.
+ *                  Using this results in a stack type of buffer.
+ *
+ * @param[in] c         Pointer to @p xifo64_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint64_t xifo64_pop_mr(xifo64_t *c){
+    register uint64_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Read */
+    temp = *c->read;
+    /* Empty */
+    *c->read = 0;
+    /* Most recent element read, return write pointer */
+    c->write = c->read;
+    /* Decrement read pointer */
+    c->read--;
+    /* Validate pointer */
+    if( c->read < c->startpool ){
+        /* Exceeded pool boundaries */
+        c->read = c->endpool;
+    }
+    /* Reduce count */
+    c->count--;
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Pop (lr) least recent from buffer (fifo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the least recently added from the buffer.
+ *                  Using this results in a fifo type of buffer.
+ *
+ * @param[in] c Pointer to @p xifo64_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint64_t xifo64_pop_lr(xifo64_t *c){
+    register uint64_t *ptemp;
+    register uint64_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Derive least recent buffer element */
+    ptemp = (c->read+1) - c->count;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read oldest buffer element */
+    /* Read to temp register */
+    temp = *ptemp;
+    /* Empty buffer element */
+    *ptemp = 0;
+    /* Reduce count */
+    c->count--;
+    /* Check full flag */
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Write to buffer
+ *
+ * @note    Readpointer is automatically set to the last added element.
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Adds a value to the buffer.
+ *                  Automatically overwrites oldest elements when full.
+ *
+ * @param[in] c         Pointer to @p xifo64_t used for configuration.
+ * @param[in] data  Data to add to buffer
+ *
+ * @return  Number of free buffer elements
+ */
+uint32_t xifo64_write(xifo64_t *c, uint64_t data){
+    /* Write data */
+    *c->write = data;
+    /* Update read pointer to most recent element */
+    c->read = c->write;
+    /* Write pointer increment */
+    c->write++;
+    /* Validate pointer */
+    if( c->write > c->endpool){
+        /* We exceeded pool boundaries */
+        c->write = c->startpool;
+    }
+    /* Update count */
+    c->count++;
+    /* Verify full */
+    if( c->count >= c->size ){
+        c->full = 1;
+        c->count = c->size;
+    }
+    /* return free elements count */
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get buffer size
+ *
+ * @param[in] c Pointer to @p xifo64_t used for configuration.
+ *
+ * @return  Size of memory pool in elements
+ */
+uint32_t xifo64_get_size(xifo64_t *c){
+    return c->size;
+}
+
+/**
+ * @brief   Get number of used elements
+ *
+ * @param[in] c Pointer to @p xifo64_t used for configuration.
+ *
+ * @return  Number of used buffer elements
+ */
+uint32_t xifo64_get_used(xifo64_t *c){
+    return c->count;
+}
+
+/**
+* @brief   Get number of free elements
+*
+* @param[in] c  Pointer to @p xifo64_t used for configuration.
+*
+* @return   Number of free elements
+*/
+uint32_t xifo64_get_free(xifo64_t *c){
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get full flag
+ *
+ * @param[in] c Pointer to @p xifo64_t used for configuration.
+ *
+ * @return  1 if full
+ */
+uint32_t xifo64_get_full(xifo64_t *c){
+    return c->full;
+}
+
+/** @} */
+#endif
+
+#if xIFO_USE_32BIT == TRUE
+/**
+ * @brief   Initialize buffer object structure.
+ *
+ * @note    Does not clear memory pool.
+ *
+ * @param[in] c   Pointer to @p xifo32_t object used for configuration.
+ * @param[in] s   Number of elements buffer can hold (size).
+ * @param[in] sp  Start of pre-allocated memory pool.
+ */
+void xifo32_init(xifo32_t *c, uint32_t s, uint32_t *sp){
+    c->startpool        = sp;
+    c->size             = s;
+    c->endpool          = &sp[--s];
+    c->full             = 0;
+    c->count            = 0;
+    c->read             = sp;
+    c->write            = sp;
+}
+
+/**
+ * @brief   Clear buffer memory pool
+ *
+ * @note    Must be used on initialised buffer object.
+ *
+ * @param[in] c   Pointer to @p xifo32_t object.
+ */
+void xifo32_clear(xifo32_t *c){
+    register uint32_t *ptemp = c->startpool;
+    register uint32_t i = c->size;
+    while(i--){
+        *ptemp++ = 0;
+    }
+}
+
+/**
+ * @brief   Read from buffer (lr) Least Recent oriented (fifo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements from the oldest element to the most recent.
+ *                  As for index[0] the least recently added element is returned.
+ *                  And for index[count] the most recent element is returned.
+ *                  This makes it possible to peek in fifo.
+ *
+ * @param[in] c         Pointer to @p xifo32_t used for configuration.
+ * @param[in] index   Index relative from least recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint32_t xifo32_read_lr(xifo32_t *c, uint32_t index){
+    register uint32_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Calculate index of oldest element */
+    index = (c->count-1) - index;
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Read from buffer (mr) Most Recent oriented (filo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements back in time.
+ *                  As for index[0] the most recently added element is returned.
+ *                  And for index[count] the oldest element is returned.
+ *                  This makes it possible to keep history. For DSP application.
+ *
+ * @param[in] c         Pointer to @p xifo32_t used for configuration.
+ * @param[in] index   Index relative from most recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint32_t xifo32_read_mr(xifo32_t *c, uint32_t index){
+    register uint32_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Pop (mr) most recent from buffer (filo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the most recently added from the buffer.
+ *                  Using this results in a stack type of buffer.
+ *
+ * @param[in] c         Pointer to @p xifo32_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint32_t xifo32_pop_mr(xifo32_t *c){
+    register uint32_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Read */
+    temp = *c->read;
+    /* Empty */
+    *c->read = 0;
+    /* Most recent element read, return write pointer */
+    c->write = c->read;
+    /* Decrement read pointer */
+    c->read--;
+    /* Validate pointer */
+    if( c->read < c->startpool ){
+        /* Exceeded pool boundaries */
+        c->read = c->endpool;
+    }
+    /* Reduce count */
+    c->count--;
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Pop (lr) least recent from buffer (fifo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the least recently added from the buffer.
+ *                  Using this results in a fifo type of buffer.
+ *
+ * @param[in] c Pointer to @p xifo32_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint32_t xifo32_pop_lr(xifo32_t *c){
+    register uint32_t *ptemp;
+    register uint32_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Derive least recent buffer element */
+    ptemp = (c->read+1) - c->count;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read oldest buffer element */
+    /* Read to temp register */
+    temp = *ptemp;
+    /* Empty buffer element */
+    *ptemp = 0;
+    /* Reduce count */
+    c->count--;
+    /* Check full flag */
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Write to buffer
+ *
+ * @note    Readpointer is automatically set to the last added element.
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Adds a value to the buffer.
+ *                  Automatically overwrites oldest elements when full.
+ *
+ * @param[in] c         Pointer to @p xifo32_t used for configuration.
+ * @param[in] data  Data to add to buffer
+ *
+ * @return  Number of free buffer elements
+ */
+uint32_t xifo32_write(xifo32_t *c, uint32_t data){
+    /* Write data */
+    *c->write = data;
+    /* Update read pointer to most recent element */
+    c->read = c->write;
+    /* Write pointer increment */
+    c->write++;
+    /* Validate pointer */
+    if( c->write > c->endpool){
+        /* We exceeded pool boundaries */
+        c->write = c->startpool;
+    }
+    /* Update count */
+    c->count++;
+    /* Verify full */
+    if( c->count >= c->size ){
+        c->full = 1;
+        c->count = c->size;
+    }
+    /* return free elements count */
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get buffer size
+ *
+ * @param[in] c Pointer to @p xifo32_t used for configuration.
+ *
+ * @return  Size of memory pool in elements
+ */
+uint32_t xifo32_get_size(xifo32_t *c){
+    return c->size;
+}
+
+/**
+ * @brief   Get number of used elements
+ *
+ * @param[in] c Pointer to @p xifo32_t used for configuration.
+ *
+ * @return  Number of used buffer elements
+ */
+uint32_t xifo32_get_used(xifo32_t *c){
+    return c->count;
+}
+
+/**
+* @brief   Get number of free elements
+*
+* @param[in] c  Pointer to @p xifo32_t used for configuration.
+*
+* @return   Number of free elements
+*/
+uint32_t xifo32_get_free(xifo32_t *c){
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get full flag
+ *
+ * @param[in] c Pointer to @p xifo32_t used for configuration.
+ *
+ * @return  1 if full
+ */
+uint32_t xifo32_get_full(xifo32_t *c){
+    return c->full;
+}
+
+/** @} */
+#endif
+
+#if xIFO_USE_16BIT == TRUE
+/**
+ * @brief   Initialize buffer object structure.
+ *
+ * @note    Does not clear memory pool.
+ *
+ * @param[in] c   Pointer to @p xifo16_t object used for configuration.
+ * @param[in] s   Number of elements buffer can hold (size).
+ * @param[in] sp  Start of pre-allocated memory pool.
+ */
+void xifo16_init(xifo16_t *c, uint32_t s, uint16_t *sp){
+    c->startpool        = sp;
+    c->size             = s;
+    c->endpool          = &sp[--s];
+    c->full             = 0;
+    c->count            = 0;
+    c->read             = sp;
+    c->write            = sp;
+}
+
+/**
+ * @brief   Clear buffer memory pool
+ *
+ * @note    Must be used on initialised buffer object.
+ *
+ * @param[in] c   Pointer to @p xifo16_t object.
+ */
+void xifo16_clear(xifo16_t *c){
+    register uint16_t *ptemp = c->startpool;
+    register uint32_t i = c->size;
+    while(i--){
+        *ptemp++ = 0;
+    }
+}
+
+/**
+ * @brief   Read from buffer (lr) Least Recent oriented (fifo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements from the oldest element to the most recent.
+ *                  As for index[0] the least recently added element is returned.
+ *                  And for index[count] the most recent element is returned.
+ *                  This makes it possible to peek in fifo.
+ *
+ * @param[in] c         Pointer to @p xifo16_t used for configuration.
+ * @param[in] index   Index relative from least recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint16_t xifo16_read_lr(xifo16_t *c, uint32_t index){
+    register uint16_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Calculate index of oldest element */
+    index = (c->count-1) - index;
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Read from buffer (mr) Most Recent oriented (filo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements back in time.
+ *                  As for index[0] the most recently added element is returned.
+ *                  And for index[count] the oldest element is returned.
+ *                  This makes it possible to keep history. For DSP application.
+ *
+ * @param[in] c         Pointer to @p xifo16_t used for configuration.
+ * @param[in] index   Index relative from most recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint16_t xifo16_read_mr(xifo16_t *c, uint32_t index){
+    register uint16_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Pop (mr) most recent from buffer (filo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the most recently added from the buffer.
+ *                  Using this results in a stack type of buffer.
+ *
+ * @param[in] c         Pointer to @p xifo16_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint16_t xifo16_pop_mr(xifo16_t *c){
+    register uint16_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Read */
+    temp = *c->read;
+    /* Empty */
+    *c->read = 0;
+    /* Most recent element read, return write pointer */
+    c->write = c->read;
+    /* Decrement read pointer */
+    c->read--;
+    /* Validate pointer */
+    if( c->read < c->startpool ){
+        /* Exceeded pool boundaries */
+        c->read = c->endpool;
+    }
+    /* Reduce count */
+    c->count--;
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Pop (lr) least recent from buffer (fifo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the least recently added from the buffer.
+ *                  Using this results in a fifo type of buffer.
+ *
+ * @param[in] c Pointer to @p xifo16_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint16_t xifo16_pop_lr(xifo16_t *c){
+    register uint16_t *ptemp;
+    register uint16_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Derive least recent buffer element */
+    ptemp = (c->read+1) - c->count;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read oldest buffer element */
+    /* Read to temp register */
+    temp = *ptemp;
+    /* Empty buffer element */
+    *ptemp = 0;
+    /* Reduce count */
+    c->count--;
+    /* Check full flag */
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Write to buffer
+ *
+ * @note    Readpointer is automatically set to the last added element.
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Adds a value to the buffer.
+ *                  Automatically overwrites oldest elements when full.
+ *
+ * @param[in] c         Pointer to @p xifo16_t used for configuration.
+ * @param[in] data  Data to add to buffer
+ *
+ * @return  Number of free buffer elements
+ */
+uint32_t xifo16_write(xifo16_t *c, uint16_t data){
+    /* Write data */
+    *c->write = data;
+    /* Update read pointer to most recent element */
+    c->read = c->write;
+    /* Write pointer increment */
+    c->write++;
+    /* Validate pointer */
+    if( c->write > c->endpool){
+        /* We exceeded pool boundaries */
+        c->write = c->startpool;
+    }
+    /* Update count */
+    c->count++;
+    /* Verify full */
+    if( c->count >= c->size ){
+        c->full = 1;
+        c->count = c->size;
+    }
+    /* return free elements count */
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get buffer size
+ *
+ * @param[in] c Pointer to @p xifo16_t used for configuration.
+ *
+ * @return  Size of memory pool in elements
+ */
+uint32_t xifo16_get_size(xifo16_t *c){
+    return c->size;
+}
+
+/**
+ * @brief   Get number of used elements
+ *
+ * @param[in] c Pointer to @p xifo16_t used for configuration.
+ *
+ * @return  Number of used buffer elements
+ */
+uint32_t xifo16_get_used(xifo16_t *c){
+    return c->count;
+}
+
+/**
+* @brief   Get number of free elements
+*
+* @param[in] c  Pointer to @p xifo16_t used for configuration.
+*
+* @return   Number of free elements
+*/
+uint32_t xifo16_get_free(xifo16_t *c){
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get full flag
+ *
+ * @param[in] c Pointer to @p xifo16_t used for configuration.
+ *
+ * @return  1 if full
+ */
+uint32_t xifo16_get_full(xifo16_t *c){
+    return c->full;
+}
+
+/** @} */
+
+#endif
+
+#if xIFO_USE_8BIT == TRUE
+/**
+ * @brief   Initialize buffer object structure.
+ *
+ * @note    Does not clear memory pool.
+ *
+ * @param[in] c   Pointer to @p xifo8_t object used for configuration.
+ * @param[in] s   Number of elements buffer can hold (size).
+ * @param[in] sp  Start of pre-allocated memory pool.
+ */
+void xifo8_init(xifo8_t *c, uint32_t s, uint8_t *sp){
+    c->startpool        = sp;
+    c->size             = s;
+    c->endpool          = &sp[--s];
+    c->full             = 0;
+    c->count            = 0;
+    c->read             = sp;
+    c->write            = sp;
+}
+
+/**
+ * @brief   Clear buffer memory pool
+ *
+ * @note    Must be used on initialised buffer object.
+ *
+ * @param[in] c   Pointer to @p xifo8_t object.
+ */
+void xifo8_clear(xifo8_t *c){
+    register uint8_t *ptemp = c->startpool;
+    register uint32_t i = c->size;
+    while(i--){
+        *ptemp++ = 0;
+    }
+}
+
+/**
+ * @brief   Read from buffer (lr) Least Recent oriented (fifo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements from the oldest element to the most recent.
+ *                  As for index[0] the least recently added element is returned.
+ *                  And for index[count] the most recent element is returned.
+ *                  This makes it possible to peek in fifo.
+ *
+ * @param[in] c         Pointer to @p xifo8_t used for configuration.
+ * @param[in] index   Index relative from least recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint8_t xifo8_read_lr(xifo8_t *c, uint32_t index){
+    register uint8_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Calculate index of oldest element */
+    index = (c->count-1) - index;
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Read from buffer (mr) Most Recent oriented (filo)
+ *
+ * @note    Buffer state will be preserved
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read n elements back in time.
+ *                  As for index[0] the most recently added element is returned.
+ *                  And for index[count] the oldest element is returned.
+ *                  This makes it possible to keep history. For DSP application.
+ *
+ * @param[in] c         Pointer to @p xifo8_t used for configuration.
+ * @param[in] index   Index relative from most recent
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint8_t xifo8_read_mr(xifo8_t *c, uint32_t index){
+    register uint8_t *ptemp;
+    /* Verify there is valid data to read */
+    if(index >= c->count){
+        return 0;   /* Nothing to read there */
+    }
+    /* Set pointer */
+    ptemp = (c->read) - index;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read most recent */
+    return *ptemp;
+}
+
+/**
+ * @brief   Pop (mr) most recent from buffer (filo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the most recently added from the buffer.
+ *                  Using this results in a stack type of buffer.
+ *
+ * @param[in] c         Pointer to @p xifo8_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint8_t xifo8_pop_mr(xifo8_t *c){
+    register uint8_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Read */
+    temp = *c->read;
+    /* Empty */
+    *c->read = 0;
+    /* Most recent element read, return write pointer */
+    c->write = c->read;
+    /* Decrement read pointer */
+    c->read--;
+    /* Validate pointer */
+    if( c->read < c->startpool ){
+        /* Exceeded pool boundaries */
+        c->read = c->endpool;
+    }
+    /* Reduce count */
+    c->count--;
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Pop (lr) least recent from buffer (fifo)
+ *
+ * @note    Buffer state will be altered
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Read and remove the least recently added from the buffer.
+ *                  Using this results in a fifo type of buffer.
+ *
+ * @param[in] c Pointer to @p xifo8_t used for configuration.
+ *
+ * @return  Contents of element or 0 if failed (element can hold 0)
+ */
+uint8_t xifo8_pop_lr(xifo8_t *c){
+    register uint8_t *ptemp;
+    register uint8_t temp;
+    /* Verify there is valid data read */
+    if(c->count == 0){
+        return 0;   /* Nothing to read there */
+    }
+    /* Derive least recent buffer element */
+    ptemp = (c->read+1) - c->count;
+    /* Validate pointer */
+    if(ptemp < c->startpool){
+        /* Exceeded pool boundaries */
+        /* Calculate overshoot (startpool - indexptr) and subtract from end */
+        /* Since one element of overshoot results in end - 1 you would miss the last value */
+        ptemp = (c->endpool+1) - (c->startpool - ptemp);
+    }
+    /* Read oldest buffer element */
+    /* Read to temp register */
+    temp = *ptemp;
+    /* Empty buffer element */
+    *ptemp = 0;
+    /* Reduce count */
+    c->count--;
+    /* Check full flag */
+    if(c->count < c->size)
+        c->full = 0;
+    return temp;
+}
+
+/**
+ * @brief   Write to buffer
+ *
+ * @note    Readpointer is automatically set to the last added element.
+ *
+ * @warning Consider this opertaion as atomic!
+ *
+ * @details Adds a value to the buffer.
+ *                  Automatically overwrites oldest elements when full.
+ *
+ * @param[in] c         Pointer to @p xifo8_t used for configuration.
+ * @param[in] data  Data to add to buffer
+ *
+ * @return  Number of free buffer elements
+ */
+uint32_t xifo8_write(xifo8_t *c, uint8_t data){
+    /* Write data */
+    *c->write = data;
+    /* Update read pointer to most recent element */
+    c->read = c->write;
+    /* Write pointer increment */
+    c->write++;
+    /* Validate pointer */
+    if( c->write > c->endpool){
+        /* We exceeded pool boundaries */
+        c->write = c->startpool;
+    }
+    /* Update count */
+    c->count++;
+    /* Verify full */
+    if( c->count >= c->size ){
+        c->full = 1;
+        c->count = c->size;
+    }
+    /* return free elements count */
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get buffer size
+ *
+ * @param[in] c Pointer to @p xifo8_t used for configuration.
+ *
+ * @return  Size of memory pool in elements
+ */
+uint32_t xifo8_get_size(xifo8_t *c){
+    return c->size;
+}
+
+/**
+ * @brief   Get number of used elements
+ *
+ * @param[in] c Pointer to @p xifo8_t used for configuration.
+ *
+ * @return  Number of used buffer elements
+ */
+uint32_t xifo8_get_used(xifo8_t *c){
+    return c->count;
+}
+
+/**
+* @brief   Get number of free elements
+*
+* @param[in] c  Pointer to @p xifo8_t used for configuration.
+*
+* @return   Number of free elements
+*/
+uint32_t xifo8_get_free(xifo8_t *c){
+    return c->size - c->count;
+}
+
+/**
+ * @brief   Get full flag
+ *
+ * @param[in] c Pointer to @p xifo8_t used for configuration.
+ *
+ * @return  1 if full
+ */
+uint32_t xifo8_get_full(xifo8_t *c){
+    return c->full;
+}
+
+/** @} */
+#endif
+
+/** @} */
--- a/xIFO.h	Mon Oct 28 19:20:00 2013 +0000
+++ b/xIFO.h	Fri Apr 04 21:36:55 2014 +0000
@@ -1,92 +1,545 @@
- 
- /**
+/**
  * @file    xifo.h
- * @brief   xifo circular buffer
- * @details xifo supplies object oriented circular buffer with 32 bit size elements. \n
- *                     To use either as FIFO (First In First Out) or as FILO (First In Last Out)
+ * @brief   xifo circular buffer for all elements
+ * @details xifo supplies object oriented circular buffer with x bit size elements. \n
+ *          To use either as FIFO (First In First Out) or as FILO (First In Last Out)
+ *          Below are defines to disable or enable any xIFO type you like.
  *
- * @author    Jeroen Lodder
- * @date        April 2013
- * @version 2
+ * @author  Jeroen Lodder
+ * @date    March 2014
+ * @version 3
+ * 
+ * Copyright (c) 2014 Jeroen Lodder
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
  *
  * @{
  */
- 
- /**
- *    Code has been tested on Cortex M0 (LPC1114)
- *  Performance table, number of core clocks
- *    Measured with a timer before and after
- *    r1 = timer->TC
- *        test_function 
- *  r2 = timer->TC
- *
- *  Function    Speed        Worst Case
- *
- *  write            69            71
- *  read_mr        59      59
- *  read_lr        63      70
- *  pop_mr        76      78
- *    pop_lr        45      45
- *
- */
-
 #ifndef _xifo_H_
 #define _xifo_H_
-
+ 
 #include <inttypes.h>
 
-#if defined(__arm__)  || defined(__DOXYGEN__)
-#pragma anon_unions                /**< Allow unnamed unions */
+#if !defined(TRUE) || defined(__DOXYGEN__)
+#define TRUE    (1)
+#endif
+#if !defined(FALSE) || defined(__DOXYGEN__)
+#define FALSE   !(TRUE)
+#endif
+ 
+#ifdef __cplusplus
+#if !defined(xIFO_USE_CPP) || defined(__DOXYGEN__)
+#define xIFO_USE_CPP            TRUE
+#endif
+#endif
+
+#if !defined(xIFO_USE_64BIT) || defined(__DOXYGEN__)
+#define xIFO_USE_64BIT          TRUE
+#endif
+
+#if !defined(xIFO_USE_32BIT) || defined(__DOXYGEN__)
+#define xIFO_USE_32BIT          TRUE
+#endif
+
+#if !defined(xIFO_USE_16BIT) || defined(__DOXYGEN__)
+#define xIFO_USE_16BIT          TRUE
+#endif
+
+#if !defined(xIFO_USE_8BIT) || defined(__DOXYGEN__)
+#define xIFO_USE_8BIT           TRUE
 #endif
 
+
+#if xIFO_USE_CPP == TRUE
+/**
+ * @brief   Circular Buffer object.
+ * @details This class holds the object of a circular buffer
+ */
+template <class xifo_dtype>
+class Xifo
+{
+public:
+    /**
+     * @brief   Initialise xifo.
+     * @note    Does not clear memory pool.
+     * @param[in] Number of elements buffer can hold (size).
+     */
+    Xifo(uint32_t size)
+    {
+        startpool = new xifo_dtype[size];
+        endpool         = &startpool[size-1];
+        isize           = size;
+        ifull           = 0;
+        icount           = 0;
+        read            = startpool;
+        pwrite          = startpool;
+    }
+
+    /**
+     * @brief   Initialise xifo.
+     * @note    Does not clear memory pool.
+     * @param[in] Number of elements buffer can hold (size).
+     * @param[in] Start of pre-allocated memory pool.
+     */
+    Xifo(uint32_t size, xifo_dtype *sp)
+    {
+        startpool       = sp;
+        endpool         = &sp[size-1];
+        isize           = size;
+        ifull           = 0;
+        icount            = 0;
+        read            = sp;
+        pwrite          = sp;
+    }
+
+    /**
+     * @brief   Deinitialise (and deallocate) buffer xifo.
+     * @note    Does not clear memory pool.
+     */
+    ~Xifo(void)
+    {
+        if(dynamic){
+            delete startpool;
+        }
+    }
+
+    /**
+     * @brief   Clear buffer memory pool
+     * @note    Must be used on initialised buffer object.
+     * @param[in] c   Pointer to @p xifo_SIZETYPE_t object.
+     */
+    void clear(void)
+    {
+        register xifo_dtype *ptemp = startpool;
+        while(ptemp <= endpool){
+            *ptemp++ = 0;
+        }
+    }
+    
+     /**
+     * @brief   Reset buffer
+     * @note    Must be used on initialised buffer object.
+     * @param[in] c   Pointer to @p xifo_SIZETYPE_t object.
+     */
+    void reset(void)
+    {
+        register xifo_dtype *ptemp = startpool;
+        while(ptemp <= endpool){
+            *ptemp++ = 0;
+        }
+        ifull       = 0;
+        icount      = 0;
+        read        = startpool;
+        pwrite      = startpool;
+    }
+
+    /**
+     * @brief   Write to buffer
+     *
+     * @note    Readpointer is automatically set to the last added element.
+     *
+     * @warning Consider this opertaion as atomic!
+     *
+     * @details Adds a value to the buffer.
+     *                  Automatically overwrites oldest elements when full.
+     *
+     * @param[in] c         Pointer to @p xifo_SIZETYPE_t used for configuration.
+     * @param[in] data  Data to add to buffer
+     *
+     * @return  Number of free buffer elements
+     */
+    uint32_t write(xifo_dtype data)
+    {
+        /* Write data */
+        *pwrite = data;
+        /* Update read pointer to most recent element */
+        read = pwrite;
+        /* Write pointer increment */
+        pwrite += 1;
+        /* Validate pointer */
+        if( pwrite > endpool){
+            /* Exceeded pool boundaries */
+            pwrite = startpool;
+        }
+        /* Update count */
+        icount++;
+        /* Verify full */
+        if( icount >= isize ){
+            ifull = 1;
+            icount = isize;
+        }
+        /* return free elements count */
+        return isize - icount;
+    }
+
+    /**
+     * @brief   Read from buffer (lr) Least Recent oriented (fifo)
+     *
+     * @note    Buffer state will be preserved
+     *
+     * @warning Consider this opertaion as atomic!
+     *
+     * @details Read n elements from the oldest element to the most recent.
+     *                  As for index[0] the least recently added element is returned.
+     *                  And for index[count] the most recent element is returned.
+     *                  This makes it possible to peek in fifo.
+     *
+     * @param[in] c         Pointer to @p xifo_SIZETYPE_t used for configuration.
+     * @param[in] index   Index relative from least recent
+     *
+     * @return  Contents of element or 0 if failed (element can hold 0)
+     */
+    xifo_dtype read_lr(uint32_t index)
+    {
+        register xifo_dtype *ptemp;
+        /* Verify there is valid data to read */
+        if(index+1 > icount){
+            return 0;
+        }
+        /* Calculate index of oldest element */
+        index = (icount-1) - index;
+        /* Set pointer */
+        ptemp = (read) - index;
+        if(ptemp < startpool){
+            /* Exceeded pool boundaries */
+            /* Calculate overshoot (startpool - indexptr) and subtract from end */
+            /* Since one element of overshoot results in end - 1 you would miss the last value */
+            ptemp = (endpool+1) - (startpool - ptemp);
+        }
+        /* Read most recent */
+        return *ptemp;
+    }
+
+    /**
+     * @brief   Pop (lr) least recent from buffer (fifo)
+     *
+     * @note    Buffer state will be altered
+     *
+     * @warning Consider this opertaion as atomic!
+     *
+     * @details Read and remove the least recently added from the buffer.
+     *                  Using this results in a fifo type of buffer.
+     *
+     * @param[in] c Pointer to @p xifo_SIZETYPE_t used for configuration.
+     *
+     * @return  Contents of element or 0 if failed (element can hold 0)
+     */
+    xifo_dtype pop_lr()
+    {
+        register xifo_dtype *ptemp;
+        xifo_dtype temp;
+        /* Verify there is valid data read */
+        if(icount == 0){
+            return 0;
+        }
+        /* Derive least recent buffer element */
+        ptemp = read+1 - icount;
+        /* Validate pointer */
+        if(ptemp < startpool){
+            /* Exceeded pool boundaries */
+            /* Calculate overshoot (startpool - indexptr) and subtract from end */
+            /* Since one element of overshoot results in end - 1 you would miss the last value */
+            ptemp = (endpool+1) - (startpool - ptemp);
+        }
+        /* Read oldest buffer element */
+        /* Read to temp register */
+        temp = *ptemp;
+        /* Empty buffer element */
+        *ptemp = 0;
+        /* Reduce count */
+        icount--;
+        /* Check full flag */
+        if(icount < isize)
+            ifull = 0;
+        return temp;
+    }
+
+    /**
+     * @brief   Read from buffer (mr) Most Recent oriented (filo)
+     *
+     * @note    Buffer state will be preserved
+     *
+     * @warning Consider this opertaion as atomic!
+     *
+     * @details Read n elements back in time.
+     *                  As for index[0] the most recently added element is returned.
+     *                  And for index[count] the oldest element is returned.
+     *                  This makes it possible to keep history. For DSP application.
+     *
+     * @param[in] c         Pointer to @p xifo_SIZETYPE_t used for configuration.
+     * @param[in] index   Index relative from most recent
+     *
+     * @return  Contents of element or 0 if failed (element can hold 0)
+     */
+    xifo_dtype read_mr(uint32_t index)
+    {
+        register xifo_dtype *ptemp;
+        /* Verify there is valid data to read */
+        if(index+1 > icount){
+            return 0;
+        }
+        /* Set pointer */
+        ptemp = read - index;
+        /* Validate pointer */
+        if(ptemp < startpool){
+            /* Exceeded pool boundaries */
+            /* Calculate overshoot (startpool - indexptr) and subtract from end */
+            /* Since one element of overshoot results in end - 1 you would miss the last value */
+            ptemp = (endpool+1) - (startpool - ptemp);
+        }
+        /* Read most recent */
+        return *ptemp;
+    }
+
+    /**
+     * @brief   Pop (mr) most recent from buffer (filo)
+     *
+     * @note    Buffer state will be altered
+     *
+     * @warning Consider this opertaion as atomic!
+     *
+     * @details Read and remove the most recently added from the buffer.
+     *                  Using this results in a stack type of buffer.
+     *
+     * @param[in] c         Pointer to @p xifo_SIZETYPE_t used for configuration.
+     *
+     * @return  Contents of element or 0 if failed (element can hold 0)
+     */
+    xifo_dtype pop_mr()
+    {
+        register xifo_dtype temp;
+        /* Verify there is valid data read */
+        if(icount == 0){
+            return 0;
+        }
+        /* Read */
+        temp = *read;
+        /* Empty */
+        *read = 0;
+        /* Most recent element read, return write pointer */
+        pwrite = read;
+        /* Decrement read pointer */
+        read--;
+        /* Validate pointer */
+        if( read < startpool ){
+            /* Exceeded pool boundaries */
+            read = endpool;
+        }
+        /* Reduce count */
+        icount--;
+        if(icount < isize)
+            ifull = 0;
+        return temp;
+    }
+
+    /* Extractors */
+    uint32_t size(){ return isize; }         /**< @brief   Get buffer size */
+    uint32_t used(){ return icount; }        /**< @brief   Get number of used elements */
+    uint32_t full(){ return ifull; }         /**< @brief   Get full flag */
+    uint32_t free(){ return isize-icount; }   /**< @brief   Get number of free elements */
+private:
+    bool dynamic;
+    xifo_dtype *startpool;         /**< @brief First element in pool */
+    xifo_dtype *endpool;    /**< @brief Last element in pool */
+    xifo_dtype *read;       /**< @brief Read pointer */
+    xifo_dtype *pwrite;     /**< @brief Write pointer */
+    /* Variables: */
+    uint32_t ifull;          /**< @brief Flag indicating buffer is full */
+    uint32_t icount;         /**< @brief Number of elements used */
+    uint32_t isize;          /**< @brief Size of buffer */
+};
+#endif
+
+#if xIFO_USE_64BIT == TRUE
 /**
  * @brief   Circular Buffer object.
  * @details This struct holds the object of a circular buffer
  */
 typedef struct  {
-/* Pointers: */
-        uint32_t *startpool;  /**< @brief First element in pool */
-        uint32_t *endpool;        /**< @brief Last element in pool */
-        uint32_t *read;                /**< @brief Read pointer */
-        uint32_t *write;            /**< @brief Write pointer */
-/* Variables: */
-        uint32_t full;        /**< @brief Flag indicating buffer is full */
-    uint32_t elementcount;/**< @brief Number of elements used */
-        uint32_t size;                /**< @brief Size of buffer */
-/* Locally used in functions to prevent stack use: */
-        /**< @brief union to prevent lvalue typecasting */  
-        union {                         
-            uint32_t temp;            /**< @brief temp variable and padding for even sized block */
-            uint32_t *ptemp;         /**< @brief temp variable and padding for even sized block */
-        };
-}xifo_t;
+    /* Pointers: */
+    uint64_t *startpool;    /**< @brief First element in pool */
+    uint64_t *endpool;      /**< @brief Last element in pool */
+    uint64_t *read;         /**< @brief Read pointer */
+    uint64_t *write;        /**< @brief Write pointer */
+    /* Variables: */
+    uint32_t full;          /**< @brief Flag indicating buffer is full */
+    uint32_t count;         /**< @brief Number of elements used */
+    uint32_t size;          /**< @brief Size of buffer */
+}xifo64_t;
+
+/**< @brief   Circular Buffer memory pool type. */
+typedef uint64_t xifo64_pool_t;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* xifo Common */
+void xifo64_init( xifo64_t *c, uint32_t size, uint64_t *startpool );
+void xifo64_clear( xifo64_t *c );
+uint32_t xifo64_write( xifo64_t *c, uint64_t data );
+/* FIFO use */
+uint64_t xifo64_read_lr( xifo64_t *c, uint32_t index );
+uint64_t xifo64_pop_lr( xifo64_t *c );
+/* LIFO use */
+uint64_t xifo64_read_mr( xifo64_t *c, uint32_t index );
+uint64_t xifo64_pop_mr( xifo64_t *c );
+/* Extractors */
+uint32_t xifo64_get_size( xifo64_t *c );
+uint32_t xifo64_get_used( xifo64_t *c );
+uint32_t xifo64_get_full( xifo64_t *c );
+uint32_t xifo64_get_free( xifo64_t *c );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#if xIFO_USE_32BIT == TRUE
 /**
- * @brief   Circular Buffer memory pool type.
+ * @brief   Circular Buffer object.
+ * @details This struct holds the object of a circular buffer
  */
-typedef unsigned int xifo_pool_t;
+typedef struct  {
+    /* Pointers: */
+    uint32_t *startpool;    /**< @brief First element in pool */
+    uint32_t *endpool;      /**< @brief Last element in pool */
+    uint32_t *read;         /**< @brief Read pointer */
+    uint32_t *write;        /**< @brief Write pointer */
+    /* Variables: */
+    uint32_t full;          /**< @brief Flag indicating buffer is full */
+    uint32_t count;         /**< @brief Number of elements used */
+    uint32_t size;          /**< @brief Size of buffer */
+}xifo32_t;
+
+/**< @brief   Circular Buffer memory pool type. */
+typedef uint32_t xifo32_pool_t;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 /* xifo Common */
-void xifo_init(xifo_t *c, uint32_t size, uint32_t *startpool);
-void xifo_clear(xifo_t *c);
-uint32_t xifo_write(xifo_t *c, uint32_t data);
+void xifo32_init( xifo32_t *c, uint32_t size, uint32_t *startpool );
+void xifo32_clear( xifo32_t *c );
+uint32_t xifo32_write( xifo32_t *c, uint32_t data );
 /* FIFO use */
-uint32_t xifo_read_lr(xifo_t *c, uint32_t index);
-uint32_t xifo_pop_lr(xifo_t *c);
+uint32_t xifo32_read_lr( xifo32_t *c, uint32_t index );
+uint32_t xifo32_pop_lr( xifo32_t *c );
 /* LIFO use */
-uint32_t xifo_read_mr(xifo_t *c, uint32_t index);
-uint32_t xifo_pop_mr(xifo_t *c);
+uint32_t xifo32_read_mr( xifo32_t *c, uint32_t index );
+uint32_t xifo32_pop_mr( xifo32_t *c );
 /* Extractors */
-uint32_t xifo_get_size(xifo_t *c);
-uint32_t xifo_get_used(xifo_t *c);
-uint32_t xifo_get_full(xifo_t *c);
-uint32_t xifo_get_free(xifo_t *c);
+uint32_t xifo32_get_size( xifo32_t *c );
+uint32_t xifo32_get_used( xifo32_t *c );
+uint32_t xifo32_get_full( xifo32_t *c );
+uint32_t xifo32_get_free( xifo32_t *c );
 #ifdef __cplusplus
 }
 #endif
+#endif
+
+#if xIFO_USE_16BIT == TRUE
+/**
+ * @brief   Circular Buffer object.
+ * @details This struct holds the object of a circular buffer
+ */
+typedef struct  {
+    /* Pointers: */
+    uint16_t *startpool;    /**< @brief First element in pool */
+    uint16_t *endpool;      /**< @brief Last element in pool */
+    uint16_t *read;         /**< @brief Read pointer */
+    uint16_t *write;        /**< @brief Write pointer */
+    /* Variables: */
+    uint32_t full;          /**< @brief Flag indicating buffer is full */
+    uint32_t count;         /**< @brief Number of elements used */
+    uint32_t size;          /**< @brief Size of buffer */
+}xifo16_t;
+
+/**
+ * @brief   Circular Buffer memory pool type.
+ */
+typedef uint16_t xifo16_pool_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* xifo Common */
+void xifo16_init( xifo16_t *c, uint32_t size, uint16_t *startpool);
+void xifo16_clear( xifo16_t *c);
+uint32_t xifo16_write( xifo16_t *c, uint16_t data);
+/* FIFO use */
+uint16_t xifo16_read_lr( xifo16_t *c, uint32_t index);
+uint16_t xifo16_pop_lr( xifo16_t *c);
+/* LIFO use */
+uint16_t xifo16_read_mr( xifo16_t *c, uint32_t index);
+uint16_t xifo16_pop_mr( xifo16_t *c);
+/* Extractors */
+uint32_t xifo16_get_size( xifo16_t *c);
+uint32_t xifo16_get_used( xifo16_t *c);
+uint32_t xifo16_get_full( xifo16_t *c);
+uint32_t xifo16_get_free( xifo16_t *c);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#if xIFO_USE_8BIT == TRUE
+/**
+ * @brief   Circular Buffer object.
+ * @details This struct holds the object of a circular buffer
+ */
+typedef struct  {
+    /* Pointers: */
+    uint8_t *startpool;     /**< @brief First element in pool */
+    uint8_t *endpool;       /**< @brief Last element in pool */
+    uint8_t *read;          /**< @brief Read pointer */
+    uint8_t *write;         /**< @brief Write pointer */
+    /* Variables: */
+    uint32_t full;          /**< @brief Flag indicating buffer is full */
+    uint32_t count;         /**< @brief Number of elements used */
+    uint32_t size;          /**< @brief Size of buffer */
+}xifo8_t;
+
+/**< @brief   Circular Buffer memory pool type. */
+typedef uint8_t xifo8_pool_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* xifo Common */
+void xifo8_init(xifo8_t *c, uint32_t size, uint8_t *startpool );
+void xifo8_clear( xifo8_t *c );
+uint32_t xifo8_write( xifo8_t *c, uint8_t data );
+/* FIFO use */
+uint8_t xifo8_read_lr( xifo8_t *c, uint32_t index );
+uint8_t xifo8_pop_lr( xifo8_t *c );
+/* LIFO use */
+uint8_t xifo8_read_mr( xifo8_t *c, uint32_t index );
+uint8_t xifo8_pop_mr( xifo8_t *c );
+/* Extractors */
+uint32_t xifo8_get_size( xifo8_t *c );
+uint32_t xifo8_get_used( xifo8_t *c );
+uint32_t xifo8_get_full( xifo8_t *c );
+uint32_t xifo8_get_free( xifo8_t *c );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
 #endif //_xifo_H_
 
 /** @} */