1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/types.h>
9 #include <zephyr/modem/ubx.h>
10 #include "gnss_u_blox_protocol_defines.h"
11 
12 #ifndef ZEPHYR_U_BLOX_PROTOCOL_
13 #define ZEPHYR_U_BLOX_PROTOCOL_
14 
15 #define UBX_BAUDRATE_COUNT			9
16 
17 /* When a configuration frame is sent, the device requires some delay to reflect the changes. */
18 /* TODO: check what is the precise waiting time for each message. */
19 #define UBX_CFG_RST_WAIT_MS			6000
20 #define UBX_CFG_GNSS_WAIT_MS			6000
21 #define UBX_CFG_NAV5_WAIT_MS			6000
22 
23 extern const uint32_t ubx_baudrate[UBX_BAUDRATE_COUNT];
24 
25 #define UBX_FRM_GET_PAYLOAD_SZ		0
26 #define UBX_CFG_ACK_PAYLOAD_SZ		2
27 #define UBX_CFG_NAK_PAYLOAD_SZ		2
28 #define UBX_CFG_RATE_PAYLOAD_SZ		6
29 #define UBX_CFG_PRT_POLL_PAYLOAD_SZ	1
30 #define UBX_CFG_PRT_POLL_FRM_SZ		(UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_PRT_POLL_PAYLOAD_SZ)
31 #define UBX_CFG_PRT_SET_PAYLOAD_SZ	20
32 #define UBX_CFG_PRT_SET_FRM_SZ		(UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_PRT_SET_PAYLOAD_SZ)
33 #define UBX_CFG_RST_PAYLOAD_SZ		4
34 #define UBX_CFG_RST_FRM_SZ		(UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_RST_PAYLOAD_SZ)
35 #define UBX_CFG_NAV5_PAYLOAD_SZ		36
36 #define UBX_CFG_NAV5_FRM_SZ		(UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_NAV5_PAYLOAD_SZ)
37 #define UBX_CFG_MSG_PAYLOAD_SZ		3
38 #define UBX_CFG_MSG_FRM_SZ		(UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_MSG_PAYLOAD_SZ)
39 #define UBX_CFG_GNSS_PAYLOAD_INIT_SZ	4
40 #define UBX_CFG_GNSS_PAYLOAD_CFG_BLK_SZ	8
41 #define UBX_CFG_GNSS_PAYLOAD_SZ(n)	\
42 	(UBX_CFG_GNSS_PAYLOAD_INIT_SZ + UBX_CFG_GNSS_PAYLOAD_CFG_BLK_SZ * n)
43 #define UBX_CFG_GNSS_FRM_SZ(n)		(UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_GNSS_PAYLOAD_SZ(n))
44 
45 
46 int ubx_create_and_validate_frame(uint8_t *ubx_frame, uint16_t ubx_frame_size, uint8_t msg_cls,
47 				  uint8_t msg_id, const void *payload, uint16_t payload_size);
48 
49 struct ubx_cfg_ack_payload {
50 	uint8_t message_class;
51 	uint8_t message_id;
52 };
53 
54 void ubx_cfg_ack_payload_default(struct ubx_cfg_ack_payload *payload);
55 
56 #define UBX_CFG_RATE_TIME_REF_UTC	0	/* Align measurements to UTC time. */
57 #define UBX_CFG_RATE_TIME_REF_GPS	1	/* Align measurements to GPS time. */
58 #define UBX_CFG_RATE_TIME_REF_GLO	2	/* Align measurements to GLONASS time. */
59 #define UBX_CFG_RATE_TIME_REF_BDS	3	/* Align measurements to BeiDou time. */
60 #define UBX_CFG_RATE_TIME_REF_GAL	4	/* Align measurements to Galileo time. */
61 
62 struct ubx_cfg_rate_payload {
63 	uint16_t meas_rate_ms;
64 	uint16_t nav_rate;
65 	uint16_t time_ref;
66 };
67 
68 void ubx_cfg_rate_payload_default(struct ubx_cfg_rate_payload *payload);
69 
70 struct ubx_cfg_prt_poll_payload {
71 	uint8_t port_id;
72 };
73 
74 void ubx_cfg_prt_poll_payload_default(struct ubx_cfg_prt_poll_payload *payload);
75 
76 #define UBX_CFG_PRT_IN_PROTO_UBX			BIT(0)
77 #define UBX_CFG_PRT_IN_PROTO_NMEA			BIT(1)
78 #define UBX_CFG_PRT_IN_PROTO_RTCM			BIT(2)
79 #define UBX_CFG_PRT_IN_PROTO_RTCM3			BIT(5)
80 #define UBX_CFG_PRT_OUT_PROTO_UBX			BIT(0)
81 #define UBX_CFG_PRT_OUT_PROTO_NMEA			BIT(1)
82 #define UBX_CFG_PRT_OUT_PROTO_RTCM3			BIT(5)
83 
84 #define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_5		0U
85 #define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_6		BIT(6)
86 #define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_7		BIT(7)
87 #define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_8		(BIT(6) | BIT(7))
88 
89 #define UBX_CFG_PRT_PORT_MODE_PARITY_EVEN		0U
90 #define UBX_CFG_PRT_PORT_MODE_PARITY_ODD		BIT(9)
91 #define UBX_CFG_PRT_PORT_MODE_PARITY_NONE		BIT(11)
92 
93 #define UBX_CFG_PRT_PORT_MODE_STOP_BITS_1		0U
94 #define UBX_CFG_PRT_PORT_MODE_STOP_BITS_1_HALF		BIT(12)
95 #define UBX_CFG_PRT_PORT_MODE_STOP_BITS_2		BIT(13)
96 #define UBX_CFG_PRT_PORT_MODE_STOP_BITS_HALF		(BIT(12) | BIT(13))
97 
98 #define UBX_CFG_PRT_RESERVED0				0x00
99 #define UBX_CFG_PRT_TX_READY_PIN_CONF_DEFAULT		0x0000
100 #define UBX_CFG_PRT_TX_READY_PIN_CONF_EN		BIT(0)
101 #define UBX_CFG_PRT_TX_READY_PIN_CONF_POL_LOW		BIT(1)
102 #define UBX_CFG_PRT_TX_READY_PIN_CONF_POL_HIGH		0U
103 #define UBX_CFG_PRT_RESERVED1				0x00
104 #define UBX_CFG_PRT_FLAGS_DEFAULT			0x0000
105 #define UBX_CFG_PRT_FLAGS_EXTENDED_TX_TIMEOUT		BIT(0)
106 
107 struct ubx_cfg_prt_set_payload {
108 	uint8_t port_id;
109 	uint8_t reserved0;
110 	uint16_t tx_ready_pin_conf;
111 	uint32_t port_mode;
112 	uint32_t baudrate;
113 	uint16_t in_proto_mask;
114 	uint16_t out_proto_mask;
115 	uint16_t flags;
116 	uint8_t reserved1;
117 };
118 
119 void ubx_cfg_prt_set_payload_default(struct ubx_cfg_prt_set_payload *payload);
120 
121 #define UBX_CFG_RST_NAV_BBR_MASK_HOT_START				0x0000
122 #define UBX_CFG_RST_NAV_BBR_MASK_WARM_START				0x0001
123 #define UBX_CFG_RST_NAV_BBR_MASK_COLD_START				0xFFFF
124 
125 #define UBX_CFG_RST_RESET_MODE_HARD_RESET				0x00
126 #define UBX_CFG_RST_RESET_MODE_CONTROLLED_SOFT_RESET			0x01
127 #define UBX_CFG_RST_RESET_MODE_CONTROLLED_SOFT_RESET_GNSS_ONLY		0x02
128 #define UBX_CFG_RST_RESET_MODE_HARD_RESET_AFTER_SHUTDOWN		0x04
129 #define UBX_CFG_RST_RESET_MODE_CONTROLLED_GNSS_STOP			0x08
130 #define UBX_CFG_RST_RESET_MODE_CONTROLLED_GNSS_START			0x09
131 
132 #define UBX_CFG_RST_RESERVED0						0x00
133 
134 struct ubx_cfg_rst_payload {
135 	uint16_t nav_bbr_mask;
136 	uint8_t reset_mode;
137 	uint8_t reserved0;
138 };
139 
140 void ubx_cfg_rst_payload_default(struct ubx_cfg_rst_payload *payload);
141 
142 #define UBX_CFG_NAV5_MASK_ALL				0x05FF
143 #define UBX_CFG_NAV5_FIX_MODE_DEFAULT			UBX_FIX_AUTO_FIX
144 #define UBX_CFG_NAV5_FIXED_ALT_DEFAULT			0
145 #define UBX_CFG_NAV5_FIXED_ALT_VAR_DEFAULT		1U
146 #define UBX_CFG_NAV5_MIN_ELEV_DEFAULT			5
147 #define UBX_CFG_NAV5_DR_LIMIT_DEFAULT			3U
148 #define UBX_CFG_NAV5_P_DOP_DEFAULT			100U
149 #define UBX_CFG_NAV5_T_DOP_DEFAULT			100U
150 #define UBX_CFG_NAV5_P_ACC_DEFAULT			100U
151 #define UBX_CFG_NAV5_T_ACC_DEFAULT			350U
152 #define UBX_CFG_NAV5_STATIC_HOLD_THRESHOLD_DEFAULT	0U
153 #define UBX_CFG_NAV5_DGNSS_TIMEOUT_DEFAULT		60U
154 #define UBX_CFG_NAV5_CNO_THRESHOLD_NUM_SVS_DEFAULT	0U
155 #define UBX_CFG_NAV5_CNO_THRESHOLD_DEFAULT		0U
156 #define UBX_CFG_NAV5_RESERVED0				0U
157 #define UBX_CFG_NAV5_STATIC_HOLD_DIST_THRESHOLD		0U
158 #define UBX_CFG_NAV5_UTC_STANDARD_DEFAULT		UBX_UTC_AUTOUTC
159 
160 struct ubx_cfg_nav5_payload {
161 	uint16_t mask;
162 	uint8_t dyn_model;
163 
164 	uint8_t fix_mode;
165 
166 	int32_t fixed_alt;
167 	uint32_t fixed_alt_var;
168 
169 	int8_t min_elev;
170 	uint8_t dr_limit;
171 
172 	uint16_t p_dop;
173 	uint16_t t_dop;
174 	uint16_t p_acc;
175 	uint16_t t_acc;
176 
177 	uint8_t static_hold_threshold;
178 	uint8_t dgnss_timeout;
179 	uint8_t cno_threshold_num_svs;
180 	uint8_t cno_threshold;
181 
182 	uint16_t reserved0;
183 
184 	uint16_t static_hold_dist_threshold;
185 	uint8_t utc_standard;
186 };
187 
188 void ubx_cfg_nav5_payload_default(struct ubx_cfg_nav5_payload *payload);
189 
190 #define UBX_CFG_GNSS_MSG_VER			0x00
191 #define UBX_CFG_GNSS_NUM_TRK_CH_HW_DEFAULT	0x31
192 #define UBX_CFG_GNSS_NUM_TRK_CH_USE_DEFAULT	0x31
193 
194 #define UBX_CFG_GNSS_RESERVED0			0x00
195 #define UBX_CFG_GNSS_FLAG_ENABLE		BIT(0)
196 #define UBX_CFG_GNSS_FLAG_DISABLE		0U
197 #define UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT		16
198 /* When gnss_id is 0 (GPS) */
199 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L1C_A	(0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
200 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L2C	(0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
201 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L5	(0x20 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
202 /* When gnss_id is 1 (SBAS) */
203 #define UBX_CFG_GNSS_FLAG_SGN_CNF_SBAS_L1C_A	(0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
204 /* When gnss_id is 2 (Galileo) */
205 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GALILEO_E1	(0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
206 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GALILEO_E5A	(0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
207 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GALILEO_E5B	(0x20 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
208 /* When gnss_id is 3 (BeiDou) */
209 #define UBX_CFG_GNSS_FLAG_SGN_CNF_BEIDOU_B1I	(0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
210 #define UBX_CFG_GNSS_FLAG_SGN_CNF_BEIDOU_B2I	(0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
211 #define UBX_CFG_GNSS_FLAG_SGN_CNF_BEIDOU_B2A	(0x80 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
212 /* When gnss_id is 4 (IMES) */
213 #define UBX_CFG_GNSS_FLAG_SGN_CNF_IMES_L1	(0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
214 /* When gnss_id is 5 (QZSS) */
215 #define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L1C_A	(0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
216 #define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L1S	(0x04 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
217 #define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L2C	(0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
218 #define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L5	(0x20 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
219 /* When gnss_id is 6 (GLONASS) */
220 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GLONASS_L1	(0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
221 #define UBX_CFG_GNSS_FLAG_SGN_CNF_GLONASS_L2	(0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
222 
223 struct ubx_cfg_gnss_payload_config_block {
224 	uint8_t gnss_id;
225 	uint8_t num_res_trk_ch;
226 	uint8_t max_num_trk_ch;
227 	uint8_t reserved0;
228 	uint32_t flags;
229 };
230 
231 struct ubx_cfg_gnss_payload {
232 	uint8_t msg_ver;
233 	uint8_t num_trk_ch_hw;
234 	uint8_t num_trk_ch_use;
235 	uint8_t num_config_blocks;
236 	struct ubx_cfg_gnss_payload_config_block config_blocks[];
237 };
238 
239 void ubx_cfg_gnss_payload_default(struct ubx_cfg_gnss_payload *payload);
240 
241 #define UBX_CFG_MSG_RATE_DEFAULT			1
242 
243 struct ubx_cfg_msg_payload {
244 	uint8_t message_class;
245 	uint8_t message_id;
246 	uint8_t rate;
247 };
248 
249 void ubx_cfg_msg_payload_default(struct ubx_cfg_msg_payload *payload);
250 
251 #endif /* ZEPHYR_U_BLOX_PROTOCOL_ */
252