Generate sine waves with 2 mbeds synchronised. Configurable amplitude and phase. Built for 50 Hz mains simulations.

Dependencies:   MODDMA mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xIFO.c Source File

xIFO.c

00001 
00002  /**
00003  * @file    xifo.c
00004  * @brief   xifo circular buffer
00005  * @details xifo supplies object oriented circular buffer with 32 bit size elements. \n
00006  *                     To use either as FIFO (First In First Out) or as FILO (First In Last Out)
00007  *
00008  * @Author    Jeroen Lodder
00009  * @Date        April 2013
00010  * @version 2
00011  *
00012  * @{
00013  */
00014 #include "xIFO.h"
00015 
00016 /**
00017  * @brief   Initialise buffer object structure.
00018  *
00019  * @note    Does not clear memory pool.
00020  *
00021  * @param[in] c   Pointer to @p xifo_t object used for configuration.
00022  * @param[in] s   Number of elements buffer can hold (size).
00023  * @param[in] sp  Start of pre-allocated memory pool.
00024  */
00025 void xifo_init(xifo_t *c, uint32_t s, uint32_t *sp){
00026     c->startpool        = sp;
00027     c->endpool          = &sp[s-1];
00028     c->size             = s;
00029     c->full             = 0;
00030     c->elementcount     = 0;
00031     c->read             = sp;
00032     c->write            = sp;
00033 }
00034 
00035 /**
00036  * @brief   Clear buffer contents
00037  *
00038  * @note    Must be used on initialised buffer object.
00039  *
00040  * @param[in] c   Pointer to @p xifo_t object.
00041  */
00042 void xifo_clear(xifo_t *c){
00043     c->ptemp = c->startpool;
00044     while(c->ptemp <= c->endpool){
00045         *c->ptemp++ = 0;        
00046     }
00047 }
00048 
00049 /**
00050  * @brief   Read from buffer (lr) Least Recent oriented (fifo)
00051  *
00052  * @note    Buffer state will be preserved
00053  *
00054  * @warning    Consider this opertaion as atomic!
00055  *
00056  * @details Read n elements from the oldest element to the most recent.
00057  *                    As for index[0] the least recently added element is returned.
00058  *                    And for index[elementcount] the most recent element is returned.
00059  *                    This makes it possible to peek in fifo.
00060  *
00061  * @param[in] c           Pointer to @p xifo_t used for configuration.
00062  * @param[in] index   Index relative from least recent
00063  *
00064  * @return    Contents of element or 0 if failed (element can hold 0)
00065  */
00066 uint32_t xifo_read_lr(xifo_t *c, uint32_t index){
00067     /* Verify there is valid data to read */
00068     if(index+1 > c->elementcount){
00069         return 0;    /* Nothing to read there */
00070     }
00071     /* Calculate index of oldest element */
00072     index = (c->elementcount-1) - index;
00073     /* Set pointer */
00074     c->ptemp = (c->read) - index;
00075     if(c->ptemp < c->startpool){
00076         /* We exceeded pool boundaries */
00077         /* Calculate overshoot (startpool - indexptr) and subtract from end */
00078         /* Since one element of overshoot results in end - 1 you would miss the last value */
00079         c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp);
00080     }
00081     /* Read most recent */
00082     return *c->ptemp;
00083 }
00084 
00085 /**
00086  * @brief   Read from buffer (mr) Most Recent oriented (filo)
00087  *
00088  * @note    Buffer state will be preserved
00089  *
00090  * @warning    Consider this opertaion as atomic!
00091  *
00092  * @details Read n elements back in time.
00093  *                    As for index[0] the most recently added element is returned.
00094  *                    And for index[elementcount] the oldest element is returned.
00095  *                    This makes it possible to keep history. For DSP application.
00096  *
00097  * @param[in] c           Pointer to @p xifo_t used for configuration.
00098  * @param[in] index   Index relative from most recent
00099  *
00100  * @return    Contents of element or 0 if failed (element can hold 0)
00101  */
00102 uint32_t xifo_read_mr(xifo_t *c, uint32_t index){
00103     /* Verify there is valid data to read */
00104     if(index+1 > c->elementcount){
00105         return 0;    /* Nothing to read there */
00106     }
00107     /* Set pointer */
00108     c->ptemp = (c->read) - index;
00109     /* Validate pointer */
00110     if(c->ptemp < c->startpool){
00111         /* We exceeded pool boundaries */
00112         /* Calculate overshoot (startpool - indexptr) and subtract from end */
00113         /* Since one element of overshoot results in end - 1 you would miss the last value */
00114         c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp);
00115     }
00116     /* Read most recent */
00117     return *c->ptemp;
00118 }
00119 
00120 /**
00121  * @brief   Pop (mr) most recent from buffer (filo)
00122  *
00123  * @note    Buffer state will be altered
00124  *
00125  * @warning    Consider this opertaion as atomic!
00126  *
00127  * @details Read and remove the most recently added from the buffer.
00128  *                     Using this results in a stack type of buffer.
00129  *
00130  * @param[in] c           Pointer to @p xifo_t used for configuration.
00131  *
00132  * @return    Contents of element or 0 if failed (element can hold 0)
00133  */
00134 uint32_t xifo_pop_mr(xifo_t *c){
00135     /* Verify there is valid data read */
00136     if(c->elementcount == 0){
00137         return 0;    /* Nothing to read there */
00138     }
00139     /* Read */
00140     c->temp = *c->read;
00141     /* Empty */
00142     *c->read = 0;
00143     /* Most recent element read, return write pointer */
00144     c->write = c->read;
00145     /* Decrement read pointer */
00146     c->read--;
00147     /* Validate pointer */
00148     if( c->read < c->startpool ){
00149         /* We exceeded pool boundaries */
00150         c->read = c->endpool;
00151     }
00152     /* Reduce elementcount */
00153     c->elementcount--;
00154     if(c->elementcount < c->size)
00155         c->full = 0;
00156     return c->temp;
00157 }
00158 
00159 /**
00160  * @brief   Pop (lr) least recent from buffer (fifo)
00161  *
00162  * @note    Buffer state will be altered
00163  *
00164  * @warning    Consider this opertaion as atomic!
00165  *
00166  * @details Read and remove the least recently added from the buffer.
00167  *                     Using this results in a fifo type of buffer.
00168  *
00169  * @param[in] c    Pointer to @p xifo_t used for configuration.
00170  *
00171  * @return    Contents of element or 0 if failed (element can hold 0)
00172  */
00173 uint32_t xifo_pop_lr(xifo_t *c){    
00174     /* Verify there is valid data read */
00175     if(c->elementcount == 0){
00176         return 0;    /* Nothing to read there */
00177     }
00178     /* Derive least recent buffer element */
00179     c->ptemp = c->read+1 - c->elementcount;
00180     /* Validate pointer */
00181     if(c->ptemp < c->startpool){
00182         /* We exceeded pool boundaries */
00183         /* Calculate overshoot (startpool - indexptr) and subtract from end */
00184         /* Since one element of overshoot results in end - 1 you would miss the last value */
00185         c->ptemp = (c->endpool+1) - (c->startpool - c->ptemp);
00186     }
00187     /* Read oldest buffer element */
00188     { /* block with temporary variable to prevent stack use */
00189         register uint32_t element;
00190         /* Read to temp register */
00191         element = *c->ptemp;
00192         /* Empty */
00193         *c->ptemp = 0;
00194         /* Clear temp register */
00195         c->temp = element;
00196     }
00197     /* Reduce elementcount */
00198     c->elementcount--;
00199     /* Check full flag */
00200     if(c->elementcount < c->size)
00201         c->full = 0;
00202     return c->temp;
00203 }
00204 
00205 /**
00206  * @brief   Write to buffer
00207  *
00208  * @note    Readpointer is automatically set to the last added element.
00209  *
00210  * @warning    Consider this opertaion as atomic!
00211  *                    
00212  * @details Adds a value to the buffer.
00213  *                    Automatically overwrites oldest elements when full.
00214  *
00215  * @param[in] c            Pointer to @p xifo_t used for configuration.
00216  * @param[in] data    Data to add to buffer
00217  *
00218  * @return    Number of free buffer elements
00219  */
00220 uint32_t xifo_write(xifo_t *c, uint32_t data){    
00221     /* Write data */
00222     *c->write = data;
00223     /* Update read pointer to most recent element */
00224     c->read = c->write;
00225     /* Write pointer increment */
00226     c->write += 1;
00227     /* Validate pointer */
00228     if( c->write > c->endpool){
00229           /* We exceeded pool boundaries */
00230             c->write = c->startpool;
00231     }
00232     /* Update elementcount */
00233     c->elementcount++;
00234     /* Verify full */
00235     if( c->elementcount >= c->size ){
00236         c->full = 1;
00237         c->elementcount = c->size;
00238     }
00239     /* return free elements count */
00240     return c->size - c->elementcount;
00241 }
00242 
00243 /**
00244  * @brief   Get buffer size
00245  *
00246  * @param[in] c    Pointer to @p xifo_t used for configuration.
00247  *
00248  * @return    Size of memory pool in elements
00249  */
00250 uint32_t xifo_get_size(xifo_t *c){
00251     return c->size;
00252 }
00253 
00254 /**
00255  * @brief   Get number of used elements
00256  *
00257  * @param[in] c    Pointer to @p xifo_t used for configuration.
00258  *
00259  * @return    Number of used buffer elements
00260  */
00261 uint32_t xifo_get_used(xifo_t *c){
00262     return c->elementcount;
00263 }
00264 
00265 /**
00266 * @brief   Get number of free elements
00267 *
00268 * @param[in] c    Pointer to @p xifo_t used for configuration.
00269 *
00270 * @return    Number of free elements
00271 */
00272 uint32_t xifo_get_free(xifo_t *c){
00273     return c->size - c->elementcount;
00274 }
00275 
00276 /**
00277  * @brief   Get full flag
00278  *
00279  * @param[in] c    Pointer to @p xifo_t used for configuration.
00280  *
00281  * @return    1 if full
00282  */
00283 uint32_t xifo_get_full(xifo_t *c){
00284     return c->full;
00285 }
00286 
00287 /** @} */