enabled specifying numeric config values using all strtof capabilities
[clinton/Smoothieware.git] / src / libs / RingBuffer.h
CommitLineData
df27a6a3 1/*
4cff3ded
AW
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
df27a6a3 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6bb45cd1 6
4cff3ded
AW
7 With chucks taken from http://en.wikipedia.org/wiki/Circular_buffer, see licence there also
8*/
9
10#ifndef RINGBUFFER_H
11#define RINGBUFFER_H
12
13
14template<class kind, int length> class RingBuffer {
15 public:
16 RingBuffer();
17 int size();
18 int capacity();
13e4a3f9 19 int next_block_index(int index);
ded56b35 20 int prev_block_index(int index);
4cff3ded
AW
21 void push_back(kind object);
22 void pop_front(kind &object);
84d01c37 23 kind* get_head_ref();
6bb45cd1 24 kind* get_tail_ref();
4cff3ded
AW
25 void get( int index, kind &object);
26 kind* get_ref( int index);
8f0b227c 27 void delete_tail();
4cff3ded
AW
28
29 kind buffer[length];
d4ee6ee2 30 volatile int tail;
ed1517a1 31 volatile int head;
4cff3ded
AW
32};
33
d4ee6ee2 34#include "sLPC17xx.h"
4cff3ded
AW
35
36template<class kind, int length> RingBuffer<kind, length>::RingBuffer(){
ed1517a1 37 this->tail = this->head = 0;
4cff3ded
AW
38}
39
40template<class kind, int length> int RingBuffer<kind, length>::capacity(){
41 return length-1;
42}
43
44template<class kind, int length> int RingBuffer<kind, length>::size(){
ed1517a1 45 //return((this->tail>this->head)?length:0)+this->head-tail;
d4ee6ee2 46 __disable_irq();
ed1517a1 47 int i = head - tail + ((tail > head)?length:0);
d4ee6ee2
JM
48 __enable_irq();
49 return i;
4cff3ded
AW
50}
51
13e4a3f9
AW
52template<class kind, int length> int RingBuffer<kind, length>::next_block_index(int index){
53 index++;
54 if (index == length) { index = 0; }
55 return(index);
56}
57
ded56b35
AW
58template<class kind, int length> int RingBuffer<kind, length>::prev_block_index(int index){
59 if (index == 0) { index = length; }
60 index--;
61 return(index);
62}
63
4cff3ded 64template<class kind, int length> void RingBuffer<kind, length>::push_back(kind object){
ed1517a1
MM
65 this->buffer[this->head] = object;
66 this->head = (head+1)&(length-1);
4cff3ded
AW
67}
68
84d01c37 69template<class kind, int length> kind* RingBuffer<kind, length>::get_head_ref(){
ed1517a1 70 return &(buffer[head]);
6476be0a
AG
71}
72
6bb45cd1
JM
73template<class kind, int length> kind* RingBuffer<kind, length>::get_tail_ref(){
74 return &(buffer[tail]);
75}
76
4cff3ded
AW
77template<class kind, int length> void RingBuffer<kind, length>::get(int index, kind &object){
78 int j= 0;
ed1517a1
MM
79 int k= this->tail;
80 while (k != this->head){
4cff3ded
AW
81 if (j == index) break;
82 j++;
83 k= (k + 1) & (length - 1);
84 }
df27a6a3 85 // TODO : this checks wether we are asked a value out of range
ed1517a1 86 //if (k == this->head){
df27a6a3 87 // return NULL;
4464301d 88 //}
4cff3ded
AW
89 object = this->buffer[k];
90}
91
92
93template<class kind, int length> kind* RingBuffer<kind, length>::get_ref(int index){
94 int j= 0;
ed1517a1
MM
95 int k= this->tail;
96 while (k != this->head){
4cff3ded
AW
97 if (j == index) break;
98 j++;
99 k= (k + 1) & (length - 1);
100 }
df27a6a3 101 // TODO : this checks wether we are asked a value out of range
ed1517a1 102 if (k == this->head){
4cff3ded
AW
103 return NULL;
104 }
105 return &(this->buffer[k]);
106}
107
108template<class kind, int length> void RingBuffer<kind, length>::pop_front(kind &object){
ed1517a1
MM
109 object = this->buffer[this->tail];
110 this->tail = (this->tail+1)&(length-1);
4cff3ded
AW
111}
112
8f0b227c 113template<class kind, int length> void RingBuffer<kind, length>::delete_tail(){
13e4a3f9
AW
114 //kind dummy;
115 //this->pop_front(dummy);
ed1517a1 116 this->tail = (this->tail+1)&(length-1);
4cff3ded
AW
117}
118
119
120#endif