16
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
17
*/
18
18
19
+ #ifdef __cplusplus
20
+
19
21
#ifndef _RING_BUFFER_
20
22
#define _RING_BUFFER_
21
23
25
27
// using a ring buffer (I think), in which head is the index of the location
26
28
// to which to write the next incoming character and tail is the index of the
27
29
// location from which to read.
30
+ #define SERIAL_BUFFER_SIZE 64
28
31
29
- #define RINGBUFFER_HAS_ADDITIONAL_STORAGE_API
30
-
31
- #ifdef RINGBUFFER_FORCE_SMALL_SIZE
32
- typedef uint8_t rb_index_type;
33
- #else
34
- typedef unsigned int rb_index_type;
35
- #endif
36
-
37
- class RingBuffer
32
+ template <int N>
33
+ class RingBufferN
38
34
{
39
- public:
40
- RingBuffer ( rb_index_type size = 64 ) ;
35
+ public:
36
+ uint8_t _aucBuffer[N] ;
37
+ volatile int _iHead ;
38
+ volatile int _iTail ;
39
+
40
+ public:
41
+ RingBufferN ( void ) ;
41
42
void store_char ( uint8_t c ) ;
42
43
void clear ();
43
44
int read_char ();
44
45
int available ();
45
46
int availableForStore ();
46
47
int peek ();
47
48
bool isFull ();
48
- void addStorage (uint8_t * _buffer, rb_index_type _size) {
49
- additionalSize = _size;
50
- additionalBuffer = _buffer;
51
- };
52
-
53
- private:
54
- rb_index_type nextIndex (rb_index_type index);
55
- uint8_t * additionalBuffer;
56
- int additionalSize = 0 ;
57
- rb_index_type size;
58
- uint8_t * _aucBuffer;
59
- volatile rb_index_type _iHead ;
60
- volatile rb_index_type _iTail ;
49
+
50
+ private:
51
+ int nextIndex (int index);
61
52
};
62
53
54
+ typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
55
+
56
+
57
+ template <int N>
58
+ RingBufferN<N>::RingBufferN( void )
59
+ {
60
+ memset ( _aucBuffer, 0 , N ) ;
61
+ clear ();
62
+ }
63
+
64
+ template <int N>
65
+ void RingBufferN<N>::store_char( uint8_t c )
66
+ {
67
+ int i = nextIndex (_iHead);
68
+
69
+ // if we should be storing the received character into the location
70
+ // just before the tail (meaning that the head would advance to the
71
+ // current location of the tail), we're about to overflow the buffer
72
+ // and so we don't write the character or advance the head.
73
+ if ( i != _iTail )
74
+ {
75
+ _aucBuffer[_iHead] = c ;
76
+ _iHead = i ;
77
+ }
78
+ }
79
+
80
+ template <int N>
81
+ void RingBufferN<N>::clear()
82
+ {
83
+ _iHead = 0 ;
84
+ _iTail = 0 ;
85
+ }
86
+
87
+ template <int N>
88
+ int RingBufferN<N>::read_char()
89
+ {
90
+ if (_iTail == _iHead)
91
+ return -1 ;
92
+
93
+ uint8_t value = _aucBuffer[_iTail];
94
+ _iTail = nextIndex (_iTail);
95
+
96
+ return value;
97
+ }
98
+
99
+ template <int N>
100
+ int RingBufferN<N>::available()
101
+ {
102
+ int delta = _iHead - _iTail;
103
+
104
+ if (delta < 0 )
105
+ return N + delta;
106
+ else
107
+ return delta;
108
+ }
109
+
110
+ template <int N>
111
+ int RingBufferN<N>::availableForStore()
112
+ {
113
+ if (_iHead >= _iTail)
114
+ return N - 1 - _iHead + _iTail;
115
+ else
116
+ return _iTail - _iHead - 1 ;
117
+ }
118
+
119
+ template <int N>
120
+ int RingBufferN<N>::peek()
121
+ {
122
+ if (_iTail == _iHead)
123
+ return -1 ;
124
+
125
+ return _aucBuffer[_iTail];
126
+ }
127
+
128
+ template <int N>
129
+ int RingBufferN<N>::nextIndex(int index)
130
+ {
131
+ return (uint32_t )(index + 1 ) % N;
132
+ }
133
+
134
+ template <int N>
135
+ bool RingBufferN<N>::isFull()
136
+ {
137
+ return (nextIndex (_iHead) == _iTail);
138
+ }
139
+
63
140
#endif /* _RING_BUFFER_ */
141
+
142
+ #endif /* __cplusplus */
0 commit comments