Skip to content

Commit 0d30531

Browse files
committed
Add generic uint8_t RingBuffer class
* cloned from samd core * implement addStorage() API to allow static/dynamic size increase
1 parent e7cda3c commit 0d30531

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

Diff for: api/RingBuffer.cpp

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
Copyright (c) 2014 Arduino. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#include "RingBuffer.h"
20+
#include <string.h>
21+
22+
RingBuffer::RingBuffer( void )
23+
{
24+
memset( _aucBuffer, 0, RINGBUFFER_SIZE ) ;
25+
clear();
26+
}
27+
28+
void RingBuffer::store_char( uint8_t c )
29+
{
30+
int i = nextIndex(_iHead);
31+
32+
// if we should be storing the received character into the location
33+
// just before the tail (meaning that the head would advance to the
34+
// current location of the tail), we're about to overflow the buffer
35+
// and so we don't write the character or advance the head.
36+
if ( i != _iTail )
37+
{
38+
if (_iHead < RINGBUFFER_SIZE) {
39+
_aucBuffer[_iHead] = c ;
40+
} else {
41+
additionalBuffer[_iHead - RINGBUFFER_SIZE] = c;
42+
}
43+
_iHead = i ;
44+
}
45+
}
46+
47+
void RingBuffer::clear()
48+
{
49+
_iHead = 0;
50+
_iTail = 0;
51+
}
52+
53+
int RingBuffer::read_char()
54+
{
55+
if(_iTail == _iHead)
56+
return -1;
57+
58+
uint8_t value;
59+
if (_iTail < RINGBUFFER_SIZE) {
60+
value = _aucBuffer[_iTail];
61+
} else {
62+
value = additionalBuffer[_iTail - RINGBUFFER_SIZE];
63+
}
64+
_iTail = nextIndex(_iTail);
65+
66+
return value;
67+
}
68+
69+
int RingBuffer::available()
70+
{
71+
int delta = _iHead - _iTail;
72+
73+
if(delta < 0)
74+
return RINGBUFFER_SIZE + additionalSize + delta;
75+
else
76+
return delta;
77+
}
78+
79+
int RingBuffer::peek()
80+
{
81+
if(_iTail == _iHead)
82+
return -1;
83+
84+
if (_iTail < RINGBUFFER_SIZE) {
85+
return _aucBuffer[_iTail];
86+
} else {
87+
return additionalBuffer[_iTail - RINGBUFFER_SIZE];
88+
}
89+
}
90+
91+
int RingBuffer::nextIndex(int index)
92+
{
93+
return (uint32_t)(index + 1) % (RINGBUFFER_SIZE + additionalSize);
94+
}
95+
96+
bool RingBuffer::isFull()
97+
{
98+
return (nextIndex(_iHead) == _iTail);
99+
}

Diff for: api/RingBuffer.h

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright (c) 2014 Arduino. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#ifndef _RING_BUFFER_
20+
#define _RING_BUFFER_
21+
22+
#include <stdint.h>
23+
24+
// Define constants and variables for buffering incoming serial data. We're
25+
// using a ring buffer (I think), in which head is the index of the location
26+
// to which to write the next incoming character and tail is the index of the
27+
// location from which to read.
28+
29+
#define RINGBUFFER_SIZE 64
30+
31+
class RingBuffer
32+
{
33+
public:
34+
uint8_t _aucBuffer[RINGBUFFER_SIZE] ;
35+
int _iHead ;
36+
int _iTail ;
37+
38+
public:
39+
RingBuffer( void ) ;
40+
void store_char( uint8_t c ) ;
41+
void clear();
42+
int read_char();
43+
int available();
44+
int peek();
45+
bool isFull();
46+
void addStorage(uint8_t* _buffer, int _size) {
47+
additionalSize = _size;
48+
additionalBuffer = _buffer;
49+
};
50+
51+
private:
52+
int nextIndex(int index);
53+
uint8_t* additionalBuffer;
54+
int additionalSize = 0;
55+
};
56+
57+
#endif /* _RING_BUFFER_ */

0 commit comments

Comments
 (0)