Multi purpose buffer module.
Embed:
(wiki syntax)
Show/hide line numbers
xIFO.cpp
00001 /** 00002 * @file xifo.c 00003 * @brief xifo circular buffer with <t>/8/16/32/64 bit elements 00004 * @details xifo supplies object oriented circular buffer with 8 bit size elements. \n 00005 * To use either as FIFO (First In First Out) or as FILO (First In Last Out) 00006 * You might want to rename this file is you are using a C compiler. 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 #include "xIFO.h" 00035 00036 #if xIFO_USE_64BIT == TRUE 00037 /** 00038 * @brief Initialize buffer object structure. 00039 * 00040 * @note Does not clear memory pool. 00041 * 00042 * @param[in] c Pointer to @p xifo64_t object used for configuration. 00043 * @param[in] s Number of elements buffer can hold (size). 00044 * @param[in] sp Start of pre-allocated memory pool. 00045 */ 00046 void xifo64_init(xifo64_t *c, uint32_t s, uint64_t *sp){ 00047 c->startpool = sp; 00048 c->size = s; 00049 c->endpool = &sp[--s]; 00050 c->full = 0; 00051 c->count = 0; 00052 c->read = sp; 00053 c->write = sp; 00054 } 00055 00056 /** 00057 * @brief Clear buffer memory pool 00058 * 00059 * @note Must be used on initialised buffer object. 00060 * 00061 * @param[in] c Pointer to @p xifo64_t object. 00062 */ 00063 void xifo64_clear(xifo64_t *c){ 00064 register uint64_t *ptemp = c->startpool; 00065 register uint32_t i = c->size; 00066 while(i--){ 00067 00068 *ptemp++ = 0; 00069 } 00070 } 00071 00072 /** 00073 * @brief Read from buffer (lr) Least Recent oriented (fifo) 00074 * 00075 * @note Buffer state will be preserved 00076 * 00077 * @warning Consider this opertaion as atomic! 00078 * 00079 * @details Read n elements from the oldest element to the most recent. 00080 * As for index[0] the least recently added element is returned. 00081 * And for index[count] the most recent element is returned. 00082 * This makes it possible to peek in fifo. 00083 * 00084 * @param[in] c Pointer to @p xifo64_t used for configuration. 00085 * @param[in] index Index relative from least recent 00086 * 00087 * @return Contents of element or 0 if failed (element can hold 0) 00088 */ 00089 uint64_t xifo64_read_lr(xifo64_t *c, uint32_t index){ 00090 register uint64_t *ptemp; 00091 /* Verify there is valid data to read */ 00092 if(index >= c->count){ 00093 return 0; /* Nothing to read there */ 00094 } 00095 /* Calculate index of oldest element */ 00096 index = (c->count-1) - index; 00097 /* Set pointer */ 00098 ptemp = (c->read) - index; 00099 if(ptemp < c->startpool){ 00100 /* Exceeded pool boundaries */ 00101 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00102 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00103 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00104 } 00105 /* Read most recent */ 00106 return *ptemp; 00107 } 00108 00109 /** 00110 * @brief Read from buffer (mr) Most Recent oriented (filo) 00111 * 00112 * @note Buffer state will be preserved 00113 * 00114 * @warning Consider this opertaion as atomic! 00115 * 00116 * @details Read n elements back in time. 00117 * As for index[0] the most recently added element is returned. 00118 * And for index[count] the oldest element is returned. 00119 * This makes it possible to keep history. For DSP application. 00120 * 00121 * @param[in] c Pointer to @p xifo64_t used for configuration. 00122 * @param[in] index Index relative from most recent 00123 * 00124 * @return Contents of element or 0 if failed (element can hold 0) 00125 */ 00126 uint64_t xifo64_read_mr(xifo64_t *c, uint32_t index){ 00127 register uint64_t *ptemp; 00128 /* Verify there is valid data to read */ 00129 if(index >= c->count){ 00130 return 0; /* Nothing to read there */ 00131 } 00132 /* Set pointer */ 00133 ptemp = (c->read) - index; 00134 /* Validate pointer */ 00135 if(ptemp < c->startpool){ 00136 /* Exceeded pool boundaries */ 00137 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00138 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00139 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00140 } 00141 /* Read most recent */ 00142 return *ptemp; 00143 } 00144 00145 /** 00146 * @brief Pop (mr) most recent from buffer (filo) 00147 * 00148 * @note Buffer state will be altered 00149 * 00150 * @warning Consider this opertaion as atomic! 00151 * 00152 * @details Read and remove the most recently added from the buffer. 00153 * Using this results in a stack type of buffer. 00154 * 00155 * @param[in] c Pointer to @p xifo64_t used for configuration. 00156 * 00157 * @return Contents of element or 0 if failed (element can hold 0) 00158 */ 00159 uint64_t xifo64_pop_mr(xifo64_t *c){ 00160 register uint64_t temp; 00161 /* Verify there is valid data read */ 00162 if(c->count == 0){ 00163 return 0; /* Nothing to read there */ 00164 } 00165 /* Read */ 00166 temp = *c->read; 00167 /* Empty */ 00168 *c->read = 0; 00169 /* Most recent element read, return write pointer */ 00170 c->write = c->read; 00171 /* Decrement read pointer */ 00172 c->read--; 00173 /* Validate pointer */ 00174 if( c->read < c->startpool ){ 00175 /* Exceeded pool boundaries */ 00176 c->read = c->endpool; 00177 } 00178 /* Reduce count */ 00179 c->count--; 00180 if(c->count < c->size) 00181 c->full = 0; 00182 return temp; 00183 } 00184 00185 /** 00186 * @brief Pop (lr) least recent from buffer (fifo) 00187 * 00188 * @note Buffer state will be altered 00189 * 00190 * @warning Consider this opertaion as atomic! 00191 * 00192 * @details Read and remove the least recently added from the buffer. 00193 * Using this results in a fifo type of buffer. 00194 * 00195 * @param[in] c Pointer to @p xifo64_t used for configuration. 00196 * 00197 * @return Contents of element or 0 if failed (element can hold 0) 00198 */ 00199 uint64_t xifo64_pop_lr(xifo64_t *c){ 00200 register uint64_t *ptemp; 00201 register uint64_t temp; 00202 /* Verify there is valid data read */ 00203 if(c->count == 0){ 00204 return 0; /* Nothing to read there */ 00205 } 00206 /* Derive least recent buffer element */ 00207 ptemp = (c->read+1) - c->count; 00208 /* Validate pointer */ 00209 if(ptemp < c->startpool){ 00210 /* Exceeded pool boundaries */ 00211 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00212 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00213 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00214 } 00215 /* Read oldest buffer element */ 00216 /* Read to temp register */ 00217 temp = *ptemp; 00218 /* Empty buffer element */ 00219 *ptemp = 0; 00220 /* Reduce count */ 00221 c->count--; 00222 /* Check full flag */ 00223 if(c->count < c->size) 00224 c->full = 0; 00225 return temp; 00226 } 00227 00228 /** 00229 * @brief Write to buffer 00230 * 00231 * @note Readpointer is automatically set to the last added element. 00232 * 00233 * @warning Consider this opertaion as atomic! 00234 * 00235 * @details Adds a value to the buffer. 00236 * Automatically overwrites oldest elements when full. 00237 * 00238 * @param[in] c Pointer to @p xifo64_t used for configuration. 00239 * @param[in] data Data to add to buffer 00240 * 00241 * @return Number of free buffer elements 00242 */ 00243 uint32_t xifo64_write(xifo64_t *c, uint64_t data){ 00244 /* Write data */ 00245 *c->write = data; 00246 /* Update read pointer to most recent element */ 00247 c->read = c->write; 00248 /* Write pointer increment */ 00249 c->write++; 00250 /* Validate pointer */ 00251 if( c->write > c->endpool){ 00252 /* We exceeded pool boundaries */ 00253 c->write = c->startpool; 00254 } 00255 /* Update count */ 00256 c->count++; 00257 /* Verify full */ 00258 if( c->count >= c->size ){ 00259 c->full = 1; 00260 c->count = c->size; 00261 } 00262 /* return free elements count */ 00263 return c->size - c->count; 00264 } 00265 00266 /** 00267 * @brief Get buffer size 00268 * 00269 * @param[in] c Pointer to @p xifo64_t used for configuration. 00270 * 00271 * @return Size of memory pool in elements 00272 */ 00273 uint32_t xifo64_get_size(xifo64_t *c){ 00274 return c->size; 00275 } 00276 00277 /** 00278 * @brief Get number of used elements 00279 * 00280 * @param[in] c Pointer to @p xifo64_t used for configuration. 00281 * 00282 * @return Number of used buffer elements 00283 */ 00284 uint32_t xifo64_get_used(xifo64_t *c){ 00285 return c->count; 00286 } 00287 00288 /** 00289 * @brief Get number of free elements 00290 * 00291 * @param[in] c Pointer to @p xifo64_t used for configuration. 00292 * 00293 * @return Number of free elements 00294 */ 00295 uint32_t xifo64_get_free(xifo64_t *c){ 00296 return c->size - c->count; 00297 } 00298 00299 /** 00300 * @brief Get full flag 00301 * 00302 * @param[in] c Pointer to @p xifo64_t used for configuration. 00303 * 00304 * @return 1 if full 00305 */ 00306 uint32_t xifo64_get_full(xifo64_t *c){ 00307 return c->full; 00308 } 00309 00310 /** @} */ 00311 #endif 00312 00313 #if xIFO_USE_32BIT == TRUE 00314 /** 00315 * @brief Initialize buffer object structure. 00316 * 00317 * @note Does not clear memory pool. 00318 * 00319 * @param[in] c Pointer to @p xifo32_t object used for configuration. 00320 * @param[in] s Number of elements buffer can hold (size). 00321 * @param[in] sp Start of pre-allocated memory pool. 00322 */ 00323 void xifo32_init(xifo32_t *c, uint32_t s, uint32_t *sp){ 00324 c->startpool = sp; 00325 c->size = s; 00326 c->endpool = &sp[--s]; 00327 c->full = 0; 00328 c->count = 0; 00329 c->read = sp; 00330 c->write = sp; 00331 } 00332 00333 /** 00334 * @brief Clear buffer memory pool 00335 * 00336 * @note Must be used on initialised buffer object. 00337 * 00338 * @param[in] c Pointer to @p xifo32_t object. 00339 */ 00340 void xifo32_clear(xifo32_t *c){ 00341 register uint32_t *ptemp = c->startpool; 00342 register uint32_t i = c->size; 00343 while(i--){ 00344 *ptemp++ = 0; 00345 } 00346 } 00347 00348 /** 00349 * @brief Read from buffer (lr) Least Recent oriented (fifo) 00350 * 00351 * @note Buffer state will be preserved 00352 * 00353 * @warning Consider this opertaion as atomic! 00354 * 00355 * @details Read n elements from the oldest element to the most recent. 00356 * As for index[0] the least recently added element is returned. 00357 * And for index[count] the most recent element is returned. 00358 * This makes it possible to peek in fifo. 00359 * 00360 * @param[in] c Pointer to @p xifo32_t used for configuration. 00361 * @param[in] index Index relative from least recent 00362 * 00363 * @return Contents of element or 0 if failed (element can hold 0) 00364 */ 00365 uint32_t xifo32_read_lr(xifo32_t *c, uint32_t index){ 00366 register uint32_t *ptemp; 00367 /* Verify there is valid data to read */ 00368 if(index >= c->count){ 00369 return 0; /* Nothing to read there */ 00370 } 00371 /* Calculate index of oldest element */ 00372 index = (c->count-1) - index; 00373 /* Set pointer */ 00374 ptemp = (c->read) - index; 00375 if(ptemp < c->startpool){ 00376 /* Exceeded pool boundaries */ 00377 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00378 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00379 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00380 } 00381 /* Read most recent */ 00382 return *ptemp; 00383 } 00384 00385 /** 00386 * @brief Read from buffer (mr) Most Recent oriented (filo) 00387 * 00388 * @note Buffer state will be preserved 00389 * 00390 * @warning Consider this opertaion as atomic! 00391 * 00392 * @details Read n elements back in time. 00393 * As for index[0] the most recently added element is returned. 00394 * And for index[count] the oldest element is returned. 00395 * This makes it possible to keep history. For DSP application. 00396 * 00397 * @param[in] c Pointer to @p xifo32_t used for configuration. 00398 * @param[in] index Index relative from most recent 00399 * 00400 * @return Contents of element or 0 if failed (element can hold 0) 00401 */ 00402 uint32_t xifo32_read_mr(xifo32_t *c, uint32_t index){ 00403 register uint32_t *ptemp; 00404 /* Verify there is valid data to read */ 00405 if(index >= c->count){ 00406 return 0; /* Nothing to read there */ 00407 } 00408 /* Set pointer */ 00409 ptemp = (c->read) - index; 00410 /* Validate pointer */ 00411 if(ptemp < c->startpool){ 00412 /* Exceeded pool boundaries */ 00413 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00414 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00415 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00416 } 00417 /* Read most recent */ 00418 return *ptemp; 00419 } 00420 00421 /** 00422 * @brief Pop (mr) most recent from buffer (filo) 00423 * 00424 * @note Buffer state will be altered 00425 * 00426 * @warning Consider this opertaion as atomic! 00427 * 00428 * @details Read and remove the most recently added from the buffer. 00429 * Using this results in a stack type of buffer. 00430 * 00431 * @param[in] c Pointer to @p xifo32_t used for configuration. 00432 * 00433 * @return Contents of element or 0 if failed (element can hold 0) 00434 */ 00435 uint32_t xifo32_pop_mr(xifo32_t *c){ 00436 register uint32_t temp; 00437 /* Verify there is valid data read */ 00438 if(c->count == 0){ 00439 return 0; /* Nothing to read there */ 00440 } 00441 /* Read */ 00442 temp = *c->read; 00443 /* Empty */ 00444 *c->read = 0; 00445 /* Most recent element read, return write pointer */ 00446 c->write = c->read; 00447 /* Decrement read pointer */ 00448 c->read--; 00449 /* Validate pointer */ 00450 if( c->read < c->startpool ){ 00451 /* Exceeded pool boundaries */ 00452 c->read = c->endpool; 00453 } 00454 /* Reduce count */ 00455 c->count--; 00456 if(c->count < c->size) 00457 c->full = 0; 00458 return temp; 00459 } 00460 00461 /** 00462 * @brief Pop (lr) least recent from buffer (fifo) 00463 * 00464 * @note Buffer state will be altered 00465 * 00466 * @warning Consider this opertaion as atomic! 00467 * 00468 * @details Read and remove the least recently added from the buffer. 00469 * Using this results in a fifo type of buffer. 00470 * 00471 * @param[in] c Pointer to @p xifo32_t used for configuration. 00472 * 00473 * @return Contents of element or 0 if failed (element can hold 0) 00474 */ 00475 uint32_t xifo32_pop_lr(xifo32_t *c){ 00476 register uint32_t *ptemp; 00477 register uint32_t temp; 00478 /* Verify there is valid data read */ 00479 if(c->count == 0){ 00480 return 0; /* Nothing to read there */ 00481 } 00482 /* Derive least recent buffer element */ 00483 ptemp = (c->read+1) - c->count; 00484 /* Validate pointer */ 00485 if(ptemp < c->startpool){ 00486 /* Exceeded pool boundaries */ 00487 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00488 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00489 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00490 } 00491 /* Read oldest buffer element */ 00492 /* Read to temp register */ 00493 temp = *ptemp; 00494 /* Empty buffer element */ 00495 *ptemp = 0; 00496 /* Reduce count */ 00497 c->count--; 00498 /* Check full flag */ 00499 if(c->count < c->size) 00500 c->full = 0; 00501 return temp; 00502 } 00503 00504 /** 00505 * @brief Write to buffer 00506 * 00507 * @note Readpointer is automatically set to the last added element. 00508 * 00509 * @warning Consider this opertaion as atomic! 00510 * 00511 * @details Adds a value to the buffer. 00512 * Automatically overwrites oldest elements when full. 00513 * 00514 * @param[in] c Pointer to @p xifo32_t used for configuration. 00515 * @param[in] data Data to add to buffer 00516 * 00517 * @return Number of free buffer elements 00518 */ 00519 uint32_t xifo32_write(xifo32_t *c, uint32_t data){ 00520 /* Write data */ 00521 *c->write = data; 00522 /* Update read pointer to most recent element */ 00523 c->read = c->write; 00524 /* Write pointer increment */ 00525 c->write++; 00526 /* Validate pointer */ 00527 if( c->write > c->endpool){ 00528 /* We exceeded pool boundaries */ 00529 c->write = c->startpool; 00530 } 00531 /* Update count */ 00532 c->count++; 00533 /* Verify full */ 00534 if( c->count >= c->size ){ 00535 c->full = 1; 00536 c->count = c->size; 00537 } 00538 /* return free elements count */ 00539 return c->size - c->count; 00540 } 00541 00542 /** 00543 * @brief Get buffer size 00544 * 00545 * @param[in] c Pointer to @p xifo32_t used for configuration. 00546 * 00547 * @return Size of memory pool in elements 00548 */ 00549 uint32_t xifo32_get_size(xifo32_t *c){ 00550 return c->size; 00551 } 00552 00553 /** 00554 * @brief Get number of used elements 00555 * 00556 * @param[in] c Pointer to @p xifo32_t used for configuration. 00557 * 00558 * @return Number of used buffer elements 00559 */ 00560 uint32_t xifo32_get_used(xifo32_t *c){ 00561 return c->count; 00562 } 00563 00564 /** 00565 * @brief Get number of free elements 00566 * 00567 * @param[in] c Pointer to @p xifo32_t used for configuration. 00568 * 00569 * @return Number of free elements 00570 */ 00571 uint32_t xifo32_get_free(xifo32_t *c){ 00572 return c->size - c->count; 00573 } 00574 00575 /** 00576 * @brief Get full flag 00577 * 00578 * @param[in] c Pointer to @p xifo32_t used for configuration. 00579 * 00580 * @return 1 if full 00581 */ 00582 uint32_t xifo32_get_full(xifo32_t *c){ 00583 return c->full; 00584 } 00585 00586 /** @} */ 00587 #endif 00588 00589 #if xIFO_USE_16BIT == TRUE 00590 /** 00591 * @brief Initialize buffer object structure. 00592 * 00593 * @note Does not clear memory pool. 00594 * 00595 * @param[in] c Pointer to @p xifo16_t object used for configuration. 00596 * @param[in] s Number of elements buffer can hold (size). 00597 * @param[in] sp Start of pre-allocated memory pool. 00598 */ 00599 void xifo16_init(xifo16_t *c, uint32_t s, uint16_t *sp){ 00600 c->startpool = sp; 00601 c->size = s; 00602 c->endpool = &sp[--s]; 00603 c->full = 0; 00604 c->count = 0; 00605 c->read = sp; 00606 c->write = sp; 00607 } 00608 00609 /** 00610 * @brief Clear buffer memory pool 00611 * 00612 * @note Must be used on initialised buffer object. 00613 * 00614 * @param[in] c Pointer to @p xifo16_t object. 00615 */ 00616 void xifo16_clear(xifo16_t *c){ 00617 register uint16_t *ptemp = c->startpool; 00618 register uint32_t i = c->size; 00619 while(i--){ 00620 *ptemp++ = 0; 00621 } 00622 } 00623 00624 /** 00625 * @brief Read from buffer (lr) Least Recent oriented (fifo) 00626 * 00627 * @note Buffer state will be preserved 00628 * 00629 * @warning Consider this opertaion as atomic! 00630 * 00631 * @details Read n elements from the oldest element to the most recent. 00632 * As for index[0] the least recently added element is returned. 00633 * And for index[count] the most recent element is returned. 00634 * This makes it possible to peek in fifo. 00635 * 00636 * @param[in] c Pointer to @p xifo16_t used for configuration. 00637 * @param[in] index Index relative from least recent 00638 * 00639 * @return Contents of element or 0 if failed (element can hold 0) 00640 */ 00641 uint16_t xifo16_read_lr(xifo16_t *c, uint32_t index){ 00642 register uint16_t *ptemp; 00643 /* Verify there is valid data to read */ 00644 if(index >= c->count){ 00645 return 0; /* Nothing to read there */ 00646 } 00647 /* Calculate index of oldest element */ 00648 index = (c->count-1) - index; 00649 /* Set pointer */ 00650 ptemp = (c->read) - index; 00651 if(ptemp < c->startpool){ 00652 /* Exceeded pool boundaries */ 00653 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00654 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00655 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00656 } 00657 /* Read most recent */ 00658 return *ptemp; 00659 } 00660 00661 /** 00662 * @brief Read from buffer (mr) Most Recent oriented (filo) 00663 * 00664 * @note Buffer state will be preserved 00665 * 00666 * @warning Consider this opertaion as atomic! 00667 * 00668 * @details Read n elements back in time. 00669 * As for index[0] the most recently added element is returned. 00670 * And for index[count] the oldest element is returned. 00671 * This makes it possible to keep history. For DSP application. 00672 * 00673 * @param[in] c Pointer to @p xifo16_t used for configuration. 00674 * @param[in] index Index relative from most recent 00675 * 00676 * @return Contents of element or 0 if failed (element can hold 0) 00677 */ 00678 uint16_t xifo16_read_mr(xifo16_t *c, uint32_t index){ 00679 register uint16_t *ptemp; 00680 /* Verify there is valid data to read */ 00681 if(index >= c->count){ 00682 return 0; /* Nothing to read there */ 00683 } 00684 /* Set pointer */ 00685 ptemp = (c->read) - index; 00686 /* Validate pointer */ 00687 if(ptemp < c->startpool){ 00688 /* Exceeded pool boundaries */ 00689 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00690 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00691 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00692 } 00693 /* Read most recent */ 00694 return *ptemp; 00695 } 00696 00697 /** 00698 * @brief Pop (mr) most recent from buffer (filo) 00699 * 00700 * @note Buffer state will be altered 00701 * 00702 * @warning Consider this opertaion as atomic! 00703 * 00704 * @details Read and remove the most recently added from the buffer. 00705 * Using this results in a stack type of buffer. 00706 * 00707 * @param[in] c Pointer to @p xifo16_t used for configuration. 00708 * 00709 * @return Contents of element or 0 if failed (element can hold 0) 00710 */ 00711 uint16_t xifo16_pop_mr(xifo16_t *c){ 00712 register uint16_t temp; 00713 /* Verify there is valid data read */ 00714 if(c->count == 0){ 00715 return 0; /* Nothing to read there */ 00716 } 00717 /* Read */ 00718 temp = *c->read; 00719 /* Empty */ 00720 *c->read = 0; 00721 /* Most recent element read, return write pointer */ 00722 c->write = c->read; 00723 /* Decrement read pointer */ 00724 c->read--; 00725 /* Validate pointer */ 00726 if( c->read < c->startpool ){ 00727 /* Exceeded pool boundaries */ 00728 c->read = c->endpool; 00729 } 00730 /* Reduce count */ 00731 c->count--; 00732 if(c->count < c->size) 00733 c->full = 0; 00734 return temp; 00735 } 00736 00737 /** 00738 * @brief Pop (lr) least recent from buffer (fifo) 00739 * 00740 * @note Buffer state will be altered 00741 * 00742 * @warning Consider this opertaion as atomic! 00743 * 00744 * @details Read and remove the least recently added from the buffer. 00745 * Using this results in a fifo type of buffer. 00746 * 00747 * @param[in] c Pointer to @p xifo16_t used for configuration. 00748 * 00749 * @return Contents of element or 0 if failed (element can hold 0) 00750 */ 00751 uint16_t xifo16_pop_lr(xifo16_t *c){ 00752 register uint16_t *ptemp; 00753 register uint16_t temp; 00754 /* Verify there is valid data read */ 00755 if(c->count == 0){ 00756 return 0; /* Nothing to read there */ 00757 } 00758 /* Derive least recent buffer element */ 00759 ptemp = (c->read+1) - c->count; 00760 /* Validate pointer */ 00761 if(ptemp < c->startpool){ 00762 /* Exceeded pool boundaries */ 00763 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00764 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00765 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00766 } 00767 /* Read oldest buffer element */ 00768 /* Read to temp register */ 00769 temp = *ptemp; 00770 /* Empty buffer element */ 00771 *ptemp = 0; 00772 /* Reduce count */ 00773 c->count--; 00774 /* Check full flag */ 00775 if(c->count < c->size) 00776 c->full = 0; 00777 return temp; 00778 } 00779 00780 /** 00781 * @brief Write to buffer 00782 * 00783 * @note Readpointer is automatically set to the last added element. 00784 * 00785 * @warning Consider this opertaion as atomic! 00786 * 00787 * @details Adds a value to the buffer. 00788 * Automatically overwrites oldest elements when full. 00789 * 00790 * @param[in] c Pointer to @p xifo16_t used for configuration. 00791 * @param[in] data Data to add to buffer 00792 * 00793 * @return Number of free buffer elements 00794 */ 00795 uint32_t xifo16_write(xifo16_t *c, uint16_t data){ 00796 /* Write data */ 00797 *c->write = data; 00798 /* Update read pointer to most recent element */ 00799 c->read = c->write; 00800 /* Write pointer increment */ 00801 c->write++; 00802 /* Validate pointer */ 00803 if( c->write > c->endpool){ 00804 /* We exceeded pool boundaries */ 00805 c->write = c->startpool; 00806 } 00807 /* Update count */ 00808 c->count++; 00809 /* Verify full */ 00810 if( c->count >= c->size ){ 00811 c->full = 1; 00812 c->count = c->size; 00813 } 00814 /* return free elements count */ 00815 return c->size - c->count; 00816 } 00817 00818 /** 00819 * @brief Get buffer size 00820 * 00821 * @param[in] c Pointer to @p xifo16_t used for configuration. 00822 * 00823 * @return Size of memory pool in elements 00824 */ 00825 uint32_t xifo16_get_size(xifo16_t *c){ 00826 return c->size; 00827 } 00828 00829 /** 00830 * @brief Get number of used elements 00831 * 00832 * @param[in] c Pointer to @p xifo16_t used for configuration. 00833 * 00834 * @return Number of used buffer elements 00835 */ 00836 uint32_t xifo16_get_used(xifo16_t *c){ 00837 return c->count; 00838 } 00839 00840 /** 00841 * @brief Get number of free elements 00842 * 00843 * @param[in] c Pointer to @p xifo16_t used for configuration. 00844 * 00845 * @return Number of free elements 00846 */ 00847 uint32_t xifo16_get_free(xifo16_t *c){ 00848 return c->size - c->count; 00849 } 00850 00851 /** 00852 * @brief Get full flag 00853 * 00854 * @param[in] c Pointer to @p xifo16_t used for configuration. 00855 * 00856 * @return 1 if full 00857 */ 00858 uint32_t xifo16_get_full(xifo16_t *c){ 00859 return c->full; 00860 } 00861 00862 /** @} */ 00863 00864 #endif 00865 00866 #if xIFO_USE_8BIT == TRUE 00867 /** 00868 * @brief Initialize buffer object structure. 00869 * 00870 * @note Does not clear memory pool. 00871 * 00872 * @param[in] c Pointer to @p xifo8_t object used for configuration. 00873 * @param[in] s Number of elements buffer can hold (size). 00874 * @param[in] sp Start of pre-allocated memory pool. 00875 */ 00876 void xifo8_init(xifo8_t *c, uint32_t s, uint8_t *sp){ 00877 c->startpool = sp; 00878 c->size = s; 00879 c->endpool = &sp[--s]; 00880 c->full = 0; 00881 c->count = 0; 00882 c->read = sp; 00883 c->write = sp; 00884 } 00885 00886 /** 00887 * @brief Clear buffer memory pool 00888 * 00889 * @note Must be used on initialised buffer object. 00890 * 00891 * @param[in] c Pointer to @p xifo8_t object. 00892 */ 00893 void xifo8_clear(xifo8_t *c){ 00894 register uint8_t *ptemp = c->startpool; 00895 register uint32_t i = c->size; 00896 while(i--){ 00897 *ptemp++ = 0; 00898 } 00899 } 00900 00901 /** 00902 * @brief Read from buffer (lr) Least Recent oriented (fifo) 00903 * 00904 * @note Buffer state will be preserved 00905 * 00906 * @warning Consider this opertaion as atomic! 00907 * 00908 * @details Read n elements from the oldest element to the most recent. 00909 * As for index[0] the least recently added element is returned. 00910 * And for index[count] the most recent element is returned. 00911 * This makes it possible to peek in fifo. 00912 * 00913 * @param[in] c Pointer to @p xifo8_t used for configuration. 00914 * @param[in] index Index relative from least recent 00915 * 00916 * @return Contents of element or 0 if failed (element can hold 0) 00917 */ 00918 uint8_t xifo8_read_lr(xifo8_t *c, uint32_t index){ 00919 register uint8_t *ptemp; 00920 /* Verify there is valid data to read */ 00921 if(index >= c->count){ 00922 return 0; /* Nothing to read there */ 00923 } 00924 /* Calculate index of oldest element */ 00925 index = (c->count-1) - index; 00926 /* Set pointer */ 00927 ptemp = (c->read) - index; 00928 if(ptemp < c->startpool){ 00929 /* Exceeded pool boundaries */ 00930 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00931 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00932 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00933 } 00934 /* Read most recent */ 00935 return *ptemp; 00936 } 00937 00938 /** 00939 * @brief Read from buffer (mr) Most Recent oriented (filo) 00940 * 00941 * @note Buffer state will be preserved 00942 * 00943 * @warning Consider this opertaion as atomic! 00944 * 00945 * @details Read n elements back in time. 00946 * As for index[0] the most recently added element is returned. 00947 * And for index[count] the oldest element is returned. 00948 * This makes it possible to keep history. For DSP application. 00949 * 00950 * @param[in] c Pointer to @p xifo8_t used for configuration. 00951 * @param[in] index Index relative from most recent 00952 * 00953 * @return Contents of element or 0 if failed (element can hold 0) 00954 */ 00955 uint8_t xifo8_read_mr(xifo8_t *c, uint32_t index){ 00956 register uint8_t *ptemp; 00957 /* Verify there is valid data to read */ 00958 if(index >= c->count){ 00959 return 0; /* Nothing to read there */ 00960 } 00961 /* Set pointer */ 00962 ptemp = (c->read) - index; 00963 /* Validate pointer */ 00964 if(ptemp < c->startpool){ 00965 /* Exceeded pool boundaries */ 00966 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 00967 /* Since one element of overshoot results in end - 1 you would miss the last value */ 00968 ptemp = (c->endpool+1) - (c->startpool - ptemp); 00969 } 00970 /* Read most recent */ 00971 return *ptemp; 00972 } 00973 00974 /** 00975 * @brief Pop (mr) most recent from buffer (filo) 00976 * 00977 * @note Buffer state will be altered 00978 * 00979 * @warning Consider this opertaion as atomic! 00980 * 00981 * @details Read and remove the most recently added from the buffer. 00982 * Using this results in a stack type of buffer. 00983 * 00984 * @param[in] c Pointer to @p xifo8_t used for configuration. 00985 * 00986 * @return Contents of element or 0 if failed (element can hold 0) 00987 */ 00988 uint8_t xifo8_pop_mr(xifo8_t *c){ 00989 register uint8_t temp; 00990 /* Verify there is valid data read */ 00991 if(c->count == 0){ 00992 return 0; /* Nothing to read there */ 00993 } 00994 /* Read */ 00995 temp = *c->read; 00996 /* Empty */ 00997 *c->read = 0; 00998 /* Most recent element read, return write pointer */ 00999 c->write = c->read; 01000 /* Decrement read pointer */ 01001 c->read--; 01002 /* Validate pointer */ 01003 if( c->read < c->startpool ){ 01004 /* Exceeded pool boundaries */ 01005 c->read = c->endpool; 01006 } 01007 /* Reduce count */ 01008 c->count--; 01009 if(c->count < c->size) 01010 c->full = 0; 01011 return temp; 01012 } 01013 01014 /** 01015 * @brief Pop (lr) least recent from buffer (fifo) 01016 * 01017 * @note Buffer state will be altered 01018 * 01019 * @warning Consider this opertaion as atomic! 01020 * 01021 * @details Read and remove the least recently added from the buffer. 01022 * Using this results in a fifo type of buffer. 01023 * 01024 * @param[in] c Pointer to @p xifo8_t used for configuration. 01025 * 01026 * @return Contents of element or 0 if failed (element can hold 0) 01027 */ 01028 uint8_t xifo8_pop_lr(xifo8_t *c){ 01029 register uint8_t *ptemp; 01030 register uint8_t temp; 01031 /* Verify there is valid data read */ 01032 if(c->count == 0){ 01033 return 0; /* Nothing to read there */ 01034 } 01035 /* Derive least recent buffer element */ 01036 ptemp = (c->read+1) - c->count; 01037 /* Validate pointer */ 01038 if(ptemp < c->startpool){ 01039 /* Exceeded pool boundaries */ 01040 /* Calculate overshoot (startpool - indexptr) and subtract from end */ 01041 /* Since one element of overshoot results in end - 1 you would miss the last value */ 01042 ptemp = (c->endpool+1) - (c->startpool - ptemp); 01043 } 01044 /* Read oldest buffer element */ 01045 /* Read to temp register */ 01046 temp = *ptemp; 01047 /* Empty buffer element */ 01048 *ptemp = 0; 01049 /* Reduce count */ 01050 c->count--; 01051 /* Check full flag */ 01052 if(c->count < c->size) 01053 c->full = 0; 01054 return temp; 01055 } 01056 01057 /** 01058 * @brief Write to buffer 01059 * 01060 * @note Readpointer is automatically set to the last added element. 01061 * 01062 * @warning Consider this opertaion as atomic! 01063 * 01064 * @details Adds a value to the buffer. 01065 * Automatically overwrites oldest elements when full. 01066 * 01067 * @param[in] c Pointer to @p xifo8_t used for configuration. 01068 * @param[in] data Data to add to buffer 01069 * 01070 * @return Number of free buffer elements 01071 */ 01072 uint32_t xifo8_write(xifo8_t *c, uint8_t data){ 01073 /* Write data */ 01074 *c->write = data; 01075 /* Update read pointer to most recent element */ 01076 c->read = c->write; 01077 /* Write pointer increment */ 01078 c->write++; 01079 /* Validate pointer */ 01080 if( c->write > c->endpool){ 01081 /* We exceeded pool boundaries */ 01082 c->write = c->startpool; 01083 } 01084 /* Update count */ 01085 c->count++; 01086 /* Verify full */ 01087 if( c->count >= c->size ){ 01088 c->full = 1; 01089 c->count = c->size; 01090 } 01091 /* return free elements count */ 01092 return c->size - c->count; 01093 } 01094 01095 /** 01096 * @brief Get buffer size 01097 * 01098 * @param[in] c Pointer to @p xifo8_t used for configuration. 01099 * 01100 * @return Size of memory pool in elements 01101 */ 01102 uint32_t xifo8_get_size(xifo8_t *c){ 01103 return c->size; 01104 } 01105 01106 /** 01107 * @brief Get number of used elements 01108 * 01109 * @param[in] c Pointer to @p xifo8_t used for configuration. 01110 * 01111 * @return Number of used buffer elements 01112 */ 01113 uint32_t xifo8_get_used(xifo8_t *c){ 01114 return c->count; 01115 } 01116 01117 /** 01118 * @brief Get number of free elements 01119 * 01120 * @param[in] c Pointer to @p xifo8_t used for configuration. 01121 * 01122 * @return Number of free elements 01123 */ 01124 uint32_t xifo8_get_free(xifo8_t *c){ 01125 return c->size - c->count; 01126 } 01127 01128 /** 01129 * @brief Get full flag 01130 * 01131 * @param[in] c Pointer to @p xifo8_t used for configuration. 01132 * 01133 * @return 1 if full 01134 */ 01135 uint32_t xifo8_get_full(xifo8_t *c){ 01136 return c->full; 01137 } 01138 01139 /** @} */ 01140 #endif 01141 01142 /** @} */
Generated on Mon Jul 18 2022 08:08:14 by 1.7.2