Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
minmea.h
1 /*
2  * Copyright © 2014 Kosma Moczek <kosma@cloudyourcar.com>
3  * This program is free software. It comes without any warranty, to the extent
4  * permitted by applicable law. You can redistribute it and/or modify it under
5  * the terms of the Do What The Fuck You Want To Public License, Version 2, as
6  * published by Sam Hocevar. See the COPYING file for more details.
7  */
8 
9 #ifndef MINMEA_H
10 #define MINMEA_H
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #include <stdio.h>
17 #include <stdint.h>
18 #include <stdbool.h>
19 #include <errno.h>
20 #include <time.h>
21 #include <math.h>
22 #ifdef MINMEA_INCLUDE_COMPAT
23 #include <minmea_compat.h>
24 #endif
25 
26 #define MINMEA_MAX_LENGTH 128
27 
28 enum minmea_sentence_id {
29  MINMEA_INVALID = -1,
30  MINMEA_UNKNOWN = 0,
31  MINMEA_SENTENCE_RMC,
32  MINMEA_SENTENCE_GGA,
33  MINMEA_SENTENCE_GSA,
34  MINMEA_SENTENCE_GLL,
35  MINMEA_SENTENCE_GST,
36  MINMEA_SENTENCE_GSV,
37  MINMEA_SENTENCE_VTG,
38  MINMEA_SENTENCE_ZDA,
39  MINMEA_SENTENCE_PUBX,
40 };
41 
42 struct minmea_float {
43  int_least32_t value;
44  int_least32_t scale;
45 };
46 
47 struct minmea_date {
48  int day;
49  int month;
50  int year;
51 };
52 
53 struct minmea_time {
54  int hours;
55  int minutes;
56  int seconds;
57  int microseconds;
58 };
59 
61  struct minmea_time time;
62  bool valid;
63  struct minmea_float latitude;
64  struct minmea_float longitude;
65  struct minmea_float speed;
66  struct minmea_float course;
67  struct minmea_date date;
68  struct minmea_float variation;
69 };
70 
72  struct minmea_time time;
73  struct minmea_float latitude;
74  struct minmea_float longitude;
75  int fix_quality;
76  int satellites_tracked;
77  struct minmea_float hdop;
78  struct minmea_float altitude; char altitude_units;
79  struct minmea_float height; char height_units;
80  int dgps_age;
81 };
82 
83 enum minmea_gll_status {
84  MINMEA_GLL_STATUS_DATA_VALID = 'A',
85  MINMEA_GLL_STATUS_DATA_NOT_VALID = 'V',
86 };
87 
88 // FAA mode added to some fields in NMEA 2.3.
89 enum minmea_faa_mode {
90  MINMEA_FAA_MODE_AUTONOMOUS = 'A',
91  MINMEA_FAA_MODE_DIFFERENTIAL = 'D',
92  MINMEA_FAA_MODE_ESTIMATED = 'E',
93  MINMEA_FAA_MODE_MANUAL = 'M',
94  MINMEA_FAA_MODE_SIMULATED = 'S',
95  MINMEA_FAA_MODE_NOT_VALID = 'N',
96  MINMEA_FAA_MODE_PRECISE = 'P',
97 };
98 
100  struct minmea_float latitude;
101  struct minmea_float longitude;
102  struct minmea_time time;
103  char status;
104  char mode;
105 };
106 
108  struct minmea_time time;
109  struct minmea_float rms_deviation;
110  struct minmea_float semi_major_deviation;
111  struct minmea_float semi_minor_deviation;
112  struct minmea_float semi_major_orientation;
113  struct minmea_float latitude_error_deviation;
114  struct minmea_float longitude_error_deviation;
115  struct minmea_float altitude_error_deviation;
116 };
117 
118 enum minmea_gsa_mode {
119  MINMEA_GPGSA_MODE_AUTO = 'A',
120  MINMEA_GPGSA_MODE_FORCED = 'M',
121 };
122 
123 enum minmea_gsa_fix_type {
124  MINMEA_GPGSA_FIX_NONE = 1,
125  MINMEA_GPGSA_FIX_2D = 2,
126  MINMEA_GPGSA_FIX_3D = 3,
127 };
128 
130  char mode;
131  int fix_type;
132  int sats[12];
133  struct minmea_float pdop;
134  struct minmea_float hdop;
135  struct minmea_float vdop;
136 };
137 
139  int nr;
140  int elevation;
141  int azimuth;
142  int snr;
143 };
144 
146  int total_msgs;
147  int msg_nr;
148  int total_sats;
149  struct minmea_sat_info sats[4];
150 };
151 
153  struct minmea_float true_track_degrees;
154  struct minmea_float magnetic_track_degrees;
155  struct minmea_float speed_knots;
156  struct minmea_float speed_kph;
157  enum minmea_faa_mode faa_mode;
158 };
159 
161  struct minmea_time time;
162  struct minmea_date date;
163  int hour_offset;
164  int minute_offset;
165 };
166 
168  int msg_id;
169  struct minmea_time time;
170  struct minmea_float latitude;
171  struct minmea_float longitude;
172  struct minmea_float altitude;
173  int status;
174  struct minmea_float h_accuracy;
175  struct minmea_float v_accuracy;
176  struct minmea_float speed;
177  struct minmea_float course;
178  struct minmea_float velocity;
179  int age;
180  struct minmea_float hdop;
181  struct minmea_float vdop;
182  struct minmea_float tdop;
183  int satellites;
184  int reserved;
185  int dr;
186 };
187 
191 uint8_t minmea_checksum(const char *sentence);
192 
196 bool minmea_check(const char *sentence, bool strict);
197 
201 bool minmea_talker_id(char talker[3], const char *sentence);
202 
206 enum minmea_sentence_id minmea_sentence_id(const char *sentence, bool strict);
207 
219 bool minmea_scan(const char *sentence, const char *format, ...);
220 
221 /*
222  * Parse a specific type of sentence. Return true on success.
223  */
224 bool minmea_parse_rmc(struct minmea_sentence_rmc *frame, const char *sentence);
225 bool minmea_parse_gga(struct minmea_sentence_gga *frame, const char *sentence);
226 bool minmea_parse_gsa(struct minmea_sentence_gsa *frame, const char *sentence);
227 bool minmea_parse_gll(struct minmea_sentence_gll *frame, const char *sentence);
228 bool minmea_parse_gst(struct minmea_sentence_gst *frame, const char *sentence);
229 bool minmea_parse_gsv(struct minmea_sentence_gsv *frame, const char *sentence);
230 bool minmea_parse_vtg(struct minmea_sentence_vtg *frame, const char *sentence);
231 bool minmea_parse_zda(struct minmea_sentence_zda *frame, const char *sentence);
232 bool minmea_parse_pubx(struct minmea_sentence_pubx *frame, const char *sentence);
233 
237 static inline int_least32_t minmea_rescale(struct minmea_float *f, int_least32_t new_scale)
238 {
239  if (f->scale == 0)
240  return 0;
241  if (f->scale == new_scale)
242  return f->value;
243  if (f->scale > new_scale)
244  return (f->value + ((f->value > 0) - (f->value < 0)) * f->scale/new_scale/2) / (f->scale/new_scale);
245  else
246  return f->value * (new_scale/f->scale);
247 }
248 
253 static inline float minmea_tofloat(struct minmea_float *f)
254 {
255  if (f->scale == 0)
256  return NAN;
257  return (float) f->value / (float) f->scale;
258 }
259 
264 static inline float minmea_tocoord(struct minmea_float *f)
265 {
266  if (f->scale == 0)
267  return NAN;
268  int_least32_t degrees = f->value / (f->scale * 100);
269  int_least32_t minutes = f->value % (f->scale * 100);
270  return (float) degrees + (float) minutes / (60 * f->scale);
271 }
272 
273 #ifdef __cplusplus
274 }
275 #endif
276 
277 #endif /* MINMEA_H */
278 
279 /* vim: set ts=4 sw=4 et: */