STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
gnss_core.c
Go to the documentation of this file.
1#include "gnss_core.h"
2
3#include <string.h>
4
5static const uint32_t kBauds[] = {9600U, 38400U, GNSS_RUN_BAUD};
6#define BAUD_COUNT (sizeof(kBauds) / sizeof(kBauds[0]))
7
8static void open_at(gnss_core_t* c, uint32_t baud) {
9 c->baud = baud;
10 c->io.set_baud(c->io.ctx, baud);
11 gnss_frame_init(&c->parser); /* bytes in flight belong to the old rate */
12}
13
14static void detect(gnss_core_t* c, uint32_t now_us) {
15 c->state = GNSS_DETECT;
16 c->deadline_us = now_us + GNSS_LISTEN_US;
17 open_at(c, kBauds[c->candidate]);
18}
19
20static void send_config(gnss_core_t* c, uint32_t now_us) {
21 static const ubx_item_t items[] = {
26 };
27 uint8_t frame[64];
28 size_t n = ubx_valset(frame, sizeof(frame), items,
29 sizeof(items) / sizeof(items[0]));
30 c->io.send(c->io.ctx, frame, (uint16_t)n);
31 c->deadline_us = now_us + GNSS_ACK_US;
32}
33
34static void configure(gnss_core_t* c, uint32_t now_us) {
35 if (c->baud != GNSS_RUN_BAUD) {
37 uint8_t frame[32];
38 size_t n = ubx_valset(frame, sizeof(frame), &baud, 1);
39 c->io.send(c->io.ctx, frame, (uint16_t)n); /* switches on receipt */
41 }
42 c->state = GNSS_CONFIG;
43 c->tries = 1;
44 send_config(c, now_us);
45}
46
47static void restart(gnss_core_t* c, uint32_t now_us) {
48 c->resets++;
49 c->candidate = 0;
50 detect(c, now_us);
51}
52
53void gnss_core_init(gnss_core_t* c, uint32_t now_us) {
54 c->state = GNSS_DETECT;
55 c->candidate = 0;
56 c->pps_us = 0;
57 detect(c, now_us);
58}
59
60void gnss_core_set_pps(gnss_core_t* c, uint32_t edge_us) {
61 c->pps_us = edge_us;
62}
63
64static void on_pvt(gnss_core_t* c, uint32_t now_us) {
67 return;
68 }
70 r.t_us = now_us;
71 r.pps_us = c->pps_us;
72 r.itow_ms = pvt.itow_ms;
73 r.lat_e7 = pvt.lat_e7;
74 r.lon_e7 = pvt.lon_e7;
75 r.hmsl_mm = pvt.hmsl_mm;
76 r.vel_n_mms = pvt.vel_n_mms;
77 r.vel_e_mms = pvt.vel_e_mms;
78 r.vel_d_mms = pvt.vel_d_mms;
79 r.hacc_mm = pvt.hacc_mm;
80 r.vacc_mm = pvt.vacc_mm;
81 r.pdop_e2 = pvt.pdop_e2;
82 r.fix_type = pvt.fix_type;
83 r.num_sv = pvt.num_sv;
84 r.flags = pvt.flags;
85 c->latest = r;
86 c->fixes++;
87 c->deadline_us = now_us + GNSS_SILENCE_US;
88 if (c->sink.record) {
89 c->sink.record(c->sink.ctx, REC_GNSS, &r, sizeof(r));
90 }
91}
92
93static void on_frame(gnss_core_t* c, gnss_frame_kind_t kind, uint32_t now_us) {
95 switch (c->state) {
96 case GNSS_DETECT:
97 c->detected_baud = c->baud;
98 configure(c, now_us);
99 break;
100 case GNSS_CONFIG:
101 if (kind == GNSS_FRAME_UBX && p->ubx_class == UBX_CLASS_ACK &&
102 p->ubx_len == 2 && p->ubx_payload[0] == UBX_CLASS_CFG &&
103 p->ubx_payload[1] == UBX_ID_CFG_VALSET) {
104 if (p->ubx_id == UBX_ID_ACK_ACK) {
105 c->configs++;
106 c->state = GNSS_RUN;
107 c->deadline_us = now_us + GNSS_SILENCE_US;
108 } else {
109 c->naks++;
110 restart(c, now_us);
111 }
112 }
113 break;
114 case GNSS_RUN:
115 if (kind != GNSS_FRAME_UBX) {
116 break;
117 }
118 if (p->ubx_class == UBX_CLASS_NAV && p->ubx_id == UBX_ID_NAV_PVT) {
119 on_pvt(c, now_us);
120 } else if (p->ubx_class == UBX_CLASS_MON &&
121 p->ubx_id == UBX_ID_MON_RF) {
122 if (ubx_parse_mon_rf(p->ubx_payload, p->ubx_len, &c->rf)) {
123 c->rf_reports++;
124 }
125 } else if (p->ubx_class == UBX_CLASS_NAV &&
126 p->ubx_id == UBX_ID_NAV_SAT) {
127 /* only the captured prefix of a long list is in hand */
128 uint16_t got = p->ubx_len < GNSS_FRAME_UBX_CAPTURE
129 ? p->ubx_len
130 : (uint16_t)GNSS_FRAME_UBX_CAPTURE;
131 if (ubx_sat_summary(p->ubx_payload, got, &c->sats)) {
132 c->sat_reports++;
133 }
134 }
135 break;
136 }
137}
138
139void gnss_core_feed(gnss_core_t* c, const uint8_t* bytes, size_t n,
140 uint32_t now_us) {
141 for (size_t i = 0; i < n; ++i) {
142 gnss_frame_kind_t kind = gnss_frame_feed(&c->parser, bytes[i]);
143 if (kind != GNSS_FRAME_NONE) {
144 on_frame(c, kind, now_us);
145 }
146 }
147}
148
149void gnss_core_poll(gnss_core_t* c, uint32_t now_us) {
150 if ((int32_t)(now_us - c->deadline_us) < 0) {
151 return;
152 }
153 switch (c->state) {
154 case GNSS_DETECT: /* nothing heard at this baud: try the next */
155 c->candidate = (uint8_t)((c->candidate + 1U) % BAUD_COUNT);
156 detect(c, now_us);
157 break;
158 case GNSS_CONFIG:
159 if (c->tries++ < GNSS_CONFIG_TRIES) {
160 send_config(c, now_us);
161 } else {
162 restart(c, now_us);
163 }
164 break;
165 case GNSS_RUN: /* fixes stopped */
166 restart(c, now_us);
167 break;
168 }
169}
170
172 if (c->state != GNSS_RUN) {
173 return false;
174 }
175 uint8_t frame[8];
176 size_t n = ubx_poll(frame, sizeof(frame), UBX_CLASS_MON, UBX_ID_MON_RF);
177 c->io.send(c->io.ctx, frame, (uint16_t)n);
179 c->io.send(c->io.ctx, frame, (uint16_t)n);
180 return true;
181}
182
183uint32_t gnss_core_wait_us(const gnss_core_t* c, uint32_t now_us) {
184 int32_t d = (int32_t)(c->deadline_us - now_us);
185 return d > 0 ? (uint32_t)d : 0U;
186}
static void pvt(fake_gnss_t *f, uint32_t t)
Definition fake_gnss.c:141
int32_t p
Definition flight_e2e.c:78
void gnss_core_feed(gnss_core_t *c, const uint8_t *bytes, size_t n, uint32_t now_us)
Definition gnss_core.c:139
void gnss_core_set_pps(gnss_core_t *c, uint32_t edge_us)
Definition gnss_core.c:60
static void on_pvt(gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:64
static void restart(gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:47
static const uint32_t kBauds[]
Definition gnss_core.c:5
static void open_at(gnss_core_t *c, uint32_t baud)
Definition gnss_core.c:8
uint32_t gnss_core_wait_us(const gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:183
static void configure(gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:34
void gnss_core_init(gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:53
void gnss_core_poll(gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:149
bool gnss_core_request_status(gnss_core_t *c)
Definition gnss_core.c:171
static void on_frame(gnss_core_t *c, gnss_frame_kind_t kind, uint32_t now_us)
Definition gnss_core.c:93
static void detect(gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:14
#define BAUD_COUNT
Definition gnss_core.c:6
static void send_config(gnss_core_t *c, uint32_t now_us)
Definition gnss_core.c:20
#define GNSS_CONFIG_TRIES
Definition gnss_core.h:35
#define GNSS_RUN_BAUD
Definition gnss_core.h:32
#define GNSS_RATE_MS
Definition gnss_core.h:37
#define GNSS_LISTEN_US
Definition gnss_core.h:33
@ GNSS_CONFIG
Definition gnss_core.h:48
@ GNSS_DETECT
Definition gnss_core.h:48
@ GNSS_RUN
Definition gnss_core.h:48
#define GNSS_SILENCE_US
Definition gnss_core.h:36
#define GNSS_ACK_US
Definition gnss_core.h:34
gnss_frame_kind_t gnss_frame_feed(gnss_frame_parser_t *p, uint8_t byte)
Definition gnss_frame.c:57
void gnss_frame_init(gnss_frame_parser_t *parser)
Definition gnss_frame.c:35
gnss_frame_kind_t
Definition gnss_frame.h:21
@ GNSS_FRAME_NONE
Definition gnss_frame.h:22
@ GNSS_FRAME_UBX
Definition gnss_frame.h:24
#define GNSS_FRAME_UBX_CAPTURE
Definition gnss_frame.h:30
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:24474
rec_gnss_t
Definition records.h:63
@ REC_GNSS
Definition records.h:23
uint32_t sat_reports
Definition gnss_core.h:67
gnss_frame_parser_t parser
Definition gnss_core.h:53
ubx_rf_t rf
Definition gnss_core.h:68
uint32_t naks
Definition gnss_core.h:64
gnss_io_t io
Definition gnss_core.h:51
uint32_t fixes
Definition gnss_core.h:62
rec_gnss_t latest
Definition gnss_core.h:65
uint32_t detected_baud
Definition gnss_core.h:61
uint32_t configs
Definition gnss_core.h:63
uint8_t candidate
Definition gnss_core.h:56
gnss_state_t state
Definition gnss_core.h:54
uint32_t deadline_us
Definition gnss_core.h:58
uint32_t pps_us
Definition gnss_core.h:59
record_sink_t sink
Definition gnss_core.h:52
uint8_t tries
Definition gnss_core.h:57
uint32_t resets
Definition gnss_core.h:64
uint32_t rf_reports
Definition gnss_core.h:67
ubx_sats_t sats
Definition gnss_core.h:69
uint32_t baud
Definition gnss_core.h:55
uint8_t ubx_payload[GNSS_FRAME_UBX_CAPTURE]
Definition gnss_frame.h:46
void(* set_baud)(void *ctx, uint32_t baud)
Definition gnss_core.h:44
void * ctx
Definition gnss_core.h:45
void(* send)(void *ctx, const uint8_t *bytes, uint16_t len)
Definition gnss_core.h:41
void * ctx
Definition records.h:32
void(* record)(void *ctx, uint8_t type, const void *data, uint8_t len)
Definition records.h:31
static boot_report_t r
static std::vector< uint8_t > frame(uint8_t hi, uint8_t lo, size_t payload_len, uint8_t fill)
One wire packet: len(4, LE) then len bytes of body, where the first 4 body bytes are ty/packet_id(2)/...
bool ubx_parse_mon_rf(const uint8_t *p, uint16_t len, ubx_rf_t *out)
Definition ubx.c:104
size_t ubx_valset(uint8_t *out, size_t cap, const ubx_item_t *items, size_t count)
Definition ubx.c:30
bool ubx_parse_nav_pvt(const uint8_t *p, uint16_t len, ubx_pvt_t *out)
Definition ubx.c:66
size_t ubx_poll(uint8_t *out, size_t cap, uint8_t cls, uint8_t id)
Definition ubx.c:96
bool ubx_sat_summary(const uint8_t *p, uint16_t len, ubx_sats_t *out)
Definition ubx.c:119
#define UBX_CLASS_CFG
Definition ubx.h:33
#define UBX_DYNMODEL_AIR4
Definition ubx.h:48
#define UBX_CLASS_ACK
Definition ubx.h:32
#define UBX_CLASS_NAV
Definition ubx.h:31
#define UBX_KEY_UART1OUTPROT_NMEA
Definition ubx.h:44
#define UBX_ID_CFG_VALSET
Definition ubx.h:40
#define UBX_ID_ACK_ACK
Definition ubx.h:38
#define UBX_ID_MON_RF
Definition ubx.h:37
#define UBX_KEY_UART1_BAUDRATE
Definition ubx.h:43
#define UBX_KEY_NAVSPG_DYNMODEL
Definition ubx.h:47
#define UBX_ID_NAV_PVT
Definition ubx.h:35
#define UBX_ID_NAV_SAT
Definition ubx.h:36
#define UBX_KEY_MSGOUT_NAV_PVT_UART1
Definition ubx.h:45
#define UBX_CLASS_MON
Definition ubx.h:34
#define UBX_KEY_RATE_MEAS
Definition ubx.h:46