Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef GPS_PARSER_H
00022 #define GPS_PARSER_H
00023
00024 #include <stdint.h>
00025 #include <avr/pgmspace.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 #include <usarts.h>
00030
00031 #include <ff.h>
00032
00041 typedef struct gps_time_s {
00042 uint8_t hour;
00043 uint8_t min;
00044 uint16_t msec;
00045 } gps_time_t;
00046
00049 typedef struct gps_date_s {
00050 uint16_t year;
00051 uint8_t month;
00052 uint8_t day;
00053 } gps_date_t;
00054
00060 typedef int32_t gps_degree_t;
00061 #define GPS_DEGREE_SCALE (10000000L)
00062 #define GPS_DEGREE_SCALE_EXP (7)
00063
00066 typedef struct gps_dms_s {
00067 int8_t sign;
00068 uint8_t deg;
00069 uint8_t min;
00070 uint8_t sec;
00071 } gps_dms_t;
00072
00075 extern gps_dms_t gps_degree_to_dms (gps_degree_t v);
00076
00079 typedef struct gps_dop_s {
00080 uint8_t dop;
00081 uint8_t dopfrac;
00082 } gps_dop_t;
00083
00086 typedef struct gps_height_s {
00087 uint16_t height;
00088 uint8_t heightfrac;
00089 char unit;
00090 } gps_height_t;
00091
00094 typedef struct gps_sat_s {
00095 uint8_t id;
00096 uint8_t has_dgps:1;
00097 uint8_t used:1;
00098 uint8_t elevation;
00099 uint16_t azimuth;
00100 uint8_t snr;
00101 uint8_t dgps_age;
00102 uint16_t dgps_corr;
00103 } gps_sat_t;
00104
00107 typedef struct {
00108 gps_time_t time;
00109 gps_date_t date;
00110 gps_degree_t lat, lon;
00111 gps_height_t height;
00112 gps_dop_t hdop;
00113 } gps_position_t;
00114
00115
00118 typedef enum {
00119 GPS_LINE_MORE = 0,
00120 GPS_LINE_CKERR,
00121 GPS_LINE_OVERFLOW,
00122 GPS_LINE_OK,
00123 GPS_LINE_FIX,
00124 GPS_LINE_TIME,
00125 GPS_LINE_SAT,
00126 } gps_line_status_t;
00127
00128 typedef struct gps_parser_s gps_parser_t;
00129
00132 typedef enum {
00133 GPSPROTO_NONE = 0,
00134 GPSPROTO_NMEA,
00135 GPSPROTO_SiRF,
00136 GPSPROTO_NUMPROTOS
00137 } gps_proto_t;
00138
00141 typedef struct gps_proto_functions_s {
00142 gps_line_status_t (*recvd) (gps_parser_t *, usart_rxdata_t);
00143 struct gps_proto_parser_s * (*newparser) (gps_parser_t *);
00144 void (*freeparser) (gps_parser_t *);
00145 const struct gps_proto_functions_s * (*switchproto) (gps_parser_t *, gps_proto_t,
00146 baudrate_t baud);
00147 gps_proto_t proto;
00148 baudrate_t baudrate_max;
00149 } PROGMEM gps_proto_functions_t;
00150
00151 extern const gps_proto_functions_t gps_proto_sirf;
00152 extern const gps_proto_functions_t gps_proto_nmea;
00153
00156 typedef struct gps_proto_parser_s {
00157 const gps_proto_functions_t * func;
00158 } gps_proto_parser_t;
00159
00162 #define MAX_NUM_SATS (18)
00163
00166 struct gps_parser_s {
00167 gps_proto_parser_t * proto_parser;
00168 usart_control_t * usart;
00169 uint8_t is_active;
00170 gps_time_t time;
00171 gps_date_t date;
00172 gps_degree_t lat;
00173 gps_degree_t lon;
00174 uint8_t num_sats;
00175 gps_dop_t hdop;
00176 gps_height_t height;
00177 struct {
00178 uint16_t speed;
00179 uint8_t speedfrac;
00180 char unit;
00181 } speed;
00182 struct {
00183 uint16_t course;
00184 uint8_t coursefrac;
00185 } course;
00187 struct {
00188 baudrate_t baud;
00189 uint8_t frame_errors;
00190 uint8_t faster;
00191 uint8_t slower;
00192 } autobaud;
00193 char * usart_name;
00202 struct {
00203 uint8_t tcnt2;
00204 } msg_timestamp[2];
00205 uint32_t msg_timestamp_ticks;
00206 gps_sat_t satellites[MAX_NUM_SATS];
00207 FIL * logfile;
00208 };
00209
00210
00213
00214 #define PROTO_CALL(FUNCP,ARGS...) \
00215 __extension__({ \
00216 __typeof__(*FUNCP) __p = (__typeof__(*FUNCP))pgm_read_word (FUNCP); \
00217 (__p) (ARGS); \
00218 })
00219
00220
00225 gps_parser_t * new_gps_parser (usart_control_t * usart);
00226
00229 inline void free_gps_parser (gps_parser_t *parser)
00230 {
00231 PROTO_CALL(&(parser->proto_parser->func->freeparser), parser);
00232 free (parser->usart_name);
00233 free (parser->logfile);
00234 free (parser);
00235 }
00236
00239 inline gps_proto_t gps_get_proto (gps_parser_t *parser)
00240 {
00241 if (parser->proto_parser)
00242 return pgm_read_byte (&(parser->proto_parser->func->proto));
00243 return GPSPROTO_NONE;
00244 }
00245
00259 gps_proto_t gps_set_proto (gps_parser_t *parser, gps_proto_t newproto,
00260 baudrate_t baud);
00261
00267 inline void gps_timestamp_set_trigger (gps_parser_t *parser, uint8_t trigger)
00268 {
00269 usart_timestamp_set_trigger (parser->usart, trigger);
00270 }
00271
00278 void gps_timestamp_start_of_message (gps_parser_t *parser);
00279
00281 baudrate_t gps_set_baudrate (gps_parser_t *parser, baudrate_t baudrate);
00282
00287 void gps_start_log (gps_parser_t * parser);
00288
00293 gps_line_status_t gps_recvd (gps_parser_t * parser, usart_rxdata_t c);
00294
00295 inline uint8_t gps_usart_can_recv (gps_parser_t * parser)
00296 {
00297 return usart_can_recv (parser->usart);
00298 }
00299
00302 gps_line_status_t gps_usart_recv_and_handle (gps_parser_t * parser,
00303 usart_rxdata_t *c);
00304
00307 int gps_format_position (char * buf, size_t sz, gps_parser_t * parser);
00308
00315 gps_sat_t * gps_get_satellite (gps_parser_t *parser, uint8_t idx);
00316
00324 uint8_t gps_get_time (gps_parser_t *parser,
00325 gps_date_t * pdate, gps_time_t * ptime);
00326
00334 uint8_t gps_get_position (gps_parser_t *parser,
00335 gps_degree_t * plat, gps_degree_t * plon);
00336
00343 uint8_t gps_get_height (gps_parser_t *parser,
00344 gps_height_t * pheight);
00345
00346 uint8_t gps_get_hdop (gps_parser_t *parser,
00347 gps_dop_t * phdop);
00348
00355 uint8_t gps_get_data (gps_parser_t * parser, gps_position_t * data);
00356
00359 inline uint8_t gps_get_source (gps_parser_t *parser,
00360 const char * *psrc, const char * *pproto,
00361 baudrate_t *baud)
00362 {
00363 extern const char * gps_proto_names[];
00364
00365 if (psrc) *psrc = parser->usart_name;
00366 if (pproto) *pproto = gps_proto_names[gps_get_proto(parser)];
00367 if (baud) *baud = parser->autobaud.baud;
00368 return 1;
00369 }
00370
00373 inline uint8_t gps_usart_is_active (gps_parser_t *parser)
00374 {
00375 return parser->is_active;
00376 }
00377
00380 inline void gps_usart_power (gps_parser_t *parser,
00381 uint8_t onoff)
00382 {
00383 usart_control_t * uc = parser->usart;
00384 if (onoff) {
00385 usart_power (uc, 1);
00386 usart_set_baudrate (uc, parser->autobaud.baud);
00387 usart_enable (uc);
00388 } else {
00389 usart_disable (uc);
00390 usart_power (uc, 0);
00391 }
00392 parser->is_active = onoff;
00393 }
00394
00405 void gps_set_parsed_time (gps_parser_t *parser,
00406 gps_date_t date,
00407 gps_time_t time);
00408
00409 #endif