Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
CC32xxEEPROMEmulation.cxx
Go to the documentation of this file.
1
34//#define LOGLEVEL VERBOSE
35#define SUPPORT_SL_R1_API
36
37#include "utils/logging.h"
38
41#include "simplelink.h"
42#include "fs.h"
43
45
46extern "C" {
47void eeprom_updated_notification();
48}
49
51 const char *name, size_t file_size_bytes)
52 : EEPROM(name, file_size_bytes)
53{
54 data_ = (uint8_t *)malloc(file_size_bytes);
56 memset(data_, 0xff, file_size_bytes);
57}
58
60{
61 bool have_rot = false;
62 // First we need to find what was the last written segment.
63 for (unsigned sector = 0; sector < SECTOR_COUNT; ++sector)
64 {
65 int handle = open_file(sector, SL_FS_READ, true);
66 if (handle < 0)
67 {
68 LOG(VERBOSE, "EEPROM: sector %u: could not open.", sector);
69 continue;
70 }
71 unsigned b = 0xaa55aaaa;
72 SlCheckResult(sl_FsRead(handle, 0, (uint8_t *)&b, 4), 4);
73 sl_FsClose(handle, nullptr, nullptr, 0);
74 LOG(VERBOSE, "EEPROM: sector %u: version %u.", sector, b);
75 if (b >= fileVersion_)
76 {
77 readSector_ = sector;
78 fileVersion_ = b;
79 have_rot = true;
80 }
81 }
82
83 if (have_rot)
84 {
85 LOG(VERBOSE, "EEPROM: read sector %u:", readSector_);
86 int handle = open_file(readSector_, SL_FS_READ);
87 int ret = sl_FsRead(handle, 4, data_, file_size());
88 if (ret < 0)
89 {
90 SlCheckResult(ret);
91 }
92 SlCheckResult(sl_FsClose(handle, nullptr, nullptr, 0));
93 } else {
94 LOG(VERBOSE, "EEPROM: no read sector");
95 }
96}
97
103
105{
106 if (!isDirty_)
107 return;
108 ++fileVersion_;
109 ++readSector_;
111 readSector_ = 0;
112 LOG(VERBOSE, "EEPROM: write sector %u version %u", readSector_, fileVersion_);
113 int handle = open_file(readSector_, SL_FS_WRITE, true);
114 if (handle < 0)
115 {
116 handle =
118 SL_FS_CREATE | SL_FS_CREATE_MAX_SIZE(file_size() + 4));
119 }
120 SlCheckResult(sl_FsWrite(handle, 0, (uint8_t *)&fileVersion_, 4), 4);
121 SlCheckResult(sl_FsWrite(handle, 4, data_, file_size()), file_size());
122 SlCheckResult(sl_FsClose(handle, nullptr, nullptr, 0));
123 isDirty_ = 0;
124}
125
127 unsigned sector, uint32_t open_mode, bool ignore_error)
128{
129 string filename(name);
130 filename.push_back('.');
131 filename.push_back('0' + sector);
132 int ret = sl_FsOpen((uint8_t *)filename.c_str(), open_mode, NULL);
133 if (!ignore_error && ret < 0)
134 {
135 SlCheckResult(ret);
136 }
137 return ret;
138}
139
141 unsigned int index, const void *buf, size_t len)
142{
143 // Boundary checks are performed by the EEPROM class.
144 if (memcmp(data_ + index, buf, len) == 0) {
145 return;
146 }
147 memcpy(data_ + index, buf, len);
148 isDirty_ = 1;
149 eeprom_updated_notification();
150}
151
152void CC32xxEEPROMEmulation::read(unsigned int index, void *buf, size_t len)
153{
154 // Boundary checks are performed by the EEPROM class.
155 memcpy(buf, data_ + index, len);
156}
void SlCheckResult(int result, int expected)
Tests that a SimpleLink request has succeeded.
uint8_t isDirty_
non-zero if we have unflushed writes.
void mount()
Must be called exactly once after creation, after the simplelink stack has been started.
uint8_t * data_
Holds the file payload in memory.
int open_file(unsigned sector, uint32_t open_mode, bool ignore_error=false)
Opens a SL file.
void flush()
Instructs the driver to write all changed data to disk.
void flush_buffers() OVERRIDE
REQUIRED: lock_ is held.
void write(unsigned int index, const void *buf, size_t len) override
Write to the EEPROM.
void read(unsigned int index, void *buf, size_t len) override
Read from the EEPROM.
CC32xxEEPROMEmulation(const char *name, size_t file_size_bytes)
Constructor.
static const uint8_t SECTOR_COUNT
The total number of files which we are round-robining.
uint8_t readSector_
The sector number of the last sector we used for reading.
unsigned fileVersion_
This number is increased by one every time the contents are flushed to a file.
Common base class for all EEPROM access.
Definition EEPROM.hxx:44
size_t file_size()
Get the maximum file size of the EEPROM file.
Definition EEPROM.hxx:81
const char * name
device name
Definition Devtab.hxx:266
#define LOG(level, message...)
Conditionally write a message to the logging output.
Definition logging.h:99
static const int VERBOSE
Loglevel that is usually not printed, reporting debugging information.
Definition logging.h:59
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138