very special ring buffer. This is only for fc_GPS1PPS_F746_F4xx library

Dependents:   fc_GPS1PPS_f746_f4xx Frq_cuntr_Nucleo-F746ZG

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?

UserRevisionLine numberNew 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