avoid ctime in GPS UART (#4824)
Co-authored-by: Nathan Schulte <nmschulte@desmas.net>
This commit is contained in:
parent
b8dee91e09
commit
261222bb04
|
@ -20,10 +20,10 @@
|
||||||
* see #testGpsParser
|
* see #testGpsParser
|
||||||
*/
|
*/
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include <time.h>
|
|
||||||
#include "nmea.h"
|
#include "nmea.h"
|
||||||
|
#include "rtc_helper.h"
|
||||||
|
|
||||||
static long hex2int(const char *a, int len) {
|
static long hex2int(const char * a, const int len) {
|
||||||
int i;
|
int i;
|
||||||
long val = 0;
|
long val = 0;
|
||||||
|
|
||||||
|
@ -35,16 +35,6 @@ static long hex2int(const char *a, int len) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int str2int(const char *a, int len) {
|
|
||||||
int i = 0, k = 0;
|
|
||||||
while (i<len) {
|
|
||||||
k = (k<<3)+(k<<1)+(*a)-'0';
|
|
||||||
a++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float gps_deg_dec(float deg_point) {
|
static float gps_deg_dec(float deg_point) {
|
||||||
float ddeg;
|
float ddeg;
|
||||||
float sec = modff(deg_point, &ddeg) * 60;
|
float sec = modff(deg_point, &ddeg) * 60;
|
||||||
|
@ -180,14 +170,14 @@ Navigational Status S=Safe C=Caution U=Unsafe V=Not valid
|
||||||
void nmea_parse_gprmc(char const * const nmea, loc_t *loc) {
|
void nmea_parse_gprmc(char const * const nmea, loc_t *loc) {
|
||||||
char const * p = (char *)nmea;
|
char const * p = (char *)nmea;
|
||||||
char dStr[GPS_MAX_STRING];
|
char dStr[GPS_MAX_STRING];
|
||||||
struct tm timp;
|
efidatetime_t dt;
|
||||||
|
|
||||||
p = strchr(p, ',') + 1; // read time
|
p = strchr(p, ',') + 1; // read time
|
||||||
str_till_comma(p, dStr);
|
str_till_comma(p, dStr);
|
||||||
if (strlen(dStr) > 5) {
|
if (strlen(dStr) > 5) {
|
||||||
timp.tm_hour = str2int(dStr,2);
|
dt.hour = str2int(dStr, 2);
|
||||||
timp.tm_min = str2int(dStr+2,2);
|
dt.minute = str2int(dStr + 2, 2);
|
||||||
timp.tm_sec = str2int(dStr+4,2);
|
dt.second = str2int(dStr + 4, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = strchr(p, ',') + 1; // read field Valid status
|
p = strchr(p, ',') + 1; // read field Valid status
|
||||||
|
@ -245,13 +235,14 @@ void nmea_parse_gprmc(char const * const nmea, loc_t *loc) {
|
||||||
p = strchr(p, ',') + 1; // read date
|
p = strchr(p, ',') + 1; // read date
|
||||||
str_till_comma(p, dStr);
|
str_till_comma(p, dStr);
|
||||||
if (strlen(dStr) > 5) {
|
if (strlen(dStr) > 5) {
|
||||||
timp.tm_mday = str2int(dStr,2);
|
dt.day = str2int(dStr, 2);
|
||||||
timp.tm_mon = str2int(dStr+2,2);
|
dt.month = str2int(dStr + 2, 2);
|
||||||
timp.tm_year = str2int(dStr+4,2)+100; // we receive -200, but standard wait -1900 = add correction
|
dt.year = 100 + // we receive -200, but standard wait -1900 = add correction
|
||||||
|
str2int(dStr + 4, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timp.tm_year > 0 ) { // check if date field is valid
|
if (dt.year > 0 ) { // check if date field is valid
|
||||||
memcpy(&loc->GPStm, &timp, sizeof(timp));
|
memcpy(&loc->time, &dt, sizeof(dt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "rusefi_types.h"
|
||||||
|
|
||||||
#define GPS_MAX_STRING 256
|
#define GPS_MAX_STRING 256
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -28,7 +30,7 @@ struct GPSlocation {
|
||||||
float speed;
|
float speed;
|
||||||
float altitude;
|
float altitude;
|
||||||
float course;
|
float course;
|
||||||
struct tm GPStm;
|
efidatetime_t time;
|
||||||
nmea_message_type type;
|
nmea_message_type type;
|
||||||
int quality;
|
int quality;
|
||||||
int satellites;
|
int satellites;
|
||||||
|
@ -42,3 +44,13 @@ int nmea_valid_checksum(const char *);
|
||||||
void nmea_parse_gpgga(char const * const, loc_t *);
|
void nmea_parse_gpgga(char const * const, loc_t *);
|
||||||
void nmea_parse_gprmc(char const * const, loc_t *);
|
void nmea_parse_gprmc(char const * const, loc_t *);
|
||||||
void gps_location(loc_t *, char const * const);
|
void gps_location(loc_t *, char const * const);
|
||||||
|
|
||||||
|
static int str2int(const char * a, const int len) {
|
||||||
|
int i = 0, k = 0;
|
||||||
|
while (i < len) {
|
||||||
|
k = (k << 3) + (k << 1) + (*a) - '0';
|
||||||
|
a++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
|
@ -11,14 +11,12 @@
|
||||||
* Kot_dnz 2014
|
* Kot_dnz 2014
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if EFI_UART_GPS
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
// todo: MISRA does not like time.h
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#if EFI_UART_GPS
|
|
||||||
|
|
||||||
|
#include "rusefi_types.h"
|
||||||
#include "console_io.h"
|
#include "console_io.h"
|
||||||
#include "eficonsole.h"
|
#include "eficonsole.h"
|
||||||
#include "nmea.h"
|
#include "nmea.h"
|
||||||
|
@ -30,13 +28,15 @@ static THD_WORKING_AREA(gpsThreadStack, UTILITY_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
// this field holds our current state
|
// this field holds our current state
|
||||||
static loc_t GPSdata;
|
static loc_t GPSdata;
|
||||||
|
static efidatetime_t lastDateTime;
|
||||||
|
|
||||||
static int gpsMesagesCount = 0;
|
static int gpsMessageCount = 0;
|
||||||
static int uartErrors = 0;
|
static int uartErrors = 0;
|
||||||
|
|
||||||
// todo: some data structure for coordinates location
|
// TODO: some data structure for coordinates location
|
||||||
// todo:
|
|
||||||
float getCurrentSpeed(void) {
|
float getCurrentSpeed(void) {
|
||||||
|
// TODO: ???
|
||||||
return GPSdata.speed;
|
return GPSdata.speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,28 +44,27 @@ static void printGpsInfo() {
|
||||||
efiPrintf("GPS RX %s", hwPortname(engineConfiguration->gps_rx_pin));
|
efiPrintf("GPS RX %s", hwPortname(engineConfiguration->gps_rx_pin));
|
||||||
efiPrintf("GPS TX %s", hwPortname(engineConfiguration->gps_tx_pin));
|
efiPrintf("GPS TX %s", hwPortname(engineConfiguration->gps_tx_pin));
|
||||||
|
|
||||||
efiPrintf("m=%d,e=%d: vehicle speed = %.2f", gpsMesagesCount, uartErrors, getCurrentSpeed());
|
efiPrintf("m=%d,e=%d: vehicle speed = %.2f", gpsMessageCount, uartErrors, getCurrentSpeed());
|
||||||
|
|
||||||
float sec = getTimeNowMs() / 1000.0;
|
float sec = getTimeNowMs() / 1000.0;
|
||||||
efiPrintf("communication speed: %.2f", gpsMesagesCount / sec);
|
efiPrintf("communication speed: %.2f", gpsMessageCount / sec);
|
||||||
|
|
||||||
efiPrintf("GPS latitude = %.2f\r\n", GPSdata.latitude);
|
efiPrintf("GPS latitude = %.2f\r\n", GPSdata.latitude);
|
||||||
efiPrintf("GPS longitude = %.2f\r\n", GPSdata.longitude);
|
efiPrintf("GPS longitude = %.2f\r\n", GPSdata.longitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tm curTm;
|
static void onGpsMessage(const char * const buffer) {
|
||||||
|
|
||||||
static void onGpsMessage(char *buffer) {
|
|
||||||
|
|
||||||
gps_location(&GPSdata, buffer);
|
gps_location(&GPSdata, buffer);
|
||||||
date_get_tm(&curTm);
|
|
||||||
|
|
||||||
if (GPSdata.quality == 4 && GPSdata.GPStm.tm_year > 0 && GPSdata.GPStm.tm_sec != curTm.tm_sec) {
|
if (GPSdata.quality == 4 && GPSdata.time.year > 0) {
|
||||||
// quality =4 (valis GxRMC), year > 0, and difference more then second
|
getRtcDateTime(&lastDateTime);
|
||||||
date_set_tm(&GPSdata.GPStm); // set GPS time
|
if (GPSdata.time.second != dateTime.second) {
|
||||||
//}
|
// quality =4 (valid GxRMC), year > 0, and difference more than second
|
||||||
|
setRtcDateTime(GPSdata.time);
|
||||||
}
|
}
|
||||||
gpsMesagesCount++;
|
}
|
||||||
|
|
||||||
|
gpsMessageCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we do not want this on stack, right?
|
// we do not want this on stack, right?
|
||||||
|
@ -116,4 +115,4 @@ void initGps(void) {
|
||||||
addConsoleAction("gpsinfo", &printGpsInfo);
|
addConsoleAction("gpsinfo", &printGpsInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EFI_UART_GPS */
|
#endif // EFI_UART_GPS
|
||||||
|
|
|
@ -284,12 +284,12 @@ TEST(misc, testGpsParser) {
|
||||||
assertEqualsM("3 speed", 11.2, GPSdata.speed);
|
assertEqualsM("3 speed", 11.2, GPSdata.speed);
|
||||||
// ASSERT_EQ( 0, GPSdata.altitude) << "3 altitude"; // GPRMC not overwrite altitude
|
// ASSERT_EQ( 0, GPSdata.altitude) << "3 altitude"; // GPRMC not overwrite altitude
|
||||||
ASSERT_EQ( 0, GPSdata.course) << "3 course";
|
ASSERT_EQ( 0, GPSdata.course) << "3 course";
|
||||||
ASSERT_EQ( 2006, GPSdata.GPStm.tm_year + 1900) << "3 GPS yy";
|
ASSERT_EQ( 2006, GPSdata.time.year + 1900) << "3 GPS yy";
|
||||||
ASSERT_EQ( 12, GPSdata.GPStm.tm_mon) << "3 GPS mm";
|
ASSERT_EQ( 12, GPSdata.time.month) << "3 GPS mm";
|
||||||
ASSERT_EQ( 26, GPSdata.GPStm.tm_mday) << "3 GPS dd";
|
ASSERT_EQ( 26, GPSdata.time.day) << "3 GPS dd";
|
||||||
ASSERT_EQ( 11, GPSdata.GPStm.tm_hour) << "3 GPS hh";
|
ASSERT_EQ( 11, GPSdata.time.hour) << "3 GPS hh";
|
||||||
ASSERT_EQ( 16, GPSdata.GPStm.tm_min) << "3 GPS mm";
|
ASSERT_EQ( 16, GPSdata.time.minute) << "3 GPS mm";
|
||||||
ASSERT_EQ( 9, GPSdata.GPStm.tm_sec) << "3 GPS ss";
|
ASSERT_EQ( 9, GPSdata.time.second) << "3 GPS ss";
|
||||||
|
|
||||||
// check again first one
|
// check again first one
|
||||||
// we need to pass a mutable string, not a constant because the parser would be modifying the string
|
// we need to pass a mutable string, not a constant because the parser would be modifying the string
|
||||||
|
|
Loading…
Reference in New Issue