Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
xIFO.h
00001 /** 00002 * @file xifo.h 00003 * @brief xifo circular buffer for all elements 00004 * @details xifo supplies object oriented circular buffer with x bit size elements. \n 00005 * To use either as FIFO (First In First Out) or as FILO (First In Last Out) 00006 * Below are defines to disable or enable any xIFO type you like. 00007 * 00008 * @author Jeroen Lodder 00009 * @date March 2014 00010 * @version 3 00011 * 00012 * Copyright (c) 2014 Jeroen Lodder 00013 * 00014 * Permission is hereby granted, free of charge, to any person obtaining a copy 00015 * of this software and associated documentation files (the "Software"), to deal 00016 * in the Software without restriction, including without limitation the rights 00017 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00018 * copies of the Software, and to permit persons to whom the Software is 00019 * furnished to do so, subject to the following conditions: 00020 * 00021 * The above copyright notice and this permission notice shall be included in all 00022 * copies or substantial portions of the Software. 00023 * 00024 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00025 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00026 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00027 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00028 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00029 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00030 * SOFTWARE. 00031 * 00032 * @{ 00033 */ 00034 #ifndef _xifo_H_ 00035 #define _xifo_H_ 00036 00037 #include <inttypes.h> 00038 00039 #if !defined(TRUE) || defined(__DOXYGEN__) 00040 #define TRUE (1) 00041 #endif 00042 #if !defined(FALSE) || defined(__DOXYGEN__) 00043 #define FALSE !(TRUE) 00044 #endif 00045 00046 #ifdef __cplusplus 00047 #if !defined(xIFO_USE_CPP) || defined(__DOXYGEN__) 00048 #define xIFO_USE_CPP TRUE 00049 #endif 00050 #endif 00051 00052 #if !defined(xIFO_USE_64BIT) || defined(__DOXYGEN__) 00053 #define xIFO_USE_64BIT TRUE 00054 #endif 00055 00056 #if !defined(xIFO_USE_32BIT) || defined(__DOXYGEN__) 00057 #define xIFO_USE_32BIT TRUE 00058 #endif 00059 00060 #if !defined(xIFO_USE_16BIT) || defined(__DOXYGEN__) 00061 #define xIFO_USE_16BIT TRUE 00062 #endif 00063 00064 #if !defined(xIFO_USE_8BIT) || defined(__DOXYGEN__) 00065 #define xIFO_USE_8BIT TRUE 00066 #endif 00067 00068 00069 #if xIFO_USE_CPP == TRUE 00070 /** 00071 * @brief Circular Buffer object. 00072 * @details This class holds the object of a circular buffer 00073 */ 00074 template <class xifo_dtype> 00075 class Xifo 00076 { 00077 public: 00078 /** 00079 * @brief Initialise xifo. 00080 * @note Does not clear memory pool. 00081 * @param[in] Number of elements buffer can hold (size). 00082 */ 00083 Xifo(uint32_t size) 00084 { 00085 startpool = new xifo_dtype[size]; 00086 endpool = &startpool[size-1]; 00087 isize = size; 00088 ifull = 0; 00089 icount = 0; 00090 read = startpool; 00091 pwrite = startpool; 00092 } 00093 00094 /** 00095 * @brief Initialise xifo. 00096 * @note Does not clear memory pool. 00097 * @param[in] Number of elements buffer can hold (size). 00098 * @param[in] Start of pre-allocated memory pool. 00099 */ 00100 Xifo(uint32_t size, xifo_dtype *sp) 00101 { 00102 startpool = sp; 00103 endpool = &sp[size-1]; 00104 isize = size; 00105 ifull = 0; 00106 icount = 0; 00107 read = sp; 00108 pwrite = sp; 00109 } 00110 00111 /** 00112 * @brief Deinitialise (and deallocate) buffer xifo. 00113 * @note Does not clear memory pool. 00114 */ 00115 ~Xifo(void) 00116 { 00117 if(dynamic){ 00118 delete startpool; 00119 } 00120 } 00121 00122 /** 00123 * @brief Clear buffer memory pool 00124 * @note Must be used on initialised buffer object. 00125 * @param[in] c Pointer to @p xifo_SIZETYPE_t object. 00126 */ 00127 void clear(void) 00128 { 00129 register xifo_dtype *ptemp = startpool; 00130 while(ptemp <= endpool){ 00131 *ptemp++ = 0; 00132 } 00133 } 00134 00135 /** 00136 * @brief Reset buffer 00137 * @note Must be used on initialised buffer object. 00138 * @param[in] c Pointer to @p xifo_SIZETYPE_t object. 00139 */ 00140 void reset(void) 00141 { 00142 register xifo_dtype *ptemp = startpool; 00143 while(ptemp <= endpool){ 00144 *ptemp++ = 0; 00145 } 00146 ifull = 0; 00147 icount = 0; 00148 read = startpool; 00149 pwrite = startpool; 00150 } 00151 00152 /** 00153 * @brief Write to buffer 00154 * 00155 * @note Readpointer is automatically set to the last added element. 00156 * 00157 * @warning Consider this opertaion as atomic! 00158 * 00159 * @details Adds a value to the buffer. 00160 * Automatically overwrites oldest elements when full. 00161 * 00162 * @param[in] c Pointer to @p xifo_SIZETYPE_t used for configuration. 00163 * @param[in] data Data to add to buffer 00164 * 00165 * @return Number of free buffer elements 00166 */ 00167 uint32_t write(xifo_dtype data) 00168 { 00169 /* Write data */ 00170 *pwrite = data; 00171 /* Update read pointer to most recent element */ 00172 read = pwrite; 00173 /* Write pointer increment */ 00174 pwrite += 1; 00175 /* Validate pointer */ 00176 if( pwrite > endpool){ 00177 /* Exceeded pool boundaries */ 00178 pwrite = startpool; 00179 } 00180 /* Update count */ 00181 icount++; 00182 /* Verify full */ 00183 if( icount >= isize ){ 00184 ifull = 1; 00185 icount = isize; 00186 } 00187 /* return free elements count */ 00188 return isize - icount; 00189 } 00190 00191 /** 00192 * @brief Read from buffer (lr) Least Recent oriented (fifo) 00193 * 00194 * @note Buffer state will be preserved 00195 * 00196 * @warning Consider this opertaion as atomic! 00197 * 00198 * @details Read n elements from the oldest element to the most recent. 00199 * As for index[0] the least recently added element is returned. 00200 * And for index[count] the most recent element is returned. 00201 * This makes it possible to peek in fifo. 00202 * 00203 * @param[in] c Pointer to @p xifo_SIZETYPE_t used for configuration. 00204 * @param[in] index Index relative from least recent 00205 * 00206 * @return Contents of element or 0 if failed (element can hold 0) 00207 */ 00208 xifo_dtype read_lr(uint32_t index) 00209 { 00210 register xifo_dtype *ptemp; 00211 /* Verify there is valid data to read */ 00212 if(index+1 > icount){ 00213 return 0; 00214 } 00215 /* Calculate index of oldest element */ 00216 index = (icount-1) - index; 00217 /* Set pointer */ 00218 ptemp = (read) - index; 00219 if(ptemp < startpool){ 00220 /* Exceeded pool boundaries */ 00221 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00222 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00223 ptemp = (endpool+1) - (startpool - ptemp); 00224 } 00225 /* Read most recent */ 00226 return *ptemp; 00227 } 00228 00229 /** 00230 * @brief Pop (lr) least recent from buffer (fifo) 00231 * 00232 * @note Buffer state will be altered 00233 * 00234 * @warning Consider this opertaion as atomic! 00235 * 00236 * @details Read and remove the least recently added from the buffer. 00237 * Using this results in a fifo type of buffer. 00238 * 00239 * @param[in] c Pointer to @p xifo_SIZETYPE_t used for configuration. 00240 * 00241 * @return Contents of element or 0 if failed (element can hold 0) 00242 */ 00243 xifo_dtype pop_lr() 00244 { 00245 register xifo_dtype *ptemp; 00246 xifo_dtype temp; 00247 /* Verify there is valid data read */ 00248 if(icount == 0){ 00249 return 0; 00250 } 00251 /* Derive least recent buffer element */ 00252 ptemp = read+1 - icount; 00253 /* Validate pointer */ 00254 if(ptemp < startpool){ 00255 /* Exceeded pool boundaries */ 00256 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00257 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00258 ptemp = (endpool+1) - (startpool - ptemp); 00259 } 00260 /* Read oldest buffer element */ 00261 /* Read to temp register */ 00262 temp = *ptemp; 00263 /* Empty buffer element */ 00264 *ptemp = 0; 00265 /* Reduce count */ 00266 icount--; 00267 /* Check full flag */ 00268 if(icount < isize) 00269 ifull = 0; 00270 return temp; 00271 } 00272 00273 /** 00274 * @brief Read from buffer (mr) Most Recent oriented (filo) 00275 * 00276 * @note Buffer state will be preserved 00277 * 00278 * @warning Consider this opertaion as atomic! 00279 * 00280 * @details Read n elements back in time. 00281 * As for index[0] the most recently added element is returned. 00282 * And for index[count] the oldest element is returned. 00283 * This makes it possible to keep history. For DSP application. 00284 * 00285 * @param[in] c Pointer to @p xifo_SIZETYPE_t used for configuration. 00286 * @param[in] index Index relative from most recent 00287 * 00288 * @return Contents of element or 0 if failed (element can hold 0) 00289 */ 00290 xifo_dtype read_mr(uint32_t index) 00291 { 00292 register xifo_dtype *ptemp; 00293 /* Verify there is valid data to read */ 00294 if(index+1 > icount){ 00295 return 0; 00296 } 00297 /* Set pointer */ 00298 ptemp = read - index; 00299 /* Validate pointer */ 00300 if(ptemp < startpool){ 00301 /* Exceeded pool boundaries */ 00302 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00303 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00304 ptemp = (endpool+1) - (startpool - ptemp); 00305 } 00306 /* Read most recent */ 00307 return *ptemp; 00308 } 00309 00310 /** 00311 * @brief Pop (mr) most recent from buffer (filo) 00312 * 00313 * @note Buffer state will be altered 00314 * 00315 * @warning Consider this opertaion as atomic! 00316 * 00317 * @details Read and remove the most recently added from the buffer. 00318 * Using this results in a stack type of buffer. 00319 * 00320 * @param[in] c Pointer to @p xifo_SIZETYPE_t used for configuration. 00321 * 00322 * @return Contents of element or 0 if failed (element can hold 0) 00323 */ 00324 xifo_dtype pop_mr() 00325 { 00326 register xifo_dtype temp; 00327 /* Verify there is valid data read */ 00328 if(icount == 0){ 00329 return 0; 00330 } 00331 /* Read */ 00332 temp = *read; 00333 /* Empty */ 00334 *read = 0; 00335 /* Most recent element read, return write pointer */ 00336 pwrite = read; 00337 /* Decrement read pointer */ 00338 read--; 00339 /* Validate pointer */ 00340 if( read < startpool ){ 00341 /* Exceeded pool boundaries */ 00342 read = endpool; 00343 } 00344 /* Reduce count */ 00345 icount--; 00346 if(icount < isize) 00347 ifull = 0; 00348 return temp; 00349 } 00350 00351 /* Extractors */ 00352 uint32_t size(){ return isize; } /**< @brief Get buffer size */ 00353 uint32_t used(){ return icount; } /**< @brief Get number of used elements */ 00354 uint32_t full(){ return ifull; } /**< @brief Get full flag */ 00355 uint32_t free(){ return isize-icount; } /**< @brief Get number of free elements */ 00356 private: 00357 bool dynamic; 00358 xifo_dtype *startpool; /**< @brief First element in pool */ 00359 xifo_dtype *endpool; /**< @brief Last element in pool */ 00360 xifo_dtype *read; /**< @brief Read pointer */ 00361 xifo_dtype *pwrite; /**< @brief Write pointer */ 00362 /* Variables: */ 00363 uint32_t ifull; /**< @brief Flag indicating buffer is full */ 00364 uint32_t icount; /**< @brief Number of elements used */ 00365 uint32_t isize; /**< @brief Size of buffer */ 00366 }; 00367 #endif 00368 00369 #if xIFO_USE_64BIT == TRUE 00370 /** 00371 * @brief Circular Buffer object. 00372 * @details This struct holds the object of a circular buffer 00373 */ 00374 typedef struct { 00375 /* Pointers: */ 00376 uint64_t *startpool; /**< @brief First element in pool */ 00377 uint64_t *endpool; /**< @brief Last element in pool */ 00378 uint64_t *read; /**< @brief Read pointer */ 00379 uint64_t *write; /**< @brief Write pointer */ 00380 /* Variables: */ 00381 uint32_t full; /**< @brief Flag indicating buffer is full */ 00382 uint32_t count; /**< @brief Number of elements used */ 00383 uint32_t size; /**< @brief Size of buffer */ 00384 }xifo64_t; 00385 00386 /**< @brief Circular Buffer memory pool type. */ 00387 typedef uint64_t xifo64_pool_t; 00388 00389 #ifdef __cplusplus 00390 extern "C" { 00391 #endif 00392 /* xifo Common */ 00393 void xifo64_init( xifo64_t *c, uint32_t size, uint64_t *startpool ); 00394 void xifo64_clear( xifo64_t *c ); 00395 uint32_t xifo64_write( xifo64_t *c, uint64_t data ); 00396 /* FIFO use */ 00397 uint64_t xifo64_read_lr( xifo64_t *c, uint32_t index ); 00398 uint64_t xifo64_pop_lr( xifo64_t *c ); 00399 /* LIFO use */ 00400 uint64_t xifo64_read_mr( xifo64_t *c, uint32_t index ); 00401 uint64_t xifo64_pop_mr( xifo64_t *c ); 00402 /* Extractors */ 00403 uint32_t xifo64_get_size( xifo64_t *c ); 00404 uint32_t xifo64_get_used( xifo64_t *c ); 00405 uint32_t xifo64_get_full( xifo64_t *c ); 00406 uint32_t xifo64_get_free( xifo64_t *c ); 00407 #ifdef __cplusplus 00408 } 00409 #endif 00410 #endif 00411 00412 #if xIFO_USE_32BIT == TRUE 00413 /** 00414 * @brief Circular Buffer object. 00415 * @details This struct holds the object of a circular buffer 00416 */ 00417 typedef struct { 00418 /* Pointers: */ 00419 uint32_t *startpool; /**< @brief First element in pool */ 00420 uint32_t *endpool; /**< @brief Last element in pool */ 00421 uint32_t *read; /**< @brief Read pointer */ 00422 uint32_t *write; /**< @brief Write pointer */ 00423 /* Variables: */ 00424 uint32_t full; /**< @brief Flag indicating buffer is full */ 00425 uint32_t count; /**< @brief Number of elements used */ 00426 uint32_t size; /**< @brief Size of buffer */ 00427 }xifo32_t; 00428 00429 /**< @brief Circular Buffer memory pool type. */ 00430 typedef uint32_t xifo32_pool_t; 00431 00432 #ifdef __cplusplus 00433 extern "C" { 00434 #endif 00435 /* xifo Common */ 00436 void xifo32_init( xifo32_t *c, uint32_t size, uint32_t *startpool ); 00437 void xifo32_clear( xifo32_t *c ); 00438 uint32_t xifo32_write( xifo32_t *c, uint32_t data ); 00439 /* FIFO use */ 00440 uint32_t xifo32_read_lr( xifo32_t *c, uint32_t index ); 00441 uint32_t xifo32_pop_lr( xifo32_t *c ); 00442 /* LIFO use */ 00443 uint32_t xifo32_read_mr( xifo32_t *c, uint32_t index ); 00444 uint32_t xifo32_pop_mr( xifo32_t *c ); 00445 /* Extractors */ 00446 uint32_t xifo32_get_size( xifo32_t *c ); 00447 uint32_t xifo32_get_used( xifo32_t *c ); 00448 uint32_t xifo32_get_full( xifo32_t *c ); 00449 uint32_t xifo32_get_free( xifo32_t *c ); 00450 #ifdef __cplusplus 00451 } 00452 #endif 00453 #endif 00454 00455 #if xIFO_USE_16BIT == TRUE 00456 /** 00457 * @brief Circular Buffer object. 00458 * @details This struct holds the object of a circular buffer 00459 */ 00460 typedef struct { 00461 /* Pointers: */ 00462 uint16_t *startpool; /**< @brief First element in pool */ 00463 uint16_t *endpool; /**< @brief Last element in pool */ 00464 uint16_t *read; /**< @brief Read pointer */ 00465 uint16_t *write; /**< @brief Write pointer */ 00466 /* Variables: */ 00467 uint32_t full; /**< @brief Flag indicating buffer is full */ 00468 uint32_t count; /**< @brief Number of elements used */ 00469 uint32_t size; /**< @brief Size of buffer */ 00470 }xifo16_t; 00471 00472 /** 00473 * @brief Circular Buffer memory pool type. 00474 */ 00475 typedef uint16_t xifo16_pool_t; 00476 00477 #ifdef __cplusplus 00478 extern "C" { 00479 #endif 00480 /* xifo Common */ 00481 void xifo16_init( xifo16_t *c, uint32_t size, uint16_t *startpool); 00482 void xifo16_clear( xifo16_t *c); 00483 uint32_t xifo16_write( xifo16_t *c, uint16_t data); 00484 /* FIFO use */ 00485 uint16_t xifo16_read_lr( xifo16_t *c, uint32_t index); 00486 uint16_t xifo16_pop_lr( xifo16_t *c); 00487 /* LIFO use */ 00488 uint16_t xifo16_read_mr( xifo16_t *c, uint32_t index); 00489 uint16_t xifo16_pop_mr( xifo16_t *c); 00490 /* Extractors */ 00491 uint32_t xifo16_get_size( xifo16_t *c); 00492 uint32_t xifo16_get_used( xifo16_t *c); 00493 uint32_t xifo16_get_full( xifo16_t *c); 00494 uint32_t xifo16_get_free( xifo16_t *c); 00495 #ifdef __cplusplus 00496 } 00497 #endif 00498 #endif 00499 00500 #if xIFO_USE_8BIT == TRUE 00501 /** 00502 * @brief Circular Buffer object. 00503 * @details This struct holds the object of a circular buffer 00504 */ 00505 typedef struct { 00506 /* Pointers: */ 00507 uint8_t *startpool; /**< @brief First element in pool */ 00508 uint8_t *endpool; /**< @brief Last element in pool */ 00509 uint8_t *read; /**< @brief Read pointer */ 00510 uint8_t *write; /**< @brief Write pointer */ 00511 /* Variables: */ 00512 uint32_t full; /**< @brief Flag indicating buffer is full */ 00513 uint32_t count; /**< @brief Number of elements used */ 00514 uint32_t size; /**< @brief Size of buffer */ 00515 }xifo8_t; 00516 00517 /**< @brief Circular Buffer memory pool type. */ 00518 typedef uint8_t xifo8_pool_t; 00519 00520 #ifdef __cplusplus 00521 extern "C" { 00522 #endif 00523 /* xifo Common */ 00524 void xifo8_init(xifo8_t *c, uint32_t size, uint8_t *startpool ); 00525 void xifo8_clear( xifo8_t *c ); 00526 uint32_t xifo8_write( xifo8_t *c, uint8_t data ); 00527 /* FIFO use */ 00528 uint8_t xifo8_read_lr( xifo8_t *c, uint32_t index ); 00529 uint8_t xifo8_pop_lr( xifo8_t *c ); 00530 /* LIFO use */ 00531 uint8_t xifo8_read_mr( xifo8_t *c, uint32_t index ); 00532 uint8_t xifo8_pop_mr( xifo8_t *c ); 00533 /* Extractors */ 00534 uint32_t xifo8_get_size( xifo8_t *c ); 00535 uint32_t xifo8_get_used( xifo8_t *c ); 00536 uint32_t xifo8_get_full( xifo8_t *c ); 00537 uint32_t xifo8_get_free( xifo8_t *c ); 00538 #ifdef __cplusplus 00539 } 00540 #endif 00541 #endif 00542 00543 #endif //_xifo_H_ 00544 00545 /** @} */
Generated on Mon Jul 18 2022 08:08:14 by
1.7.2