-
Notifications
You must be signed in to change notification settings - Fork 1
/
fifo.h
165 lines (146 loc) · 3.96 KB
/
fifo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/**
* @file
* @author Joshua Boyd <[email protected]>
* @version 1.0
*
* @description DESCRIPTION
*
* Macros for statically allocated, circular buffer, character FIFOs.
*
* NOTE: change the types in MAKE_FIFO to support types other than
* chars. Should just work for any primitive type, and only
* a little more work for structs.
*
* The basic usage is to MAKE_FIFO your fifo, giving it a name and size
* then GET, PUT, etc, the fifo of that name.
*
*/
/**
* Make a new FIFO.
*
* @param prefix - the name of the fifo, eg. 485_tx, or 232_rx.
* @param size - number of elements in the fifo.
*/
#define MAKE_FIFO(prefix, size) \
char prefix ##_buffer[size+1];\
long prefix ##_next_in = 0;\
long prefix ##_next_out = 0;\
long prefix ##_len = 0; \
long prefix ##_ovfl=0;
#define BUF_SIZE(prefix) (sizeof(prefix ##_buffer))
/**
* Get and remove an element from the FIFO.
*
* Value here works a little like a reference in C++.
*
* @param name of the fifo
* @param Location for the returned element.
*/
#define GET(prefix, value) { \
value=prefix ##_buffer[prefix ##_next_out]; \
prefix ##_len--; \
prefix ##_next_out = (prefix ##_next_out+1) % BUF_SIZE(prefix);}
/**
* Get an element from the FIFO without removing it.
*
* Value here works a little like a reference in C++.
*
* @param name of the fifo
* @param Location for the returned element.
*/
#define PEEK(prefix, value) { \
value=prefix ##_buffer[prefix ##_next_out];}
/**
* Remove an element from the FIFO without getting it.
*
* @param name of the fifo
*/
#define REMOVE(prefix) { \
prefix ##_len--; \
prefix ##_next_out = (prefix ##_next_out+1) % BUF_SIZE(prefix);}
/**
* Return the index of the next input location.
*
* NOTICE: This is the only macro meant for internal use, and not the
* application programmer.
*/
#define NEXT_IN(prefix) ((prefix ##_next_in + 1) % BUF_SIZE( prefix ))
/**
* Put an element into the FIFO.
*
* @param name of the fifo
* @param Value of the new element.
*/
#define PUT(prefix, value) { char t; \
prefix ##_len++; \
prefix ##_buffer[ prefix ##_next_in ] = value; \
t = prefix ##_next_in; \
prefix ##_next_in = ( prefix ##_next_in + 1) % BUF_SIZE( prefix ); \
if(prefix ##_next_in == prefix ##_next_out) { \
prefix ##_next_in = t; \
prefix ##_ovfl = 1; }}
/**
*
* Set the points back to as if it were empty.
* Doesn't erase the data, but only a GET or PEEK will
* return garbage after this has been called.
*
* @param Name of the FIFO
*/
#define FLUSH(prefix) {prefix ##_len = prefix ##_next_in = prefix ##_next_out = 0;}
/**
* Is the FIFO empty? True/False
*
* @param FIFO name
* @return T/F
*/
#define IS_EMPTY(prefix) (prefix ##_next_in == prefix ##_next_out)
/**
* Is there any data? True/False.
* Basically the opposite of IS_EMPTY
*
* @param Name of the FIFO
* @return TRUE/FALSE
*/
#define IS_NOT_EMPTY(prefix) (prefix ##_next_in != prefix ##_next_out)
/**
* Is there any data? True/False.
* Basically the opposite of IS_EMPTY
* The same as IS_NOT_EMPTY
*
* @param Name of the FIFO
* @return TRUE/FALSE
*/
#define KBHIT IS_NOT_EMPTY
/**
*
* Is the FIFO full? True/False
*
* @param FIFO name
* @return TRUE/FALSE
*/
#define IS_FULL(prefix) (prefix ##_len == BUF_SIZE(prefix)-1 )
#define DEPTH(prefix) (prefix ##_len)
/*> prefix ##_next_out ? \
prefix ##_next_in - prefix ##_next_out :\
prefix ##_next_out - prefix ##_next_in )
*/
#define FREE(prefix) (BUF_SIZE(prefix) - DEPTH(prefix) -1)
/**
* Is there free space?
* This is basically the opposite of IS_FULL
*
* @param FIFO name
* @return TRUE/FALSE
*/
#define IS_NOT_FULL(prefix) (!IS_FULL(prefix))
/**
* Is there free space?
* THis is the same as IS_NOT_FULL.
* This is basically the opposite of IS_FULL
*
* @param FIFO name
* @return TRUE/FALSE
*/
#define AVAIL IS_NOT_FULL
#define OVFL(prefix) (prefix ##_ovfl)