00001 /* FIFO declarations */ 00002 /* Copyright (C) 2009 Holger Dietze 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) version 3. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef FIFO_H 00019 #define FIFO_H 00020 00021 #include <avr/interrupt.h> 00022 00030 typedef struct fifo_item_s { 00031 uint8_t data; 00032 uint8_t flags; 00033 } fifo_item_t; 00034 00037 typedef uint8_t fifo_size_t; 00038 00041 typedef struct fifo_s { 00042 fifo_item_t * buffer; 00043 fifo_size_t size; 00044 fifo_size_t head; 00045 fifo_size_t tail; 00046 fifo_size_t num_items; 00047 uint8_t overflow:1; 00048 uint8_t underflow:1; 00049 } fifo_t; 00050 00057 void fifo_init (fifo_t * fifo, fifo_item_t * buffer, fifo_size_t size); 00058 00061 inline fifo_item_t * fifo_get_buffer (fifo_t * f) { return f->buffer; } 00062 00065 inline uint8_t fifo_is_empty (const fifo_t * f) { return f->num_items == 0; } 00066 00069 inline uint8_t fifo_is_full (const fifo_t * f) { return f->num_items == f->size; } 00070 00078 inline void fifo_putQ_item (fifo_t * f, fifo_item_t c) 00079 { 00080 fifo_size_t head; 00081 head = f->head; 00082 if (f->num_items < f->size) { 00083 /* still room in buf */ 00084 f->buffer[head++] = c; 00085 if (head >= f->size) { 00086 /* wrap around to start of buffer */ 00087 head = 0; 00088 } 00089 f->head = head; 00090 f->num_items++; 00091 } else { 00092 /* set overflow flag, char is lost */ 00093 f->overflow = 1; 00094 } 00095 } 00096 00104 inline fifo_item_t fifo_getQ_item (fifo_t * f) 00105 { 00106 fifo_size_t tail; 00107 tail = f->tail; 00108 if (f->num_items) { 00109 fifo_item_t data = f->buffer[tail++]; 00110 if (tail >= f->size) { 00111 /* wrap around to start of buffer */ 00112 tail = 0; 00113 } 00114 f->tail = tail; 00115 f->num_items--; 00116 return data; 00117 } 00118 f->underflow = 1; 00119 return (fifo_item_t){0,0xFF}; 00120 } 00121 00124 fifo_item_t fifo_get_item (fifo_t * f); 00126 inline uint8_t fifo_get_uint8 (fifo_t * f) 00127 { return fifo_get_item (f).data; } 00128 00131 void fifo_put_item (fifo_t * f, fifo_item_t i); 00133 inline void fifo_put_uint8 (fifo_t * f, uint8_t b) 00134 { fifo_put_item (f, (fifo_item_t){b, 0}); } 00135 00136 #endif