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