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
Revision 2:6013f6d867e5, committed 2014-04-04
- 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
--- 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_ /** @} */