1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "gnss_u_blox_protocol.h"
8 
9 const uint32_t ubx_baudrate[UBX_BAUDRATE_COUNT] = {
10 	4800,
11 	9600,
12 	19200,
13 	38400,
14 	57600,
15 	115200,
16 	230400,
17 	460800,
18 	921600,
19 };
20 
ubx_validate_payload_size_ack(uint8_t msg_id,uint16_t payload_size)21 static inline int ubx_validate_payload_size_ack(uint8_t msg_id, uint16_t payload_size)
22 {
23 	switch (msg_id) {
24 	case UBX_ACK_ACK:
25 		return payload_size == UBX_CFG_ACK_PAYLOAD_SZ ? 0 : -1;
26 	case UBX_ACK_NAK:
27 		return payload_size == UBX_CFG_NAK_PAYLOAD_SZ ? 0 : -1;
28 	default:
29 		return -1;
30 	}
31 }
32 
ubx_validate_payload_size_cfg(uint8_t msg_id,uint16_t payload_size)33 static inline int ubx_validate_payload_size_cfg(uint8_t msg_id, uint16_t payload_size)
34 {
35 	switch (msg_id) {
36 	case UBX_CFG_RATE:
37 		return payload_size == UBX_CFG_RATE_PAYLOAD_SZ ? 0 : -1;
38 	case UBX_CFG_PRT:
39 		return (payload_size == UBX_CFG_PRT_POLL_PAYLOAD_SZ ||
40 		       payload_size == UBX_CFG_PRT_SET_PAYLOAD_SZ) ? 0 : -1;
41 	case UBX_CFG_RST:
42 		return payload_size == UBX_CFG_RST_PAYLOAD_SZ ? 0 : -1;
43 	case UBX_CFG_NAV5:
44 		return payload_size == UBX_CFG_NAV5_PAYLOAD_SZ ? 0 : -1;
45 	case UBX_CFG_GNSS:
46 		return ((payload_size - UBX_CFG_GNSS_PAYLOAD_INIT_SZ) %
47 		       UBX_CFG_GNSS_PAYLOAD_CFG_BLK_SZ == 0) ? 0 : -1;
48 	case UBX_CFG_MSG:
49 		return payload_size == UBX_CFG_MSG_PAYLOAD_SZ ? 0 : -1;
50 	default:
51 		return -1;
52 	}
53 }
54 
ubx_validate_payload_size(uint8_t msg_cls,uint8_t msg_id,uint16_t payload_size)55 static inline int ubx_validate_payload_size(uint8_t msg_cls, uint8_t msg_id, uint16_t payload_size)
56 {
57 	if (payload_size == 0) {
58 		return 0;
59 	}
60 
61 	if (payload_size > UBX_PAYLOAD_SZ_MAX) {
62 		return -1;
63 	}
64 
65 	switch (msg_cls) {
66 	case UBX_CLASS_ACK:
67 		return ubx_validate_payload_size_ack(msg_id, payload_size);
68 	case UBX_CLASS_CFG:
69 		return ubx_validate_payload_size_cfg(msg_id, payload_size);
70 	default:
71 		return -1;
72 	}
73 }
74 
ubx_create_and_validate_frame(uint8_t * ubx_frame,uint16_t ubx_frame_size,uint8_t msg_cls,uint8_t msg_id,const void * payload,uint16_t payload_size)75 int ubx_create_and_validate_frame(uint8_t *ubx_frame, uint16_t ubx_frame_size, uint8_t msg_cls,
76 				  uint8_t msg_id, const void *payload, uint16_t payload_size)
77 {
78 	if (ubx_validate_payload_size(msg_cls, msg_id, payload_size)) {
79 		return -1;
80 	}
81 
82 	return modem_ubx_create_frame(ubx_frame, ubx_frame_size, msg_cls, msg_id, payload,
83 				      payload_size);
84 }
85 
ubx_cfg_ack_payload_default(struct ubx_cfg_ack_payload * payload)86 void ubx_cfg_ack_payload_default(struct ubx_cfg_ack_payload *payload)
87 {
88 	payload->message_class = UBX_CLASS_CFG;
89 	payload->message_id = UBX_CFG_PRT;
90 }
91 
ubx_cfg_rate_payload_default(struct ubx_cfg_rate_payload * payload)92 void ubx_cfg_rate_payload_default(struct ubx_cfg_rate_payload *payload)
93 {
94 	payload->meas_rate_ms = 1000;
95 	payload->nav_rate = 1;
96 	payload->time_ref = UBX_CFG_RATE_TIME_REF_UTC;
97 }
98 
ubx_cfg_prt_poll_payload_default(struct ubx_cfg_prt_poll_payload * payload)99 void ubx_cfg_prt_poll_payload_default(struct ubx_cfg_prt_poll_payload *payload)
100 {
101 	payload->port_id = UBX_PORT_NUMBER_UART;
102 }
103 
ubx_cfg_prt_set_payload_default(struct ubx_cfg_prt_set_payload * payload)104 void ubx_cfg_prt_set_payload_default(struct ubx_cfg_prt_set_payload *payload)
105 {
106 	payload->port_id = UBX_PORT_NUMBER_UART;
107 	payload->reserved0 = UBX_CFG_PRT_RESERVED0;
108 	payload->tx_ready_pin_conf = UBX_CFG_PRT_TX_READY_PIN_CONF_POL_HIGH;
109 	payload->port_mode = UBX_CFG_PRT_PORT_MODE_CHAR_LEN_8 | UBX_CFG_PRT_PORT_MODE_PARITY_NONE |
110 			     UBX_CFG_PRT_PORT_MODE_STOP_BITS_1;
111 	payload->baudrate = ubx_baudrate[3];
112 	payload->in_proto_mask = UBX_CFG_PRT_IN_PROTO_UBX | UBX_CFG_PRT_IN_PROTO_NMEA |
113 				 UBX_CFG_PRT_IN_PROTO_RTCM;
114 	payload->out_proto_mask = UBX_CFG_PRT_OUT_PROTO_UBX | UBX_CFG_PRT_OUT_PROTO_NMEA |
115 				  UBX_CFG_PRT_OUT_PROTO_RTCM3;
116 	payload->flags = UBX_CFG_PRT_FLAGS_DEFAULT;
117 	payload->reserved1 = UBX_CFG_PRT_RESERVED1;
118 }
119 
ubx_cfg_rst_payload_default(struct ubx_cfg_rst_payload * payload)120 void ubx_cfg_rst_payload_default(struct ubx_cfg_rst_payload *payload)
121 {
122 	payload->nav_bbr_mask = UBX_CFG_RST_NAV_BBR_MASK_HOT_START;
123 	payload->reset_mode = UBX_CFG_RST_RESET_MODE_CONTROLLED_SOFT_RESET;
124 	payload->reserved0 = UBX_CFG_RST_RESERVED0;
125 }
126 
ubx_cfg_nav5_payload_default(struct ubx_cfg_nav5_payload * payload)127 void ubx_cfg_nav5_payload_default(struct ubx_cfg_nav5_payload *payload)
128 {
129 	payload->mask = UBX_CFG_NAV5_MASK_ALL;
130 	payload->dyn_model = UBX_DYN_MODEL_PORTABLE;
131 
132 	payload->fix_mode = UBX_FIX_AUTO_FIX;
133 
134 	payload->fixed_alt = UBX_CFG_NAV5_FIXED_ALT_DEFAULT;
135 	payload->fixed_alt_var = UBX_CFG_NAV5_FIXED_ALT_VAR_DEFAULT;
136 
137 	payload->min_elev = UBX_CFG_NAV5_MIN_ELEV_DEFAULT;
138 	payload->dr_limit = UBX_CFG_NAV5_DR_LIMIT_DEFAULT;
139 
140 	payload->p_dop = UBX_CFG_NAV5_P_DOP_DEFAULT;
141 	payload->t_dop = UBX_CFG_NAV5_T_DOP_DEFAULT;
142 	payload->p_acc = UBX_CFG_NAV5_P_ACC_DEFAULT;
143 	payload->t_acc = UBX_CFG_NAV5_T_ACC_DEFAULT;
144 
145 	payload->static_hold_threshold = UBX_CFG_NAV5_STATIC_HOLD_THRESHOLD_DEFAULT;
146 	payload->dgnss_timeout = UBX_CFG_NAV5_DGNSS_TIMEOUT_DEFAULT;
147 	payload->cno_threshold_num_svs = UBX_CFG_NAV5_CNO_THRESHOLD_NUM_SVS_DEFAULT;
148 	payload->cno_threshold = UBX_CFG_NAV5_CNO_THRESHOLD_DEFAULT;
149 
150 	payload->reserved0 = UBX_CFG_NAV5_RESERVED0;
151 
152 	payload->static_hold_dist_threshold = UBX_CFG_NAV5_STATIC_HOLD_DIST_THRESHOLD;
153 	payload->utc_standard = UBX_CFG_NAV5_UTC_STANDARD_DEFAULT;
154 }
155 
156 static struct ubx_cfg_gnss_payload_config_block ubx_cfg_gnss_payload_config_block_default = {
157 	.gnss_id = UBX_GNSS_ID_GPS,
158 	.num_res_trk_ch = 0x00,
159 	.max_num_trk_ch = 0x00,
160 	.reserved0 = UBX_CFG_GNSS_RESERVED0,
161 	.flags = UBX_CFG_GNSS_FLAG_ENABLE | UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L1C_A,
162 };
163 
ubx_cfg_gnss_payload_default(struct ubx_cfg_gnss_payload * payload)164 void ubx_cfg_gnss_payload_default(struct ubx_cfg_gnss_payload *payload)
165 {
166 	payload->msg_ver = UBX_CFG_GNSS_MSG_VER;
167 	payload->num_trk_ch_hw = UBX_CFG_GNSS_NUM_TRK_CH_HW_DEFAULT;
168 	payload->num_trk_ch_use = UBX_CFG_GNSS_NUM_TRK_CH_USE_DEFAULT;
169 
170 	for (int i = 0; i < payload->num_config_blocks; ++i) {
171 		payload->config_blocks[i] = ubx_cfg_gnss_payload_config_block_default;
172 	}
173 }
174 
ubx_cfg_msg_payload_default(struct ubx_cfg_msg_payload * payload)175 void ubx_cfg_msg_payload_default(struct ubx_cfg_msg_payload *payload)
176 {
177 	payload->message_class = UBX_CLASS_NMEA;
178 	payload->message_id = UBX_NMEA_GGA;
179 	payload->rate = UBX_CFG_MSG_RATE_DEFAULT;
180 }
181