Avionics
Core avionics package for CURE flight computers
Loading...
Searching...
No Matches
DataSaverSPI.h
Go to the documentation of this file.
1#ifndef DATASAVERSPI_H
2#define DATASAVERSPI_H
3
4#include "ArduinoHAL.h"
7#include <array>
8#include <cstdlib>
9
10
11#define METADATA_START_ADDRESS 0x000000 // Start writing metadata at the beginning of the flash
12#define DATA_START_ADDRESS 0x001000 // Start writing data after 1 sector (4kB) of metadata
13#define POST_LAUNCH_FLAG_ADDRESS 0x000000 // Address of the post-launch flag
14#define LAUNCH_START_ADDRESS_ADDRESS 0x000001 // Address of the launch start address (32 bits)
15
16#define POST_LAUNCH_FLAG_TRUE 0x00 // Flag to indicate post-launch mode is active
17#define POST_LAUNCH_FLAG_FALSE 0x01 // Flag to indicate post-launch mode is not active
18
19constexpr uint8_t EMPTY_PAGE = 0xFF;
20
21
22#pragma pack(push, 1) // Pack the struct to avoid padding between the name and datas
23typedef struct { // NOLINT(altera-struct-pack-align)
24 uint8_t name;
25 float data;
26} Record_t;
27
28typedef struct { // NOLINT(altera-struct-pack-align)
29 uint8_t name;
30 uint32_t timestamp_ms;
32#pragma pack(pop) // Stop packing from here on out
33
39class DataSaverSPI : public IDataSaver {
40public:
41
42 static constexpr size_t BUFFER_SIZE = 256;
43
52 DataSaverSPI(uint16_t timestampInterval_ms, Adafruit_SPIFlash *flash);
53
65 int saveDataPoint(const DataPoint& dataPoint, uint8_t name) override;
66
73 int saveTimestamp(uint32_t timestamp_ms);
74
79 virtual bool begin() override;
80
93 bool isPostLaunchMode();
94
101 void clearPostLaunchMode();
102
120 void launchDetected(uint32_t launchTimestamp_ms);
121
133 void dumpData(Stream &serial, bool ignoreEmptyPages);
134
144 void clearInternalState();
145
154 void eraseAllData();
155
159 uint32_t getLastTimestamp() const {
160 return lastTimestamp_ms;
161 }
162
168 return lastDataPoint;
169 }
170
171 uint32_t getLaunchWriteAddress() const {
172 return launchWriteAddress;
173 }
174
175 uint32_t getNextWriteAddress() const {
176 return nextWriteAddress;
177 }
178
184 lastTimestamp_ms = 0;
185 }
186
192 return this->postLaunchMode;
193 }
194
195private:
196 // Interval at which to store the timestamp in flash
197 uint16_t timestampInterval_ms;
198
199 // The last timestamp we actually wrote to flash
200 uint32_t lastTimestamp_ms;
201
202 // The timestamp this module was given for launch
203 uint32_t launchTimestamp_ms;
204
205 // The last data point written
206 DataPoint lastDataPoint;
207
208 // Flash driver
209 Adafruit_SPIFlash *flash;
210
211 // Next address in flash at which to write
212 uint32_t nextWriteAddress;
213
214 // Address at which launch was detected
215 uint32_t launchWriteAddress;
216
217 bool postLaunchMode;
218
219private:
224 bool writeToFlash(const uint8_t* data, size_t length);
225
229 bool readFromFlash(uint32_t& readAddress, uint8_t* buffer, size_t length);
230
231 // Write buffer to improve write performance
232 uint8_t buffer[BUFFER_SIZE] = {};
233 size_t bufferIndex = 0;
234 uint32_t bufferFlushes = 0; // Keep track of how many times the buffer has been flushed
235
236public:
241 size_t getBufferIndex() const {
242 return bufferIndex;
243 }
244
249 uint32_t getBufferFlushes() const {
250 return bufferFlushes;
251 }
252
254 return isChipFullDueToPostLaunchProtection;
255 }
256
258 return rebootedInPostLaunchMode;
259 }
260
261private:
262
270 int flushBuffer();
271
279 int addDataToBuffer(const uint8_t* data, size_t length);
280
281
282 // Overloaded functions to add data to the buffer from a Record_t or TimestampRecord_t
283 // More efficient than callling addDataToBuffer with each part of the record
284 int addRecordToBuffer(Record_t * record) {
285 return addDataToBuffer(reinterpret_cast<const uint8_t*>(record), 5);
286 }
287
288 int addRecordToBuffer(TimestampRecord_t * record) {
289 return addDataToBuffer(reinterpret_cast<const uint8_t*>(record), 5);
290 }
291
292 // The chip will keep overwriting data forever unless post launch data is being protected.
293 // Once it wraps back around to the launchWriteAddress, it will stop writing data.
294 bool isChipFullDueToPostLaunchProtection;
295
296 // If the fc boots and is already in post launch mode, then do not write to flash
297 // calling clearPostLaunchMode() will allow writing to flash again after a reboot
298 bool rebootedInPostLaunchMode = false;
299};
300
301#endif // DATA_SAVER_SPI_H
constexpr uint8_t EMPTY_PAGE
Timestamped float measurement container.
Definition DataPoint.h:11
DataSaverSPI(uint16_t timestampInterval_ms, Adafruit_SPIFlash *flash)
Construct a new DataSaverSPI object.
void resetTimestamp()
Resets the timestamp to 0. Can be used to start a new flight during runtime. Useful for testing.
static constexpr size_t BUFFER_SIZE
size_t getBufferIndex() const
Returns the current buffer index Useful for testing.
uint32_t getLaunchWriteAddress() const
bool getIsChipFullDueToPostLaunchProtection() const
bool quickGetPostLaunchMode()
Returns whether the flash chip is in post-launch mode without updating the postLaunchMode flag or rea...
uint32_t getNextWriteAddress() const
int saveDataPoint(const DataPoint &dataPoint, uint8_t name) override
Saves a DataPoint to SPI flash.
void clearInternalState()
Resets all internal state values (buffer, lastDataPoint, nextWriteAddress, lastTimestamp_ms) Does not...
uint32_t getLastTimestamp() const
Returns the last timestamp that was actually written to flash.
bool isPostLaunchMode()
Returns whether the metadata from the flash chip indicates that it contains post-launch data that has...
void clearPostLaunchMode()
Clears the post-launch mode flag on the flash chip **WARNING: This will allow the data to be overwrit...
DataPoint getLastDataPoint() const
Returns the last DataPoint that was written (not necessarily including timestamp, just the data chunk...
void eraseAllData()
Clears/erases the entire flash chip to start fresh.
int saveTimestamp(uint32_t timestamp_ms)
Persist a bare timestamp entry to flash.
uint32_t getBufferFlushes() const
Returns the current buffer flush count Useful for testing.
bool getRebootedInPostLaunchMode() const
void dumpData(Stream &serial, bool ignoreEmptyPages)
Dumps all data from flash to Serial.
virtual bool begin() override
Initialize the flash chip and metadata.
void launchDetected(uint32_t launchTimestamp_ms)
Call this when launch is detected to set the post-launch flag and prevent any data from being overwri...
Abstract interface for persisting timestamped data points.
Definition DataSaver.h:13
uint8_t name
float data
uint32_t timestamp_ms