/**************************************************************************** * apps/include/cle.h * * Copyright © 2014 Kosma Moczek * * This program is free software. It comes without any warranty, to the extent * permitted by applicable law. You can redistribute it and/or modify it under * the terms of the Do What The Fuck You Want To Public License, Version 2, as * published by Sam Hocevar. See the COPYING file for more details. * ****************************************************************************/ #ifndef __APPS_INCLUDE_GPSUTILS_MINMEA_H #define __APPS_INCLUDE_GPSUTILS_MINMEA_H /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define MINMEA_MAX_LENGTH 80 /**************************************************************************** * Public Types ****************************************************************************/ enum minmea_sentence_id { MINMEA_INVALID = -1, MINMEA_UNKNOWN = 0, MINMEA_SENTENCE_RMC, MINMEA_SENTENCE_GGA, MINMEA_SENTENCE_GSA, MINMEA_SENTENCE_GLL, MINMEA_SENTENCE_GST, MINMEA_SENTENCE_GSV, }; struct minmea_float { int_least32_t value; int_least32_t scale; }; struct minmea_date { int day; int month; int year; }; struct minmea_time { int hours; int minutes; int seconds; int microseconds; }; struct minmea_sentence_rmc { struct minmea_time time; bool valid; struct minmea_float latitude; struct minmea_float longitude; struct minmea_float speed; struct minmea_float course; struct minmea_date date; struct minmea_float variation; }; struct minmea_sentence_gga { struct minmea_time time; struct minmea_float latitude; struct minmea_float longitude; int fix_quality; int satellites_tracked; struct minmea_float hdop; struct minmea_float altitude; char altitude_units; struct minmea_float height; char height_units; int dgps_age; }; enum minmea_gll_status { MINMEA_GLL_STATUS_DATA_VALID = 'A', MINMEA_GLL_STATUS_DATA_NOT_VALID = 'V', }; enum minmea_gll_mode { MINMEA_GLL_MODE_AUTONOMOUS = 'A', MINMEA_GLL_MODE_DPGS = 'D', MINMEA_GLL_MODE_DR = 'E', }; struct minmea_sentence_gll { struct minmea_float latitude; struct minmea_float longitude; struct minmea_time time; char status; char mode; }; struct minmea_sentence_gst { struct minmea_time time; struct minmea_float rms_deviation; struct minmea_float semi_major_deviation; struct minmea_float semi_minor_deviation; struct minmea_float semi_major_orientation; struct minmea_float latitude_error_deviation; struct minmea_float longitude_error_deviation; struct minmea_float altitude_error_deviation; }; enum minmea_gsa_mode { MINMEA_GPGSA_MODE_AUTO = 'A', MINMEA_GPGSA_MODE_FORCED = 'M', }; enum minmea_gsa_fix_type { MINMEA_GPGSA_FIX_NONE = 1, MINMEA_GPGSA_FIX_2D = 2, MINMEA_GPGSA_FIX_3D = 3, }; struct minmea_sentence_gsa { char mode; int fix_type; int sats[12]; struct minmea_float pdop; struct minmea_float hdop; struct minmea_float vdop; }; struct minmea_sat_info { int nr; int elevation; int azimuth; int snr; }; struct minmea_sentence_gsv { int total_msgs; int msg_nr; int total_sats; struct minmea_sat_info sats[4]; }; #ifdef __cplusplus extern "C" { #endif /**************************************************************************** * Public Function Prototypes ****************************************************************************/ /* Calculate raw sentence checksum. Does not check sentence integrity. */ uint8_t minmea_checksum(FAR const char *sentence); /* Check sentence validity and checksum. Returns true for valid sentences. */ bool minmea_check(FAR const char *sentence, bool strict); /* Determine talker identifier. */ bool minmea_talker_id(char talker[3], FAR const char *sentence); /* Determine sentence identifier. */ enum minmea_sentence_id minmea_sentence_id(FAR const char *sentence, bool strict); /* Scanf-like processor for NMEA sentences. Supports the following formats: * c - single character (char *) * d - direction, returned as 1/-1, default 0 (int *) * f - fractional, returned as value + scale (int *, int *) * i - decimal, default zero (int *) * s - string (char *) * t - talker identifier and type (char *) * T - date/time stamp (int *, int *, int *) * Returns true on success. See library source code for details. */ bool minmea_scan(const char *sentence, const char *format, ...); /* Parse a specific type of sentence. Return true on success. */ bool minmea_parse_rmc(struct minmea_sentence_rmc *frame, const char *sentence); bool minmea_parse_gga(struct minmea_sentence_gga *frame, const char *sentence); bool minmea_parse_gsa(struct minmea_sentence_gsa *frame, const char *sentence); bool minmea_parse_gll(struct minmea_sentence_gll *frame, const char *sentence); bool minmea_parse_gst(struct minmea_sentence_gst *frame, const char *sentence); bool minmea_parse_gsv(struct minmea_sentence_gsv *frame, const char *sentence); /* Convert GPS UTC date/time representation to a UNIX timestamp. */ int minmea_gettime(FAR struct timespec *ts, FAR const struct minmea_date *date, FAR const struct minmea_time *time_); /* Rescale a fixed-point value to a different scale. Rounds towards zero. */ static inline int_least32_t minmea_rescale(FAR struct minmea_float *f, int_least32_t new_scale) { if (f->scale == 0) { return 0; } if (f->scale == new_scale) { return f->value; } if (f->scale > new_scale) { return (f->value + ((f->value > 0) - (f->value < 0)) * f->scale / new_scale / 2) / (f->scale / new_scale); } else { return f->value * (new_scale / f->scale); } } /* Convert a fixed-point value to a floating-point value. * Returns NaN for "unknown" values. */ static inline float minmea_tofloat(FAR struct minmea_float *f) { if (f->scale == 0) { return NAN; } return (float) f->value / (float) f->scale; } /* Convert a raw coordinate to a floating point DD.DDD... value. * Returns NaN for "unknown" values. */ static inline float minmea_tocoord(FAR struct minmea_float *f) { if (f->scale == 0) { return NAN; } int_least32_t degrees = f->value / (f->scale * 100); int_least32_t minutes = f->value % (f->scale * 100); return (float) degrees + (float) minutes / (60 * f->scale); } #ifdef __cplusplus } #endif #endif /* __APPS_INCLUDE_GPSUTILS_MINMEA_H */