Library for Modtronix NZ32 STM32 boards, like the NZ32-SC151, NZ32-SB072, NZ32-SE411 and others
mx_circular_buffer.h
- Committer:
- modtronix-com
- Date:
- 2015-09-10
- Revision:
- 7:709130701ac7
- Parent:
- 4:43abdd8eda40
- Child:
- 17:86034c970ea0
File content as of revision 7:709130701ac7:
/** * File: mx_circular_buffer.h * * Author: Modtronix Engineering - www.modtronix.com * * Description: * * Software License Agreement: * This software has been written or modified by Modtronix Engineering. The code * may be modified and can be used free of charge for commercial and non commercial * applications. If this is modified software, any license conditions from original * software also apply. Any redistribution must include reference to 'Modtronix * Engineering' and web link(www.modtronix.com) in the file header. * * THIS SOFTWARE IS PROVIDED IN AN 'AS IS' CONDITION. NO WARRANTIES, WHETHER EXPRESS, * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE * COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. */ #ifndef SRC_MX_CIRCULAR_BUFFER_H_ #define SRC_MX_CIRCULAR_BUFFER_H_ #include "mx_buffer_base.h" /** Templated Circular buffer class */ template<typename T, uint32_t BufferSize, typename CounterType = uint32_t> class MxCircularBuffer : public MxBuffer { public: MxCircularBuffer() : _head(0), _tail(0), _full(false) { } ~MxCircularBuffer() { } /** Adds an object to the buffer. If no space in buffer, this function does nothing. * do anything! * Use getFree() function prior to this function to ensure buffer has enough free space! * * @param data Data to be pushed to the buffer * * @return Returns true if character added to buffer, else false */ bool put(const T& data) { if (isFull()) { return false; } _pool[_head++] = data; _head %= BufferSize; if (_head == _tail) { _full = true; } return true; } /** Adds given array to the buffer. This function checks if buffer has enough space. * If not enough space available, nothing is added, and this function returns 0. * * @param buf Source buffer containing array to add to buffer * @param bufSize Size of array to add to buffer * * @return Returns true if character added to buffer, else false */ bool putArray(uint8_t* buf, uint16_t bufSize) { bool retVal = false; int i; if (getFree() < bufSize) { return false; } for(i=0; i<bufSize; i++) { retVal = retVal | put(buf[i]); } return retVal; } /** Gets and remove and object from the buffer. Ensure buffer is NOT empty before calling this function! * * @return Read data */ T get() { if (!isEmpty()) { T retData; retData = _pool[_tail++]; _tail %= BufferSize; _full = false; return retData; } return 0; } /** Gets and object from the buffer, but do NOT remove it. Ensure buffer is NOT empty before calling * this function! If buffer is empty, will return an undefined value. * * @return Read data */ T peek() { return _pool[_tail]; } /** Gets an object from the buffer at given offset, but do NOT remove it. Given offset is a value from * 0 to n. Ensure buffer has as many objects as the offset requested! For example, if buffer has 5 objects * available, given offset can be a value from 0 to 4. * * @param offset Offset of requested object. A value from 0-n, where (n+1) = available objects = getAvailable() * @return Object at given offset */ T peekAt(CounterType offset) { return _pool[(offset+_tail)%BufferSize]; } /** Gets the last object added to the buffer, but do NOT remove it. * * @return Object at given offset */ T peekLastAdded() { return _pool[(_head-1)%BufferSize]; } /** Gets and object from the buffer. Returns true if OK, else false * * @param data Variable to put read data into * @return True if the buffer is not empty and data contains a transaction, false otherwise */ bool getAndCheck(T& data) { if (!isEmpty()) { data = _pool[_tail++]; _tail %= BufferSize; _full = false; return true; } return false; } /** Check if the buffer is empty * * @return True if the buffer is empty, false if not */ bool isEmpty() { return (_head == _tail) && !_full; } /** Check if the buffer is full * * @return True if the buffer is full, false if not */ bool isFull() { return _full; } /** Get number of available bytes in buffer * @return Number of available bytes in buffer */ CounterType getAvailable() { if (_head != _tail) { CounterType avail; avail = _head - _tail; avail %= BufferSize; return avail; } //Head=Tail. Can be full or empty if (_full==false) { return 0; } else { return BufferSize; } } /** Get number of free bytes in buffer available for writing data to. * @return Number of free bytes in buffer available for writing data to. */ CounterType getFree() { CounterType free; //Full if (_full==true) { return 0; } //Empty if(_head == _tail) { return BufferSize; } free = _tail - _head; free %= BufferSize; return free; } /** Reset the buffer */ void reset() { _head = 0; _tail = 0; _full = false; } private: T _pool[BufferSize]; volatile CounterType _head; volatile CounterType _tail; volatile bool _full; }; #endif /* SRC_MX_CIRCULAR_BUFFER_H_ */