Xmega Application Note


fifo.c

Go to the documentation of this file.
00001 /*This file is prepared for Doxygen automatic documentation generation.*/
00020 /* Copyright (c) 2010 Atmel Corporation. All rights reserved.
00021  *
00022  * Redistribution and use in source and binary forms, with or without
00023  * modification, are permitted provided that the following conditions are met:
00024  *
00025  * 1. Redistributions of source code must retain the above copyright notice, this
00026  * list of conditions and the following disclaimer.
00027  *
00028  * 2. Redistributions in binary form must reproduce the above copyright notice,
00029  * this list of conditions and the following disclaimer in the documentation
00030  * and/or other materials provided with the distribution.
00031  *
00032  * 3. The name of Atmel may not be used to endorse or promote products derived
00033  * from this software without specific prior written permission.
00034  *
00035  * 4. This software may only be redistributed and used in connection with an Atmel
00036  * AVR product.
00037  *
00038  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00039  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00040  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00041  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00042  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00043  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00044  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00045  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00046  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00047  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00048  *
00049  */
00050 
00051 #include "compiler.h"
00052 #include "fifo.h"
00053 
00054 int fifo_init_no_malloc(fifo_desc_t *fifo_desc, void *buffer, uint16_t size,
00055       uint16_t element_size)
00056 {
00057         uint16_t tmp;
00058 
00059         // Check the size parameter. It must be a 2-power.
00060         tmp = size >> ctz(size);
00061         if (tmp != 1) {
00062                 // We prefer catching this critical situation that way since most of users does not
00063                 // even test return value...
00064                 while (1) {
00065                 }
00066                 //return FIFO_ERROR;
00067         }
00068 
00069         // Keep the alignement
00070         fifo_desc->align = element_size;
00071 
00072         // Fifo starts empty.
00073         fifo_desc->rd_id = fifo_desc->wr_id = 0;
00074 
00075         // Save the size parameter.
00076         fifo_desc->size = size;
00077 
00078         // Save the buffer pointer
00079         fifo_desc->buffer.u8ptr = buffer;
00080 
00081         return FIFO_OK;
00082 }
00083 
00084 int fifo_init_malloc(fifo_desc_t **fifo_desc, uint16_t size,
00085       uint16_t element_size)
00086 {
00087         uint16_t tmp;
00088 
00089         // Check the size parameter. It must be a 2-power.
00090         tmp = size >> ctz(size);
00091         if (tmp != 1) {
00092                 // We prefer catching this critical situation that way since most of users does not
00093                 // even test return value...
00094                 while (1) {
00095                 }
00096                 //return FIFO_ERROR;
00097         }
00098 
00099         if (!(*fifo_desc = malloc(sizeof(fifo_desc_t))))
00100                 return FIFO_ERROR;
00101 
00102         // Allocate memory for the buffer.
00103         if (!((*fifo_desc)->buffer.u8ptr = malloc(size))) {
00104                 free(*fifo_desc);
00105                 return FIFO_ERROR;
00106         }
00107 
00108         // Keep the alignement
00109         (*fifo_desc)->align = element_size;
00110 
00111         // Fifo starts empty.
00112         (*fifo_desc)->rd_id = (*fifo_desc)->wr_id = 0;
00113 
00114         // Save the size parameter.
00115         (*fifo_desc)->size = size;
00116 
00117         return FIFO_OK;
00118 }
00119 
00120 void fifo_reset(fifo_desc_t *fifo_desc)
00121 {
00122         // Fifo starts empty.
00123         fifo_desc->rd_id = fifo_desc->wr_id = 0;
00124 }
00125 
00126 void fifo_stop_malloc(fifo_desc_t **fifo_desc)
00127 {
00128         // Free allocated memory
00129         if ((*fifo_desc)->buffer.u8ptr) {
00130                 free((void*) (*fifo_desc)->buffer.u8ptr);
00131                 (*fifo_desc)->buffer.u8ptr = NULL;
00132         }
00133         if (*fifo_desc) {
00134                 free((void*) *fifo_desc);
00135                 *fifo_desc = NULL;
00136         }
00137 }
00138 
00139 uint16_t fifo_get_used_size(fifo_desc_t *fifo_desc)
00140 {
00141         uint16_t val;
00142         val = fifo_desc->wr_id + 2 * fifo_desc->size;
00143         val -= fifo_desc->rd_id;
00144         return val & ((2 * fifo_desc->size) - 1);
00145 }
00146 
00147 uint16_t fifo_get_free_size(fifo_desc_t *fifo_desc)
00148 {
00149         return fifo_desc->size - fifo_get_used_size(fifo_desc);
00150 }
00151 
00152 int fifo_push(fifo_desc_t *fifo_desc, uint32_t item)
00153 {
00154         uint8_t wr_id;
00155         if (fifo_get_free_size(fifo_desc) == 0)
00156                 return FIFO_ERROR_OVERFLOW;
00157 
00158         wr_id = fifo_desc->wr_id;
00159 
00160         if (fifo_desc->align == FIFO_ELEMENT_8BITS)
00161                 fifo_desc->buffer.u8ptr[wr_id & (fifo_desc->size - 1)] = item;
00162         else if (fifo_desc->align == FIFO_ELEMENT_16BITS)
00163                 fifo_desc->buffer.u16ptr[wr_id & (fifo_desc->size - 1)] = item;
00164         else
00165                 // if( fifo_desc->align==FIFO_ELEMENT_32BITS )
00166                 fifo_desc->buffer.u32ptr[wr_id & (fifo_desc->size - 1)] = item;
00167 
00168         // Must be the last thing to do.
00169         fifo_desc->wr_id = (wr_id + 1) & ((2 * fifo_desc->size) - 1);
00170         return FIFO_OK;
00171 }
00172 
00173 int fifo_pull(fifo_desc_t *fifo_desc, void *item)
00174 {
00175         uint8_t rd_id;
00176         if (fifo_get_used_size(fifo_desc) == 0)
00177                 return FIFO_ERROR_UNDERFLOW;
00178 
00179         rd_id = fifo_desc->rd_id;
00180         if (fifo_desc->align == FIFO_ELEMENT_8BITS)
00181                 *(uint8_t*) item = fifo_desc->buffer.u8ptr[rd_id & (fifo_desc->size - 1)];
00182         else if (fifo_desc->align == FIFO_ELEMENT_16BITS)
00183                 *(uint16_t*) item = fifo_desc->buffer.u16ptr[rd_id
00184                       & (fifo_desc->size - 1)];
00185         else
00186                 // if( fifo_desc->align==FIFO_ELEMENT_32BITS )
00187                 *(uint32_t*) item = fifo_desc->buffer.u32ptr[rd_id
00188                       & (fifo_desc->size - 1)];
00189 
00190         // Must be the last thing to do.
00191         fifo_desc->rd_id = (rd_id + 1) & ((2 * fifo_desc->size) - 1);
00192         return FIFO_OK;
00193 }
@DOC_TITLE@
Generated on Fri Oct 22 12:15:25 2010 for AVR1300 Using the Xmega ADC by doxygen 1.6.3