drivers: gnss: match: Change RMC/GGA sync from timeout to UTC

Change the synchronization of RMC and GGA NMEA messages from a
timeout to matching their UTC timestamps.

Signed-off-by: Bjarki Arge Andreasen <bjarki@arge-andreasen.me>
This commit is contained in:
Bjarki Arge Andreasen 2024-01-16 14:37:01 +01:00 committed by Carles Cufí
parent f0b4e4c88d
commit 1bc8490c6c
5 changed files with 31 additions and 52 deletions

View file

@ -10,16 +10,22 @@
#include <string.h>
#include "gnss_parse.h"
#include "gnss_nmea0183.h"
#include "gnss_nmea0183_match.h"
static bool gnss_nmea0183_match_timed_out(struct gnss_nmea0183_match_data *data)
static int gnss_nmea0183_match_parse_utc(char **argv, uint16_t argc, uint32_t *utc)
{
int64_t delta;
int64_t i64;
delta = k_uptime_delta(&data->timestamp);
data->timestamp = k_uptime_get();
return ((uint16_t)delta) > data->timeout_ms;
if ((gnss_parse_dec_to_milli(argv[1], &i64) < 0) ||
(i64 < 0) ||
(i64 > UINT32_MAX)) {
return -EINVAL;
}
*utc = (uint32_t)i64;
return 0;
}
#if CONFIG_GNSS_SATELLITES
@ -30,10 +36,15 @@ static void gnss_nmea0183_match_reset_gsv(struct gnss_nmea0183_match_data *data)
}
#endif
static void gnss_nmea0183_match_reset(struct gnss_nmea0183_match_data *data)
static void gnss_nmea0183_match_publish(struct gnss_nmea0183_match_data *data)
{
data->gga_received = false;
data->rmc_received = false;
if ((data->gga_utc == 0) || (data->rmc_utc == 0)) {
return;
}
if (data->gga_utc == data->rmc_utc) {
gnss_publish_data(data->gnss, &data->data);
}
}
void gnss_nmea0183_match_gga_callback(struct modem_chat *chat, char **argv, uint16_t argc,
@ -41,19 +52,15 @@ void gnss_nmea0183_match_gga_callback(struct modem_chat *chat, char **argv, uint
{
struct gnss_nmea0183_match_data *data = user_data;
if (gnss_nmea0183_match_timed_out(data)) {
gnss_nmea0183_match_reset(data);
}
if (gnss_nmea0183_parse_gga((const char **)argv, argc, &data->data) < 0) {
return;
}
data->gga_received = true;
if (data->gga_received && data->rmc_received) {
gnss_publish_data(data->gnss, &data->data);
if (gnss_nmea0183_match_parse_utc(argv, argc, &data->gga_utc) < 0) {
return;
}
gnss_nmea0183_match_publish(data);
}
void gnss_nmea0183_match_rmc_callback(struct modem_chat *chat, char **argv, uint16_t argc,
@ -61,19 +68,15 @@ void gnss_nmea0183_match_rmc_callback(struct modem_chat *chat, char **argv, uint
{
struct gnss_nmea0183_match_data *data = user_data;
if (gnss_nmea0183_match_timed_out(data)) {
gnss_nmea0183_match_reset(data);
}
if (gnss_nmea0183_parse_rmc((const char **)argv, argc, &data->data) < 0) {
return;
}
data->rmc_received = true;
if (data->gga_received && data->rmc_received) {
gnss_publish_data(data->gnss, &data->data);
if (gnss_nmea0183_match_parse_utc(argv, argc, &data->rmc_utc) < 0) {
return;
}
gnss_nmea0183_match_publish(data);
}
#if CONFIG_GNSS_SATELLITES
@ -84,10 +87,6 @@ void gnss_nmea0183_match_gsv_callback(struct modem_chat *chat, char **argv, uint
struct gnss_nmea0183_gsv_header header;
int ret;
if (gnss_nmea0183_match_timed_out(data)) {
gnss_nmea0183_match_reset(data);
}
if (gnss_nmea0183_parse_gsv_header((const char **)argv, argc, &header) < 0) {
return;
}
@ -124,7 +123,7 @@ int gnss_nmea0183_match_init(struct gnss_nmea0183_match_data *data,
const struct gnss_nmea0183_match_config *config)
{
__ASSERT(data != NULL, "data argument must be provided");
__ASSERT(config != NULL, "data argument must be provided");
__ASSERT(config != NULL, "config argument must be provided");
memset(data, 0, sizeof(struct gnss_nmea0183_match_data));
data->gnss = config->gnss;
@ -132,6 +131,5 @@ int gnss_nmea0183_match_init(struct gnss_nmea0183_match_data *data,
data->satellites = config->satellites;
data->satellites_size = config->satellites_size;
#endif
data->timeout_ms = config->timeout_ms;
return 0;
}

View file

@ -49,11 +49,9 @@ struct gnss_nmea0183_match_data {
uint16_t satellites_size;
uint16_t satellites_length;
#endif
int64_t timestamp;
uint16_t timeout_ms;
uint8_t gga_received : 1;
uint8_t rmc_received : 1;
uint8_t gsv_message_number : 6;
uint32_t gga_utc;
uint32_t rmc_utc;
uint8_t gsv_message_number;
};
/** GNSS NMEA0183 match configuration structure */
@ -66,8 +64,6 @@ struct gnss_nmea0183_match_config {
/** Number of elements in buffer for parsed satellites */
uint16_t satellites_size;
#endif
/** The maximum time from the first to the last NMEA0183 message of a fix */
uint16_t timeout_ms;
};
/**

View file

@ -29,7 +29,6 @@ LOG_MODULE_REGISTER(gnss_nmea_generic, CONFIG_GNSS_LOG_LEVEL);
struct gnss_nmea_generic_config {
const struct device *uart;
uint16_t nmea_timeout_ms;
};
struct gnss_nmea_generic_data {
@ -83,7 +82,6 @@ static struct gnss_driver_api gnss_api = {
static int gnss_nmea_generic_init_nmea0183_match(const struct device *dev)
{
const struct gnss_nmea_generic_config *cfg = dev->config;
struct gnss_nmea_generic_data *data = dev->data;
const struct gnss_nmea0183_match_config match_config = {
@ -92,7 +90,6 @@ static int gnss_nmea_generic_init_nmea0183_match(const struct device *dev)
.satellites = data->satellites,
.satellites_size = ARRAY_SIZE(data->satellites),
#endif
.timeout_ms = cfg->nmea_timeout_ms,
};
return gnss_nmea0183_match_init(&data->match_data, &match_config);
@ -163,7 +160,6 @@ static int gnss_nmea_generic_init(const struct device *dev)
#define GNSS_NMEA_GENERIC(inst) \
static struct gnss_nmea_generic_config gnss_nmea_generic_cfg_##inst = { \
.uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \
.nmea_timeout_ms = DT_INST_PROP(inst, nmea_timeout_ms), \
}; \
\
static struct gnss_nmea_generic_data gnss_nmea_generic_data_##inst; \

View file

@ -649,7 +649,6 @@ static int quectel_lcx6g_init_nmea0183_match(const struct device *dev)
.satellites = data->satellites,
.satellites_size = ARRAY_SIZE(data->satellites),
#endif
.timeout_ms = 50,
};
return gnss_nmea0183_match_init(&data->match_data, &config);

View file

@ -20,13 +20,3 @@ compatible: "gnss-nmea-generic"
include:
- uart-device.yaml
properties:
nmea-timeout-ms:
type: int
default: 500
description: |
Synchronization timeout for NMEA sentences. The NMEA parser is expecting
to receive a GGA and RMC sentences within this time frame to publish a
location data. Set accordingly to the UART datarate and location
reporting frequency. Defaults to 500ms if unspecified.