BayEOS-Arduino  1.8.0_0.0.4
BayEOSBuffer.cpp
1 #include "BayEOSBuffer.h"
2 
3 BayEOSBuffer::BayEOSBuffer(void) {
4 #if SERIAL_DEBUG
5 // Serial.println("BayEOSBuffer");
6 #endif
7  _rtc = NULL;
8  _framesDiscarded = 0;
9 }
10 
11 
12 uint8_t BayEOSBuffer::b_seek(unsigned long pos) {
13  _pos = pos;
14  return seek(pos);
15 }
16 uint8_t BayEOSBuffer::b_write(const uint8_t b) {
17  _res = write(b);
18  _pos++;
19  if (_pos == _max_length) {
20  b_seek(0);
21  }
22  return _res;
23 
24 }
25 uint8_t BayEOSBuffer::b_write(const uint8_t *b, uint8_t length) {
26  //calculate length for first write
27  _res = (((unsigned long) (_pos + length)) <= _max_length ?
28  length : _max_length - _pos);
29  _res = write(b, _res);
30  if (_res<0)
31  return 0; //error!!
32  _pos += _res;
33  if (_pos == _max_length) {
34  b_seek(0);
35  }
36  if (_res < length) {
37  //second write
38  _res = write(b + _res, length - _res);
39  if(_res<0)
40  return 0; //error!!
41  _pos+=_res;
42  _res = length;
43  }
44  return _res;
45 
46 }
47 
48 int BayEOSBuffer::b_read() {
49  _res = read();
50  _pos++;
51  if (_pos == _max_length) {
52  b_seek(0);
53  }
54  return _res;
55 }
56 
57 int BayEOSBuffer::b_read(uint8_t *dest, int length) {
58  //calculate length for first read
59  _res = (((unsigned long) (_pos + length)) <= _max_length ?
60  length : _max_length - _pos);
61  _res = read(dest, _res);
62  if (_res == -1)
63  return -1;
64  _pos += _res;
65  if (_pos == _max_length) {
66  b_seek(0);
67  }
68  if (_res < length) {
69  //second read
70  _res = read(dest + _res, length - _res);
71  if (_res == -1) return -1;
72  _pos = _res;
73  _res = length;
74  }
75  return _res;
76 }
77 
78 unsigned long BayEOSBuffer::available(void) {
79  return ((unsigned long) (_max_length + _write_pos - _read_pos))
80  % _max_length;
81 }
82 
83 uint8_t BayEOSBuffer::freeSpace(uint8_t length) {
84  if (_end == _write_pos)
85  return (_max_length > (unsigned long) length);
86 #if SERIAL_DEBUG
87  Serial.print("Space: ");
88  Serial.print(length);
89  Serial.print(" ");
90  Serial.print((((unsigned long) (_max_length + _end - _write_pos)) % _max_length));
91  Serial.print(" Free: ");
92  Serial.println((((unsigned long) (_max_length + _end - _write_pos)) % _max_length)> (unsigned long) length);
93 #endif
94  return (((unsigned long) (_max_length + _end - _write_pos)) % _max_length)
95  > (unsigned long) length;
96 }
97 
98 int BayEOSBuffer::readPacket(uint8_t *dest) {
99  return b_read(dest, _packet_length);
100 }
101 
102 uint8_t BayEOSBuffer::readBinary(unsigned long pos, uint8_t length,
103  uint8_t *dest) {
104  b_seek(pos);
105  return b_read(dest, length);
106 }
107 
108 uint8_t BayEOSBuffer::readBinary(unsigned long pos, unsigned long stop,
109  uint8_t length, uint8_t *dest) {
110  b_seek(pos);
111  unsigned long remaining= ((unsigned long) (_max_length + stop - pos))
112  % _max_length;
113  if(remaining<length) length=remaining;
114  return b_read(dest, length);
115 }
116 
117 void BayEOSBuffer::set(unsigned long pos) {
118 #if SERIAL_DEBUG
119  Serial.print("Set: ");
120  Serial.println(pos);
121 #endif
122 
123  _read_pos = pos;
124  _write_pos = pos;
125  _end = pos;
126 #if SERIAL_DEBUG
127  Serial.print(" --end: ");
128  Serial.print(_end);
129  Serial.print(" -- write: ");
130  Serial.print(_write_pos);
131  Serial.print(" -- read: ");
132  Serial.println(_read_pos);
133 #endif
134 }
135 
136 void BayEOSBuffer::seekReadPointer(unsigned long pos) {
137  _read_pos = pos;
138 }
139 
141  set(0);
142  resetStorage();
143 }
144 
146  return initPacket(_read_pos);
147 }
148 
149 uint8_t BayEOSBuffer::initPacket(unsigned long pos) {
150  uint8_t* p = (uint8_t*) &_millis;
151  b_seek(pos);
152  b_read(p, 4);
153  _packet_length = b_read();
154 #if SERIAL_DEBUG
155  Serial.println("init Packet: ");
156  Serial.print("length: ");
157  Serial.print(_packet_length);
158  Serial.print(" --end: ");
159  Serial.print(_end);
160  Serial.print(" -- write: ");
161  Serial.print(_write_pos);
162  Serial.print(" -- read: ");
163  Serial.println(_read_pos);
164 #endif
165  return _packet_length;
166 }
167 
168 void BayEOSBuffer::next(void) {
169  if (_packet_length == 0) {
170 #if SERIAL_DEBUG
171  Serial.println("Packet Length is 0. This should not happen...");
172 #endif
173  _read_pos = _write_pos;
174  } else {
175  _read_pos += _packet_length + 5;
176 #if SERIAL_DEBUG
177  Serial.println("next(): Set _read_pos");
178 #endif
179  }
180 
181  if (_read_pos >= _max_length)
182  _read_pos -= _max_length;
183 #if SERIAL_DEBUG
184  Serial.print("Next Packet: ");
185  Serial.print("length: ");
186  Serial.print(_packet_length);
187  Serial.print(" --end: ");
188  Serial.print(_end);
189  Serial.print(" -- write: ");
190  Serial.print(_write_pos);
191  Serial.print(" -- read: ");
192  Serial.println(_read_pos);
193 #endif
194 }
195 
196 uint8_t BayEOSBuffer::addPacket(const uint8_t *payload, uint8_t length) {
197  uint8_t move_read_pos = 0;
198  while (!freeSpace(length+5)) {
199  //Write Pointer überholt END Pointer
200  if (_end == _read_pos) {
201  _framesDiscarded = 1;
202  move_read_pos = 1;
203 #if SERIAL_DEBUG
204  Serial.println("Verwerfe Paket");
205 #endif
206  }
207  _end += initPacket(_end) + 5;
208  if (_end >= _max_length)
209  _end -= _max_length;
210  if (move_read_pos)
211  _read_pos = _end;
212  }
213 
214  b_seek(_write_pos);
215 
216  unsigned long time = getTime();
217  uint8_t* b = (uint8_t *) &time;
218  b_write(b, 4);
219  b_write(length);
220  b_write(payload, length);
221 
222  _write_pos += length + 5;
223  if (_write_pos >= _max_length)
224  _write_pos -= _max_length;
225 
226 #if SERIAL_DEBUG
227  Serial.println();
228  Serial.print("end: ");
229  Serial.print(_end);
230  Serial.print(" -- write: ");
231  Serial.print(_write_pos);
232  Serial.print(" -- read: ");
233  Serial.println(_read_pos);
234  Serial.println();
235 #endif
236  flush();
237  return length + 5;
238 }
239 
241  return _packet_length;
242 }
243 
244 unsigned long BayEOSBuffer::packetMillis(void){
245  return _millis;
246 }
247 
248 
249 void BayEOSBuffer::setRTC(RTC& rtc,boolean absolute_time) {
250  _rtc = &rtc;
251  _absoluteTime=absolute_time;
252 }
253 
254 uint8_t BayEOSBuffer::rtc(void){
255  if(_rtc!=NULL) return 1;
256  return 0;
257 }
258 
259 
260 unsigned long BayEOSBuffer::getTime(void){
261  if(_rtc!=NULL){
262  //DateTime now=_rtc->now();
263  return _rtc->now().get();
264  }
265  return millis();
266 }
267 
268 unsigned long BayEOSBuffer::writePos(void){ return _write_pos; }
269 unsigned long BayEOSBuffer::readPos(void){ return _read_pos; }
270 unsigned long BayEOSBuffer::endPos(void){ return _end; }
271 unsigned long BayEOSBuffer::length(void){ return _max_length; }
272 
273 
274 
275 //PROGMEM prog_uint8_t daysInMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
276 
277 static uint8_t daysInMonth[] =
278  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
279 
280 // number of days since 2000/01/01, valid for 2001..2099
281 static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) {
282  if (y >= 2000)
283  y -= 2000;
284  uint16_t days = d;
285  for (uint8_t i = 1; i < m; ++i)
286  days += daysInMonth[(i - 1)];
287 // days += pgm_read_byte(daysInMonth + i - 1);
288  if (m > 2 && y % 4 == 0)
289  ++days;
290  return days + 365 * y + (y + 3) / 4 - 1;
291 }
292 
293 static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) {
294  return ((days * 24L + h) * 60 + m) * 60 + s;
295 }
296 
298 // DateTime implementation - ignores time zones and DST changes
299 // NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second
300 
301 DateTime::DateTime(long t) {
302  ss = t % 60;
303  t /= 60;
304  mm = t % 60;
305  t /= 60;
306  hh = t % 24;
307  uint16_t days = t / 24;
308  uint8_t leap;
309  for (yOff = 0;; ++yOff) {
310  leap = yOff % 4 == 0;
311  if (days < (uint16_t) 365 + leap)
312  break;
313  days -= 365 + leap;
314  }
315  for (m = 1;; ++m) {
316  uint8_t daysPerMonth = daysInMonth[(m - 1)]; //pgm_read_byte(daysInMonth + m - 1);
317  if (leap && m == 2)
318  ++daysPerMonth;
319  if (days < daysPerMonth)
320  break;
321  days -= daysPerMonth;
322  }
323  d = days + 1;
324 }
325 
326 DateTime::DateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour,
327  uint8_t min, uint8_t sec) {
328  if (year >= 2000)
329  year -= 2000;
330  yOff = year;
331  m = month;
332  d = day;
333  hh = hour;
334  mm = min;
335  ss = sec;
336 }
337 
338 static uint8_t conv2d(const char* p) {
339  uint8_t v = 0;
340  if ('0' <= *p && *p <= '9')
341  v = *p - '0';
342  return 10 * v + *++p - '0';
343 }
344 
345 // A convenient constructor for using "the compiler's time":
346 // DateTime now (__DATE__, __TIME__);
347 // NOTE: using PSTR would further reduce the RAM footprint
348 DateTime::DateTime(const char* date, const char* time) {
349  // sample input: date = "Dec 26 2009", time = "12:34:56"
350  yOff = conv2d(date + 9);
351  // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
352  switch (date[0]) {
353  case 'J':
354  m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7;
355  break;
356  case 'F':
357  m = 2;
358  break;
359  case 'A':
360  m = date[2] == 'r' ? 4 : 8;
361  break;
362  case 'M':
363  m = date[2] == 'r' ? 3 : 5;
364  break;
365  case 'S':
366  m = 9;
367  break;
368  case 'O':
369  m = 10;
370  break;
371  case 'N':
372  m = 11;
373  break;
374  case 'D':
375  m = 12;
376  break;
377  }
378 
379  d = conv2d(date + 4);
380  hh = conv2d(time);
381  mm = conv2d(time + 3);
382  ss = conv2d(time + 6);
383 }
384 
385 uint8_t DateTime::dayOfWeek() const {
386  uint16_t day = get() / SECONDS_PER_DAY;
387  return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6
388 }
389 
390 long DateTime::get() const {
391  uint16_t days = date2days(yOff, m, d);
392  return time2long(days, hh, mm, ss);
393 }
394 
395 uint16_t DateTime::year() const { return 2000 + yOff; }
396 uint8_t DateTime::month() const { return m; }
397 uint8_t DateTime::day() const { return d; }
398 uint8_t DateTime::hour() const { return hh; }
399 uint8_t DateTime::minute() const { return mm; }
400 uint8_t DateTime::second() const { return ss; }
401 
void seekReadPointer(unsigned long pos)
int readPacket(uint8_t *dest)
void reset(void)
void set(unsigned long pos)
uint8_t initPacket(unsigned long pos)
uint8_t rtc(void)
unsigned long packetMillis(void)
void next(void)
uint8_t freeSpace(uint8_t length)
uint8_t readBinary(unsigned long pos, uint8_t length, uint8_t *dest)
unsigned long available(void)
void setRTC(RTC &rtc, boolean absolute_time=true)
uint8_t packetLength(void)
uint8_t addPacket(const uint8_t *payload, uint8_t length)
uint8_t initNextPacket(void)