Library for Modtronix NZ32 STM32 boards, like the NZ32-SC151, NZ32-SB072, NZ32-SE411 and others

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mx_circular_buffer.h Source File

mx_circular_buffer.h

00001 /**
00002  * File:      mx_circular_buffer.h
00003  *
00004  * Author:    Modtronix Engineering - www.modtronix.com
00005  *
00006  * Description:
00007  *
00008  * Software License Agreement:
00009  * This software has been written or modified by Modtronix Engineering. The code
00010  * may be modified and can be used free of charge for commercial and non commercial
00011  * applications. If this is modified software, any license conditions from original
00012  * software also apply. Any redistribution must include reference to 'Modtronix
00013  * Engineering' and web link(www.modtronix.com) in the file header.
00014  *
00015  * THIS SOFTWARE IS PROVIDED IN AN 'AS IS' CONDITION. NO WARRANTIES, WHETHER EXPRESS,
00016  * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
00017  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE
00018  * COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
00019  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
00020  */
00021 #ifndef SRC_MX_CIRCULAR_BUFFER_H_
00022 #define SRC_MX_CIRCULAR_BUFFER_H_
00023 
00024 #include "nz32s_default_config.h"
00025 #include "mx_buffer_base.h"
00026 
00027 /** Templated Circular buffer class
00028  */
00029 template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
00030 class MxCircularBuffer : public MxBuffer {
00031 public:
00032     MxCircularBuffer() : _head(0), _tail(0), _full(false) {
00033     }
00034 
00035     ~MxCircularBuffer() {
00036     }
00037 
00038 
00039     /** Adds an object to the buffer. If no space in buffer, this function does nothing.
00040      * do anything!
00041      * Use getFree() function prior to this function to ensure buffer has enough free space!
00042      *
00043      * @param data Data to be pushed to the buffer
00044      *
00045      * @return Returns true if character added to buffer, else false
00046      */
00047     bool put(const T& data) {
00048         if (isFull()) {
00049             return false;
00050         }
00051         _pool[_head++] = data;
00052         _head %= BufferSize;
00053         if (_head == _tail) {
00054             _full = true;
00055         }
00056         return true;
00057     }
00058 
00059 
00060     /** Adds given array to the buffer. This function checks if buffer has enough space.
00061      * If not enough space available, nothing is added, and this function returns 0.
00062      *
00063      * @param buf Source buffer containing array to add to buffer
00064      * @param bufSize Size of array to add to buffer
00065      *
00066      * @return Returns true if character added to buffer, else false
00067      */
00068     bool putArray(uint8_t* buf, uint16_t bufSize) {
00069         bool retVal = false;
00070         int i;
00071 
00072         if (getFree() < bufSize) {
00073             return false;
00074         }
00075 
00076         for(i=0; i<bufSize; i++) {
00077             retVal = retVal | put(buf[i]);
00078         }
00079         return retVal;
00080     }
00081 
00082 
00083     /** Gets and remove and object from the buffer. Ensure buffer is NOT empty before calling this function!
00084      *
00085      * @return Read data
00086      */
00087     T get() {
00088         if (!isEmpty()) {
00089             T retData;
00090             retData = _pool[_tail++];
00091             _tail %= BufferSize;
00092             _full = false;
00093             return retData;
00094         }
00095         return 0;
00096     }
00097 
00098 
00099     /** Gets and object from the buffer, but do NOT remove it. Ensure buffer is NOT empty before calling
00100      * this function! If buffer is empty, will return an undefined value.
00101      *
00102      * @return Read data
00103      */
00104     T peek() {
00105         return _pool[_tail];
00106     }
00107 
00108 
00109     /** Gets an object from the buffer at given offset, but do NOT remove it. Given offset is a value from
00110      * 0 to n. Ensure buffer has as many objects as the offset requested! For example, if buffer has 5 objects
00111      * available, given offset can be a value from 0 to 4.
00112      *
00113      * @param offset Offset of requested object. A value from 0-n, where (n+1) = available objects = getAvailable()
00114      * @return Object at given offset
00115      */
00116     T peekAt(CounterType offset) {
00117         return _pool[(offset+_tail)%BufferSize];
00118     }
00119 
00120 
00121     /** Gets the last object added to the buffer, but do NOT remove it.
00122      *
00123      * @return Object at given offset
00124      */
00125     T peekLastAdded() {
00126         return _pool[(_head-1)%BufferSize];
00127     }
00128 
00129 
00130     /** Gets and object from the buffer. Returns true if OK, else false
00131      *
00132      * @param data Variable to put read data into
00133      * @return True if the buffer is not empty and data contains a transaction, false otherwise
00134      */
00135     bool getAndCheck(T& data) {
00136         if (!isEmpty()) {
00137             data = _pool[_tail++];
00138             _tail %= BufferSize;
00139             _full = false;
00140             return true;
00141         }
00142         return false;
00143     }
00144 
00145 
00146     /** Check if the buffer is empty
00147      *
00148      * @return True if the buffer is empty, false if not
00149      */
00150     bool isEmpty() {
00151         return (_head == _tail) && !_full;
00152     }
00153 
00154 
00155     /** Check if the buffer is full
00156      *
00157      * @return True if the buffer is full, false if not
00158      */
00159     bool isFull() {
00160         return _full;
00161     }
00162 
00163 
00164     /** Get number of available bytes in buffer
00165      * @return Number of available bytes in buffer
00166      */
00167     CounterType getAvailable() {
00168         if (_head != _tail) {
00169             CounterType avail;
00170             avail = _head - _tail;
00171             avail %= BufferSize;
00172             return avail;
00173         }
00174 
00175         //Head=Tail. Can be full or empty
00176         if (_full==false) {
00177             return 0;
00178         }
00179         else {
00180             return BufferSize;
00181         }
00182     }
00183 
00184 
00185     /** Get number of free bytes in buffer available for writing data to.
00186      * @return Number of free bytes in buffer available for writing data to.
00187      */
00188     CounterType getFree() {
00189         CounterType free;
00190         //Full
00191         if (_full==true) {
00192             return 0;
00193         }
00194         //Empty
00195         if(_head == _tail) {
00196             return BufferSize;
00197         }
00198         free = _tail - _head;
00199         free %= BufferSize;
00200         return free;
00201     }
00202 
00203 
00204     /** Reset the buffer
00205      */
00206     void reset() {
00207         _head = 0;
00208         _tail = 0;
00209         _full = false;
00210     }
00211 
00212 
00213 
00214 private:
00215     T _pool[BufferSize];
00216     volatile CounterType _head;
00217     volatile CounterType _tail;
00218     volatile bool _full;
00219 };
00220 
00221 #endif /* SRC_MX_CIRCULAR_BUFFER_H_ */