Generate sine waves with 2 mbeds synchronised. Configurable amplitude and phase. Built for 50 Hz mains simulations.
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 /** @} */
Generated on Thu Jul 14 2022 08:02:50 by 1.7.2