very special ring buffer. This is only for fc_GPS1PPS_F746_F4xx library
Dependents: fc_GPS1PPS_f746_f4xx Frq_cuntr_Nucleo-F746ZG
RingBuff.cpp@0:e206b41f0032, 2016-11-16 (annotated)
- Committer:
- kenjiArai
- Date:
- Wed Nov 16 13:08:35 2016 +0000
- Revision:
- 0:e206b41f0032
very special ring buffer only for Frequency counter
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:e206b41f0032 | 1 | /* |
kenjiArai | 0:e206b41f0032 | 2 | * mbed Library program / Ring Buffer |
kenjiArai | 0:e206b41f0032 | 3 | * CAUTION!! |
kenjiArai | 0:e206b41f0032 | 4 | * This is very special ring buffer which save newest data and remember |
kenjiArai | 0:e206b41f0032 | 5 | * some amount of old data. |
kenjiArai | 0:e206b41f0032 | 6 | * If write newest data into the buffer, lose oldest data. |
kenjiArai | 0:e206b41f0032 | 7 | * Don't use this library as normal type of a FIFO ring buffer!! |
kenjiArai | 0:e206b41f0032 | 8 | * |
kenjiArai | 0:e206b41f0032 | 9 | * Copyright (c) 2016 Kenji Arai / JH1PJL |
kenjiArai | 0:e206b41f0032 | 10 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:e206b41f0032 | 11 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 0:e206b41f0032 | 12 | * Created: September 18th, 2016 |
kenjiArai | 0:e206b41f0032 | 13 | * Revised: November 8th, 2016 |
kenjiArai | 0:e206b41f0032 | 14 | * |
kenjiArai | 0:e206b41f0032 | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
kenjiArai | 0:e206b41f0032 | 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
kenjiArai | 0:e206b41f0032 | 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
kenjiArai | 0:e206b41f0032 | 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
kenjiArai | 0:e206b41f0032 | 19 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
kenjiArai | 0:e206b41f0032 | 20 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR |
kenjiArai | 0:e206b41f0032 | 21 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
kenjiArai | 0:e206b41f0032 | 22 | */ |
kenjiArai | 0:e206b41f0032 | 23 | |
kenjiArai | 0:e206b41f0032 | 24 | #include <stdint.h> |
kenjiArai | 0:e206b41f0032 | 25 | #include <stdlib.h> |
kenjiArai | 0:e206b41f0032 | 26 | #include "mbed.h" |
kenjiArai | 0:e206b41f0032 | 27 | #include "RingBuff.h" |
kenjiArai | 0:e206b41f0032 | 28 | |
kenjiArai | 0:e206b41f0032 | 29 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 30 | RingBuff<T>::RingBuff(const int16_t size) |
kenjiArai | 0:e206b41f0032 | 31 | :buffer_size(size) |
kenjiArai | 0:e206b41f0032 | 32 | { |
kenjiArai | 0:e206b41f0032 | 33 | head = tail = 0; |
kenjiArai | 0:e206b41f0032 | 34 | buff = (T *)malloc(buffer_size * sizeof(T)); |
kenjiArai | 0:e206b41f0032 | 35 | } |
kenjiArai | 0:e206b41f0032 | 36 | |
kenjiArai | 0:e206b41f0032 | 37 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 38 | RingBuff<T>::~RingBuff() |
kenjiArai | 0:e206b41f0032 | 39 | { |
kenjiArai | 0:e206b41f0032 | 40 | free(buff); |
kenjiArai | 0:e206b41f0032 | 41 | } |
kenjiArai | 0:e206b41f0032 | 42 | |
kenjiArai | 0:e206b41f0032 | 43 | //------------------------------------------------------------------------------ |
kenjiArai | 0:e206b41f0032 | 44 | // Ring Buffer Control |
kenjiArai | 0:e206b41f0032 | 45 | //------------------------------------------------------------------------------ |
kenjiArai | 0:e206b41f0032 | 46 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 47 | int16_t RingBuff<T>::ring_is_buf_full (void){ |
kenjiArai | 0:e206b41f0032 | 48 | if (tail == head + 1 || |
kenjiArai | 0:e206b41f0032 | 49 | (head == buffer_size - 1 && tail == 0)){ |
kenjiArai | 0:e206b41f0032 | 50 | return 1; |
kenjiArai | 0:e206b41f0032 | 51 | }else { |
kenjiArai | 0:e206b41f0032 | 52 | return 0; |
kenjiArai | 0:e206b41f0032 | 53 | } |
kenjiArai | 0:e206b41f0032 | 54 | } |
kenjiArai | 0:e206b41f0032 | 55 | |
kenjiArai | 0:e206b41f0032 | 56 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 57 | void RingBuff<T>::ring_put_dt (T dt){ |
kenjiArai | 0:e206b41f0032 | 58 | if (ring_is_buf_full()){ |
kenjiArai | 0:e206b41f0032 | 59 | buff[head++] = dt; |
kenjiArai | 0:e206b41f0032 | 60 | tail++; |
kenjiArai | 0:e206b41f0032 | 61 | if (head == buffer_size){ |
kenjiArai | 0:e206b41f0032 | 62 | head = 0; |
kenjiArai | 0:e206b41f0032 | 63 | } |
kenjiArai | 0:e206b41f0032 | 64 | if (tail == buffer_size){ |
kenjiArai | 0:e206b41f0032 | 65 | tail = 0; |
kenjiArai | 0:e206b41f0032 | 66 | } |
kenjiArai | 0:e206b41f0032 | 67 | } else { // Not full yet |
kenjiArai | 0:e206b41f0032 | 68 | buff[head++] = dt; |
kenjiArai | 0:e206b41f0032 | 69 | if (head == buffer_size){ |
kenjiArai | 0:e206b41f0032 | 70 | head = 0; |
kenjiArai | 0:e206b41f0032 | 71 | tail = 1; |
kenjiArai | 0:e206b41f0032 | 72 | } |
kenjiArai | 0:e206b41f0032 | 73 | } |
kenjiArai | 0:e206b41f0032 | 74 | } |
kenjiArai | 0:e206b41f0032 | 75 | |
kenjiArai | 0:e206b41f0032 | 76 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 77 | T RingBuff<T>::ring_get_newest_dt (void){ |
kenjiArai | 0:e206b41f0032 | 78 | T dt; |
kenjiArai | 0:e206b41f0032 | 79 | |
kenjiArai | 0:e206b41f0032 | 80 | if (ring_is_buf_empty()){ |
kenjiArai | 0:e206b41f0032 | 81 | return 0; |
kenjiArai | 0:e206b41f0032 | 82 | } |
kenjiArai | 0:e206b41f0032 | 83 | do{ // check interrupt |
kenjiArai | 0:e206b41f0032 | 84 | head_temp = head; |
kenjiArai | 0:e206b41f0032 | 85 | if (head == 0){ |
kenjiArai | 0:e206b41f0032 | 86 | dt = buff[buffer_size - 1]; |
kenjiArai | 0:e206b41f0032 | 87 | } else { |
kenjiArai | 0:e206b41f0032 | 88 | dt = buff[head - 1]; |
kenjiArai | 0:e206b41f0032 | 89 | } |
kenjiArai | 0:e206b41f0032 | 90 | } while(head != head_temp); |
kenjiArai | 0:e206b41f0032 | 91 | return dt; |
kenjiArai | 0:e206b41f0032 | 92 | } |
kenjiArai | 0:e206b41f0032 | 93 | |
kenjiArai | 0:e206b41f0032 | 94 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 95 | T RingBuff<T>::ring_get_pointed_dt (int16_t offset){ |
kenjiArai | 0:e206b41f0032 | 96 | int16_t hd; |
kenjiArai | 0:e206b41f0032 | 97 | T dt; |
kenjiArai | 0:e206b41f0032 | 98 | |
kenjiArai | 0:e206b41f0032 | 99 | if (ring_is_buf_empty()){ |
kenjiArai | 0:e206b41f0032 | 100 | return 0; |
kenjiArai | 0:e206b41f0032 | 101 | } |
kenjiArai | 0:e206b41f0032 | 102 | do { |
kenjiArai | 0:e206b41f0032 | 103 | head_temp = head; |
kenjiArai | 0:e206b41f0032 | 104 | int16_t sz = ring_get_buf_size(); |
kenjiArai | 0:e206b41f0032 | 105 | if (head == 0){ |
kenjiArai | 0:e206b41f0032 | 106 | hd = buffer_size - 1; |
kenjiArai | 0:e206b41f0032 | 107 | } else { |
kenjiArai | 0:e206b41f0032 | 108 | hd = head - 1; |
kenjiArai | 0:e206b41f0032 | 109 | } |
kenjiArai | 0:e206b41f0032 | 110 | if (sz == buffer_size){ // Buffer is full |
kenjiArai | 0:e206b41f0032 | 111 | if (sz < offset){ // error |
kenjiArai | 0:e206b41f0032 | 112 | dt = 0; |
kenjiArai | 0:e206b41f0032 | 113 | } else { // data is in buffer |
kenjiArai | 0:e206b41f0032 | 114 | if (hd >= offset){ |
kenjiArai | 0:e206b41f0032 | 115 | dt = buff[hd - offset]; |
kenjiArai | 0:e206b41f0032 | 116 | } else { |
kenjiArai | 0:e206b41f0032 | 117 | dt = buff[buffer_size - (offset - hd)]; |
kenjiArai | 0:e206b41f0032 | 118 | } |
kenjiArai | 0:e206b41f0032 | 119 | } |
kenjiArai | 0:e206b41f0032 | 120 | } else { // Buffer is not full |
kenjiArai | 0:e206b41f0032 | 121 | if (sz <= offset){ // error |
kenjiArai | 0:e206b41f0032 | 122 | dt = 0; |
kenjiArai | 0:e206b41f0032 | 123 | } else { |
kenjiArai | 0:e206b41f0032 | 124 | dt = buff[hd - offset]; |
kenjiArai | 0:e206b41f0032 | 125 | } |
kenjiArai | 0:e206b41f0032 | 126 | } |
kenjiArai | 0:e206b41f0032 | 127 | } while(head != head_temp); |
kenjiArai | 0:e206b41f0032 | 128 | return dt; |
kenjiArai | 0:e206b41f0032 | 129 | } |
kenjiArai | 0:e206b41f0032 | 130 | |
kenjiArai | 0:e206b41f0032 | 131 | |
kenjiArai | 0:e206b41f0032 | 132 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 133 | int16_t RingBuff<T>::ring_get_buf_size (void){ |
kenjiArai | 0:e206b41f0032 | 134 | if (head == tail){ // empty |
kenjiArai | 0:e206b41f0032 | 135 | return 0; |
kenjiArai | 0:e206b41f0032 | 136 | } |
kenjiArai | 0:e206b41f0032 | 137 | if (head > tail){ // Not full yet |
kenjiArai | 0:e206b41f0032 | 138 | return head; |
kenjiArai | 0:e206b41f0032 | 139 | } else { // full |
kenjiArai | 0:e206b41f0032 | 140 | return buffer_size; |
kenjiArai | 0:e206b41f0032 | 141 | } |
kenjiArai | 0:e206b41f0032 | 142 | } |
kenjiArai | 0:e206b41f0032 | 143 | |
kenjiArai | 0:e206b41f0032 | 144 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 145 | void RingBuff<T>::ring_clear_buf (void){ |
kenjiArai | 0:e206b41f0032 | 146 | head = tail = 0; |
kenjiArai | 0:e206b41f0032 | 147 | } |
kenjiArai | 0:e206b41f0032 | 148 | |
kenjiArai | 0:e206b41f0032 | 149 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 150 | int16_t RingBuff<T>::ring_is_buf_empty (void){ |
kenjiArai | 0:e206b41f0032 | 151 | if (head == tail){ |
kenjiArai | 0:e206b41f0032 | 152 | return 1; // Empty |
kenjiArai | 0:e206b41f0032 | 153 | } else { |
kenjiArai | 0:e206b41f0032 | 154 | return 0; |
kenjiArai | 0:e206b41f0032 | 155 | } |
kenjiArai | 0:e206b41f0032 | 156 | } |
kenjiArai | 0:e206b41f0032 | 157 | |
kenjiArai | 0:e206b41f0032 | 158 | template <typename T> |
kenjiArai | 0:e206b41f0032 | 159 | void RingBuff<T>::debug_print_all_buffer (void){ |
kenjiArai | 0:e206b41f0032 | 160 | printf("\r\nhead = %d, tail = %d, size =%d \r\n", head, tail, ring_get_buf_size()); |
kenjiArai | 0:e206b41f0032 | 161 | #if 1 |
kenjiArai | 0:e206b41f0032 | 162 | printf("%d, %.0f\r\n", head, (double)buff[head]); |
kenjiArai | 0:e206b41f0032 | 163 | printf("%d, %.0f\r\n", head-1, (double)buff[head-1]); |
kenjiArai | 0:e206b41f0032 | 164 | printf("%d, %.0f\r\n", head-2, (double)buff[head-2]); |
kenjiArai | 0:e206b41f0032 | 165 | printf("%d, %.0f\r\n", head-3, (double)buff[head-3]); |
kenjiArai | 0:e206b41f0032 | 166 | printf("%d, %.0f\r\n", head-4, (double)buff[head-4]); |
kenjiArai | 0:e206b41f0032 | 167 | printf("%d, %.0f\r\n", head-5, (double)buff[head-5]); |
kenjiArai | 0:e206b41f0032 | 168 | printf("%d, %.0f\r\n", head-6, (double)buff[head-6]); |
kenjiArai | 0:e206b41f0032 | 169 | #else |
kenjiArai | 0:e206b41f0032 | 170 | printf("print all buffer contents\r\n"); |
kenjiArai | 0:e206b41f0032 | 171 | for (uint16_t n = 0;n < buffer_size; n++){ |
kenjiArai | 0:e206b41f0032 | 172 | printf("%d, %.0f\r\n", (double)buff[n]); |
kenjiArai | 0:e206b41f0032 | 173 | } |
kenjiArai | 0:e206b41f0032 | 174 | #endif |
kenjiArai | 0:e206b41f0032 | 175 | } |
kenjiArai | 0:e206b41f0032 | 176 | |
kenjiArai | 0:e206b41f0032 | 177 | //------------------------------------------------------------------------------ |
kenjiArai | 0:e206b41f0032 | 178 | // force compiler to create code for template |
kenjiArai | 0:e206b41f0032 | 179 | //------------------------------------------------------------------------------ |
kenjiArai | 0:e206b41f0032 | 180 | template class RingBuff<uint64_t>; |
kenjiArai | 0:e206b41f0032 | 181 | template class RingBuff<uint32_t>; |
kenjiArai | 0:e206b41f0032 | 182 | template class RingBuff<uint16_t>; |
kenjiArai | 0:e206b41f0032 | 183 |