Library for Modtronix NZ32 STM32 boards, like the NZ32-SC151, NZ32-SB072, NZ32-SE411 and others
mx_circular_buffer.h@19:42ae82a8f571, 2016-08-19 (annotated)
- Committer:
- modtronix-com
- Date:
- Fri Aug 19 15:52:51 2016 +1000
- Revision:
- 19:42ae82a8f571
- Parent:
- 17:86034c970ea0
Added tag v1.1 for changeset 37e7c8fac8c7
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
modtronix | 4:43abdd8eda40 | 1 | /** |
modtronix | 4:43abdd8eda40 | 2 | * File: mx_circular_buffer.h |
modtronix | 4:43abdd8eda40 | 3 | * |
modtronix | 4:43abdd8eda40 | 4 | * Author: Modtronix Engineering - www.modtronix.com |
modtronix | 4:43abdd8eda40 | 5 | * |
modtronix | 4:43abdd8eda40 | 6 | * Description: |
modtronix | 4:43abdd8eda40 | 7 | * |
modtronix | 4:43abdd8eda40 | 8 | * Software License Agreement: |
modtronix | 4:43abdd8eda40 | 9 | * This software has been written or modified by Modtronix Engineering. The code |
modtronix | 4:43abdd8eda40 | 10 | * may be modified and can be used free of charge for commercial and non commercial |
modtronix | 4:43abdd8eda40 | 11 | * applications. If this is modified software, any license conditions from original |
modtronix | 4:43abdd8eda40 | 12 | * software also apply. Any redistribution must include reference to 'Modtronix |
modtronix | 4:43abdd8eda40 | 13 | * Engineering' and web link(www.modtronix.com) in the file header. |
modtronix | 4:43abdd8eda40 | 14 | * |
modtronix | 4:43abdd8eda40 | 15 | * THIS SOFTWARE IS PROVIDED IN AN 'AS IS' CONDITION. NO WARRANTIES, WHETHER EXPRESS, |
modtronix | 4:43abdd8eda40 | 16 | * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF |
modtronix | 4:43abdd8eda40 | 17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE |
modtronix | 4:43abdd8eda40 | 18 | * COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR |
modtronix | 4:43abdd8eda40 | 19 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
modtronix | 4:43abdd8eda40 | 20 | */ |
modtronix | 4:43abdd8eda40 | 21 | #ifndef SRC_MX_CIRCULAR_BUFFER_H_ |
modtronix | 4:43abdd8eda40 | 22 | #define SRC_MX_CIRCULAR_BUFFER_H_ |
modtronix | 4:43abdd8eda40 | 23 | |
modtronix-com |
17:86034c970ea0 | 24 | #include "nz32s_default_config.h" |
modtronix | 4:43abdd8eda40 | 25 | #include "mx_buffer_base.h" |
modtronix | 4:43abdd8eda40 | 26 | |
modtronix | 4:43abdd8eda40 | 27 | /** Templated Circular buffer class |
modtronix | 4:43abdd8eda40 | 28 | */ |
modtronix | 4:43abdd8eda40 | 29 | template<typename T, uint32_t BufferSize, typename CounterType = uint32_t> |
modtronix | 4:43abdd8eda40 | 30 | class MxCircularBuffer : public MxBuffer { |
modtronix | 4:43abdd8eda40 | 31 | public: |
modtronix | 4:43abdd8eda40 | 32 | MxCircularBuffer() : _head(0), _tail(0), _full(false) { |
modtronix | 4:43abdd8eda40 | 33 | } |
modtronix | 4:43abdd8eda40 | 34 | |
modtronix | 4:43abdd8eda40 | 35 | ~MxCircularBuffer() { |
modtronix | 4:43abdd8eda40 | 36 | } |
modtronix | 4:43abdd8eda40 | 37 | |
modtronix | 4:43abdd8eda40 | 38 | |
modtronix | 4:43abdd8eda40 | 39 | /** Adds an object to the buffer. If no space in buffer, this function does nothing. |
modtronix | 4:43abdd8eda40 | 40 | * do anything! |
modtronix | 4:43abdd8eda40 | 41 | * Use getFree() function prior to this function to ensure buffer has enough free space! |
modtronix | 4:43abdd8eda40 | 42 | * |
modtronix | 4:43abdd8eda40 | 43 | * @param data Data to be pushed to the buffer |
modtronix | 4:43abdd8eda40 | 44 | * |
modtronix | 4:43abdd8eda40 | 45 | * @return Returns true if character added to buffer, else false |
modtronix | 4:43abdd8eda40 | 46 | */ |
modtronix | 4:43abdd8eda40 | 47 | bool put(const T& data) { |
modtronix | 4:43abdd8eda40 | 48 | if (isFull()) { |
modtronix | 4:43abdd8eda40 | 49 | return false; |
modtronix | 4:43abdd8eda40 | 50 | } |
modtronix | 4:43abdd8eda40 | 51 | _pool[_head++] = data; |
modtronix | 4:43abdd8eda40 | 52 | _head %= BufferSize; |
modtronix | 4:43abdd8eda40 | 53 | if (_head == _tail) { |
modtronix | 4:43abdd8eda40 | 54 | _full = true; |
modtronix | 4:43abdd8eda40 | 55 | } |
modtronix | 4:43abdd8eda40 | 56 | return true; |
modtronix | 4:43abdd8eda40 | 57 | } |
modtronix | 4:43abdd8eda40 | 58 | |
modtronix | 4:43abdd8eda40 | 59 | |
modtronix | 4:43abdd8eda40 | 60 | /** Adds given array to the buffer. This function checks if buffer has enough space. |
modtronix | 4:43abdd8eda40 | 61 | * If not enough space available, nothing is added, and this function returns 0. |
modtronix | 4:43abdd8eda40 | 62 | * |
modtronix | 4:43abdd8eda40 | 63 | * @param buf Source buffer containing array to add to buffer |
modtronix | 4:43abdd8eda40 | 64 | * @param bufSize Size of array to add to buffer |
modtronix | 4:43abdd8eda40 | 65 | * |
modtronix | 4:43abdd8eda40 | 66 | * @return Returns true if character added to buffer, else false |
modtronix | 4:43abdd8eda40 | 67 | */ |
modtronix | 4:43abdd8eda40 | 68 | bool putArray(uint8_t* buf, uint16_t bufSize) { |
modtronix | 4:43abdd8eda40 | 69 | bool retVal = false; |
modtronix | 4:43abdd8eda40 | 70 | int i; |
modtronix | 4:43abdd8eda40 | 71 | |
modtronix | 4:43abdd8eda40 | 72 | if (getFree() < bufSize) { |
modtronix | 4:43abdd8eda40 | 73 | return false; |
modtronix | 4:43abdd8eda40 | 74 | } |
modtronix | 4:43abdd8eda40 | 75 | |
modtronix | 4:43abdd8eda40 | 76 | for(i=0; i<bufSize; i++) { |
modtronix | 4:43abdd8eda40 | 77 | retVal = retVal | put(buf[i]); |
modtronix | 4:43abdd8eda40 | 78 | } |
modtronix | 4:43abdd8eda40 | 79 | return retVal; |
modtronix | 4:43abdd8eda40 | 80 | } |
modtronix | 4:43abdd8eda40 | 81 | |
modtronix | 4:43abdd8eda40 | 82 | |
modtronix | 4:43abdd8eda40 | 83 | /** Gets and remove and object from the buffer. Ensure buffer is NOT empty before calling this function! |
modtronix | 4:43abdd8eda40 | 84 | * |
modtronix | 4:43abdd8eda40 | 85 | * @return Read data |
modtronix | 4:43abdd8eda40 | 86 | */ |
modtronix | 4:43abdd8eda40 | 87 | T get() { |
modtronix | 4:43abdd8eda40 | 88 | if (!isEmpty()) { |
modtronix | 4:43abdd8eda40 | 89 | T retData; |
modtronix | 4:43abdd8eda40 | 90 | retData = _pool[_tail++]; |
modtronix | 4:43abdd8eda40 | 91 | _tail %= BufferSize; |
modtronix | 4:43abdd8eda40 | 92 | _full = false; |
modtronix | 4:43abdd8eda40 | 93 | return retData; |
modtronix | 4:43abdd8eda40 | 94 | } |
modtronix | 4:43abdd8eda40 | 95 | return 0; |
modtronix | 4:43abdd8eda40 | 96 | } |
modtronix | 4:43abdd8eda40 | 97 | |
modtronix | 4:43abdd8eda40 | 98 | |
modtronix | 4:43abdd8eda40 | 99 | /** Gets and object from the buffer, but do NOT remove it. Ensure buffer is NOT empty before calling |
modtronix | 4:43abdd8eda40 | 100 | * this function! If buffer is empty, will return an undefined value. |
modtronix | 4:43abdd8eda40 | 101 | * |
modtronix | 4:43abdd8eda40 | 102 | * @return Read data |
modtronix | 4:43abdd8eda40 | 103 | */ |
modtronix | 4:43abdd8eda40 | 104 | T peek() { |
modtronix | 4:43abdd8eda40 | 105 | return _pool[_tail]; |
modtronix | 4:43abdd8eda40 | 106 | } |
modtronix | 4:43abdd8eda40 | 107 | |
modtronix | 4:43abdd8eda40 | 108 | |
modtronix | 4:43abdd8eda40 | 109 | /** Gets an object from the buffer at given offset, but do NOT remove it. Given offset is a value from |
modtronix | 4:43abdd8eda40 | 110 | * 0 to n. Ensure buffer has as many objects as the offset requested! For example, if buffer has 5 objects |
modtronix | 4:43abdd8eda40 | 111 | * available, given offset can be a value from 0 to 4. |
modtronix | 4:43abdd8eda40 | 112 | * |
modtronix | 4:43abdd8eda40 | 113 | * @param offset Offset of requested object. A value from 0-n, where (n+1) = available objects = getAvailable() |
modtronix | 4:43abdd8eda40 | 114 | * @return Object at given offset |
modtronix | 4:43abdd8eda40 | 115 | */ |
modtronix | 4:43abdd8eda40 | 116 | T peekAt(CounterType offset) { |
modtronix | 4:43abdd8eda40 | 117 | return _pool[(offset+_tail)%BufferSize]; |
modtronix | 4:43abdd8eda40 | 118 | } |
modtronix | 4:43abdd8eda40 | 119 | |
modtronix | 4:43abdd8eda40 | 120 | |
modtronix | 4:43abdd8eda40 | 121 | /** Gets the last object added to the buffer, but do NOT remove it. |
modtronix | 4:43abdd8eda40 | 122 | * |
modtronix | 4:43abdd8eda40 | 123 | * @return Object at given offset |
modtronix | 4:43abdd8eda40 | 124 | */ |
modtronix | 4:43abdd8eda40 | 125 | T peekLastAdded() { |
modtronix | 4:43abdd8eda40 | 126 | return _pool[(_head-1)%BufferSize]; |
modtronix | 4:43abdd8eda40 | 127 | } |
modtronix | 4:43abdd8eda40 | 128 | |
modtronix | 4:43abdd8eda40 | 129 | |
modtronix | 4:43abdd8eda40 | 130 | /** Gets and object from the buffer. Returns true if OK, else false |
modtronix | 4:43abdd8eda40 | 131 | * |
modtronix | 4:43abdd8eda40 | 132 | * @param data Variable to put read data into |
modtronix | 4:43abdd8eda40 | 133 | * @return True if the buffer is not empty and data contains a transaction, false otherwise |
modtronix | 4:43abdd8eda40 | 134 | */ |
modtronix | 4:43abdd8eda40 | 135 | bool getAndCheck(T& data) { |
modtronix | 4:43abdd8eda40 | 136 | if (!isEmpty()) { |
modtronix | 4:43abdd8eda40 | 137 | data = _pool[_tail++]; |
modtronix | 4:43abdd8eda40 | 138 | _tail %= BufferSize; |
modtronix | 4:43abdd8eda40 | 139 | _full = false; |
modtronix | 4:43abdd8eda40 | 140 | return true; |
modtronix | 4:43abdd8eda40 | 141 | } |
modtronix | 4:43abdd8eda40 | 142 | return false; |
modtronix | 4:43abdd8eda40 | 143 | } |
modtronix | 4:43abdd8eda40 | 144 | |
modtronix | 4:43abdd8eda40 | 145 | |
modtronix | 4:43abdd8eda40 | 146 | /** Check if the buffer is empty |
modtronix | 4:43abdd8eda40 | 147 | * |
modtronix | 4:43abdd8eda40 | 148 | * @return True if the buffer is empty, false if not |
modtronix | 4:43abdd8eda40 | 149 | */ |
modtronix | 4:43abdd8eda40 | 150 | bool isEmpty() { |
modtronix | 4:43abdd8eda40 | 151 | return (_head == _tail) && !_full; |
modtronix | 4:43abdd8eda40 | 152 | } |
modtronix | 4:43abdd8eda40 | 153 | |
modtronix | 4:43abdd8eda40 | 154 | |
modtronix | 4:43abdd8eda40 | 155 | /** Check if the buffer is full |
modtronix | 4:43abdd8eda40 | 156 | * |
modtronix | 4:43abdd8eda40 | 157 | * @return True if the buffer is full, false if not |
modtronix | 4:43abdd8eda40 | 158 | */ |
modtronix | 4:43abdd8eda40 | 159 | bool isFull() { |
modtronix | 4:43abdd8eda40 | 160 | return _full; |
modtronix | 4:43abdd8eda40 | 161 | } |
modtronix | 4:43abdd8eda40 | 162 | |
modtronix | 4:43abdd8eda40 | 163 | |
modtronix | 4:43abdd8eda40 | 164 | /** Get number of available bytes in buffer |
modtronix | 4:43abdd8eda40 | 165 | * @return Number of available bytes in buffer |
modtronix | 4:43abdd8eda40 | 166 | */ |
modtronix | 4:43abdd8eda40 | 167 | CounterType getAvailable() { |
modtronix-com |
7:709130701ac7 | 168 | if (_head != _tail) { |
modtronix-com |
7:709130701ac7 | 169 | CounterType avail; |
modtronix-com |
7:709130701ac7 | 170 | avail = _head - _tail; |
modtronix-com |
7:709130701ac7 | 171 | avail %= BufferSize; |
modtronix-com |
7:709130701ac7 | 172 | return avail; |
modtronix-com |
7:709130701ac7 | 173 | } |
modtronix-com |
7:709130701ac7 | 174 | |
modtronix-com |
7:709130701ac7 | 175 | //Head=Tail. Can be full or empty |
modtronix-com |
7:709130701ac7 | 176 | if (_full==false) { |
modtronix | 4:43abdd8eda40 | 177 | return 0; |
modtronix | 4:43abdd8eda40 | 178 | } |
modtronix-com |
7:709130701ac7 | 179 | else { |
modtronix-com |
7:709130701ac7 | 180 | return BufferSize; |
modtronix-com |
7:709130701ac7 | 181 | } |
modtronix | 4:43abdd8eda40 | 182 | } |
modtronix | 4:43abdd8eda40 | 183 | |
modtronix | 4:43abdd8eda40 | 184 | |
modtronix | 4:43abdd8eda40 | 185 | /** Get number of free bytes in buffer available for writing data to. |
modtronix | 4:43abdd8eda40 | 186 | * @return Number of free bytes in buffer available for writing data to. |
modtronix | 4:43abdd8eda40 | 187 | */ |
modtronix | 4:43abdd8eda40 | 188 | CounterType getFree() { |
modtronix | 4:43abdd8eda40 | 189 | CounterType free; |
modtronix | 4:43abdd8eda40 | 190 | //Full |
modtronix | 4:43abdd8eda40 | 191 | if (_full==true) { |
modtronix | 4:43abdd8eda40 | 192 | return 0; |
modtronix | 4:43abdd8eda40 | 193 | } |
modtronix | 4:43abdd8eda40 | 194 | //Empty |
modtronix | 4:43abdd8eda40 | 195 | if(_head == _tail) { |
modtronix | 4:43abdd8eda40 | 196 | return BufferSize; |
modtronix | 4:43abdd8eda40 | 197 | } |
modtronix | 4:43abdd8eda40 | 198 | free = _tail - _head; |
modtronix | 4:43abdd8eda40 | 199 | free %= BufferSize; |
modtronix | 4:43abdd8eda40 | 200 | return free; |
modtronix | 4:43abdd8eda40 | 201 | } |
modtronix | 4:43abdd8eda40 | 202 | |
modtronix | 4:43abdd8eda40 | 203 | |
modtronix | 4:43abdd8eda40 | 204 | /** Reset the buffer |
modtronix | 4:43abdd8eda40 | 205 | */ |
modtronix | 4:43abdd8eda40 | 206 | void reset() { |
modtronix | 4:43abdd8eda40 | 207 | _head = 0; |
modtronix | 4:43abdd8eda40 | 208 | _tail = 0; |
modtronix | 4:43abdd8eda40 | 209 | _full = false; |
modtronix | 4:43abdd8eda40 | 210 | } |
modtronix | 4:43abdd8eda40 | 211 | |
modtronix | 4:43abdd8eda40 | 212 | |
modtronix | 4:43abdd8eda40 | 213 | |
modtronix | 4:43abdd8eda40 | 214 | private: |
modtronix | 4:43abdd8eda40 | 215 | T _pool[BufferSize]; |
modtronix | 4:43abdd8eda40 | 216 | volatile CounterType _head; |
modtronix | 4:43abdd8eda40 | 217 | volatile CounterType _tail; |
modtronix | 4:43abdd8eda40 | 218 | volatile bool _full; |
modtronix | 4:43abdd8eda40 | 219 | }; |
modtronix | 4:43abdd8eda40 | 220 | |
modtronix | 4:43abdd8eda40 | 221 | #endif /* SRC_MX_CIRCULAR_BUFFER_H_ */ |