very special ring buffer. This is only for fc_GPS1PPS_F746_F4xx library

Dependents:   fc_GPS1PPS_f746_f4xx Frq_cuntr_Nucleo-F746ZG

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Wed Nov 16 13:08:35 2016 +0000
Commit message:
very special ring buffer only for Frequency counter

Changed in this revision

RingBuff.cpp Show annotated file Show diff for this revision Revisions of this file
RingBuff.h Show annotated file Show diff for this revision Revisions of this file
--- /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>;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RingBuff.h	Wed Nov 16 13:08:35 2016 +0000
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef _RINGBUFF_H
+#define _RINGBUFF_H
+
+#define BUFFER_SIZE 4096
+
+template <typename T>
+class RingBuff
+{
+
+private:
+    const int16_t buffer_size;
+    int16_t head;
+    int16_t head_temp;
+    int16_t tail;
+    int16_t tail_temp;
+    T *    buff;
+
+public:
+    RingBuff(const int16_t size=BUFFER_SIZE);
+    ~RingBuff();
+
+    void        ring_put_dt (T dt);
+    T           ring_get_newest_dt (void);
+    T           ring_get_pointed_dt (int16_t offset);
+    int16_t     ring_is_buf_full (void);
+    int16_t     ring_get_buf_size (void);
+    void        ring_clear_buf (void);
+    int16_t     ring_is_buf_empty (void);
+    void        debug_print_all_buffer(void);
+
+};
+
+#endif /* _RINGBUFF_H */