Guido Ottaviani / Mbed 2 deprecated LeonardoMbos

Dependencies:   mbos Watchdog TextLCD mbed ConfigFile

Committer:
guiott
Date:
Sun Jan 29 16:06:12 2012 +0000
Revision:
0:d177c0087d1f

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
guiott 0:d177c0087d1f 1 /*
guiott 0:d177c0087d1f 2 *
guiott 0:d177c0087d1f 3 * NMEA library
guiott 0:d177c0087d1f 4 * URL: http://nmea.sourceforge.net
guiott 0:d177c0087d1f 5 * Author: Tim (xtimor@gmail.com)
guiott 0:d177c0087d1f 6 * Licence: http://www.gnu.org/licenses/lgpl.html
guiott 0:d177c0087d1f 7 * $Id: parse.c 17 2008-03-11 11:56:11Z xtimor $
guiott 0:d177c0087d1f 8 *
guiott 0:d177c0087d1f 9 */
guiott 0:d177c0087d1f 10
guiott 0:d177c0087d1f 11 /**
guiott 0:d177c0087d1f 12 * \file parse.h
guiott 0:d177c0087d1f 13 * \brief Functions of a low level for analysis of
guiott 0:d177c0087d1f 14 * packages of NMEA stream.
guiott 0:d177c0087d1f 15 *
guiott 0:d177c0087d1f 16 * \code
guiott 0:d177c0087d1f 17 * ...
guiott 0:d177c0087d1f 18 * ptype = nmea_pack_type(
guiott 0:d177c0087d1f 19 * (const char *)parser->buffer + nparsed + 1,
guiott 0:d177c0087d1f 20 * parser->buff_use - nparsed - 1);
guiott 0:d177c0087d1f 21 *
guiott 0:d177c0087d1f 22 * if(0 == (node = malloc(sizeof(nmeaParserNODE))))
guiott 0:d177c0087d1f 23 * goto mem_fail;
guiott 0:d177c0087d1f 24 *
guiott 0:d177c0087d1f 25 * node->pack = 0;
guiott 0:d177c0087d1f 26 *
guiott 0:d177c0087d1f 27 * switch(ptype)
guiott 0:d177c0087d1f 28 * {
guiott 0:d177c0087d1f 29 * case GPGGA:
guiott 0:d177c0087d1f 30 * if(0 == (node->pack = malloc(sizeof(nmeaGPGGA))))
guiott 0:d177c0087d1f 31 * goto mem_fail;
guiott 0:d177c0087d1f 32 * node->packType = GPGGA;
guiott 0:d177c0087d1f 33 * if(!nmea_parse_GPGGA(
guiott 0:d177c0087d1f 34 * (const char *)parser->buffer + nparsed,
guiott 0:d177c0087d1f 35 * sen_sz, (nmeaGPGGA *)node->pack))
guiott 0:d177c0087d1f 36 * {
guiott 0:d177c0087d1f 37 * free(node);
guiott 0:d177c0087d1f 38 * node = 0;
guiott 0:d177c0087d1f 39 * }
guiott 0:d177c0087d1f 40 * break;
guiott 0:d177c0087d1f 41 * case GPGSA:
guiott 0:d177c0087d1f 42 * if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
guiott 0:d177c0087d1f 43 * goto mem_fail;
guiott 0:d177c0087d1f 44 * node->packType = GPGSA;
guiott 0:d177c0087d1f 45 * if(!nmea_parse_GPGSA(
guiott 0:d177c0087d1f 46 * (const char *)parser->buffer + nparsed,
guiott 0:d177c0087d1f 47 * sen_sz, (nmeaGPGSA *)node->pack))
guiott 0:d177c0087d1f 48 * {
guiott 0:d177c0087d1f 49 * free(node);
guiott 0:d177c0087d1f 50 * node = 0;
guiott 0:d177c0087d1f 51 * }
guiott 0:d177c0087d1f 52 * break;
guiott 0:d177c0087d1f 53 * ...
guiott 0:d177c0087d1f 54 * \endcode
guiott 0:d177c0087d1f 55 */
guiott 0:d177c0087d1f 56
guiott 0:d177c0087d1f 57 #include "nmea/tok.h"
guiott 0:d177c0087d1f 58 #include "nmea/parse.h"
guiott 0:d177c0087d1f 59 #include "nmea/context.h"
guiott 0:d177c0087d1f 60 #include "nmea/gmath.h"
guiott 0:d177c0087d1f 61 #include "nmea/units.h"
guiott 0:d177c0087d1f 62
guiott 0:d177c0087d1f 63 #include <string.h>
guiott 0:d177c0087d1f 64 #include <stdio.h>
guiott 0:d177c0087d1f 65
guiott 0:d177c0087d1f 66 int _nmea_parse_time(const char *buff, int buff_sz, nmeaTIME *res)
guiott 0:d177c0087d1f 67 {
guiott 0:d177c0087d1f 68 int success = 0;
guiott 0:d177c0087d1f 69
guiott 0:d177c0087d1f 70 switch(buff_sz)
guiott 0:d177c0087d1f 71 {
guiott 0:d177c0087d1f 72 case sizeof("hhmmss") - 1:
guiott 0:d177c0087d1f 73 success = (3 == nmea_scanf(buff, buff_sz,
guiott 0:d177c0087d1f 74 "%2d%2d%2d", &(res->hour), &(res->min), &(res->sec)
guiott 0:d177c0087d1f 75 ));
guiott 0:d177c0087d1f 76 break;
guiott 0:d177c0087d1f 77 case sizeof("hhmmss.s") - 1:
guiott 0:d177c0087d1f 78 case sizeof("hhmmss.ss") - 1:
guiott 0:d177c0087d1f 79 case sizeof("hhmmss.sss") - 1:
guiott 0:d177c0087d1f 80 success = (4 == nmea_scanf(buff, buff_sz,
guiott 0:d177c0087d1f 81 "%2d%2d%2d.%d", &(res->hour), &(res->min), &(res->sec), &(res->hsec)
guiott 0:d177c0087d1f 82 ));
guiott 0:d177c0087d1f 83 break;
guiott 0:d177c0087d1f 84 default:
guiott 0:d177c0087d1f 85 nmea_error("Parse of time error (format error)!");
guiott 0:d177c0087d1f 86 success = 0;
guiott 0:d177c0087d1f 87 break;
guiott 0:d177c0087d1f 88 }
guiott 0:d177c0087d1f 89
guiott 0:d177c0087d1f 90 return (success?0:-1);
guiott 0:d177c0087d1f 91 }
guiott 0:d177c0087d1f 92
guiott 0:d177c0087d1f 93 /**
guiott 0:d177c0087d1f 94 * \brief Define packet type by header (nmeaPACKTYPE).
guiott 0:d177c0087d1f 95 * @param buff a constant character pointer of packet buffer.
guiott 0:d177c0087d1f 96 * @param buff_sz buffer size.
guiott 0:d177c0087d1f 97 * @return The defined packet type
guiott 0:d177c0087d1f 98 * @see nmeaPACKTYPE
guiott 0:d177c0087d1f 99 */
guiott 0:d177c0087d1f 100 int nmea_pack_type(const char *buff, int buff_sz)
guiott 0:d177c0087d1f 101 {
guiott 0:d177c0087d1f 102 static const char *pheads[] = {
guiott 0:d177c0087d1f 103 "GPGGA",
guiott 0:d177c0087d1f 104 "GPGSA",
guiott 0:d177c0087d1f 105 "GPGSV",
guiott 0:d177c0087d1f 106 "GPRMC",
guiott 0:d177c0087d1f 107 "GPVTG",
guiott 0:d177c0087d1f 108 };
guiott 0:d177c0087d1f 109
guiott 0:d177c0087d1f 110 NMEA_ASSERT(buff);
guiott 0:d177c0087d1f 111
guiott 0:d177c0087d1f 112 if(buff_sz < 5)
guiott 0:d177c0087d1f 113 return GPNON;
guiott 0:d177c0087d1f 114 else if(0 == memcmp(buff, pheads[0], 5))
guiott 0:d177c0087d1f 115 return GPGGA;
guiott 0:d177c0087d1f 116 else if(0 == memcmp(buff, pheads[1], 5))
guiott 0:d177c0087d1f 117 return GPGSA;
guiott 0:d177c0087d1f 118 else if(0 == memcmp(buff, pheads[2], 5))
guiott 0:d177c0087d1f 119 return GPGSV;
guiott 0:d177c0087d1f 120 else if(0 == memcmp(buff, pheads[3], 5))
guiott 0:d177c0087d1f 121 return GPRMC;
guiott 0:d177c0087d1f 122 else if(0 == memcmp(buff, pheads[4], 5))
guiott 0:d177c0087d1f 123 return GPVTG;
guiott 0:d177c0087d1f 124
guiott 0:d177c0087d1f 125 return GPNON;
guiott 0:d177c0087d1f 126 }
guiott 0:d177c0087d1f 127
guiott 0:d177c0087d1f 128 /**
guiott 0:d177c0087d1f 129 * \brief Find tail of packet ("\r\n") in buffer and check control sum (CRC).
guiott 0:d177c0087d1f 130 * @param buff a constant character pointer of packets buffer.
guiott 0:d177c0087d1f 131 * @param buff_sz buffer size.
guiott 0:d177c0087d1f 132 * @param res_crc a integer pointer for return CRC of packet (must be defined).
guiott 0:d177c0087d1f 133 * @return Number of bytes to packet tail.
guiott 0:d177c0087d1f 134 */
guiott 0:d177c0087d1f 135 int nmea_find_tail(const char *buff, int buff_sz, int *res_crc)
guiott 0:d177c0087d1f 136 {
guiott 0:d177c0087d1f 137 static const int tail_sz = 3 /* *[CRC] */ + 2 /* \r\n */;
guiott 0:d177c0087d1f 138
guiott 0:d177c0087d1f 139 const char *end_buff = buff + buff_sz;
guiott 0:d177c0087d1f 140 int nread = 0;
guiott 0:d177c0087d1f 141 int crc = 0;
guiott 0:d177c0087d1f 142
guiott 0:d177c0087d1f 143 NMEA_ASSERT(buff && res_crc);
guiott 0:d177c0087d1f 144
guiott 0:d177c0087d1f 145 *res_crc = -1;
guiott 0:d177c0087d1f 146
guiott 0:d177c0087d1f 147 for(;buff < end_buff; ++buff, ++nread)
guiott 0:d177c0087d1f 148 {
guiott 0:d177c0087d1f 149 if(('$' == *buff) && nread)
guiott 0:d177c0087d1f 150 {
guiott 0:d177c0087d1f 151 buff = 0;
guiott 0:d177c0087d1f 152 break;
guiott 0:d177c0087d1f 153 }
guiott 0:d177c0087d1f 154 else if('*' == *buff)
guiott 0:d177c0087d1f 155 {
guiott 0:d177c0087d1f 156 if(buff + tail_sz <= end_buff && '\r' == buff[3] && '\n' == buff[4])
guiott 0:d177c0087d1f 157 {
guiott 0:d177c0087d1f 158 *res_crc = nmea_atoi(buff + 1, 2, 16);
guiott 0:d177c0087d1f 159 nread = buff_sz - (int)(end_buff - (buff + tail_sz));
guiott 0:d177c0087d1f 160 if(*res_crc != crc)
guiott 0:d177c0087d1f 161 {
guiott 0:d177c0087d1f 162 *res_crc = -1;
guiott 0:d177c0087d1f 163 buff = 0;
guiott 0:d177c0087d1f 164 }
guiott 0:d177c0087d1f 165 }
guiott 0:d177c0087d1f 166
guiott 0:d177c0087d1f 167 break;
guiott 0:d177c0087d1f 168 }
guiott 0:d177c0087d1f 169 else if(nread)
guiott 0:d177c0087d1f 170 crc ^= (int)*buff;
guiott 0:d177c0087d1f 171 }
guiott 0:d177c0087d1f 172
guiott 0:d177c0087d1f 173 if(*res_crc < 0 && buff)
guiott 0:d177c0087d1f 174 nread = 0;
guiott 0:d177c0087d1f 175
guiott 0:d177c0087d1f 176 return nread;
guiott 0:d177c0087d1f 177 }
guiott 0:d177c0087d1f 178
guiott 0:d177c0087d1f 179 /**
guiott 0:d177c0087d1f 180 * \brief Parse GGA packet from buffer.
guiott 0:d177c0087d1f 181 * @param buff a constant character pointer of packet buffer.
guiott 0:d177c0087d1f 182 * @param buff_sz buffer size.
guiott 0:d177c0087d1f 183 * @param pack a pointer of packet which will filled by function.
guiott 0:d177c0087d1f 184 * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
guiott 0:d177c0087d1f 185 */
guiott 0:d177c0087d1f 186 int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack)
guiott 0:d177c0087d1f 187 {
guiott 0:d177c0087d1f 188 char time_buff[NMEA_TIMEPARSE_BUF];
guiott 0:d177c0087d1f 189
guiott 0:d177c0087d1f 190 NMEA_ASSERT(buff && pack);
guiott 0:d177c0087d1f 191
guiott 0:d177c0087d1f 192 memset(pack, 0, sizeof(nmeaGPGGA));
guiott 0:d177c0087d1f 193
guiott 0:d177c0087d1f 194 nmea_trace_buff(buff, buff_sz);
guiott 0:d177c0087d1f 195
guiott 0:d177c0087d1f 196 if(14 != nmea_scanf(buff, buff_sz,
guiott 0:d177c0087d1f 197 "$GPGGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
guiott 0:d177c0087d1f 198 &(time_buff[0]),
guiott 0:d177c0087d1f 199 &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
guiott 0:d177c0087d1f 200 &(pack->sig), &(pack->satinuse), &(pack->HDOP), &(pack->elv), &(pack->elv_units),
guiott 0:d177c0087d1f 201 &(pack->diff), &(pack->diff_units), &(pack->dgps_age), &(pack->dgps_sid)))
guiott 0:d177c0087d1f 202 {
guiott 0:d177c0087d1f 203 nmea_error("GPGGA parse error!");
guiott 0:d177c0087d1f 204 return 0;
guiott 0:d177c0087d1f 205 }
guiott 0:d177c0087d1f 206
guiott 0:d177c0087d1f 207 if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
guiott 0:d177c0087d1f 208 {
guiott 0:d177c0087d1f 209 nmea_error("GPGGA time parse error!");
guiott 0:d177c0087d1f 210 return 0;
guiott 0:d177c0087d1f 211 }
guiott 0:d177c0087d1f 212
guiott 0:d177c0087d1f 213 return 1;
guiott 0:d177c0087d1f 214 }
guiott 0:d177c0087d1f 215
guiott 0:d177c0087d1f 216 /**
guiott 0:d177c0087d1f 217 * \brief Parse GSA packet from buffer.
guiott 0:d177c0087d1f 218 * @param buff a constant character pointer of packet buffer.
guiott 0:d177c0087d1f 219 * @param buff_sz buffer size.
guiott 0:d177c0087d1f 220 * @param pack a pointer of packet which will filled by function.
guiott 0:d177c0087d1f 221 * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
guiott 0:d177c0087d1f 222 */
guiott 0:d177c0087d1f 223 int nmea_parse_GPGSA(const char *buff, int buff_sz, nmeaGPGSA *pack)
guiott 0:d177c0087d1f 224 {
guiott 0:d177c0087d1f 225 NMEA_ASSERT(buff && pack);
guiott 0:d177c0087d1f 226
guiott 0:d177c0087d1f 227 memset(pack, 0, sizeof(nmeaGPGSA));
guiott 0:d177c0087d1f 228
guiott 0:d177c0087d1f 229 nmea_trace_buff(buff, buff_sz);
guiott 0:d177c0087d1f 230
guiott 0:d177c0087d1f 231 if(17 != nmea_scanf(buff, buff_sz,
guiott 0:d177c0087d1f 232 "$GPGSA,%C,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f*",
guiott 0:d177c0087d1f 233 &(pack->fix_mode), &(pack->fix_type),
guiott 0:d177c0087d1f 234 &(pack->sat_prn[0]), &(pack->sat_prn[1]), &(pack->sat_prn[2]), &(pack->sat_prn[3]), &(pack->sat_prn[4]), &(pack->sat_prn[5]),
guiott 0:d177c0087d1f 235 &(pack->sat_prn[6]), &(pack->sat_prn[7]), &(pack->sat_prn[8]), &(pack->sat_prn[9]), &(pack->sat_prn[10]), &(pack->sat_prn[11]),
guiott 0:d177c0087d1f 236 &(pack->PDOP), &(pack->HDOP), &(pack->VDOP)))
guiott 0:d177c0087d1f 237 {
guiott 0:d177c0087d1f 238 nmea_error("GPGSA parse error!");
guiott 0:d177c0087d1f 239 return 0;
guiott 0:d177c0087d1f 240 }
guiott 0:d177c0087d1f 241
guiott 0:d177c0087d1f 242 return 1;
guiott 0:d177c0087d1f 243 }
guiott 0:d177c0087d1f 244
guiott 0:d177c0087d1f 245 /**
guiott 0:d177c0087d1f 246 * \brief Parse GSV packet from buffer.
guiott 0:d177c0087d1f 247 * @param buff a constant character pointer of packet buffer.
guiott 0:d177c0087d1f 248 * @param buff_sz buffer size.
guiott 0:d177c0087d1f 249 * @param pack a pointer of packet which will filled by function.
guiott 0:d177c0087d1f 250 * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
guiott 0:d177c0087d1f 251 */
guiott 0:d177c0087d1f 252 int nmea_parse_GPGSV(const char *buff, int buff_sz, nmeaGPGSV *pack)
guiott 0:d177c0087d1f 253 {
guiott 0:d177c0087d1f 254 int nsen, nsat;
guiott 0:d177c0087d1f 255
guiott 0:d177c0087d1f 256 NMEA_ASSERT(buff && pack);
guiott 0:d177c0087d1f 257
guiott 0:d177c0087d1f 258 memset(pack, 0, sizeof(nmeaGPGSV));
guiott 0:d177c0087d1f 259
guiott 0:d177c0087d1f 260 nmea_trace_buff(buff, buff_sz);
guiott 0:d177c0087d1f 261
guiott 0:d177c0087d1f 262 nsen = nmea_scanf(buff, buff_sz,
guiott 0:d177c0087d1f 263 "$GPGSV,%d,%d,%d,"
guiott 0:d177c0087d1f 264 "%d,%d,%d,%d,"
guiott 0:d177c0087d1f 265 "%d,%d,%d,%d,"
guiott 0:d177c0087d1f 266 "%d,%d,%d,%d,"
guiott 0:d177c0087d1f 267 "%d,%d,%d,%d*",
guiott 0:d177c0087d1f 268 &(pack->pack_count), &(pack->pack_index), &(pack->sat_count),
guiott 0:d177c0087d1f 269 &(pack->sat_data[0].id), &(pack->sat_data[0].elv), &(pack->sat_data[0].azimuth), &(pack->sat_data[0].sig),
guiott 0:d177c0087d1f 270 &(pack->sat_data[1].id), &(pack->sat_data[1].elv), &(pack->sat_data[1].azimuth), &(pack->sat_data[1].sig),
guiott 0:d177c0087d1f 271 &(pack->sat_data[2].id), &(pack->sat_data[2].elv), &(pack->sat_data[2].azimuth), &(pack->sat_data[2].sig),
guiott 0:d177c0087d1f 272 &(pack->sat_data[3].id), &(pack->sat_data[3].elv), &(pack->sat_data[3].azimuth), &(pack->sat_data[3].sig));
guiott 0:d177c0087d1f 273
guiott 0:d177c0087d1f 274 nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
guiott 0:d177c0087d1f 275 nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
guiott 0:d177c0087d1f 276 nsat = nsat * 4 + 3 /* first three sentence`s */;
guiott 0:d177c0087d1f 277
guiott 0:d177c0087d1f 278 if(nsen < nsat || nsen > (NMEA_SATINPACK * 4 + 3))
guiott 0:d177c0087d1f 279 {
guiott 0:d177c0087d1f 280 nmea_error("GPGSV parse error!");
guiott 0:d177c0087d1f 281 return 0;
guiott 0:d177c0087d1f 282 }
guiott 0:d177c0087d1f 283
guiott 0:d177c0087d1f 284 return 1;
guiott 0:d177c0087d1f 285 }
guiott 0:d177c0087d1f 286
guiott 0:d177c0087d1f 287 /**
guiott 0:d177c0087d1f 288 * \brief Parse RMC packet from buffer.
guiott 0:d177c0087d1f 289 * @param buff a constant character pointer of packet buffer.
guiott 0:d177c0087d1f 290 * @param buff_sz buffer size.
guiott 0:d177c0087d1f 291 * @param pack a pointer of packet which will filled by function.
guiott 0:d177c0087d1f 292 * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
guiott 0:d177c0087d1f 293 */
guiott 0:d177c0087d1f 294 int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack)
guiott 0:d177c0087d1f 295 {
guiott 0:d177c0087d1f 296 int nsen;
guiott 0:d177c0087d1f 297
guiott 0:d177c0087d1f 298 char time_buff[NMEA_TIMEPARSE_BUF];
guiott 0:d177c0087d1f 299
guiott 0:d177c0087d1f 300 NMEA_ASSERT(buff && pack);
guiott 0:d177c0087d1f 301
guiott 0:d177c0087d1f 302 memset(pack, 0, sizeof(nmeaGPRMC));
guiott 0:d177c0087d1f 303
guiott 0:d177c0087d1f 304 nmea_trace_buff(buff, buff_sz);
guiott 0:d177c0087d1f 305
guiott 0:d177c0087d1f 306 nsen = nmea_scanf(buff, buff_sz,
guiott 0:d177c0087d1f 307 "$GPRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C*",
guiott 0:d177c0087d1f 308 &(time_buff[0]),
guiott 0:d177c0087d1f 309 &(pack->status), &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
guiott 0:d177c0087d1f 310 &(pack->speed), &(pack->direction),
guiott 0:d177c0087d1f 311 &(pack->utc.day), &(pack->utc.mon), &(pack->utc.year),
guiott 0:d177c0087d1f 312 &(pack->declination), &(pack->declin_ew), &(pack->mode));
guiott 0:d177c0087d1f 313
guiott 0:d177c0087d1f 314 if(nsen != 13 && nsen != 14)
guiott 0:d177c0087d1f 315 {
guiott 0:d177c0087d1f 316 nmea_error("GPRMC parse error!");
guiott 0:d177c0087d1f 317 return 0;
guiott 0:d177c0087d1f 318 }
guiott 0:d177c0087d1f 319
guiott 0:d177c0087d1f 320 if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
guiott 0:d177c0087d1f 321 {
guiott 0:d177c0087d1f 322 nmea_error("GPRMC time parse error!");
guiott 0:d177c0087d1f 323 return 0;
guiott 0:d177c0087d1f 324 }
guiott 0:d177c0087d1f 325
guiott 0:d177c0087d1f 326 if(pack->utc.year < 90)
guiott 0:d177c0087d1f 327 pack->utc.year += 100;
guiott 0:d177c0087d1f 328 pack->utc.mon -= 1;
guiott 0:d177c0087d1f 329
guiott 0:d177c0087d1f 330 return 1;
guiott 0:d177c0087d1f 331 }
guiott 0:d177c0087d1f 332
guiott 0:d177c0087d1f 333 /**
guiott 0:d177c0087d1f 334 * \brief Parse VTG packet from buffer.
guiott 0:d177c0087d1f 335 * @param buff a constant character pointer of packet buffer.
guiott 0:d177c0087d1f 336 * @param buff_sz buffer size.
guiott 0:d177c0087d1f 337 * @param pack a pointer of packet which will filled by function.
guiott 0:d177c0087d1f 338 * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
guiott 0:d177c0087d1f 339 */
guiott 0:d177c0087d1f 340 int nmea_parse_GPVTG(const char *buff, int buff_sz, nmeaGPVTG *pack)
guiott 0:d177c0087d1f 341 {
guiott 0:d177c0087d1f 342 NMEA_ASSERT(buff && pack);
guiott 0:d177c0087d1f 343
guiott 0:d177c0087d1f 344 memset(pack, 0, sizeof(nmeaGPVTG));
guiott 0:d177c0087d1f 345
guiott 0:d177c0087d1f 346 nmea_trace_buff(buff, buff_sz);
guiott 0:d177c0087d1f 347
guiott 0:d177c0087d1f 348 if(8 != nmea_scanf(buff, buff_sz,
guiott 0:d177c0087d1f 349 "$GPVTG,%f,%C,%f,%C,%f,%C,%f,%C*",
guiott 0:d177c0087d1f 350 &(pack->dir), &(pack->dir_t),
guiott 0:d177c0087d1f 351 &(pack->dec), &(pack->dec_m),
guiott 0:d177c0087d1f 352 &(pack->spn), &(pack->spn_n),
guiott 0:d177c0087d1f 353 &(pack->spk), &(pack->spk_k)))
guiott 0:d177c0087d1f 354 {
guiott 0:d177c0087d1f 355 nmea_error("GPVTG parse error!");
guiott 0:d177c0087d1f 356 return 0;
guiott 0:d177c0087d1f 357 }
guiott 0:d177c0087d1f 358
guiott 0:d177c0087d1f 359 if( pack->dir_t != 'T' ||
guiott 0:d177c0087d1f 360 pack->dec_m != 'M' ||
guiott 0:d177c0087d1f 361 pack->spn_n != 'N' ||
guiott 0:d177c0087d1f 362 pack->spk_k != 'K')
guiott 0:d177c0087d1f 363 {
guiott 0:d177c0087d1f 364 nmea_error("GPVTG parse error (format error)!");
guiott 0:d177c0087d1f 365 return 0;
guiott 0:d177c0087d1f 366 }
guiott 0:d177c0087d1f 367
guiott 0:d177c0087d1f 368 return 1;
guiott 0:d177c0087d1f 369 }
guiott 0:d177c0087d1f 370
guiott 0:d177c0087d1f 371 /**
guiott 0:d177c0087d1f 372 * \brief Fill nmeaINFO structure by GGA packet data.
guiott 0:d177c0087d1f 373 * @param pack a pointer of packet structure.
guiott 0:d177c0087d1f 374 * @param info a pointer of summary information structure.
guiott 0:d177c0087d1f 375 */
guiott 0:d177c0087d1f 376 void nmea_GPGGA2info(nmeaGPGGA *pack, nmeaINFO *info)
guiott 0:d177c0087d1f 377 {
guiott 0:d177c0087d1f 378 NMEA_ASSERT(pack && info);
guiott 0:d177c0087d1f 379
guiott 0:d177c0087d1f 380 info->utc.hour = pack->utc.hour;
guiott 0:d177c0087d1f 381 info->utc.min = pack->utc.min;
guiott 0:d177c0087d1f 382 info->utc.sec = pack->utc.sec;
guiott 0:d177c0087d1f 383 info->utc.hsec = pack->utc.hsec;
guiott 0:d177c0087d1f 384 info->sig = pack->sig;
guiott 0:d177c0087d1f 385 info->HDOP = pack->HDOP;
guiott 0:d177c0087d1f 386 info->elv = pack->elv;
guiott 0:d177c0087d1f 387 info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
guiott 0:d177c0087d1f 388 info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
guiott 0:d177c0087d1f 389 info->smask |= GPGGA;
guiott 0:d177c0087d1f 390 }
guiott 0:d177c0087d1f 391
guiott 0:d177c0087d1f 392 /**
guiott 0:d177c0087d1f 393 * \brief Fill nmeaINFO structure by GSA packet data.
guiott 0:d177c0087d1f 394 * @param pack a pointer of packet structure.
guiott 0:d177c0087d1f 395 * @param info a pointer of summary information structure.
guiott 0:d177c0087d1f 396 */
guiott 0:d177c0087d1f 397 void nmea_GPGSA2info(nmeaGPGSA *pack, nmeaINFO *info)
guiott 0:d177c0087d1f 398 {
guiott 0:d177c0087d1f 399 int i, j, nuse = 0;
guiott 0:d177c0087d1f 400
guiott 0:d177c0087d1f 401 NMEA_ASSERT(pack && info);
guiott 0:d177c0087d1f 402
guiott 0:d177c0087d1f 403 info->fix = pack->fix_type;
guiott 0:d177c0087d1f 404 info->PDOP = pack->PDOP;
guiott 0:d177c0087d1f 405 info->HDOP = pack->HDOP;
guiott 0:d177c0087d1f 406 info->VDOP = pack->VDOP;
guiott 0:d177c0087d1f 407
guiott 0:d177c0087d1f 408 for(i = 0; i < NMEA_MAXSAT; ++i)
guiott 0:d177c0087d1f 409 {
guiott 0:d177c0087d1f 410 for(j = 0; j < info->satinfo.inview; ++j)
guiott 0:d177c0087d1f 411 {
guiott 0:d177c0087d1f 412 if(pack->sat_prn[i] && pack->sat_prn[i] == info->satinfo.sat[j].id)
guiott 0:d177c0087d1f 413 {
guiott 0:d177c0087d1f 414 info->satinfo.sat[j].in_use = 1;
guiott 0:d177c0087d1f 415 nuse++;
guiott 0:d177c0087d1f 416 }
guiott 0:d177c0087d1f 417 }
guiott 0:d177c0087d1f 418 }
guiott 0:d177c0087d1f 419
guiott 0:d177c0087d1f 420 info->satinfo.inuse = nuse;
guiott 0:d177c0087d1f 421 info->smask |= GPGSA;
guiott 0:d177c0087d1f 422 }
guiott 0:d177c0087d1f 423
guiott 0:d177c0087d1f 424 /**
guiott 0:d177c0087d1f 425 * \brief Fill nmeaINFO structure by GSV packet data.
guiott 0:d177c0087d1f 426 * @param pack a pointer of packet structure.
guiott 0:d177c0087d1f 427 * @param info a pointer of summary information structure.
guiott 0:d177c0087d1f 428 */
guiott 0:d177c0087d1f 429 void nmea_GPGSV2info(nmeaGPGSV *pack, nmeaINFO *info)
guiott 0:d177c0087d1f 430 {
guiott 0:d177c0087d1f 431 int isat, isi, nsat;
guiott 0:d177c0087d1f 432
guiott 0:d177c0087d1f 433 NMEA_ASSERT(pack && info);
guiott 0:d177c0087d1f 434
guiott 0:d177c0087d1f 435 if(pack->pack_index > pack->pack_count ||
guiott 0:d177c0087d1f 436 pack->pack_index * NMEA_SATINPACK > NMEA_MAXSAT)
guiott 0:d177c0087d1f 437 return;
guiott 0:d177c0087d1f 438
guiott 0:d177c0087d1f 439 if(pack->pack_index < 1)
guiott 0:d177c0087d1f 440 pack->pack_index = 1;
guiott 0:d177c0087d1f 441
guiott 0:d177c0087d1f 442 info->satinfo.inview = pack->sat_count;
guiott 0:d177c0087d1f 443
guiott 0:d177c0087d1f 444 nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
guiott 0:d177c0087d1f 445 nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
guiott 0:d177c0087d1f 446
guiott 0:d177c0087d1f 447 for(isat = 0; isat < nsat; ++isat)
guiott 0:d177c0087d1f 448 {
guiott 0:d177c0087d1f 449 isi = (pack->pack_index - 1) * NMEA_SATINPACK + isat;
guiott 0:d177c0087d1f 450 info->satinfo.sat[isi].id = pack->sat_data[isat].id;
guiott 0:d177c0087d1f 451 info->satinfo.sat[isi].elv = pack->sat_data[isat].elv;
guiott 0:d177c0087d1f 452 info->satinfo.sat[isi].azimuth = pack->sat_data[isat].azimuth;
guiott 0:d177c0087d1f 453 info->satinfo.sat[isi].sig = pack->sat_data[isat].sig;
guiott 0:d177c0087d1f 454 }
guiott 0:d177c0087d1f 455
guiott 0:d177c0087d1f 456 info->smask |= GPGSV;
guiott 0:d177c0087d1f 457 }
guiott 0:d177c0087d1f 458
guiott 0:d177c0087d1f 459 /**
guiott 0:d177c0087d1f 460 * \brief Fill nmeaINFO structure by RMC packet data.
guiott 0:d177c0087d1f 461 * @param pack a pointer of packet structure.
guiott 0:d177c0087d1f 462 * @param info a pointer of summary information structure.
guiott 0:d177c0087d1f 463 */
guiott 0:d177c0087d1f 464 void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info)
guiott 0:d177c0087d1f 465 {
guiott 0:d177c0087d1f 466 NMEA_ASSERT(pack && info);
guiott 0:d177c0087d1f 467
guiott 0:d177c0087d1f 468 if('A' == pack->status)
guiott 0:d177c0087d1f 469 {
guiott 0:d177c0087d1f 470 if(NMEA_SIG_BAD == info->sig)
guiott 0:d177c0087d1f 471 info->sig = NMEA_SIG_MID;
guiott 0:d177c0087d1f 472 if(NMEA_FIX_BAD == info->fix)
guiott 0:d177c0087d1f 473 info->fix = NMEA_FIX_2D;
guiott 0:d177c0087d1f 474 }
guiott 0:d177c0087d1f 475 else if('V' == pack->status)
guiott 0:d177c0087d1f 476 {
guiott 0:d177c0087d1f 477 info->sig = NMEA_SIG_BAD;
guiott 0:d177c0087d1f 478 info->fix = NMEA_FIX_BAD;
guiott 0:d177c0087d1f 479 }
guiott 0:d177c0087d1f 480
guiott 0:d177c0087d1f 481 info->utc = pack->utc;
guiott 0:d177c0087d1f 482 info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
guiott 0:d177c0087d1f 483 info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
guiott 0:d177c0087d1f 484 info->speed = pack->speed * NMEA_TUD_KNOTS;
guiott 0:d177c0087d1f 485 info->direction = pack->direction;
guiott 0:d177c0087d1f 486 info->smask |= GPRMC;
guiott 0:d177c0087d1f 487 }
guiott 0:d177c0087d1f 488
guiott 0:d177c0087d1f 489 /**
guiott 0:d177c0087d1f 490 * \brief Fill nmeaINFO structure by VTG packet data.
guiott 0:d177c0087d1f 491 * @param pack a pointer of packet structure.
guiott 0:d177c0087d1f 492 * @param info a pointer of summary information structure.
guiott 0:d177c0087d1f 493 */
guiott 0:d177c0087d1f 494 void nmea_GPVTG2info(nmeaGPVTG *pack, nmeaINFO *info)
guiott 0:d177c0087d1f 495 {
guiott 0:d177c0087d1f 496 NMEA_ASSERT(pack && info);
guiott 0:d177c0087d1f 497
guiott 0:d177c0087d1f 498 info->direction = pack->dir;
guiott 0:d177c0087d1f 499 info->declination = pack->dec;
guiott 0:d177c0087d1f 500 info->speed = pack->spk;
guiott 0:d177c0087d1f 501 info->smask |= GPVTG;
guiott 0:d177c0087d1f 502 }