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.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