-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add FRAM based ring buffer class (#24)
* initial version FRAM_RINGBUFFER class * add (object, size) API calls * add persistence interface * update documentation + version number
- Loading branch information
1 parent
a572a68
commit d2a0622
Showing
13 changed files
with
892 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
// | ||
// FILE: FRAM_RINGBUFFER.h | ||
// AUTHOR: Rob Tillaart | ||
// DATE: 2022-10-03 | ||
// PURPOSE: Arduino library for I2C FRAM based RING BUFFER | ||
// URL: https://github.com/RobTillaart/FRAM_I2C | ||
// | ||
|
||
|
||
#include "FRAM_RINGBUFFER.h" | ||
|
||
|
||
FRAM_RINGBUFFER::FRAM_RINGBUFFER() | ||
{ | ||
} | ||
|
||
|
||
uint32_t FRAM_RINGBUFFER::begin(FRAM *fram, uint32_t size, uint32_t start) | ||
{ | ||
_fram = fram; | ||
_size = size; | ||
_start = start + 20; // allocate 5 uint32_t for storage. | ||
flush(); | ||
_saved = false; | ||
return _start + _size; // first free FRAM location. | ||
} | ||
|
||
|
||
////////////////////////////////////////////////////////////////// | ||
// | ||
// ADMINISTRATIVE | ||
// | ||
void FRAM_RINGBUFFER::flush() | ||
{ | ||
_front = _tail = _start; | ||
_count = 0; | ||
_saved = false; | ||
} | ||
|
||
|
||
uint32_t FRAM_RINGBUFFER::size() | ||
{ | ||
return _size; | ||
} | ||
|
||
|
||
uint32_t FRAM_RINGBUFFER::count() | ||
{ | ||
return _count; | ||
} | ||
|
||
|
||
bool FRAM_RINGBUFFER::full() | ||
{ | ||
return _count == _size; | ||
} | ||
|
||
|
||
bool FRAM_RINGBUFFER::empty() | ||
{ | ||
return _count == 0; | ||
} | ||
|
||
|
||
uint32_t FRAM_RINGBUFFER::free() | ||
{ | ||
return _size - _count; | ||
} | ||
|
||
|
||
float FRAM_RINGBUFFER::freePercent() | ||
{ | ||
return (100.0 * _count) / _size; | ||
} | ||
|
||
// DEBUG | ||
// uint32_t FRAM_RINGBUFFER::tail() { return _tail; }; | ||
// uint32_t FRAM_RINGBUFFER::front() { return _front; }; | ||
|
||
|
||
////////////////////////////////////////////////////////////////// | ||
// | ||
// BYTE INTERFACE | ||
// | ||
int FRAM_RINGBUFFER::write(uint8_t value) | ||
{ | ||
if (full()) return FRAM_RB_ERR_BUF_FULL; | ||
_fram->write8(_front, value); | ||
_saved = false; | ||
_front++; | ||
_count++; | ||
if (_front >= _start + _size) _front = _start; | ||
return 1; | ||
} | ||
|
||
|
||
int FRAM_RINGBUFFER::read() | ||
{ | ||
if (empty()) return FRAM_RB_ERR_BUF_EMPTY; | ||
int value = _fram->read8(_tail); | ||
_saved = false; | ||
_tail++; | ||
_count--; | ||
if (_tail >= _start + _size) _tail = _start; | ||
return value; | ||
} | ||
|
||
|
||
int FRAM_RINGBUFFER::peek() | ||
{ | ||
if (empty()) return FRAM_RB_ERR_BUF_EMPTY; | ||
int value = _fram->read8(_tail); | ||
return value; | ||
} | ||
|
||
|
||
/////////////////////////////////////////////////// | ||
// | ||
// MAKE RINGBUFFER PERSISTENT OVER REBOOTS | ||
// | ||
bool FRAM_RINGBUFFER::isSaved() | ||
{ | ||
return _saved; | ||
} | ||
|
||
|
||
void FRAM_RINGBUFFER::save() | ||
{ | ||
uint32_t pos = _start - 20; | ||
if (not _saved) | ||
{ | ||
uint32_t checksum = _size + _front + _tail + _count; | ||
_fram->write32(pos + 0, _size ); | ||
_fram->write32(pos + 4, _front); | ||
_fram->write32(pos + 8, _tail ); | ||
_fram->write32(pos + 12, _count); | ||
_fram->write32(pos + 16, checksum); | ||
_saved = true; | ||
} | ||
} | ||
|
||
|
||
bool FRAM_RINGBUFFER::load() | ||
{ | ||
uint32_t pos = _start - 20; | ||
uint32_t size = _fram->read32(pos + 0); | ||
uint32_t front = _fram->read32(pos + 4); | ||
uint32_t tail = _fram->read32(pos + 8); | ||
uint32_t count = _fram->read32(pos + 12); | ||
uint32_t checksum = _fram->read32(pos + 16); | ||
// checksum test should be enough. | ||
// optional these are possible | ||
// (_start <= _front) && (_front < _start + _size); | ||
// (_start <= _tail) && (_tail < _start + _size); | ||
_saved = (checksum == size + front + tail + count); | ||
if (_saved) | ||
{ | ||
_size = size; | ||
_front = front; | ||
_tail = tail; | ||
_count = count; | ||
} | ||
return _saved; | ||
} | ||
|
||
|
||
void FRAM_RINGBUFFER::wipe() | ||
{ | ||
uint32_t pos = _start - 20; // also overwrite metadata | ||
while (pos < _start + _size - 4) // prevent writing adjacent FRAM | ||
{ | ||
_fram->write32(pos, 0xFFFFFFFF); | ||
pos += 4; | ||
} | ||
while (pos < _start + _size) // if _size not a multiple of 4. | ||
{ | ||
_fram->write8(pos, 0xFF); | ||
pos++; | ||
} | ||
flush(); // reset internal variables too. | ||
} | ||
|
||
|
||
|
||
// -- END OF FILE -- | ||
|
Oops, something went wrong.