ACwing FC firmware
STM32WB55: attitude IEKF, altitude Kalman filter, flight core, protocol v2
Loading...
Searching...
No Matches
cfg_store.c
Go to the documentation of this file.
1
5#include "cfg_store.h"
6#include <string.h>
7#include <stddef.h>
8
9uint32_t cfg_crc32(const void *data, uint32_t len)
10{
11 const uint8_t *p = (const uint8_t *)data;
12 uint32_t c = 0xFFFFFFFFu;
13 while (len--) {
14 c ^= *p++;
15 for (int k = 0; k < 8; ++k) c = (c >> 1) ^ (0xEDB88320u & (0u - (c & 1u)));
16 }
17 return ~c;
18}
19
20/* ---- version 1 layout (firmware 0.4.x), kept to migrate it ---- */
21#define V1_PARAMS 24 /* P_TAKEOFF_ALT .. P_COMPASS_PRIMARY */
30typedef struct {
31 uint32_t magic;
32 uint16_t version;
33 uint16_t size;
34 uint32_t seq;
35 float params[V1_PARAMS];
36 char name[16];
38 uint32_t bak_mask;
39 uint32_t crc;
41
42/* 0 = not valid, else the version */
43static int valid_version(const void *page)
44{
45 const cfg_image_t *im = (const cfg_image_t *)page;
46 if (!im || im->magic != CFG_MAGIC) return 0;
47 if (im->version == CFG_VERSION && im->size == sizeof(cfg_image_t) &&
48 im->crc == cfg_crc32(im, offsetof(cfg_image_t, crc))) return CFG_VERSION;
49 const cfg_image_v1_t *v1 = (const cfg_image_v1_t *)page;
50 if (v1->version == 1u && v1->size == sizeof(cfg_image_v1_t) &&
51 v1->crc == cfg_crc32(v1, offsetof(cfg_image_v1_t, crc))) return 1;
52 return 0;
53}
54static int valid(const cfg_image_t *im) { return valid_version(im) == CFG_VERSION; }
55
56static int latest_page(void)
57{
58 int best = -1;
59 uint32_t seq = 0;
60 for (int p = 0; p < CFG_PAGES; ++p) {
61 const cfg_image_t *im = (const cfg_image_t *)cfg_flash_page(p);
62 if (!valid_version(im)) continue;
63 if (best < 0 || (int32_t)(im->seq - seq) > 0) { best = p; seq = im->seq; }
64 }
65 return best;
66}
67
68static void cal_from_v1(cal_set_t *d, const cal_set_v1_t *s)
69{
70 cal_set_defaults(d, s->compass.hi);
71 d->accel = s->accel; d->level = s->level; d->gyro = s->gyro;
72 d->compass = s->compass; d->motors = s->motors;
73 d->done_mask = s->done_mask;
74}
75
76void cfg_params_put(cfg_image_t *img, const float v[PARAM_COUNT])
77{
78 memset(img->params, 0, sizeof img->params);
79 for (int i = 0; i < PARAM_COUNT && i < (int)CFG_PARAM_SLOTS; ++i) {
80 img->params[i].id = g_param_def[i].id;
81 img->params[i].value = v[i];
82 }
83}
84
85void cfg_params_get(const cfg_image_t *img, float v[PARAM_COUNT])
86{
87 for (int i = 0; i < PARAM_COUNT; ++i) v[i] = g_param_def[i].def;
88 for (unsigned k = 0; k < CFG_PARAM_SLOTS; ++k) {
89 if (!img->params[k].id) continue;
90 const int i = params_index(img->params[k].id);
91 if (i >= 0) v[i] = img->params[k].value;
92 }
93}
94
96{
97 const int p = latest_page();
98 if (p < 0) return -1;
99 const void *pg = cfg_flash_page(p);
100 if (valid_version(pg) == CFG_VERSION) { memcpy(out, pg, sizeof *out); return 0; }
101
102 /* version 1 -> 2 */
103 const cfg_image_v1_t *v1 = (const cfg_image_v1_t *)pg;
104 memset(out, 0, sizeof *out);
105 out->magic = CFG_MAGIC; out->version = 1u; out->size = sizeof *out; out->seq = v1->seq;
106 float v[PARAM_COUNT];
107 for (int i = 0; i < PARAM_COUNT; ++i) v[i] = (i < V1_PARAMS) ? v1->params[i] : g_param_def[i].def;
108 cfg_params_put(out, v);
109 memcpy(out->name, v1->name, sizeof out->name);
110 cal_from_v1(&out->cal, &v1->cal);
111 cal_from_v1(&out->bak, &v1->bak);
112 out->bak_mask = v1->bak_mask;
113 out->batt_used_scale_i = 1.0f;
114 return 0;
115}
116
118{
119 const int cur = latest_page();
120 uint32_t seq = 1;
121 int page = 0;
122 if (cur >= 0) {
123 seq = ((const cfg_image_t *)cfg_flash_page(cur))->seq + 1u;
124 page = (cur + 1) % CFG_PAGES;
125 }
126 img->magic = CFG_MAGIC; img->version = CFG_VERSION; img->size = sizeof *img;
127 img->seq = seq;
128 img->crc = cfg_crc32(img, offsetof(cfg_image_t, crc));
129 if (cfg_flash_write(page, img, sizeof *img) != 0) return -1;
130 return valid((const cfg_image_t *)cfg_flash_page(page)) ? 0 : -1; /* read back */
131}
132
133_Static_assert(sizeof(cfg_image_t) <= 4096u, "configuration image must fit one flash page");
134_Static_assert(P_COMPASS_PRIMARY == V1_PARAMS - 1, "version 1 parameters are the first 24 of the table");
static batt_state_t s
Definition battery.c:21
void cal_set_defaults(cal_set_t *s, const float hi[3])
Definition calib_mgr.c:60
int cfg_save(cfg_image_t *img)
writes img (seq and crc filled here) to the other page; 0 = ok
Definition cfg_store.c:117
void cfg_params_put(cfg_image_t *img, const float v[PARAM_COUNT])
parameters <-> slots (unknown ids ignored, missing ids -> default)
Definition cfg_store.c:76
void cfg_params_get(const cfg_image_t *img, float v[PARAM_COUNT])
Definition cfg_store.c:85
static int valid_version(const void *page)
Definition cfg_store.c:43
static void cal_from_v1(cal_set_t *d, const cal_set_v1_t *s)
Definition cfg_store.c:68
static int latest_page(void)
Definition cfg_store.c:56
#define V1_PARAMS
Definition cfg_store.c:21
uint32_t cfg_crc32(const void *data, uint32_t len)
Definition cfg_store.c:9
static int valid(const cfg_image_t *im)
Definition cfg_store.c:54
int cfg_load(cfg_image_t *out)
latest valid image (version 1 converted); returns 0 if found, -1 if none (out left untouched)
Definition cfg_store.c:95
Persistent configuration: parameters, drone name, calibrations and one backup per calibration type (H...
#define CFG_PAGES
Definition cfg_store.h:55
#define CFG_PARAM_SLOTS
room for parameters added later
Definition cfg_store.h:23
const void * cfg_flash_page(int page)
memory-mapped page
#define CFG_VERSION
Definition cfg_store.h:22
int cfg_flash_write(int page, const void *data, uint32_t len)
erase + program; 0 = ok
#define CFG_MAGIC
"ACWC"
Definition cfg_store.h:21
static int pg(void *c, uint32_t a, const void *buf, uint32_t n)
uint8_t seq
Definition log_task.c:48
const param_def_t g_param_def[PARAM_COUNT]
Definition params.c:11
int params_index(uint16_t id)
-1 if unknown
Definition params.c:50
@ PARAM_COUNT
Definition params.h:29
@ P_COMPASS_PRIMARY
Definition params.h:26
uint8_t level
PV2_BATT_OK / LOW / CRITICAL / EMERGENCY
Definition battery.h:54
cal_level_t level
Definition calib_mgr.h:34
cal_motors_t motors
Definition calib_mgr.h:37
cal_compass_t compass
Definition calib_mgr.h:36
cal_accel_t accel
Definition calib_mgr.h:33
cal_gyro_t gyro
Definition calib_mgr.h:35
uint32_t done_mask
bit (type-1): this calibration was done and saved
Definition calib_mgr.h:39
cal_motors_t motors
Definition cfg_store.c:27
cal_gyro_t gyro
Definition cfg_store.c:25
cal_level_t level
Definition cfg_store.c:24
cal_compass_t compass
Definition cfg_store.c:26
cal_accel_t accel
Definition cfg_store.c:23
uint32_t done_mask
Definition cfg_store.c:28
Version 2.
Definition cfg_store.h:34
uint32_t crc
CRC-32 of everything above
Definition cfg_store.h:47
cal_set_t bak
previous set, per type (CAL_RESTORE)
Definition cfg_store.h:42
float batt_used_scale_i
current scale it was counted with
Definition cfg_store.h:45
cfg_param_t params[CFG_PARAM_SLOTS]
Definition cfg_store.h:39
char name[16]
Definition cfg_store.h:40
uint16_t version
Definition cfg_store.h:36
uint16_t size
Definition cfg_store.h:37
uint32_t magic
Definition cfg_store.h:35
uint32_t seq
Definition cfg_store.h:38
cal_set_t cal
saved calibrations
Definition cfg_store.h:41
uint32_t bak_mask
bit (type-1): bak holds a set for it
Definition cfg_store.h:43
uint16_t version
Definition cfg_store.c:32
cal_set_v1_t cal
Definition cfg_store.c:37
uint16_t size
Definition cfg_store.c:33
char name[16]
Definition cfg_store.c:36
uint32_t magic
Definition cfg_store.c:31
uint32_t bak_mask
Definition cfg_store.c:38
uint32_t crc
Definition cfg_store.c:39
cal_set_v1_t bak
Definition cfg_store.c:37
uint32_t seq
Definition cfg_store.c:34
float params[V1_PARAMS]
Definition cfg_store.c:35
uint16_t id
0 = empty slot
Definition cfg_store.h:27
float value
Definition cfg_store.h:29
uint16_t id
Definition params.h:33
float def
Definition params.h:34