1 /**
2 * \file
3 *
4 * \brief This file controls the software FIFO management.
5 *
6 * These functions manages FIFOs thanks to simple a API. The FIFO can
7 * be 100% full thanks to a double-index range implementation. For example,
8 * a FIFO of 4 elements can be implemented: the FIFO can really hold up to 4
9 * elements.
10 * This is particularly well suited for any kind of application needing a lot of
11 * small FIFO.
12 *
13 * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
14 *
15 * \asf_license_start
16 *
17 * \page License
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright notice,
23 * this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials provided with the distribution.
28 *
29 * 3. The name of Atmel may not be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * 4. This software may only be redistributed and used in connection with an
33 * Atmel microcontroller product.
34 *
35 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
38 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
39 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
43 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
44 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45 * POSSIBILITY OF SUCH DAMAGE.
46 *
47 * \asf_license_stop
48 *
49 */
50 /*
51 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
52 */
53
54 #ifndef _FIFO_H_
55 #define _FIFO_H_
56
57 #include "compiler.h"
58
59 /**
60 * \defgroup fifo_group First-In-First-Out Buffer (FIFO)
61 *
62 * See \ref fifo_quickstart.
63 *
64 * These functions manages FIFOs thanks to simple a API. The FIFO can
65 * be 100% full thanks to a double-index range implementation. For example,
66 * a FIFO of 4 elements can be implemented: the FIFO can really hold up to 4
67 * elements. This is particularly well suited for any kind of application
68 * needing a lot of small FIFO. The maximum fifo size is 128 items (uint8,
69 * uint16 or uint32). Note that the driver, thanks to its conception, does
70 * not use interrupt protection.
71 *
72 * @{
73 */
74
75 //! Error codes used by FIFO driver.
76 enum {
77 FIFO_OK = 0, //!< Normal operation.
78 FIFO_ERROR_OVERFLOW, //!< Attempt to push something in a FIFO that is full.
79 FIFO_ERROR_UNDERFLOW, //!< Attempt to pull something from a FIFO that is empty
80 FIFO_ERROR, //!< Error condition during FIFO initialization
81 };
82
83 //! FIFO descriptor used by FIFO driver.
84 struct fifo_desc {
85 union
86 {
87 uint32_t *u32ptr; //!< Pointer to unsigned-32 bits location
88 uint16_t *u16ptr; //!< Pointer to unsigned-16 bits location
89 uint8_t *u8ptr; //!< Pointer to unsigned-8 bits location
90 } buffer;
91 volatile uint8_t read_index; //!< Read index
92 volatile uint8_t write_index; //!< Write index
93 uint8_t size; //!< Size of the FIFO (unit is in number of 'element')
94 uint8_t mask; //!< Mask used to speed up FIFO operation (wrapping)
95 };
96
97 typedef struct fifo_desc fifo_desc_t;
98
99 /**
100 * \brief Initializes a new software FIFO for a certain 'size'.
101 *
102 * \pre Both fifo descriptor and buffer must be allocated by the caller before.
103 *
104 * \param fifo_desc Pointer on the FIFO descriptor.
105 * \param buffer Pointer on the FIFO buffer.
106 * \param size Size of the buffer (unit is in number of 'elements').
107 * It must be a 2-power and <= to 128.
108 *
109 * \return Status
110 * \retval FIFO_OK when no error occurred.
111 * \retval FIFO_ERROR when the size is not a 2-power.
112 */
113 int fifo_init(fifo_desc_t *fifo_desc, void *buffer, uint8_t size);
114
115 /**
116 * \brief Returns the number of elements in the FIFO.
117 *
118 * \param fifo_desc The FIFO descriptor.
119 *
120 * \return The number of used elements.
121 */
fifo_get_used_size(fifo_desc_t * fifo_desc)122 static inline uint8_t fifo_get_used_size(fifo_desc_t *fifo_desc)
123 {
124 return ((fifo_desc->write_index - fifo_desc->read_index) & fifo_desc->mask);
125 }
126
127 /**
128 * \brief Returns the remaining free spaces of the FIFO (in number of elements).
129 *
130 * \param fifo_desc The FIFO descriptor.
131 *
132 * \return The number of free elements.
133 */
fifo_get_free_size(fifo_desc_t * fifo_desc)134 static inline uint8_t fifo_get_free_size(fifo_desc_t *fifo_desc)
135 {
136 return fifo_desc->size - fifo_get_used_size(fifo_desc);
137 }
138
139 /**
140 * \brief Tests if a FIFO is empty.
141 *
142 * \param fifo_desc The FIFO descriptor.
143 *
144 * \return Status
145 * \retval true when the FIFO is empty.
146 * \retval false when the FIFO is not empty.
147 */
fifo_is_empty(fifo_desc_t * fifo_desc)148 static inline bool fifo_is_empty(fifo_desc_t *fifo_desc)
149 {
150 return (fifo_desc->write_index == fifo_desc->read_index);
151 }
152
153 /**
154 * \brief Tests if a FIFO is full.
155 *
156 * \param fifo_desc The FIFO descriptor.
157 *
158 * \return Status
159 * \retval true when the FIFO is full.
160 * \retval false when the FIFO is not full.
161 */
fifo_is_full(fifo_desc_t * fifo_desc)162 static inline bool fifo_is_full(fifo_desc_t *fifo_desc)
163 {
164 return (fifo_get_used_size(fifo_desc) == fifo_desc->size);
165 }
166
167 /**
168 * \brief Puts a new 8-bits element into the FIFO.
169 *
170 * \param fifo_desc The FIFO descriptor.
171 * \param item extracted element.
172 */
fifo_push_uint8_nocheck(fifo_desc_t * fifo_desc,uint32_t item)173 static inline void fifo_push_uint8_nocheck(fifo_desc_t *fifo_desc, uint32_t item)
174 {
175 uint8_t write_index;
176
177 write_index = fifo_desc->write_index;
178 fifo_desc->buffer.u8ptr[write_index & (fifo_desc->mask >> 1)] = item;
179 write_index = (write_index + 1) & fifo_desc->mask;
180
181 // Must be the last thing to do.
182 barrier();
183 fifo_desc->write_index = write_index;
184 }
185
186 /**
187 * \brief Puts a new 8-bits element into the FIFO and
188 * checks for a possible overflow.
189 *
190 * \param fifo_desc The FIFO descriptor.
191 * \param item extracted element.
192 *
193 * \return Status
194 * \retval FIFO_OK when no error occurred.
195 * \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
196 */
fifo_push_uint8(fifo_desc_t * fifo_desc,uint32_t item)197 static inline int fifo_push_uint8(fifo_desc_t *fifo_desc, uint32_t item)
198 {
199 uint8_t write_index;
200
201 if (fifo_is_full(fifo_desc)) {
202 return FIFO_ERROR_OVERFLOW;
203 }
204
205 write_index = fifo_desc->write_index;
206 fifo_desc->buffer.u8ptr[write_index & (fifo_desc->mask >> 1)] = item;
207 write_index = (write_index + 1) & fifo_desc->mask;
208
209 // Must be the last thing to do.
210 barrier();
211 fifo_desc->write_index = write_index;
212
213 return FIFO_OK;
214 }
215
216 /**
217 * \brief Puts a new 16-bits element into the FIFO.
218 *
219 * \param fifo_desc The FIFO descriptor.
220 * \param item extracted element.
221 */
fifo_push_uint16_nocheck(fifo_desc_t * fifo_desc,uint32_t item)222 static inline void fifo_push_uint16_nocheck(fifo_desc_t *fifo_desc, uint32_t item)
223 {
224 uint8_t write_index;
225
226 write_index = fifo_desc->write_index;
227 fifo_desc->buffer.u16ptr[write_index & (fifo_desc->mask >> 1)] = item;
228 write_index = (write_index + 1) & fifo_desc->mask;
229
230 // Must be the last thing to do.
231 barrier();
232 fifo_desc->write_index = write_index;
233 }
234
235 /**
236 * \brief Puts a new 16-bits element into the FIFO and
237 * checks for a possible overflow.
238 *
239 * \param fifo_desc The FIFO descriptor.
240 * \param item extracted element.
241 *
242 * \return Status
243 * \retval FIFO_OK when no error occurred.
244 * \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
245 */
fifo_push_uint16(fifo_desc_t * fifo_desc,uint32_t item)246 static inline int fifo_push_uint16(fifo_desc_t *fifo_desc, uint32_t item)
247 {
248 uint8_t write_index;
249
250 if (fifo_is_full(fifo_desc)) {
251 return FIFO_ERROR_OVERFLOW;
252 }
253
254 write_index = fifo_desc->write_index;
255 fifo_desc->buffer.u16ptr[write_index & (fifo_desc->mask >> 1)] = item;
256 write_index = (write_index + 1) & fifo_desc->mask;
257
258 // Must be the last thing to do.
259 barrier();
260 fifo_desc->write_index = write_index;
261
262 return FIFO_OK;
263 }
264
265 /**
266 * \brief Puts a new 32-bits element into the FIFO.
267 *
268 * \param fifo_desc The FIFO descriptor.
269 * \param item extracted element.
270 */
fifo_push_uint32_nocheck(fifo_desc_t * fifo_desc,uint32_t item)271 static inline void fifo_push_uint32_nocheck(fifo_desc_t *fifo_desc, uint32_t item)
272 {
273 uint8_t write_index;
274
275 write_index = fifo_desc->write_index;
276 fifo_desc->buffer.u32ptr[write_index & (fifo_desc->mask >> 1)] = item;
277 write_index = (write_index + 1) & fifo_desc->mask;
278
279 // Must be the last thing to do.
280 barrier();
281 fifo_desc->write_index = write_index;
282 }
283
284 /**
285 * \brief Puts a new 32-bits element into the FIFO and
286 * checks for a possible overflow.
287 *
288 * \param fifo_desc The FIFO descriptor.
289 * \param item extracted element.
290 *
291 * \return Status
292 * \retval FIFO_OK when no error occurred.
293 * \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
294 */
fifo_push_uint32(fifo_desc_t * fifo_desc,uint32_t item)295 static inline int fifo_push_uint32(fifo_desc_t *fifo_desc, uint32_t item)
296 {
297 uint8_t write_index;
298
299 if (fifo_is_full(fifo_desc)) {
300 return FIFO_ERROR_OVERFLOW;
301 }
302
303 write_index = fifo_desc->write_index;
304 fifo_desc->buffer.u32ptr[write_index & (fifo_desc->mask >> 1)] = item;
305 write_index = (write_index + 1) & fifo_desc->mask;
306
307 // Must be the last thing to do.
308 barrier();
309 fifo_desc->write_index = write_index;
310
311 return FIFO_OK;
312 }
313
314 /**
315 * \brief Gets a 8-bits element from the FIFO.
316 *
317 * \param fifo_desc The FIFO descriptor.
318 *
319 * \return extracted element.
320 */
fifo_pull_uint8_nocheck(fifo_desc_t * fifo_desc)321 static inline uint8_t fifo_pull_uint8_nocheck(fifo_desc_t *fifo_desc)
322 {
323 uint8_t read_index;
324 uint8_t item;
325
326 read_index = fifo_desc->read_index;
327 item = fifo_desc->buffer.u8ptr[read_index & (fifo_desc->mask >> 1)];
328 read_index = (read_index + 1) & fifo_desc->mask;
329
330 // Must be the last thing to do.
331 barrier();
332 fifo_desc->read_index = read_index;
333
334 return item;
335 }
336
337 /**
338 * \brief Gets a 8-bits element from the FIFO and
339 * checks for a possible underflow.
340 *
341 * \param fifo_desc The FIFO descriptor.
342 * \param item extracted element.
343 *
344 * \return Status
345 * \retval FIFO_OK when no error occurred.
346 * \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
347 */
fifo_pull_uint8(fifo_desc_t * fifo_desc,uint8_t * item)348 static inline int fifo_pull_uint8(fifo_desc_t *fifo_desc, uint8_t *item)
349 {
350 uint8_t read_index;
351
352 if (fifo_is_empty(fifo_desc)) {
353 return FIFO_ERROR_UNDERFLOW;
354 }
355
356 read_index = fifo_desc->read_index;
357 *item = fifo_desc->buffer.u8ptr[read_index & (fifo_desc->mask >> 1)];
358 read_index = (read_index + 1) & fifo_desc->mask;
359
360 // Must be the last thing to do.
361 barrier();
362 fifo_desc->read_index = read_index;
363
364 return FIFO_OK;
365 }
366
367 /**
368 * \brief Gets a 16-bits element from the FIFO.
369 *
370 * \param fifo_desc The FIFO descriptor.
371 *
372 * \return extracted element.
373 */
fifo_pull_uint16_nocheck(fifo_desc_t * fifo_desc)374 static inline uint16_t fifo_pull_uint16_nocheck(fifo_desc_t *fifo_desc)
375 {
376 uint8_t read_index;
377 uint16_t item;
378
379 read_index = fifo_desc->read_index;
380 item = fifo_desc->buffer.u16ptr[read_index & (fifo_desc->mask >> 1)];
381 read_index = (read_index + 1) & fifo_desc->mask;
382
383 // Must be the last thing to do.
384 barrier();
385 fifo_desc->read_index = read_index;
386
387 return item;
388 }
389
390 /**
391 * \brief Gets a 16-bits element from the FIFO and
392 * checks for a possible underflow.
393 *
394 * \param fifo_desc The FIFO descriptor.
395 * \param item extracted element.
396 *
397 * \return Status
398 * \retval FIFO_OK when no error occurred.
399 * \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
400 */
fifo_pull_uint16(fifo_desc_t * fifo_desc,uint16_t * item)401 static inline int fifo_pull_uint16(fifo_desc_t *fifo_desc, uint16_t *item)
402 {
403 uint8_t read_index;
404
405 if (fifo_is_empty(fifo_desc)) {
406 return FIFO_ERROR_UNDERFLOW;
407 }
408
409 read_index = fifo_desc->read_index;
410 *item = fifo_desc->buffer.u16ptr[read_index & (fifo_desc->mask >> 1)];
411 read_index = (read_index + 1) & fifo_desc->mask;
412
413 // Must be the last thing to do.
414 barrier();
415 fifo_desc->read_index = read_index;
416
417 return FIFO_OK;
418 }
419
420 /**
421 * \brief Gets a 32-bits element from the FIFO
422 *
423 * \param fifo_desc The FIFO descriptor.
424 *
425 * \return extracted element.
426 */
fifo_pull_uint32_nocheck(fifo_desc_t * fifo_desc)427 static inline uint32_t fifo_pull_uint32_nocheck(fifo_desc_t *fifo_desc)
428 {
429 uint8_t read_index;
430 uint32_t item;
431
432 read_index = fifo_desc->read_index;
433 item = fifo_desc->buffer.u32ptr[read_index & (fifo_desc->mask >> 1)];
434 read_index = (read_index + 1) & fifo_desc->mask;
435
436 // Must be the last thing to do.
437 barrier();
438 fifo_desc->read_index = read_index;
439
440 return item;
441 }
442
443 /**
444 * \brief Gets a 32-bits element from the FIFO and
445 * checks for a possible underflow.
446 *
447 * \param fifo_desc The FIFO descriptor.
448 * \param item extracted element.
449 *
450 * \return Status
451 * \retval FIFO_OK when no error occurred.
452 * \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
453 */
fifo_pull_uint32(fifo_desc_t * fifo_desc,uint32_t * item)454 static inline int fifo_pull_uint32(fifo_desc_t *fifo_desc, uint32_t *item)
455 {
456 uint8_t read_index;
457
458 if (fifo_is_empty(fifo_desc)) {
459 return FIFO_ERROR_UNDERFLOW;
460 }
461
462 read_index = fifo_desc->read_index;
463 *item = fifo_desc->buffer.u32ptr[read_index & (fifo_desc->mask >> 1)];
464 read_index = (read_index + 1) & fifo_desc->mask;
465
466 // Must be the last thing to do.
467 barrier();
468 fifo_desc->read_index = read_index;
469
470 return FIFO_OK;
471 }
472
473 /**
474 * \brief Gets a 32-bits element from the FIFO but does
475 * not remove it from the FIFO.
476 *
477 * \param fifo_desc The FIFO descriptor.
478 *
479 * \retval item extracted element.
480 */
fifo_peek_uint32(fifo_desc_t * fifo_desc)481 static inline uint32_t fifo_peek_uint32(fifo_desc_t *fifo_desc)
482 {
483 return fifo_desc->buffer.u32ptr[fifo_desc->read_index & (fifo_desc->mask >> 1)];
484 }
485
486 /**
487 * \brief Gets a 16-bits element from the FIFO but does
488 * not remove it from the FIFO.
489 *
490 * \param fifo_desc The FIFO descriptor.
491 *
492 * \retval item extracted element.
493 */
fifo_peek_uint16(fifo_desc_t * fifo_desc)494 static inline uint16_t fifo_peek_uint16(fifo_desc_t *fifo_desc)
495 {
496 return fifo_desc->buffer.u16ptr[fifo_desc->read_index & (fifo_desc->mask >> 1)];
497 }
498
499 /**
500 * \brief Gets a 8-bits element from the FIFO but does
501 * not remove it from the FIFO.
502 *
503 * \param fifo_desc The FIFO descriptor.
504 *
505 * \retval item extracted element.
506 */
fifo_peek_uint8(fifo_desc_t * fifo_desc)507 static inline uint8_t fifo_peek_uint8(fifo_desc_t *fifo_desc)
508 {
509 return fifo_desc->buffer.u8ptr[fifo_desc->read_index & (fifo_desc->mask >> 1)];
510 }
511
512 /**
513 * \brief Flushes a software FIFO.
514 *
515 * \param fifo_desc The FIFO descriptor.
516 */
fifo_flush(fifo_desc_t * fifo_desc)517 static inline void fifo_flush(fifo_desc_t *fifo_desc)
518 {
519 // Fifo starts empty.
520 fifo_desc->read_index = fifo_desc->write_index = 0;
521 }
522
523 /**
524 * @}
525 */
526
527 /**
528 * \page fifo_quickstart Quick start guide for First-In-First-Out Buffer (FIFO)
529 *
530 * This is the quick start guide for the \ref fifo_group, with
531 * step-by-step instructions on how to configure and use the driver in a
532 * selection of use cases.
533 *
534 * The use cases contain several code fragments. The code fragments in the
535 * steps for setup can be copied into a custom initialization function, while
536 * the steps for usage can be copied into, e.g., the main application function.
537 *
538 * \section fifo_use_cases FIFO use cases
539 * - \ref fifo_basic_use_case
540 * - \subpage fifo_use_case_1
541 *
542 * \section fifo_basic_use_case Basic use case - Push and pull
543 * In this use case, an element will be pushed to the FIFO, and the same
544 * element will be pulled from it.
545 *
546 * \section fifo_basic_use_case_setup Setup steps
547 *
548 * \subsection fifo_basic_use_case_setup_code Example code
549 * The following must be added to the project:
550 * \code
551 #define FIFO_BUFFER_LENGTH 4
552 #define PUSH_VALUE 0x12345678
553 union buffer_element {
554 uint8_t byte;
555 uint16_t halfword;
556 uint32_t word;
557 };
558 \endcode
559 *
560 * Add to application initialization:
561 * \code
562 union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH];
563 fifo_desc_t fifo_desc;
564 fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH);
565 \endcode
566 *
567 * \subsection fifo_basic_use_case_setup_flow Workflow
568 * -# Create a FIFO buffer of FIFO_BUFFER_LENGTH elements, capable
569 * of holding a byte, halfword or word:
570 * - \code union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH]; \endcode
571 * -# Create a FIFO buffer descriptor that contains information about the
572 * location of the FIFO buffer, its size and where to read from or write to
573 * upon the next buffer pull or push:
574 * - \code fifo_desc_t fifo_desc; \endcode
575 * -# Initialize the FIFO:
576 * - \code fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH); \endcode
577 *
578 * \section fifo_basic_use_case_usage Usage steps
579 *
580 * \subsection fifo_basic_use_case_usage_code Example code
581 * Add to application C-file:
582 * \code
583 uint8_t status;
584 uint8_t pull_value;
585 status = fifo_push_uint8(&fifo_desc, PUSH_VALUE & 0xff);
586 status = fifo_pull_uint8(&fifo_desc, &pull_value);
587 \endcode
588 *
589 * \subsection fifo_basic_use_case_usage_flow Workflow
590 * -# Create a variable to hold the return status from the FIFO:
591 * - \code uint8_t status; \endcode
592 * -# Create a variable to hold the pulled value from the FIFO:
593 * - \code uint8_t pull_value; \endcode
594 * -# Put a new 8-bit element into the FIFO:
595 * - \code status = fifo_push_uint8(&fifo_desc, PUSH_VALUE & 0xff); \endcode
596 * \note The status variable will contain \ref FIFO_OK if no error occurred.
597 * -# Get the 8-bit element from the FIFO:
598 * - \code status = fifo_pull_uint8(&fifo_desc, &pull_value); \endcode
599 * \note The status variable will contain \ref FIFO_OK if no error occurred.
600 */
601
602 /**
603 * \page fifo_use_case_1 Push and flush
604 *
605 * In this use case, two elements will be pushed to the FIFO, and the FIFO
606 * will be flushed.
607 *
608 * \section fifo_use_case_1_setup Setup steps
609 *
610 * \subsection fifo_use_case_1_setup_code Example code
611 * The following must be added to the project:
612 * \code
613 #define FIFO_BUFFER_LENGTH 4
614 #define PUSH_VALUE 0x12345678
615 union buffer_element {
616 uint8_t byte;
617 uint16_t halfword;
618 uint32_t word;
619 };
620 \endcode
621 *
622 * Add to application initialization:
623 * \code
624 union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH];
625 fifo_desc_t fifo_desc;
626 fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH);
627 \endcode
628 *
629 * \subsection fifo_use_case_1_setup_flow Workflow
630 * -# Create a FIFO buffer of FIFO_BUFFER_LENGTH elements, capable
631 * of holding a byte, halfword or word:
632 * - \code union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH]; \endcode
633 * -# Create a FIFO buffer descriptor that containing information about the
634 * location of the FIFO buffer, its size and where to read from or write to
635 * upon the next buffer pull or push:
636 * - \code fifo_desc_t fifo_desc; \endcode
637 * -# Initialize the FIFO:
638 * - \code fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH); \endcode
639 * \section fifo_use_case_1_usage Usage steps
640 *
641 * \subsection fifo_use_case_1_usage_code Example code
642 * Add to application C-file:
643 * \code
644 uint8_t status;
645 bool fifo_empty;
646 status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff);
647 status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff);
648 fifo_flush(&fifo_desc);
649 fifo_empty = fifo_is_empty(&fifo_desc);
650 \endcode
651 *
652 * \subsection fifo_use_case_1_usage_flow Workflow
653 * -# Create a variable to hold the return status from the FIFO:
654 * - \code uint8_t status; \endcode
655 * -# Create a variable to hold the pulled value from the FIFO:
656 * - \code uint16_t pull_value; \endcode
657 * -# Put two new 16-bit element into the FIFO:
658 * - \code status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff); \endcode
659 * - \code status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff); \endcode
660 * \note The status variable will contain \ref FIFO_OK if no error occurred.
661 * -# Flush the FIFO:
662 * - \code fifo_flush(&fifo_desc); \endcode
663 * -# Check that the FIFO is empty after flushing:
664 * - \code fifo_empty = fifo_is_empty(&fifo_desc); \endcode
665 * \note The fifo_empty variable will be true if the FIFO is empty.
666 */
667
668 #endif // _FIFO_H_
669