Data Structures | Typedefs | Functions

nmea_hl.c File Reference

NMEA parser implementation. More...

#include <stdlib.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include "nmea_hl.h"
#include "display.h"

Data Structures

struct  gps_dm_s

Typedefs

typedef struct gps_dm_s gps_dm_t

Functions

gps_line_status_t nmea_recvd (gps_parser_t *parser, usart_rxdata_t c)
 give one character to NMEA parser
gps_proto_parser_tnew_nmea_parser (gps_parser_t *parser)
void free_nmea_parser (gps_parser_t *parser)

Detailed Description

NMEA parser implementation.

Some description of the NMEA protocol can be found at the gpsd project site, at interest here is the SiRF NMEA Protocol Reference Manual(2.2). In the future, we will also need the SiRF Binary Protocol Reference Manual(2.4).


Typedef Documentation

typedef struct gps_dm_s gps_dm_t

parsed NMEA latitude or longitude


Function Documentation

gps_line_status_t nmea_recvd ( gps_parser_t ,
usart_rxdata_t   
)

give one character to NMEA parser

Returns:
information about last received line (if any)

{
  gps_parser_t * p = parser; /* for shorter source code */
  proto_nmea_parser_t * pp = (proto_nmea_parser_t*)parser->proto_parser;
  gps_line_status_t ret;

  if (c.flags & USART_NO_RX) {
    return GPS_LINE_CKERR;
  }
  if (c.flags & USART_FRAME_ERROR) {
    return GPS_LINE_MORE;
  }
  if (pp->bufidx >= sizeof(pp->buf)-1) {
    /* no more space in buffer */
    if (c.data == '$') {
      /* uBlox may intermix binary and NMEA sentences, at
       * least this is what I understand from docs */
      pp->bufidx = 0;
      pp->buf[(pp->bufidx)++] = c.data;
      return GPS_LINE_MORE;
    }
    if (c.data == '\n') {
      /* line finished -> reset */
      pp->bufidx = 0;
      /* but return error indication anyway */
    }
    return GPS_LINE_OVERFLOW;
  }

  if (pp->bufidx == 0) {
    /* save timestamp */
    gps_timestamp_start_of_message (parser);
  }

  pp->buf[pp->bufidx++] = c.data;
  if (c.data != '\n') {
    /* not finished yet */
    return GPS_LINE_MORE;
  }

  
  /* put in terminating NUL byte */
  pp->buf[pp->bufidx] = '\0';
  /* reset start index */
  pp->bufidx = 0;

  /* check checksum */
  if (nmea_line_csum_check (pp)) {
    return GPS_LINE_CKERR;
  }

  /* now we have a complete line with correct checksum
   * and we can start parsing */
  ret = nmea_line_parse (p);

  return ret;
}