Line data Source code
1 0 : /*
2 : * Copyright (c) 2025 Croxel Inc.
3 : * Copyright (c) 2025 CogniPilot Foundation
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : #ifndef ZEPHYR_MODEM_UBX_PROTOCOL_
9 : #define ZEPHYR_MODEM_UBX_PROTOCOL_
10 :
11 : #include <stdint.h>
12 : #include <zephyr/modem/ubx/checksum.h>
13 :
14 0 : #define UBX_FRAME_HEADER_SZ 6
15 0 : #define UBX_FRAME_FOOTER_SZ 2
16 0 : #define UBX_FRAME_SZ_WITHOUT_PAYLOAD (UBX_FRAME_HEADER_SZ + UBX_FRAME_FOOTER_SZ)
17 0 : #define UBX_FRAME_SZ(payload_size) (payload_size + UBX_FRAME_SZ_WITHOUT_PAYLOAD)
18 :
19 0 : #define UBX_PREAMBLE_SYNC_CHAR_1 0xB5
20 0 : #define UBX_PREAMBLE_SYNC_CHAR_2 0x62
21 :
22 0 : #define UBX_FRAME_PREAMBLE_SYNC_CHAR_1_IDX 0
23 0 : #define UBX_FRAME_PREAMBLE_SYNC_CHAR_2_IDX 1
24 0 : #define UBX_FRAME_MSG_CLASS_IDX 2
25 :
26 0 : #define UBX_PAYLOAD_SZ_MAX 512
27 0 : #define UBX_FRAME_SZ_MAX UBX_FRAME_SZ(UBX_PAYLOAD_SZ_MAX)
28 :
29 0 : struct ubx_frame {
30 0 : uint8_t preamble_sync_char_1;
31 0 : uint8_t preamble_sync_char_2;
32 0 : uint8_t class;
33 0 : uint8_t id;
34 0 : uint16_t payload_size;
35 0 : uint8_t payload_and_checksum[];
36 : };
37 :
38 0 : struct ubx_frame_match {
39 0 : uint8_t class;
40 0 : uint8_t id;
41 : struct {
42 0 : uint8_t *buf;
43 0 : uint16_t len;
44 0 : } payload;
45 : };
46 :
47 0 : enum ubx_class_id {
48 : UBX_CLASS_ID_NAV = 0x01, /* Navigation Results Messages */
49 : UBX_CLASS_ID_RXM = 0x02, /* Receiver Manager Messages */
50 : UBX_CLASS_ID_INF = 0x04, /* Information Messages */
51 : UBX_CLASS_ID_ACK = 0x05, /* Ack/Nak Messages */
52 : UBX_CLASS_ID_CFG = 0x06, /* Configuration Input Messages */
53 : UBX_CLASS_ID_UPD = 0x09, /* Firmware Update Messages */
54 : UBX_CLASS_ID_MON = 0x0A, /* Monitoring Messages */
55 : UBX_CLASS_ID_TIM = 0x0D, /* Timing Messages */
56 : UBX_CLASS_ID_MGA = 0x13, /* Multiple GNSS Assistance Messages */
57 : UBX_CLASS_ID_LOG = 0x21, /* Logging Messages */
58 : UBX_CLASS_ID_SEC = 0x27, /* Security Feature Messages */
59 : UBX_CLASS_ID_NMEA_STD = 0xF0, /* Note: Only used to configure message rate */
60 : UBX_CLASS_ID_NMEA_PUBX = 0xF1, /* Note: Only used to configure message rate */
61 : };
62 :
63 0 : enum ubx_msg_id_nav {
64 : UBX_MSG_ID_NAV_PVT = 0x07,
65 : UBX_MSG_ID_NAV_SAT = 0x35,
66 : };
67 :
68 0 : enum ubx_nav_fix_type {
69 : UBX_NAV_FIX_TYPE_NO_FIX = 0,
70 : UBX_NAV_FIX_TYPE_DR = 1,
71 : UBX_NAV_FIX_TYPE_2D = 2,
72 : UBX_NAV_FIX_TYPE_3D = 3,
73 : UBX_NAV_FIX_TYPE_GNSS_DR_COMBINED = 4,
74 : UBX_NAV_FIX_TYPE_TIME_ONLY = 5,
75 : };
76 :
77 0 : enum ubx_nav_hp_dgnss_mode {
78 : UBX_NAV_HP_DGNSS_MODE_RTK_FLOAT = 2,
79 : UBX_NAV_HP_DGNSS_MODE_RTK_FIXED = 3,
80 : };
81 :
82 0 : #define UBX_NAV_PVT_VALID_DATE BIT(0)
83 0 : #define UBX_NAV_PVT_VALID_TIME BIT(1)
84 0 : #define UBX_NAV_PVT_VALID_UTC_TOD BIT(2)
85 0 : #define UBX_NAV_PVT_VALID_MAGN BIT(3)
86 :
87 0 : #define UBX_NAV_PVT_FLAGS_GNSS_FIX_OK BIT(0)
88 0 : #define UBX_NAV_PVT_FLAGS_GNSS_CARR_SOLN_FLOATING BIT(6)
89 0 : #define UBX_NAV_PVT_FLAGS_GNSS_CARR_SOLN_FIXED BIT(7)
90 :
91 0 : #define UBX_NAV_PVT_FLAGS3_INVALID_LLH BIT(0)
92 :
93 0 : struct ubx_nav_pvt {
94 : struct {
95 0 : uint32_t itow;
96 0 : uint16_t year;
97 0 : uint8_t month;
98 0 : uint8_t day;
99 0 : uint8_t hour;
100 0 : uint8_t minute;
101 0 : uint8_t second;
102 0 : uint8_t valid;
103 0 : uint32_t tacc;
104 0 : int32_t nano;
105 0 : } __packed time;
106 0 : uint8_t fix_type; /** See ubx_nav_fix_type */
107 1 : uint8_t flags;
108 0 : uint8_t flags2;
109 : struct {
110 0 : uint8_t num_sv;
111 0 : int32_t longitude; /* Longitude. Degrees. scaling: 1e-7 */
112 0 : int32_t latitude; /* Latitude. Degrees. scaling: 1e-7 */
113 0 : int32_t height; /* Height above ellipsoid. mm */
114 0 : int32_t hmsl; /* Height above mean sea level. mm */
115 0 : uint32_t horiz_acc; /* Horizontal accuracy estimate. mm */
116 0 : uint32_t vert_acc; /* Vertical accuracy estimate. mm */
117 0 : int32_t vel_north; /* NED north velocity. mm/s */
118 0 : int32_t vel_east; /* NED east velocity. mm/s */
119 0 : int32_t vel_down; /* NED down velocity. mm/s */
120 0 : int32_t ground_speed; /* Ground Speed (2D). mm/s */
121 0 : int32_t head_motion; /* Heading of Motion (2D). Degrees. scaling: 1e-5 */
122 0 : uint32_t speed_acc; /* Speed accuracy estimated. mm/s */
123 0 : uint32_t head_acc; /** Heading accuracy estimate (both motion and vehicle).
124 : * Degrees. scaling: 1e-5.
125 : */
126 1 : uint16_t pdop; /* scaling: 1e-2 */
127 0 : uint16_t flags3;
128 0 : uint32_t reserved;
129 0 : int32_t head_vehicle; /* Heading of vehicle (2D). Degrees. Valid if
130 : * flags.head_vehicle_valid is set.
131 : */
132 0 : int16_t mag_decl; /* Magnetic declination. Degrees. */
133 0 : uint16_t magacc; /* Magnetic declination accuracy. Degrees. scaling: 1e-2 */
134 0 : } __packed nav;
135 : } __packed;
136 :
137 0 : enum ubx_nav_sat_health {
138 : UBX_NAV_SAT_HEALTH_UNKNOWN = 0,
139 : UBX_NAV_SAT_HEALTH_HEALTHY = 1,
140 : UBX_NAV_SAT_HEALTH_UNHEALTHY = 2,
141 : };
142 :
143 0 : enum ubx_gnss_id {
144 : UBX_GNSS_ID_GPS = 0,
145 : UBX_GNSS_ID_SBAS = 1,
146 : UBX_GNSS_ID_GALILEO = 2,
147 : UBX_GNSS_ID_BEIDOU = 3,
148 : UBX_GNSS_ID_QZSS = 5,
149 : UBX_GNSS_ID_GLONASS = 6,
150 : };
151 :
152 0 : #define UBX_NAV_SAT_FLAGS_SV_USED BIT(3)
153 0 : #define UBX_NAV_SAT_FLAGS_RTCM_CORR_USED BIT(17)
154 :
155 0 : struct ubx_nav_sat {
156 0 : uint32_t itow;
157 0 : uint8_t version; /* Message version. */
158 0 : uint8_t num_sv;
159 0 : uint16_t reserved1;
160 0 : struct ubx_nav_sat_info {
161 0 : uint8_t gnss_id; /* See ubx_gnss_id */
162 0 : uint8_t sv_id;
163 0 : uint8_t cno; /* Carrier-to-noise ratio. dBHz */
164 0 : int8_t elevation; /* Elevation (range: +/- 90). Degrees */
165 0 : int16_t azimuth; /* Azimuth (range: 0 - 360). Degrees */
166 0 : int16_t pseu_res; /* Pseudorange Residual. Meters */
167 0 : uint32_t flags;
168 0 : } sat[];
169 : };
170 :
171 0 : enum ubx_msg_id_ack {
172 : UBX_MSG_ID_ACK = 0x01,
173 : UBX_MSG_ID_NAK = 0x00
174 : };
175 :
176 0 : enum ubx_msg_id_cfg {
177 : UBX_MSG_ID_CFG_PRT = 0x00,
178 : UBX_MSG_ID_CFG_MSG = 0x01,
179 : UBX_MSG_ID_CFG_RST = 0x04,
180 : UBX_MSG_ID_CFG_RATE = 0x08,
181 : UBX_MSG_ID_CFG_NAV5 = 0x24,
182 : UBX_MSG_ID_CFG_VAL_SET = 0x8A,
183 : UBX_MSG_ID_CFG_VAL_GET = 0x8B,
184 : };
185 :
186 0 : enum ubx_msg_id_mon {
187 : UBX_MSG_ID_MON_VER = 0x04,
188 : UBX_MSG_ID_MON_GNSS = 0x28,
189 : };
190 :
191 0 : struct ubx_ack {
192 0 : uint8_t class;
193 0 : uint8_t id;
194 : };
195 :
196 0 : #define UBX_GNSS_SELECTION_GPS BIT(0)
197 0 : #define UBX_GNSS_SELECTION_GLONASS BIT(1)
198 0 : #define UBX_GNSS_SELECTION_BEIDOU BIT(2)
199 0 : #define UBX_GNSS_SELECTION_GALILEO BIT(3)
200 :
201 0 : struct ubx_mon_gnss {
202 0 : uint8_t ver;
203 : struct {
204 0 : uint8_t supported;
205 0 : uint8_t default_enabled;
206 0 : uint8_t enabled;
207 0 : } selection;
208 0 : uint8_t simultaneous;
209 0 : uint8_t reserved1[3];
210 : } __packed;
211 :
212 0 : enum ubx_cfg_port_id {
213 : UBX_CFG_PORT_ID_DDC = 0,
214 : UBX_CFG_PORT_ID_UART = 1,
215 : UBX_CFG_PORT_ID_USB = 2,
216 : UBX_CFG_PORT_ID_SPI = 3,
217 : };
218 :
219 0 : enum ubx_cfg_char_len {
220 : UBX_CFG_PRT_PORT_MODE_CHAR_LEN_5 = 0, /* Not supported */
221 : UBX_CFG_PRT_PORT_MODE_CHAR_LEN_6 = 1, /* Not supported */
222 : UBX_CFG_PRT_PORT_MODE_CHAR_LEN_7 = 2, /* Supported only with parity */
223 : UBX_CFG_PRT_PORT_MODE_CHAR_LEN_8 = 3,
224 : };
225 :
226 0 : enum ubx_cfg_parity {
227 : UBX_CFG_PRT_PORT_MODE_PARITY_EVEN = 0,
228 : UBX_CFG_PRT_PORT_MODE_PARITY_ODD = 1,
229 : UBX_CFG_PRT_PORT_MODE_PARITY_NONE = 4,
230 : };
231 :
232 0 : enum ubx_cfg_stop_bits {
233 : UBX_CFG_PRT_PORT_MODE_STOP_BITS_1 = 0,
234 : UBX_CFG_PRT_PORT_MODE_STOP_BITS_1_5 = 1,
235 : UBX_CFG_PRT_PORT_MODE_STOP_BITS_2 = 2,
236 : UBX_CFG_PRT_PORT_MODE_STOP_BITS_0_5 = 3,
237 : };
238 :
239 0 : #define UBX_CFG_PRT_MODE_CHAR_LEN(val) (((val) & BIT_MASK(2)) << 6)
240 0 : #define UBX_CFG_PRT_MODE_PARITY(val) (((val) & BIT_MASK(3)) << 9)
241 0 : #define UBX_CFG_PRT_MODE_STOP_BITS(val) (((val) & BIT_MASK(2)) << 12)
242 :
243 0 : #define UBX_CFG_PRT_PROTO_MASK_UBX BIT(0)
244 0 : #define UBX_CFG_PRT_PROTO_MASK_NMEA BIT(1)
245 0 : #define UBX_CFG_PRT_PROTO_MASK_RTCM3 BIT(5)
246 :
247 0 : struct ubx_cfg_prt {
248 0 : uint8_t port_id; /* See ubx_cfg_port_id */
249 0 : uint8_t reserved1;
250 0 : uint16_t rx_ready_pin;
251 0 : uint32_t mode;
252 0 : uint32_t baudrate;
253 0 : uint16_t in_proto_mask;
254 0 : uint16_t out_proto_mask;
255 0 : uint16_t flags;
256 0 : uint16_t reserved2;
257 : };
258 :
259 0 : enum ubx_dyn_model {
260 : UBX_DYN_MODEL_PORTABLE = 0,
261 : UBX_DYN_MODEL_STATIONARY = 2,
262 : UBX_DYN_MODEL_PEDESTRIAN = 3,
263 : UBX_DYN_MODEL_AUTOMOTIVE = 4,
264 : UBX_DYN_MODEL_SEA = 5,
265 : UBX_DYN_MODEL_AIRBORNE_1G = 6,
266 : UBX_DYN_MODEL_AIRBORNE_2G = 7,
267 : UBX_DYN_MODEL_AIRBORNE_4G = 8,
268 : UBX_DYN_MODEL_WRIST = 9,
269 : UBX_DYN_MODEL_BIKE = 10,
270 : };
271 :
272 0 : enum ubx_fix_mode {
273 : UBX_FIX_MODE_2D_ONLY = 1,
274 : UBX_FIX_MODE_3D_ONLY = 2,
275 : UBX_FIX_MODE_AUTO = 3,
276 : };
277 :
278 0 : enum ubx_utc_standard {
279 : UBX_UTC_STANDARD_AUTOMATIC = 0,
280 : UBX_UTC_STANDARD_GPS = 3,
281 : UBX_UTC_STANDARD_GALILEO = 5,
282 : UBX_UTC_STANDARD_GLONASS = 6,
283 : UBX_UTC_STANDARD_BEIDOU = 7,
284 : };
285 :
286 0 : #define UBX_CFG_NAV5_APPLY_DYN BIT(0)
287 0 : #define UBX_CFG_NAV5_APPLY_FIX_MODE BIT(2)
288 :
289 0 : struct ubx_cfg_nav5 {
290 0 : uint16_t apply;
291 0 : uint8_t dyn_model; /* Dynamic platform model. See ubx_dyn_model */
292 0 : uint8_t fix_mode; /* Position fixing mode. See ubx_fix_mode */
293 0 : int32_t fixed_alt; /* Fixed altitude for 2D fix mode. Meters */
294 0 : uint32_t fixed_alt_var; /* Variance for Fixed altitude in 2D mode. Sq. meters */
295 0 : int8_t min_elev; /* Minimum Elevation to use a GNSS satellite in Navigation. Degrees */
296 0 : uint8_t dr_limit; /* Reserved */
297 0 : uint16_t p_dop; /* Position DOP mask */
298 0 : uint16_t t_dop; /* Time DOP mask */
299 0 : uint16_t p_acc; /* Position accuracy mask. Meters */
300 0 : uint16_t t_acc; /* Time accuracy mask. Meters */
301 0 : uint8_t static_hold_thresh; /* Static hold threshold. cm/s */
302 0 : uint8_t dgnss_timeout; /* DGNSS timeout. Seconds */
303 0 : uint8_t cno_thresh_num_svs; /* Number of satellites required above cno_thresh */
304 0 : uint8_t cno_thresh; /* C/N0 threshold for GNSS signals. dbHz */
305 0 : uint8_t reserved1[2];
306 0 : uint16_t static_hold_max_dist; /* Static hold distance threshold. Meters */
307 0 : uint8_t utc_standard; /* UTC standard to be used. See ubx_utc_standard */
308 0 : uint8_t reserved2[5];
309 : } __packed;
310 :
311 0 : enum ubx_cfg_rst_start_mode {
312 : UBX_CFG_RST_HOT_START = 0x0000,
313 : UBX_CFG_RST_WARM_START = 0x0001,
314 : UBX_CFG_RST_COLD_START = 0xFFFF,
315 : };
316 :
317 0 : enum ubx_cfg_rst_mode {
318 : UBX_CFG_RST_MODE_HW = 0x00,
319 : UBX_CFG_RST_MODE_SW = 0x01,
320 : UBX_CFG_RST_MODE_GNSS_STOP = 0x08,
321 : UBX_CFG_RST_MODE_GNSS_START = 0x09,
322 : };
323 :
324 0 : struct ubx_cfg_rst {
325 0 : uint16_t nav_bbr_mask;
326 0 : uint8_t reset_mode;
327 0 : uint8_t reserved;
328 : };
329 :
330 0 : enum ubx_cfg_rate_time_ref {
331 : UBX_CFG_RATE_TIME_REF_UTC = 0,
332 : UBX_CFG_RATE_TIME_REF_GPS = 1,
333 : UBX_CFG_RATE_TIME_REF_GLONASS = 2,
334 : UBX_CFG_RATE_TIME_REF_BEIDOU = 3,
335 : UBX_CFG_RATE_TIME_REF_GALILEO = 4,
336 : UBX_CFG_RATE_TIME_REF_NAVIC = 5,
337 : };
338 :
339 0 : struct ubx_cfg_rate {
340 0 : uint16_t meas_rate_ms;
341 0 : uint16_t nav_rate;
342 0 : uint16_t time_ref;
343 : };
344 :
345 0 : enum ubx_cfg_val_ver {
346 : UBX_CFG_VAL_VER_SIMPLE = 0,
347 : UBX_CFG_VAL_VER_TRANSACTION = 1,
348 : };
349 :
350 0 : struct ubx_cfg_val_hdr {
351 0 : uint8_t ver; /* See ubx_cfg_val_ver */
352 0 : uint8_t layer;
353 0 : uint16_t position;
354 : } __packed;
355 :
356 0 : struct ubx_cfg_val_u8 {
357 0 : struct ubx_cfg_val_hdr hdr;
358 0 : uint32_t key;
359 0 : uint8_t value;
360 : } __packed;
361 :
362 0 : struct ubx_cfg_val_u16 {
363 0 : struct ubx_cfg_val_hdr hdr;
364 0 : uint32_t key;
365 0 : uint16_t value;
366 : } __packed;
367 :
368 0 : struct ubx_cfg_val_u32 {
369 0 : struct ubx_cfg_val_hdr hdr;
370 0 : uint32_t key;
371 0 : uint32_t value;
372 : } __packed;
373 :
374 0 : enum ubx_msg_id_nmea_std {
375 : UBX_MSG_ID_NMEA_STD_DTM = 0x0A,
376 : UBX_MSG_ID_NMEA_STD_GBQ = 0x44,
377 : UBX_MSG_ID_NMEA_STD_GBS = 0x09,
378 : UBX_MSG_ID_NMEA_STD_GGA = 0x00,
379 : UBX_MSG_ID_NMEA_STD_GLL = 0x01,
380 : UBX_MSG_ID_NMEA_STD_GLQ = 0x43,
381 : UBX_MSG_ID_NMEA_STD_GNQ = 0x42,
382 : UBX_MSG_ID_NMEA_STD_GNS = 0x0D,
383 : UBX_MSG_ID_NMEA_STD_GPQ = 0x40,
384 : UBX_MSG_ID_NMEA_STD_GRS = 0x06,
385 : UBX_MSG_ID_NMEA_STD_GSA = 0x02,
386 : UBX_MSG_ID_NMEA_STD_GST = 0x07,
387 : UBX_MSG_ID_NMEA_STD_GSV = 0x03,
388 : UBX_MSG_ID_NMEA_STD_RMC = 0x04,
389 : UBX_MSG_ID_NMEA_STD_THS = 0x0E,
390 : UBX_MSG_ID_NMEA_STD_TXT = 0x41,
391 : UBX_MSG_ID_NMEA_STD_VLW = 0x0F,
392 : UBX_MSG_ID_NMEA_STD_VTG = 0x05,
393 : UBX_MSG_ID_NMEA_STD_ZDA = 0x08,
394 : };
395 :
396 0 : enum ubx_msg_id_nmea_pubx {
397 : UBX_MSG_ID_NMEA_PUBX_CONFIG = 0x41,
398 : UBX_MSG_ID_NMEA_PUBX_POSITION = 0x00,
399 : UBX_MSG_ID_NMEA_PUBX_RATE = 0x40,
400 : UBX_MSG_ID_NMEA_PUBX_SVSTATUS = 0x03,
401 : UBX_MSG_ID_NMEA_PUBX_TIME = 0x04,
402 : };
403 :
404 0 : struct ubx_cfg_msg_rate {
405 0 : uint8_t class;
406 0 : uint8_t id;
407 0 : uint8_t rate;
408 : };
409 :
410 0 : struct ubx_mon_ver {
411 0 : char sw_ver[30];
412 0 : char hw_ver[10];
413 : };
414 :
415 1 : static inline uint16_t ubx_calc_checksum(const struct ubx_frame *frame, size_t len)
416 : {
417 : uint8_t ck_a = 0;
418 : uint8_t ck_b = 0;
419 : const uint8_t *data = (const uint8_t *)frame;
420 :
421 : /** Mismatch in expected and actual length results in an invalid frame */
422 : if (len != UBX_FRAME_SZ(frame->payload_size)) {
423 : return 0xFFFF;
424 : }
425 :
426 : for (int i = UBX_FRAME_MSG_CLASS_IDX ; i < (UBX_FRAME_SZ(frame->payload_size) - 2) ; i++) {
427 : ck_a = ck_a + data[i];
428 : ck_b = ck_b + ck_a;
429 : }
430 :
431 : return ((ck_a & 0xFF) | ((ck_b & 0xFF) << 8));
432 : }
433 :
434 0 : static inline int ubx_frame_encode(uint8_t class, uint8_t id,
435 : const uint8_t *payload, size_t payload_len,
436 : uint8_t *buf, size_t buf_len)
437 : {
438 : if (buf_len < UBX_FRAME_SZ(payload_len)) {
439 : return -EINVAL;
440 : }
441 :
442 : struct ubx_frame *frame = (struct ubx_frame *)buf;
443 :
444 : frame->preamble_sync_char_1 = UBX_PREAMBLE_SYNC_CHAR_1;
445 : frame->preamble_sync_char_2 = UBX_PREAMBLE_SYNC_CHAR_2;
446 : frame->class = class;
447 : frame->id = id;
448 : frame->payload_size = payload_len;
449 : memcpy(frame->payload_and_checksum, payload, payload_len);
450 :
451 : uint16_t checksum = ubx_calc_checksum(frame, UBX_FRAME_SZ(payload_len));
452 :
453 : frame->payload_and_checksum[payload_len] = checksum & 0xFF;
454 : frame->payload_and_checksum[payload_len + 1] = (checksum >> 8) & 0xFF;
455 :
456 : return UBX_FRAME_SZ(payload_len);
457 : }
458 :
459 0 : #define UBX_FRAME_DEFINE(_name, _frame) \
460 : const static struct ubx_frame _name = _frame
461 :
462 0 : #define UBX_FRAME_ARRAY_DEFINE(_name, ...) \
463 : const struct ubx_frame *_name[] = {__VA_ARGS__};
464 :
465 0 : #define UBX_FRAME_ACK_INITIALIZER(_class_id, _msg_id) \
466 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_ACK, UBX_MSG_ID_ACK, _class_id, _msg_id)
467 :
468 0 : #define UBX_FRAME_NAK_INITIALIZER(_class_id, _msg_id) \
469 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_ACK, UBX_MSG_ID_NAK, _class_id, _msg_id)
470 :
471 0 : #define UBX_FRAME_CFG_RST_INITIALIZER(_start_mode, _reset_mode) \
472 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_CFG, UBX_MSG_ID_CFG_RST, \
473 : (_start_mode & 0xFF), ((_start_mode >> 8) & 0xFF), \
474 : _reset_mode, 0)
475 :
476 0 : #define UBX_FRAME_CFG_RATE_INITIALIZER(_meas_rate_ms, _nav_rate, _time_ref) \
477 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_CFG, UBX_MSG_ID_CFG_RATE, \
478 : (_meas_rate_ms & 0xFF), ((_meas_rate_ms >> 8) & 0xFF), \
479 : (_nav_rate & 0xFF), ((_nav_rate >> 8) & 0xFF), \
480 : (_time_ref & 0xFF), ((_time_ref >> 8) & 0xFF))
481 :
482 0 : #define UBX_FRAME_CFG_MSG_RATE_INITIALIZER(_class_id, _msg_id, _rate) \
483 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_CFG, UBX_MSG_ID_CFG_MSG, \
484 : _class_id, _msg_id, _rate)
485 :
486 0 : #define UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(_key, _value) \
487 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_CFG, UBX_MSG_ID_CFG_VAL_SET, \
488 : 0x00, 0x01, 0x00, 0x00, \
489 : ((_key) & 0xFF), (((_key) >> 8) & 0xFF), \
490 : (((_key) >> 16) & 0xFF), (((_key) >> 24) & 0xFF), \
491 : ((_value) & 0xFF))
492 :
493 0 : #define UBX_FRAME_CFG_VAL_SET_U16_INITIALIZER(_key, _value) \
494 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_CFG, UBX_MSG_ID_CFG_VAL_SET, \
495 : 0x00, 0x01, 0x00, 0x00, \
496 : ((_key) & 0xFF), (((_key) >> 8) & 0xFF), \
497 : (((_key) >> 16) & 0xFF), (((_key) >> 24) & 0xFF), \
498 : ((_value) & 0xFF), (((_value) >> 8) & 0xFF))
499 :
500 0 : #define UBX_FRAME_CFG_VAL_SET_U32_INITIALIZER(_key, _value) \
501 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_CFG, UBX_MSG_ID_CFG_VAL_SET, \
502 : 0x00, 0x01, 0x00, 0x00, \
503 : ((_key) & 0xFF), (((_key) >> 8) & 0xFF), \
504 : (((_key) >> 16) & 0xFF), (((_key) >> 24) & 0xFF), \
505 : ((_value) & 0xFF), (((_value) >> 8) & 0xFF), \
506 : (((_value) >> 16) & 0xFF), (((_value) >> 24) & 0xFF))
507 :
508 0 : #define UBX_FRAME_CFG_VAL_GET_INITIALIZER(_key) \
509 : UBX_FRAME_INITIALIZER_PAYLOAD(UBX_CLASS_ID_CFG, UBX_MSG_ID_CFG_VAL_GET, \
510 : 0x00, 0x00, 0x00, 0x00, \
511 : ((_key) & 0xFF), (((_key) >> 8) & 0xFF), \
512 : (((_key) >> 16) & 0xFF), (((_key) >> 24) & 0xFF))
513 :
514 0 : #define UBX_FRAME_INITIALIZER_PAYLOAD(_class_id, _msg_id, ...) \
515 : _UBX_FRAME_INITIALIZER_PAYLOAD(_class_id, _msg_id, __VA_ARGS__)
516 :
517 : #define _UBX_FRAME_INITIALIZER_PAYLOAD(_class_id, _msg_id, ...) \
518 : { \
519 : .preamble_sync_char_1 = UBX_PREAMBLE_SYNC_CHAR_1, \
520 : .preamble_sync_char_2 = UBX_PREAMBLE_SYNC_CHAR_2, \
521 : .class = _class_id, \
522 : .id = _msg_id, \
523 : .payload_size = (NUM_VA_ARGS(__VA_ARGS__)) & 0xFFFF, \
524 : .payload_and_checksum = { \
525 : __VA_ARGS__, \
526 : UBX_CSUM(_class_id, _msg_id, \
527 : ((NUM_VA_ARGS(__VA_ARGS__)) & 0xFF), \
528 : (((NUM_VA_ARGS(__VA_ARGS__)) >> 8) & 0xFF), \
529 : __VA_ARGS__), \
530 : }, \
531 : }
532 :
533 0 : #define UBX_FRAME_GET_INITIALIZER(_class_id, _msg_id) \
534 : { \
535 : .preamble_sync_char_1 = UBX_PREAMBLE_SYNC_CHAR_1, \
536 : .preamble_sync_char_2 = UBX_PREAMBLE_SYNC_CHAR_2, \
537 : .class = _class_id, \
538 : .id = _msg_id, \
539 : .payload_size = 0, \
540 : .payload_and_checksum = { \
541 : UBX_CSUM(_class_id, _msg_id, 0, 0), \
542 : }, \
543 : }
544 :
545 : #endif /* ZEPHYR_MODEM_UBX_PROTOCOL_ */
|