STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
flight_log.cpp
Go to the documentation of this file.
1#include "flight_log.h"
2
3#include <SPIMemory.h>
4#include <string.h>
5
6#include "config.h"
7#include "flight_state.h"
8
9namespace {
10
11SPIFlash* s_flash = nullptr;
12uint32_t s_logBase = 0;
13uint32_t s_logEnd = 0;
14uint32_t s_nextAddr = 0;
15
16// Bitmap: sectors in log region (max 128 × 4 KiB = 512 KiB)
17constexpr unsigned MAX_SECTORS = 128;
19
20bool sectorMarked(unsigned idx) {
21 return (s_sectorErased[idx / 8] & (1U << (idx % 8))) != 0;
22}
23
24void sectorMark(unsigned idx) {
25 s_sectorErased[idx / 8] |= static_cast<uint8_t>(1U << (idx % 8));
26}
27
28bool sectorEnsureErased(uint32_t absAddr) {
29 if (absAddr < s_logBase || absAddr >= s_logEnd)
30 return false;
31 const uint32_t off = absAddr - s_logBase;
32 const unsigned idx = static_cast<unsigned>(off / 4096U);
33 if (idx >= MAX_SECTORS)
34 return false;
35 if (sectorMarked(idx))
36 return true;
37 const uint32_t secBase = s_logBase + static_cast<uint32_t>(idx) * 4096U;
38 if (!s_flash->eraseSector(secBase))
39 return false;
40 sectorMark(idx);
41 return true;
42}
43
44bool appendSpanning(const uint8_t* data, size_t len) {
45 if (!s_flash || s_nextAddr + len > s_logEnd)
46 return false;
47 const uint32_t start = s_nextAddr;
48 const uint32_t end = s_nextAddr + static_cast<uint32_t>(len) - 1U;
49 const uint32_t firstSec = (start / 4096U) * 4096U;
50 const uint32_t lastSec = (end / 4096U) * 4096U;
51 for (uint32_t a = firstSec; a <= lastSec; a += 4096U) {
53 return false;
54 }
55 if (!s_flash->writeByteArray(s_nextAddr, const_cast<uint8_t*>(data), len))
56 return false;
57 s_nextAddr += static_cast<uint32_t>(len);
58 return true;
59}
60
61// Record: [0xDA][0x4E][ver=1][flags=0] [tag u16 LE] [t_ms u32 LE] [payload_len
62// u16 LE] [payload...]
63constexpr uint8_t REC_VER = 1;
64constexpr size_t REC_HEADER = 12;
65
66bool appendRecord(uint16_t tag, uint32_t t_ms, const void* payload,
67 uint16_t payload_len) {
68 uint8_t buf[REC_HEADER + 256];
69 if (REC_HEADER + payload_len > sizeof(buf))
70 return false;
71 buf[0] = 0xDA;
72 buf[1] = 0x4E;
73 buf[2] = REC_VER;
74 buf[3] = 0;
75 memcpy(buf + 4, &tag, 2);
76 memcpy(buf + 6, &t_ms, 4);
77 memcpy(buf + 10, &payload_len, 2);
78 memcpy(buf + REC_HEADER, payload, payload_len);
79 return appendSpanning(buf, REC_HEADER + payload_len);
80}
81
82} // namespace
83
84bool flightLogInit(SPIFlash& flash, uint32_t capacityBytes) {
85 s_flash = &flash;
86 memset(s_sectorErased, 0, sizeof(s_sectorErased));
87 if (capacityBytes <= FLIGHT_LOG_REGION_BYTES)
88 return false;
89 s_logBase = capacityBytes - FLIGHT_LOG_REGION_BYTES;
90 s_logEnd = capacityBytes;
92 return true;
93}
94
96#if !FLIGHT_LOG_ENABLE
97 return false;
98#else
100#endif
101}
102
104 uint8_t reason) {
105#if !FLIGHT_LOG_ENABLE
106 (void)from;
107 (void)to;
108 (void)t_ms;
109 (void)reason;
110 return;
111#endif
112 if (!s_flash)
113 return;
114 uint8_t pl[3];
115 pl[0] = static_cast<uint8_t>(from);
116 pl[1] = static_cast<uint8_t>(to);
117 pl[2] = reason;
118 (void)appendRecord(5, t_ms, pl, sizeof(pl)); // tag 5 = FLIGHT_STATE
119}
120
121void logMcp3201(uint16_t raw, float psi, uint32_t t_ms) {
122 if (!sensorsShouldLog() || !s_flash)
123 return;
124 uint8_t pl[6];
125 memcpy(pl, &raw, 2);
126 memcpy(pl + 2, &psi, 4);
127 (void)appendRecord(1, t_ms, pl, sizeof(pl));
128}
129
130void logLis3dh(float ax_g, float ay_g, float az_g, uint32_t t_ms) {
131 if (!sensorsShouldLog() || !s_flash)
132 return;
133 float pl[3] = {ax_g, ay_g, az_g};
134 (void)appendRecord(2, t_ms, pl, sizeof(pl));
135}
136
137void logLps28dfw(float hpa, float temp_c, float alt_m, uint32_t t_ms) {
138 if (!sensorsShouldLog() || !s_flash)
139 return;
140 float pl[3] = {hpa, temp_c, alt_m};
141 (void)appendRecord(3, t_ms, pl, sizeof(pl));
142}
143
144void logIsm330(float ax, float ay, float az, float gx, float gy, float gz,
145 uint32_t t_ms) {
146 if (!sensorsShouldLog() || !s_flash)
147 return;
148 float pl[6] = {ax, ay, az, gx, gy, gz};
149 (void)appendRecord(4, t_ms, pl, sizeof(pl));
150}
151
153 // Reserved for future buffered flush / wear leveling
154}
FlightState
Definition flight_state.h:5
static constexpr uint32_t FLIGHT_LOG_REGION_BYTES
Definition config.h:83
void logLis3dh(float ax_g, float ay_g, float az_g, uint32_t t_ms)
bool flightLogInit(SPIFlash &flash, uint32_t capacityBytes)
bool sensorsShouldLog()
void logMcp3201(uint16_t raw, float psi, uint32_t t_ms)
void logIsm330(float ax, float ay, float az, float gx, float gy, float gz, uint32_t t_ms)
void logFlightStateTransition(FlightState from, FlightState to, uint32_t t_ms, uint8_t reason)
void logLps28dfw(float hpa, float temp_c, float alt_m, uint32_t t_ms)
void flightLogService()
FlightState flightStateGet()
static void start(gnss_frame_parser_t *p, uint8_t byte)
Definition gnss_frame.c:45
*brief create JSON pointer *sa reference_tokens const string_t & a
Definition json.hpp:13877
*brief create JSON pointer *sa reference_tokens end()
bool sectorEnsureErased(uint32_t absAddr)
uint8_t s_sectorErased[MAX_SECTORS/8]
bool appendRecord(uint16_t tag, uint32_t t_ms, const void *payload, uint16_t payload_len)
bool appendSpanning(const uint8_t *data, size_t len)