very special ring buffer. This is only for fc_GPS1PPS_F746_F4xx library

Dependents:   fc_GPS1PPS_f746_f4xx Frq_cuntr_Nucleo-F746ZG

Revision:
0:e206b41f0032
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RingBuff.cpp	Wed Nov 16 13:08:35 2016 +0000
@@ -0,0 +1,183 @@
+/*
+ * mbed Library program / Ring Buffer
+ *  CAUTION!!
+ *  This is very special ring buffer which save newest data and remember
+ *   some amount of old data. 
+ *  If write newest data into the buffer, lose oldest data.
+ *  Don't use this library as normal type of a FIFO ring buffer!!
+ *
+ * Copyright (c) 2016 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created:    September 18th, 2016
+ *      Revised:    November   8th, 2016
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include "mbed.h"
+#include "RingBuff.h"
+
+template <typename T>
+RingBuff<T>::RingBuff(const int16_t size)
+    :buffer_size(size)
+{
+    head = tail = 0;
+    buff = (T *)malloc(buffer_size * sizeof(T));
+}
+
+template <typename T>
+RingBuff<T>::~RingBuff()
+{
+    free(buff);
+}
+
+//------------------------------------------------------------------------------
+// Ring Buffer Control
+//------------------------------------------------------------------------------
+template <typename T>
+int16_t RingBuff<T>::ring_is_buf_full (void){
+    if (tail == head + 1 ||
+        (head == buffer_size - 1 && tail == 0)){
+        return 1;
+    }else {
+        return 0;
+    }
+}
+
+template <typename T>
+void RingBuff<T>::ring_put_dt (T dt){
+    if (ring_is_buf_full()){
+        buff[head++] = dt;
+        tail++;
+        if (head == buffer_size){
+            head = 0;
+        }
+        if (tail == buffer_size){
+            tail = 0;
+        }
+    } else {    // Not full yet
+        buff[head++] = dt;
+        if (head == buffer_size){
+            head = 0;
+            tail = 1;
+        }
+    }
+}
+
+template <typename T>
+T RingBuff<T>::ring_get_newest_dt (void){
+    T dt;
+
+    if (ring_is_buf_empty()){
+        return 0;
+    }
+    do{ // check interrupt
+        head_temp = head;
+        if (head == 0){
+            dt = buff[buffer_size - 1];
+        } else {
+            dt = buff[head - 1];
+        }
+    } while(head != head_temp);
+    return dt;
+}
+
+template <typename T>
+T RingBuff<T>::ring_get_pointed_dt (int16_t offset){
+    int16_t hd;
+    T dt;
+
+    if (ring_is_buf_empty()){
+        return 0;
+    }
+    do {
+        head_temp = head;
+        int16_t sz = ring_get_buf_size();
+        if (head == 0){
+            hd = buffer_size - 1;
+        } else {
+            hd = head - 1;
+        }
+        if (sz == buffer_size){ // Buffer is full
+            if (sz < offset){   // error
+                dt = 0;
+            } else {            // data is in buffer
+                if (hd >= offset){
+                    dt = buff[hd - offset];
+                } else {
+                    dt = buff[buffer_size - (offset - hd)];
+                }
+            }
+        } else {                // Buffer is not full
+            if (sz <= offset){  // error
+                dt = 0;
+            } else {
+                dt = buff[hd - offset];
+            }
+        }
+    } while(head != head_temp);
+    return dt;
+}
+
+
+template <typename T>
+int16_t RingBuff<T>::ring_get_buf_size (void){
+    if (head == tail){      // empty
+        return 0;
+    }
+    if (head > tail){       // Not full yet
+        return head;
+    } else {                // full
+        return buffer_size;
+    }
+}
+
+template <typename T>
+void RingBuff<T>::ring_clear_buf (void){
+    head = tail = 0;
+}
+
+template <typename T>
+int16_t RingBuff<T>::ring_is_buf_empty (void){
+    if (head == tail){
+        return 1;           // Empty
+    } else {
+        return 0;
+    }
+}
+
+template <typename T>
+void RingBuff<T>::debug_print_all_buffer (void){
+    printf("\r\nhead = %d, tail = %d, size =%d \r\n", head, tail, ring_get_buf_size());
+#if 1
+    printf("%d, %.0f\r\n", head,   (double)buff[head]);
+    printf("%d, %.0f\r\n", head-1, (double)buff[head-1]);
+    printf("%d, %.0f\r\n", head-2, (double)buff[head-2]);
+    printf("%d, %.0f\r\n", head-3, (double)buff[head-3]);
+    printf("%d, %.0f\r\n", head-4, (double)buff[head-4]);
+    printf("%d, %.0f\r\n", head-5, (double)buff[head-5]);
+    printf("%d, %.0f\r\n", head-6, (double)buff[head-6]); 
+#else
+    printf("print all buffer contents\r\n");
+    for (uint16_t n = 0;n < buffer_size; n++){
+        printf("%d, %.0f\r\n", (double)buff[n]);
+    }
+#endif
+}
+
+//------------------------------------------------------------------------------
+// force compiler to create code for template
+//------------------------------------------------------------------------------
+template class RingBuff<uint64_t>;
+template class RingBuff<uint32_t>;
+template class RingBuff<uint16_t>;
+