Skip to content

Commit 5a345fa

Browse files
committed
gnss: u-blox f9p: Add RTK integration to driver
Enable driver to consume RTK data-correction messages published in order to enhance GNSS Navigation results. Signed-off-by: Luis Ubieda <luisf@croxel.com>
1 parent 64f13eb commit 5a345fa

File tree

9 files changed

+94
-18
lines changed

9 files changed

+94
-18
lines changed

drivers/gnss/Kconfig.u_blox_f9p

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,14 @@ config GNSS_U_BLOX_F9P_SATELLITES_COUNT
4949
default 24
5050

5151
endif # GNSS_SATELLITES
52+
53+
if GNSS_RTK
54+
55+
config GNSS_U_BLOX_F9P_RTK
56+
bool "Use RTK to improve fix accuracy"
57+
default y
58+
depends on GNSS_RTK_PROTOCOL_RTCM3
59+
60+
endif # GNSS_RTK
61+
5262
endif # GNSS_U_BLOX_F9P

drivers/gnss/gnss_u_blox_f9p.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <zephyr/modem/backend/uart.h>
1919

2020
#include "gnss_ubx_common.h"
21+
#include <zephyr/gnss/rtk/rtk.h>
2122

2223
#include <zephyr/logging/log.h>
2324
LOG_MODULE_REGISTER(ubx_f9p, CONFIG_GNSS_LOG_LEVEL);
@@ -81,6 +82,19 @@ UBX_FRAME_DEFINE(enable_nav,
8182
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_MSG_OUT_UBX_NAV_PVT_UART1, 1));
8283
UBX_FRAME_DEFINE(nav_fix_mode_auto,
8384
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_NAV_CFG_FIX_MODE, UBX_FIX_MODE_AUTO));
85+
UBX_FRAME_DEFINE(enable_prot_in_ubx,
86+
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_UART1_PROTO_IN_UBX, 1));
87+
UBX_FRAME_DEFINE(enable_prot_in_rtcm3,
88+
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_UART1_PROTO_IN_RTCM3X, 1));
89+
UBX_FRAME_DEFINE(enable_prot_out_ubx,
90+
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_UART1_PROTO_OUT_UBX, 1));
91+
UBX_FRAME_DEFINE(disable_prot_out_rtcm3,
92+
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_UART1_PROTO_OUT_RTCM3X, 0));
93+
UBX_FRAME_DEFINE(enable_ubx_rtcm_rsp,
94+
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_MSG_OUT_UBX_RXM_RTCM_UART1, 1));
95+
UBX_FRAME_DEFINE(set_rtk_fix_mode,
96+
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_NAV_HP_CFG_GNSS_MODE,
97+
UBX_NAV_HP_DGNSS_MODE_RTK_FIXED));
8498
#if CONFIG_GNSS_SATELLITES
8599
UBX_FRAME_DEFINE(enable_sat,
86100
UBX_FRAME_CFG_VAL_SET_U8_INITIALIZER(UBX_KEY_MSG_OUT_UBX_NAV_SAT_UART1, 1));
@@ -91,6 +105,8 @@ UBX_FRAME_ARRAY_DEFINE(u_blox_f9p_init_seq,
91105
&disable_nmea_gbs, &disable_nmea_gll, &disable_nmea_gns, &disable_nmea_grs,
92106
&disable_nmea_gsa, &disable_nmea_gst, &disable_nmea_vlw, &disable_nmea_vtg,
93107
&disable_nmea_zda, &enable_nav, &nav_fix_mode_auto,
108+
&enable_prot_in_ubx, &enable_prot_in_rtcm3, &enable_prot_out_ubx,
109+
&disable_prot_out_rtcm3, &enable_ubx_rtcm_rsp, &set_rtk_fix_mode,
94110
#if CONFIG_GNSS_SATELLITES
95111
&enable_sat,
96112
#endif
@@ -122,7 +138,7 @@ static int ubx_f9p_msg_get(const struct device *dev, const struct ubx_frame *req
122138
data->script.inst.retry_count = 2;
123139
data->script.inst.match.filter.class = req->class;
124140
data->script.inst.match.filter.id = req->id;
125-
data->script.inst.request.buf = req;
141+
data->script.inst.request.buf = (const uint8_t *)req;
126142
data->script.inst.request.len = len;
127143

128144
err = modem_ubx_run_script(&data->ubx.inst, &data->script.inst);
@@ -153,7 +169,7 @@ static int ubx_f9p_msg_send(const struct device *dev, const struct ubx_frame *re
153169
data->script.inst.retry_count = wait_for_ack ? 2 : 0;
154170
data->script.inst.match.filter.class = wait_for_ack ? UBX_CLASS_ID_ACK : 0;
155171
data->script.inst.match.filter.id = UBX_MSG_ID_ACK;
156-
data->script.inst.request.buf = req;
172+
data->script.inst.request.buf = (const uint8_t *)req;
157173
data->script.inst.request.len = len;
158174

159175
err = modem_ubx_run_script(&data->ubx.inst, &data->script.inst);
@@ -187,6 +203,19 @@ static int ubx_f9p_msg_payload_send(const struct device *dev, uint8_t class, uin
187203
return err;
188204
}
189205

206+
#if CONFIG_GNSS_U_BLOX_F9P_RTK
207+
208+
static void f9p_rtk_data_cb(const struct device *dev, const struct gnss_rtk_data *data)
209+
{
210+
/** In this case, we forward the frame directly to the modem. It can either use
211+
* it or not depending on the RTCM3 message type and its alignment with what the
212+
* GNSS modem has observed.
213+
*/
214+
(void)ubx_f9p_msg_send(dev, (const void *)data->data, data->len, false);
215+
}
216+
217+
#endif /* CONFIG_GNSS_U_BLOX_F9P_RTK */
218+
190219
static inline int init_modem(const struct device *dev)
191220
{
192221
int err;
@@ -516,6 +545,10 @@ static DEVICE_API(gnss, ublox_f9p_driver_api) = {
516545
\
517546
static struct ubx_f9p_data ubx_f9p_data_##inst; \
518547
\
548+
COND_CODE_1(CONFIG_GNSS_U_BLOX_F9P_RTK, \
549+
(GNSS_RTK_DATA_CALLBACK_DEFINE(DEVICE_DT_INST_GET(inst), f9p_rtk_data_cb)), \
550+
()); \
551+
\
519552
DEVICE_DT_INST_DEFINE(inst, \
520553
ublox_f9p_init, \
521554
NULL, \

drivers/gnss/gnss_u_blox_m8.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static int ubx_m8_msg_get(const struct device *dev, const struct ubx_frame *req,
121121
data->script.inst.retry_count = 2;
122122
data->script.inst.match.filter.class = req->class;
123123
data->script.inst.match.filter.id = req->id;
124-
data->script.inst.request.buf = req;
124+
data->script.inst.request.buf = (const uint8_t *)req;
125125
data->script.inst.request.len = len;
126126

127127
err = modem_ubx_run_script(&data->ubx.inst, &data->script.inst);
@@ -153,7 +153,7 @@ static int ubx_m8_msg_send(const struct device *dev, const struct ubx_frame *req
153153
data->script.inst.retry_count = wait_for_ack ? 2 : 0;
154154
data->script.inst.match.filter.class = wait_for_ack ? UBX_CLASS_ID_ACK : 0;
155155
data->script.inst.match.filter.id = UBX_MSG_ID_ACK;
156-
data->script.inst.request.buf = req;
156+
data->script.inst.request.buf = (const uint8_t *)req;
157157
data->script.inst.request.len = len;
158158

159159
err = modem_ubx_run_script(&data->ubx.inst, &data->script.inst);

drivers/gnss/gnss_ubx_common.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,24 @@ void gnss_ubx_common_pvt_callback(struct modem_ubx *ubx, const struct ubx_frame
2727
if ((nav_pvt->flags & UBX_NAV_PVT_FLAGS_GNSS_FIX_OK) &&
2828
!(nav_pvt->nav.flags3 & UBX_NAV_PVT_FLAGS3_INVALID_LLH)) {
2929

30-
switch (nav_pvt->fix_type) {
31-
case UBX_NAV_FIX_TYPE_DR:
32-
case UBX_NAV_FIX_TYPE_GNSS_DR_COMBINED:
30+
if (nav_pvt->flags & UBX_NAV_PVT_FLAGS_GNSS_CARR_SOLN_FLOATING) {
31+
fix_quality = GNSS_FIX_QUALITY_FLOAT_RTK;
32+
fix_status = GNSS_FIX_STATUS_DGNSS_FIX;
33+
} else if (nav_pvt->flags & UBX_NAV_PVT_FLAGS_GNSS_CARR_SOLN_FIXED) {
34+
fix_quality = GNSS_FIX_QUALITY_RTK;
35+
fix_status = GNSS_FIX_STATUS_DGNSS_FIX;
36+
} else if (
37+
(nav_pvt->fix_type == UBX_NAV_FIX_TYPE_GNSS_DR_COMBINED) ||
38+
(nav_pvt->fix_type == UBX_NAV_FIX_TYPE_DR)) {
39+
3340
fix_quality = GNSS_FIX_QUALITY_ESTIMATED;
3441
fix_status = GNSS_FIX_STATUS_ESTIMATED_FIX;
35-
break;
36-
case UBX_NAV_FIX_TYPE_2D:
37-
case UBX_NAV_FIX_TYPE_3D:
42+
} else if (
43+
(nav_pvt->fix_type == UBX_NAV_FIX_TYPE_2D) ||
44+
(nav_pvt->fix_type == UBX_NAV_FIX_TYPE_3D)) {
45+
3846
fix_quality = GNSS_FIX_QUALITY_GNSS_SPS;
3947
fix_status = GNSS_FIX_STATUS_GNSS_FIX;
40-
break;
41-
default:
42-
break;
4348
}
4449
}
4550

@@ -127,6 +132,7 @@ void gnss_ubx_common_satellite_callback(struct modem_ubx *ubx, const struct ubx_
127132
.azimuth = ubx_sat->sat[i].azimuth,
128133
.system = gnss_system,
129134
.is_tracked = (ubx_sat->sat[i].flags & UBX_NAV_SAT_FLAGS_SV_USED),
135+
.is_corrected = (ubx_sat->sat[i].flags & UBX_NAV_SAT_FLAGS_RTCM_CORR_USED)
130136
};
131137

132138
data->satellites.data[i] = sat;

include/zephyr/drivers/gnss.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ struct gnss_satellite {
211211
enum gnss_system system;
212212
/** True if satellite is being tracked */
213213
uint8_t is_tracked : 1;
214+
/** True if satellite tracking has RTK corrections */
215+
uint8_t is_corrected : 1;
214216
};
215217

216218
/** Template for GNSS satellites callback */

include/zephyr/modem/ubx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct modem_ubx_match {
5353

5454
struct modem_ubx_script {
5555
struct {
56-
const struct ubx_frame *buf;
56+
const uint8_t *buf;
5757
uint16_t len;
5858
} request;
5959
struct {

include/zephyr/modem/ubx/keys.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ enum ubx_keys_msg_out {
2424
UBX_KEY_MSG_OUT_NMEA_ZDA_UART1 = 0x209100d9,
2525
UBX_KEY_MSG_OUT_UBX_NAV_PVT_UART1 = 0x20910007,
2626
UBX_KEY_MSG_OUT_UBX_NAV_SAT_UART1 = 0x20910016,
27+
UBX_KEY_MSG_OUT_UBX_RXM_RTCM_UART1 = 0x20910269,
2728
};
2829

2930
enum ubx_keys_rate {
@@ -36,4 +37,17 @@ enum ubx_keys_nav_cfg {
3637
UBX_KEY_NAV_CFG_DYN_MODEL = 0x20110021,
3738
};
3839

40+
enum ubx_keys_uart1_proto {
41+
UBX_KEY_UART1_PROTO_IN_UBX = 0x10730001,
42+
UBX_KEY_UART1_PROTO_IN_NMEA = 0x10730002,
43+
UBX_KEY_UART1_PROTO_IN_RTCM3X = 0x10730004,
44+
UBX_KEY_UART1_PROTO_OUT_UBX = 0x10740001,
45+
UBX_KEY_UART1_PROTO_OUT_NMEA = 0x10740002,
46+
UBX_KEY_UART1_PROTO_OUT_RTCM3X = 0x10740004,
47+
};
48+
49+
enum ubx_keys_nav_hp_cfg {
50+
UBX_KEY_NAV_HP_CFG_GNSS_MODE = 0x20140011,
51+
};
52+
3953
#endif /* ZEPHYR_MODEM_UBX_KEYS_ */

include/zephyr/modem/ubx/protocol.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,19 @@ enum ubx_nav_fix_type {
7474
UBX_NAV_FIX_TYPE_TIME_ONLY = 5,
7575
};
7676

77+
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+
7782
#define UBX_NAV_PVT_VALID_DATE BIT(0)
7883
#define UBX_NAV_PVT_VALID_TIME BIT(1)
7984
#define UBX_NAV_PVT_VALID_UTC_TOD BIT(2)
8085
#define UBX_NAV_PVT_VALID_MAGN BIT(3)
8186

8287
#define UBX_NAV_PVT_FLAGS_GNSS_FIX_OK BIT(0)
88+
#define UBX_NAV_PVT_FLAGS_GNSS_CARR_SOLN_FLOATING (BIT(6))
89+
#define UBX_NAV_PVT_FLAGS_GNSS_CARR_SOLN_FIXED (BIT(7))
8390

8491
#define UBX_NAV_PVT_FLAGS3_INVALID_LLH BIT(0)
8592

@@ -143,6 +150,7 @@ enum ubx_gnss_id {
143150
};
144151

145152
#define UBX_NAV_SAT_FLAGS_SV_USED BIT(3)
153+
#define UBX_NAV_SAT_FLAGS_RTCM_CORR_USED BIT(17)
146154

147155
struct ubx_nav_sat {
148156
uint32_t itow;

samples/drivers/gnss/rtk/src/main.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ static void gnss_data_cb(const struct device *dev, const struct gnss_data *data)
2222
if (data->info.fix_status != GNSS_FIX_STATUS_NO_FIX) {
2323
if (gnss_get_latest_timepulse(dev, &timepulse) == 0) {
2424
timepulse_ns = k_ticks_to_ns_near64(timepulse);
25-
printf("Got a fix @ %lld ns\n", timepulse_ns);
25+
printf("Got a fix (type: %d) @ %lld ns\n",
26+
data->info.fix_status, timepulse_ns);
2627
} else {
27-
printf("Got a fix!\n");
28+
printf("Got a fix (type: %d)\n", data->info.fix_status);
2829
}
2930
}
3031
}
@@ -35,12 +36,14 @@ static void gnss_satellites_cb(const struct device *dev, const struct gnss_satel
3536
uint16_t size)
3637
{
3738
unsigned int tracked_count = 0;
39+
unsigned int corrected_count = 0;
3840

3941
for (unsigned int i = 0; i != size; ++i) {
4042
tracked_count += satellites[i].is_tracked;
43+
corrected_count += satellites[i].is_corrected;
4144
}
42-
printf("%u satellite%s reported (of which %u tracked)!\n",
43-
size, size > 1 ? "s" : "", tracked_count);
45+
printf("%u satellite%s reported (of which %u tracked, of which %u has RTK corrections)!\n",
46+
size, size > 1 ? "s" : "", tracked_count, corrected_count);
4447
}
4548
#endif
4649
GNSS_SATELLITES_CALLBACK_DEFINE(GNSS_MODEM, gnss_satellites_cb);

0 commit comments

Comments
 (0)