EEPROMextent
Arduino EEPROM library
CircularBuffer.cpp
1 /*************************************************************
2 project: <EEPROMextent>
3 author: <Thierry PARIS>
4 description: <Class for a circular buffer of data stored in EEPROM>
5 *************************************************************/
6 
7 #include "CircularBuffer.hpp"
8 
9 /*
10 A circular buffer is a way to reduce the use of each EEPROM cell,
11 and improve life time of the full EEPROM memory.
12 An index of bytes is stored at the beginning of the area.
13 Each index represents a data area.
14 
15 |0|1|2|3|4||---0---|---1---|---2---|---3---|---4---|
16 */
17 
18 byte CircularBuffer::FindEnd()
19 {
20  /*
21  prev is the previous value from the item in the list
22  |..|..|prev|i|..|..|
23 
24  we begin with the first item of the list. In this case, the previous is the last one:
25  |i|..|..|..|..|prev|
26  */
27 
28  int prevpos = this->startListPos + this->replicaNumber - 1;
29  byte prev = EEPROMextent.readByte(prevpos);
30 
31  for (int i = 0; i < this->replicaNumber; i++)
32  {
33  int pos = this->startListPos + i;
34 
35  // Checks it the current value is really the previous value + 1 :
36  // 4 must be 3+1, 0 must be 255 + 1 !
37  if (prev + 1 != EEPROMextent.readByte(pos))
38  return prevpos - this->startListPos;
39 
40  prev = EEPROMextent.readByte(pos);
41  prevpos = pos;
42  }
43 
44  // Should never reach this code !
45 
46  return 255;
47 }
48 
49 void * CircularBuffer::read(void* outpData)
50 {
51  byte place = this->FindEnd();
52  eeprom_read_block((uint8_t *)outpData, (const uint8_t *)INT64 (this->startListPos + this->replicaNumber + (this->elementSize * place)), this->elementSize);
53 
54  return outpData;
55 }
56 
57 void CircularBuffer::write(void* inpData, bool inUpdate)
58 {
59  byte place = this->FindEnd();
60  byte itemNb = EEPROMextent.readByte(this->startListPos + place);
61 
62  place++;
63  if (place >= this->replicaNumber)
64  place = 0;
65 
66  if (inUpdate)
67  {
68  EEPROMextent.updateByte(this->startListPos + place, ++itemNb);
69  eeprom_update_block((const uint8_t *)inpData, (uint8_t *)INT64 (this->startListPos + this->replicaNumber + (this->elementSize * place)), this->elementSize);
70  }
71  else
72  {
73  EEPROMextent.writeByte(this->startListPos + place, ++itemNb);
74  eeprom_write_block((const uint8_t *)inpData, (uint8_t *)INT64 (this->startListPos + this->replicaNumber + (this->elementSize * place)), this->elementSize);
75  }
76 }
77 
79 {
80  EEPROMextent.clear(this->startListPos, (this->elementSize + 1) * this->replicaNumber);
81 }
82 
84 {
85  byte place = this->FindEnd();
86  return this->startListPos + this->replicaNumber + (this->elementSize * place);
87 }
88 
90 {
91  byte place = this->FindEnd();
92  byte itemNb = EEPROMextent.readByte(this->startListPos + place);
93 
94  place++;
95  if (place >= this->replicaNumber)
96  place = 0;
97 
98  EEPROMextent.updateByte(this->startListPos + place, ++itemNb);
99 
100  return this->startListPos + this->replicaNumber + (this->elementSize * place);
101 }
102 
103 #ifdef VISUALSTUDIO
104 //#include "Serial.hpp"
105 #endif
106 
107 #ifdef EEPROMEXTENT_DEBUG_MODE
108 void CircularBuffer::printStatus()
109 {
110  Serial.print(F("CB Status : "));
111  for (int i = 0; i < this->replicaNumber; i++)
112  {
113  Serial.print(F("|"));
114  Serial.print(EEPROMextent.readByte(this->startListPos + i));
115  }
116  Serial.println(F("|"));
117 }
118 #endif
119 
120 
121 
void updateByte(int address, uint8_t value)
Definition: EEPROMextent.h:85
void write(void *inpObject, bool inUpdate = false)
void clear(int address, int inSize, byte inFillCharacter = 0)
void clear() const
void writeByte(int address, uint8_t value)
Definition: EEPROMextent.h:76
void * read(void *outpObject)
uint8_t readByte(int address)
Definition: EEPROMextent.h:68