STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
sensors_core.c
Go to the documentation of this file.
1#include "sensors_core.h"
2
3#include "dev_h3lis100dl.h"
4#include "dev_ism330dhcx.h"
5
6/* Modular microsecond comparisons: a is at or after b. */
7static bool reached(uint32_t now, uint32_t t) {
8 return (int32_t)(now - t) >= 0;
9}
10
11static void emit(sensors_core_t* c, uint8_t type, const void* data,
12 uint8_t len) {
13 if (c->sink.record) {
14 c->sink.record(c->sink.ctx, type, data, len);
15 }
16}
17
18static void failed(sensors_device_t* d, int err, uint32_t now_us) {
19 d->errors++;
20 d->last_error = err;
21 if (++d->error_streak >= SENSORS_MAX_ERRORS) {
22 d->ok = false;
23 d->retry_at_us = now_us + SENSORS_RETRY_US;
24 }
25}
26
27static void succeeded(sensors_device_t* d) {
28 d->samples++;
29 d->error_streak = 0;
30}
31
32static void init_imu(sensors_core_t* c, uint32_t now_us) {
33 c->imu.inits++;
34 int err = ism330_init(&c->imu_bus);
35 c->imu.ok = err == DEV_OK;
36 c->imu.last_error = err;
37 c->imu.error_streak = 0;
38 c->imu.retry_at_us = now_us + SENSORS_RETRY_US;
39 c->imu_last_us = now_us;
40}
41
42static void init_highg(sensors_core_t* c, uint32_t now_us) {
43 c->highg.inits++;
44 int err = h3lis_init(&c->highg_bus);
45 c->highg.ok = err == DEV_OK;
46 c->highg.last_error = err;
47 c->highg.error_streak = 0;
49 c->highg_last_us = now_us;
50}
51
52static void init_baro(sensors_core_t* c, uint32_t now_us) {
53 c->baro.inits++;
54 int err = ms5611_read_prom(&c->baro_bus, &c->prom);
55 c->baro.ok = err == DEV_OK;
56 c->baro.last_error = err;
57 c->baro.error_streak = 0;
58 c->baro.retry_at_us = now_us + SENSORS_RETRY_US;
59 c->baro_phase = 0;
60 c->baro_due_us = now_us;
61}
62
63void sensors_core_init(sensors_core_t* c, uint32_t now_us) {
64 init_imu(c, now_us);
65 init_highg(c, now_us);
66 init_baro(c, now_us);
67}
68
70 (void)ism330_power_down(&c->imu_bus);
71 (void)h3lis_power_down(&c->highg_bus);
72 c->imu.ok = false;
73 c->highg.ok = false;
74 c->baro.ok = false;
75 c->baro_phase = 0;
76}
77
78static void read_imu(sensors_core_t* c, uint32_t t_us, uint32_t now_us) {
80 int err = ism330_read(&c->imu_bus, &s);
81 c->imu_last_us = now_us;
82 if (err != DEV_OK) {
83 failed(&c->imu, err, now_us);
84 return;
85 }
87 r.t_us = t_us;
88 r.temp = s.temp;
89 for (int i = 0; i < 3; ++i) { /* packed record: no member pointers */
90 r.gyro[i] = s.gyro[i];
91 r.accel[i] = s.accel[i];
92 }
93 c->imu_latest = r;
94 succeeded(&c->imu);
95 emit(c, REC_IMU, &r, sizeof(r));
96}
97
98static void read_highg(sensors_core_t* c, uint32_t t_us, uint32_t now_us) {
100 int err = h3lis_read(&c->highg_bus, &s);
101 c->highg_last_us = now_us;
102 if (err != DEV_OK) {
103 failed(&c->highg, err, now_us);
104 return;
105 }
107 r.t_us = t_us;
108 for (int i = 0; i < 3; ++i) {
109 r.accel[i] = s.accel[i];
110 }
111 c->highg_latest = r;
112 succeeded(&c->highg);
113 emit(c, REC_HIGHG, &r, sizeof(r));
114}
115
116static void step_baro(sensors_core_t* c, uint32_t now_us) {
117 int err = DEV_OK;
118 uint32_t raw = 0;
119 switch (c->baro_phase) {
120 case 0:
122 c->baro_phase = 1;
123 break;
124 case 1:
125 err = ms5611_read_adc(&c->baro_bus, &raw);
126 if (err == DEV_OK) {
127 c->baro_d1 = raw;
128 c->baro_d1_us = now_us;
130 }
131 c->baro_phase = err == DEV_OK ? 2 : 0;
132 break;
133 default:
134 err = ms5611_read_adc(&c->baro_bus, &raw);
135 if (err == DEV_OK) {
136 int32_t temp_c100, pressure_pa;
137 ms5611_compensate(&c->prom, c->baro_d1, raw, &temp_c100,
138 &pressure_pa);
140 r.t_us = c->baro_d1_us;
141 r.temp_c100 = temp_c100;
142 r.pressure_pa = pressure_pa;
143 c->baro_latest = r;
144 succeeded(&c->baro);
145 emit(c, REC_BARO, &r, sizeof(r));
147 }
148 c->baro_phase = err == DEV_OK ? 1 : 0;
149 break;
150 }
151 if (err != DEV_OK) {
152 failed(&c->baro, err, now_us);
153 }
154 c->baro_due_us = now_us + (c->baro_phase ? SENSORS_BARO_STEP_US : 0U);
155}
156
157void sensors_core_step(sensors_core_t* c, uint32_t events, uint32_t imu_edge_us,
158 uint32_t highg_edge_us, uint32_t now_us) {
159 /* IMU */
160 if (c->imu.ok) {
161 if (events & SENSORS_EV_IMU) {
162 read_imu(c, imu_edge_us, now_us);
163 } else if (reached(now_us,
165 c->imu.missed_drdy++;
166 read_imu(c, now_us, now_us);
167 }
168 } else if (reached(now_us, c->imu.retry_at_us)) {
169 init_imu(c, now_us);
170 }
171 /* High-g: level DRDY, so a timeout read also re-arms the edge. */
172 if (c->highg.ok) {
173 if (events & SENSORS_EV_HIGHG) {
174 read_highg(c, highg_edge_us, now_us);
175 } else if (reached(now_us,
177 c->highg.missed_drdy++;
178 read_highg(c, now_us, now_us);
179 }
180 } else if (reached(now_us, c->highg.retry_at_us)) {
181 init_highg(c, now_us);
182 }
183 /* Barometer */
184 if (c->baro.ok) {
185 if (reached(now_us, c->baro_due_us)) {
186 step_baro(c, now_us);
187 }
188 } else if (reached(now_us, c->baro.retry_at_us)) {
189 init_baro(c, now_us);
190 }
191}
192
193static uint32_t until(uint32_t now, uint32_t t) {
194 int32_t d = (int32_t)(t - now);
195 return d > 0 ? (uint32_t)d : 0U;
196}
197
198static uint32_t sooner(uint32_t a, uint32_t b) {
199 return a < b ? a : b;
200}
201
202uint32_t sensors_core_wait_us(const sensors_core_t* c, uint32_t now_us) {
203 uint32_t wait = SENSORS_RETRY_US;
204 wait = sooner(
205 wait, c->imu.ok
206 ? until(now_us, c->imu_last_us + 2U * SENSORS_IMU_PERIOD_US)
207 : until(now_us, c->imu.retry_at_us));
208 wait = sooner(wait, c->highg.ok
209 ? until(now_us, c->highg_last_us +
211 : until(now_us, c->highg.retry_at_us));
212 wait = sooner(wait, c->baro.ok ? until(now_us, c->baro_due_us)
213 : until(now_us, c->baro.retry_at_us));
214 return wait;
215}
@ DEV_OK
Definition dev_bus.h:17
int h3lis_power_down(const dev_bus_t *bus)
int h3lis_read(const dev_bus_t *bus, h3lis_sample_t *out)
int h3lis_init(const dev_bus_t *bus)
int ism330_init(const dev_bus_t *bus)
int ism330_power_down(const dev_bus_t *bus)
int ism330_read(const dev_bus_t *bus, ism330_sample_t *out)
int ms5611_read_adc(const dev_bus_t *bus, uint32_t *raw)
Definition dev_ms5611.c:59
int ms5611_start(const dev_bus_t *bus, ms5611_conversion_t which)
Definition dev_ms5611.c:50
int ms5611_read_prom(const dev_bus_t *bus, ms5611_prom_t *prom)
Definition dev_ms5611.c:29
void ms5611_compensate(const ms5611_prom_t *prom, uint32_t d1, uint32_t d2, int32_t *temp_c100, int32_t *pressure_pa)
Definition dev_ms5611.c:72
@ MS5611_D1_PRESSURE
Definition dev_ms5611.h:36
@ MS5611_D2_TEMPERATURE
Definition dev_ms5611.h:37
*brief create JSON pointer *sa reference_tokens const string_t const string_t & b
Definition json.hpp:13878
*brief create JSON pointer *sa reference_tokens const string_t & a
Definition json.hpp:13877
rec_baro_t
Definition records.h:51
rec_highg_t
Definition records.h:45
@ REC_HIGHG
Definition records.h:21
@ REC_BARO
Definition records.h:22
@ REC_IMU
Definition records.h:20
rec_imu_t
Definition records.h:40
static void init_highg(sensors_core_t *c, uint32_t now_us)
static void init_baro(sensors_core_t *c, uint32_t now_us)
static void emit(sensors_core_t *c, uint8_t type, const void *data, uint8_t len)
static bool reached(uint32_t now, uint32_t t)
Definition sensors_core.c:7
static void read_highg(sensors_core_t *c, uint32_t t_us, uint32_t now_us)
uint32_t sensors_core_wait_us(const sensors_core_t *c, uint32_t now_us)
void sensors_core_init(sensors_core_t *c, uint32_t now_us)
static void failed(sensors_device_t *d, int err, uint32_t now_us)
static uint32_t until(uint32_t now, uint32_t t)
void sensors_core_stop(sensors_core_t *c)
static void step_baro(sensors_core_t *c, uint32_t now_us)
static void read_imu(sensors_core_t *c, uint32_t t_us, uint32_t now_us)
static void init_imu(sensors_core_t *c, uint32_t now_us)
void sensors_core_step(sensors_core_t *c, uint32_t events, uint32_t imu_edge_us, uint32_t highg_edge_us, uint32_t now_us)
static void succeeded(sensors_device_t *d)
static uint32_t sooner(uint32_t a, uint32_t b)
#define SENSORS_RETRY_US
#define SENSORS_BARO_STEP_US
#define SENSORS_MAX_ERRORS
#define SENSORS_HIGHG_PERIOD_US
#define SENSORS_IMU_PERIOD_US
#define SENSORS_EV_HIGHG
#define SENSORS_EV_IMU
void * ctx
Definition records.h:32
void(* record)(void *ctx, uint8_t type, const void *data, uint8_t len)
Definition records.h:31
rec_highg_t highg_latest
dev_bus_t imu_bus
dev_bus_t baro_bus
uint32_t baro_d1
uint32_t baro_d1_us
dev_bus_t highg_bus
uint32_t imu_last_us
sensors_device_t highg
uint8_t baro_phase
sensors_device_t imu
uint32_t highg_last_us
rec_imu_t imu_latest
uint32_t baro_due_us
sensors_device_t baro
rec_baro_t baro_latest
ms5611_prom_t prom
sensors_sink_t sink
uint32_t retry_at_us
uint32_t error_streak
uint32_t missed_drdy
static boot_report_t r