Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lypinator 0:bb348c97df44 1 /* mbed Microcontroller Library
lypinator 0:bb348c97df44 2 * Copyright (c) 2015 ARM Limited
lypinator 0:bb348c97df44 3 *
lypinator 0:bb348c97df44 4 * Licensed under the Apache License, Version 2.0 (the "License");
lypinator 0:bb348c97df44 5 * you may not use this file except in compliance with the License.
lypinator 0:bb348c97df44 6 * You may obtain a copy of the License at
lypinator 0:bb348c97df44 7 *
lypinator 0:bb348c97df44 8 * http://www.apache.org/licenses/LICENSE-2.0
lypinator 0:bb348c97df44 9 *
lypinator 0:bb348c97df44 10 * Unless required by applicable law or agreed to in writing, software
lypinator 0:bb348c97df44 11 * distributed under the License is distributed on an "AS IS" BASIS,
lypinator 0:bb348c97df44 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lypinator 0:bb348c97df44 13 * See the License for the specific language governing permissions and
lypinator 0:bb348c97df44 14 * limitations under the License.
lypinator 0:bb348c97df44 15 */
lypinator 0:bb348c97df44 16 #ifndef MBED_CIRCULARBUFFER_H
lypinator 0:bb348c97df44 17 #define MBED_CIRCULARBUFFER_H
lypinator 0:bb348c97df44 18
lypinator 0:bb348c97df44 19 #include "platform/mbed_critical.h"
lypinator 0:bb348c97df44 20 #include "platform/mbed_assert.h"
lypinator 0:bb348c97df44 21
lypinator 0:bb348c97df44 22 namespace mbed {
lypinator 0:bb348c97df44 23
lypinator 0:bb348c97df44 24 namespace internal {
lypinator 0:bb348c97df44 25 /* Detect if CounterType of the Circular buffer is of unsigned type. */
lypinator 0:bb348c97df44 26 template<typename T>
lypinator 0:bb348c97df44 27 struct is_unsigned {
lypinator 0:bb348c97df44 28 static const bool value = false;
lypinator 0:bb348c97df44 29 };
lypinator 0:bb348c97df44 30 template<>
lypinator 0:bb348c97df44 31 struct is_unsigned<unsigned char> {
lypinator 0:bb348c97df44 32 static const bool value = true;
lypinator 0:bb348c97df44 33 };
lypinator 0:bb348c97df44 34 template<>
lypinator 0:bb348c97df44 35 struct is_unsigned<unsigned short> {
lypinator 0:bb348c97df44 36 static const bool value = true;
lypinator 0:bb348c97df44 37 };
lypinator 0:bb348c97df44 38 template<>
lypinator 0:bb348c97df44 39 struct is_unsigned<unsigned int> {
lypinator 0:bb348c97df44 40 static const bool value = true;
lypinator 0:bb348c97df44 41 };
lypinator 0:bb348c97df44 42 template<>
lypinator 0:bb348c97df44 43 struct is_unsigned<unsigned long> {
lypinator 0:bb348c97df44 44 static const bool value = true;
lypinator 0:bb348c97df44 45 };
lypinator 0:bb348c97df44 46 template<>
lypinator 0:bb348c97df44 47 struct is_unsigned<unsigned long long> {
lypinator 0:bb348c97df44 48 static const bool value = true;
lypinator 0:bb348c97df44 49 };
lypinator 0:bb348c97df44 50 };
lypinator 0:bb348c97df44 51
lypinator 0:bb348c97df44 52 /** \addtogroup platform */
lypinator 0:bb348c97df44 53 /** @{*/
lypinator 0:bb348c97df44 54 /**
lypinator 0:bb348c97df44 55 * \defgroup platform_CircularBuffer CircularBuffer functions
lypinator 0:bb348c97df44 56 * @{
lypinator 0:bb348c97df44 57 */
lypinator 0:bb348c97df44 58
lypinator 0:bb348c97df44 59 /** Templated Circular buffer class
lypinator 0:bb348c97df44 60 *
lypinator 0:bb348c97df44 61 * @note Synchronization level: Interrupt safe
lypinator 0:bb348c97df44 62 * @note CounterType must be unsigned and consistent with BufferSize
lypinator 0:bb348c97df44 63 */
lypinator 0:bb348c97df44 64 template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
lypinator 0:bb348c97df44 65 class CircularBuffer {
lypinator 0:bb348c97df44 66 public:
lypinator 0:bb348c97df44 67 CircularBuffer() : _head(0), _tail(0), _full(false)
lypinator 0:bb348c97df44 68 {
lypinator 0:bb348c97df44 69 MBED_STATIC_ASSERT(
lypinator 0:bb348c97df44 70 internal::is_unsigned<CounterType>::value,
lypinator 0:bb348c97df44 71 "CounterType must be unsigned"
lypinator 0:bb348c97df44 72 );
lypinator 0:bb348c97df44 73
lypinator 0:bb348c97df44 74 MBED_STATIC_ASSERT(
lypinator 0:bb348c97df44 75 (sizeof(CounterType) >= sizeof(uint32_t)) ||
lypinator 0:bb348c97df44 76 (BufferSize < (((uint64_t) 1) << (sizeof(CounterType) * 8))),
lypinator 0:bb348c97df44 77 "Invalid BufferSize for the CounterType"
lypinator 0:bb348c97df44 78 );
lypinator 0:bb348c97df44 79 }
lypinator 0:bb348c97df44 80
lypinator 0:bb348c97df44 81 ~CircularBuffer()
lypinator 0:bb348c97df44 82 {
lypinator 0:bb348c97df44 83 }
lypinator 0:bb348c97df44 84
lypinator 0:bb348c97df44 85 /** Push the transaction to the buffer. This overwrites the buffer if it's
lypinator 0:bb348c97df44 86 * full
lypinator 0:bb348c97df44 87 *
lypinator 0:bb348c97df44 88 * @param data Data to be pushed to the buffer
lypinator 0:bb348c97df44 89 */
lypinator 0:bb348c97df44 90 void push(const T &data)
lypinator 0:bb348c97df44 91 {
lypinator 0:bb348c97df44 92 core_util_critical_section_enter();
lypinator 0:bb348c97df44 93 if (full()) {
lypinator 0:bb348c97df44 94 _tail++;
lypinator 0:bb348c97df44 95 _tail %= BufferSize;
lypinator 0:bb348c97df44 96 }
lypinator 0:bb348c97df44 97 _pool[_head++] = data;
lypinator 0:bb348c97df44 98 _head %= BufferSize;
lypinator 0:bb348c97df44 99 if (_head == _tail) {
lypinator 0:bb348c97df44 100 _full = true;
lypinator 0:bb348c97df44 101 }
lypinator 0:bb348c97df44 102 core_util_critical_section_exit();
lypinator 0:bb348c97df44 103 }
lypinator 0:bb348c97df44 104
lypinator 0:bb348c97df44 105 /** Pop the transaction from the buffer
lypinator 0:bb348c97df44 106 *
lypinator 0:bb348c97df44 107 * @param data Data to be popped from the buffer
lypinator 0:bb348c97df44 108 * @return True if the buffer is not empty and data contains a transaction, false otherwise
lypinator 0:bb348c97df44 109 */
lypinator 0:bb348c97df44 110 bool pop(T &data)
lypinator 0:bb348c97df44 111 {
lypinator 0:bb348c97df44 112 bool data_popped = false;
lypinator 0:bb348c97df44 113 core_util_critical_section_enter();
lypinator 0:bb348c97df44 114 if (!empty()) {
lypinator 0:bb348c97df44 115 data = _pool[_tail++];
lypinator 0:bb348c97df44 116 _tail %= BufferSize;
lypinator 0:bb348c97df44 117 _full = false;
lypinator 0:bb348c97df44 118 data_popped = true;
lypinator 0:bb348c97df44 119 }
lypinator 0:bb348c97df44 120 core_util_critical_section_exit();
lypinator 0:bb348c97df44 121 return data_popped;
lypinator 0:bb348c97df44 122 }
lypinator 0:bb348c97df44 123
lypinator 0:bb348c97df44 124 /** Check if the buffer is empty
lypinator 0:bb348c97df44 125 *
lypinator 0:bb348c97df44 126 * @return True if the buffer is empty, false if not
lypinator 0:bb348c97df44 127 */
lypinator 0:bb348c97df44 128 bool empty() const
lypinator 0:bb348c97df44 129 {
lypinator 0:bb348c97df44 130 core_util_critical_section_enter();
lypinator 0:bb348c97df44 131 bool is_empty = (_head == _tail) && !_full;
lypinator 0:bb348c97df44 132 core_util_critical_section_exit();
lypinator 0:bb348c97df44 133 return is_empty;
lypinator 0:bb348c97df44 134 }
lypinator 0:bb348c97df44 135
lypinator 0:bb348c97df44 136 /** Check if the buffer is full
lypinator 0:bb348c97df44 137 *
lypinator 0:bb348c97df44 138 * @return True if the buffer is full, false if not
lypinator 0:bb348c97df44 139 */
lypinator 0:bb348c97df44 140 bool full() const
lypinator 0:bb348c97df44 141 {
lypinator 0:bb348c97df44 142 core_util_critical_section_enter();
lypinator 0:bb348c97df44 143 bool full = _full;
lypinator 0:bb348c97df44 144 core_util_critical_section_exit();
lypinator 0:bb348c97df44 145 return full;
lypinator 0:bb348c97df44 146 }
lypinator 0:bb348c97df44 147
lypinator 0:bb348c97df44 148 /** Reset the buffer
lypinator 0:bb348c97df44 149 *
lypinator 0:bb348c97df44 150 */
lypinator 0:bb348c97df44 151 void reset()
lypinator 0:bb348c97df44 152 {
lypinator 0:bb348c97df44 153 core_util_critical_section_enter();
lypinator 0:bb348c97df44 154 _head = 0;
lypinator 0:bb348c97df44 155 _tail = 0;
lypinator 0:bb348c97df44 156 _full = false;
lypinator 0:bb348c97df44 157 core_util_critical_section_exit();
lypinator 0:bb348c97df44 158 }
lypinator 0:bb348c97df44 159
lypinator 0:bb348c97df44 160 /** Get the number of elements currently stored in the circular_buffer */
lypinator 0:bb348c97df44 161 CounterType size() const
lypinator 0:bb348c97df44 162 {
lypinator 0:bb348c97df44 163 core_util_critical_section_enter();
lypinator 0:bb348c97df44 164 CounterType elements;
lypinator 0:bb348c97df44 165 if (!_full) {
lypinator 0:bb348c97df44 166 if (_head < _tail) {
lypinator 0:bb348c97df44 167 elements = BufferSize + _head - _tail;
lypinator 0:bb348c97df44 168 } else {
lypinator 0:bb348c97df44 169 elements = _head - _tail;
lypinator 0:bb348c97df44 170 }
lypinator 0:bb348c97df44 171 } else {
lypinator 0:bb348c97df44 172 elements = BufferSize;
lypinator 0:bb348c97df44 173 }
lypinator 0:bb348c97df44 174 core_util_critical_section_exit();
lypinator 0:bb348c97df44 175 return elements;
lypinator 0:bb348c97df44 176 }
lypinator 0:bb348c97df44 177
lypinator 0:bb348c97df44 178 /** Peek into circular buffer without popping
lypinator 0:bb348c97df44 179 *
lypinator 0:bb348c97df44 180 * @param data Data to be peeked from the buffer
lypinator 0:bb348c97df44 181 * @return True if the buffer is not empty and data contains a transaction, false otherwise
lypinator 0:bb348c97df44 182 */
lypinator 0:bb348c97df44 183 bool peek(T &data) const
lypinator 0:bb348c97df44 184 {
lypinator 0:bb348c97df44 185 bool data_updated = false;
lypinator 0:bb348c97df44 186 core_util_critical_section_enter();
lypinator 0:bb348c97df44 187 if (!empty()) {
lypinator 0:bb348c97df44 188 data = _pool[_tail];
lypinator 0:bb348c97df44 189 data_updated = true;
lypinator 0:bb348c97df44 190 }
lypinator 0:bb348c97df44 191 core_util_critical_section_exit();
lypinator 0:bb348c97df44 192 return data_updated;
lypinator 0:bb348c97df44 193 }
lypinator 0:bb348c97df44 194
lypinator 0:bb348c97df44 195 private:
lypinator 0:bb348c97df44 196 T _pool[BufferSize];
lypinator 0:bb348c97df44 197 volatile CounterType _head;
lypinator 0:bb348c97df44 198 volatile CounterType _tail;
lypinator 0:bb348c97df44 199 volatile bool _full;
lypinator 0:bb348c97df44 200 };
lypinator 0:bb348c97df44 201
lypinator 0:bb348c97df44 202 /**@}*/
lypinator 0:bb348c97df44 203
lypinator 0:bb348c97df44 204 /**@}*/
lypinator 0:bb348c97df44 205
lypinator 0:bb348c97df44 206 }
lypinator 0:bb348c97df44 207
lypinator 0:bb348c97df44 208 #endif