very special ring buffer. This is only for fc_GPS1PPS_F746_F4xx library
Dependents: fc_GPS1PPS_f746_f4xx Frq_cuntr_Nucleo-F746ZG
RingBuff.cpp
- Committer:
- kenjiArai
- Date:
- 2016-11-16
- Revision:
- 0:e206b41f0032
File content as of revision 0:e206b41f0032:
/* * 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>;