BSPACM  20150113
Board Support Package for ARM Cortex-M Microcontrollers
fifo.h
Go to the documentation of this file.
1 /* Copyright 2014, Peter A. Bigot
2  *
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * * Neither the name of the software nor the names of its contributors may be
16  * used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
48 #ifndef BSPACM_INTERNAL_UTILITY_FIFO_H
49 #define BSPACM_INTERNAL_UTILITY_FIFO_H
50 
51 #include <bspacm/core.h>
52 #include <stddef.h>
53 
101 typedef struct sFIFO {
105  volatile uint16_t head;
106 
109  volatile uint16_t tail;
110 
117  const uint16_t size;
118 
121  volatile uint8_t cell[];
122 } sFIFO;
123 
137 #define FIFO_DEFINE_ALLOCATION(allocation_, size_) \
138  static union { \
139  sFIFO fifo; \
140  uint8_t allocation[(size_) + sizeof(sFIFO)]; \
141  } allocation_ = { { 0, 0, sizeof(allocation_) - offsetof(sFIFO, cell) } }
142 
150 #define FIFO_FROM_ALLOCATION(allocation_) (&(allocation_).fifo)
151 
164 #define FIFO_ADJUST_OFFSET(fp_,v_) ((v_) % (fp_)->size)
165 
167 static BSPACM_CORE_INLINE
168 void
170 {
171  fp->head = 0;
172  fp->tail = 0;
173 }
174 
178 static BSPACM_CORE_INLINE
179 uint16_t
180 fifo_length (const sFIFO * fp)
181 {
182  uint16_t h = fp->head;
183  uint16_t t = fp->tail;
184  return (h - t) + ((h < t) ? fp->size : 0U);
185 }
186 
188 static BSPACM_CORE_INLINE
189 int
190 fifo_empty (const sFIFO * fp)
191 {
192  return fp->head == fp->tail;
193 }
194 
197 static BSPACM_CORE_INLINE
198 int
199 fifo_full (const sFIFO * fp)
200 {
201  return (fp->size - 1) == fifo_length(fp);
202 }
203 
217 static BSPACM_CORE_INLINE
218 int
220  int force_if_empty)
221 {
222  uint16_t t = fp->tail;
223  int was_empty = (fp->head == t);
224  int rv = was_empty ? -1 : fp->cell[t];
225  if (force_if_empty || (! was_empty)) {
226  fp->tail = FIFO_ADJUST_OFFSET(fp, 1U + t);
227  }
228  return rv;
229 }
230 
246 static BSPACM_CORE_INLINE
247 int
248 fifo_push_head (sFIFO * fp, uint8_t v)
249 {
250  uint16_t h = fp->head;
251  uint16_t t = fp->tail;
252  int rv = (h != t);
253 
254  fp->cell[h] = v;
255  h = FIFO_ADJUST_OFFSET(fp, 1U + h);
256  fp->head = h;
257  if (h == t) {
258  (void)fifo_pop_tail(fp, 1);
259  rv = -1;
260  }
261  return rv;
262 }
263 
277 static BSPACM_CORE_INLINE
278 int
280  uint8_t * bps,
281  uint8_t * bpe)
282 {
283  uint16_t h = fp->head;
284  uint16_t t = fp->tail;
285  uint8_t * bp = bps;
286  while ((bp < bpe) && (h != t)) {
287  *bp++ = fp->cell[t];
288  t = FIFO_ADJUST_OFFSET(fp, 1U + t);
289  }
290  fp->tail = t;
291  return bp - bps;
292 }
293 
294 #endif /* BSPACM_INTERNAL_UTILITY_FIFO_H */
static BSPACM_CORE_INLINE int fifo_full(const sFIFO *fp)
Definition: fifo.h:199
volatile uint8_t cell[]
Definition: fifo.h:121
static BSPACM_CORE_INLINE int fifo_push_head(sFIFO *fp, uint8_t v)
Definition: fifo.h:248
Common header included by all BSPACM leaf headers.
volatile uint16_t tail
Definition: fifo.h:109
#define FIFO_ADJUST_OFFSET(fp_, v_)
Definition: fifo.h:164
volatile uint16_t head
Definition: fifo.h:105
static BSPACM_CORE_INLINE void fifo_reset(sFIFO *fp)
Definition: fifo.h:169
static BSPACM_CORE_INLINE uint16_t fifo_length(const sFIFO *fp)
Definition: fifo.h:180
#define BSPACM_CORE_INLINE
Definition: core.h:65
struct sFIFO sFIFO
static BSPACM_CORE_INLINE int fifo_empty(const sFIFO *fp)
Definition: fifo.h:190
static BSPACM_CORE_INLINE int fifo_pop_into_buffer(sFIFO *fp, uint8_t *bps, uint8_t *bpe)
Definition: fifo.h:279
static BSPACM_CORE_INLINE int fifo_pop_tail(sFIFO *fp, int force_if_empty)
Definition: fifo.h:219
const uint16_t size
Definition: fifo.h:117
Definition: fifo.h:101