Skip to content

Commit 7f159dd

Browse files
committedJun 22, 2015
Separate NMEA parser and GPS hardware-specific functions
1 parent a6fceb5 commit 7f159dd

File tree

5 files changed

+988
-942
lines changed

5 files changed

+988
-942
lines changed
 

‎stm32l151rdt6-dev/GPS.c

+28-792
Large diffs are not rendered by default.

‎stm32l151rdt6-dev/GPS.h

+3-139
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// Define to prevent recursive inclusion -------------------------------------
21
#ifndef __GPS_H
32
#define __GPS_H
43

@@ -8,7 +7,7 @@
87

98
// Size constants
109
#define GPS_BUFFER_SIZE 1024 // Size of GPS buffer
11-
#define MAX_SATELLITES_VIEW 12 // Maximum number of satellites in view to handle
10+
1211

1312
// GPS commands
1413
// MTK test packet (MTK should respond with "$PMTK001,0,3*30")
@@ -39,151 +38,16 @@
3938
// Disable periodic mode
4039
#define PMTK_SET_PERIODIC_MODE_NORMAL "$PMTK225,0*"
4140

42-
// Factor for translating PDOP to accuracy in meters
43-
// This very rough value representing GPS horizontal position accuracy
44-
#define GPS_DOP_FACTOR 5
45-
46-
// Simple boolean
47-
#ifndef BOOL
48-
#define BOOL
49-
typedef enum {
50-
FALSE = 0,
51-
TRUE = !FALSE
52-
} bool;
53-
#endif
54-
55-
56-
// NMEA sentence type
57-
enum {
58-
// GPS sentences
59-
NMEA_GPGLL,
60-
NMEA_GPRMC,
61-
NMEA_GPVTG,
62-
NMEA_GPGGA,
63-
NMEA_GPGSA,
64-
NMEA_GPGSV,
65-
NMEA_GPZDA,
66-
// MTK sentences
67-
NMEA_PMTK001,
68-
NMEA_PMTK010,
69-
NMEA_PMTK011,
70-
// Status sentences
71-
NMEA_INVALID, // Sentence validation failed
72-
NMEA_UNKNOWN, // Unsupported sentence found
73-
NMEA_NOTFOUND // No sentence has been found
74-
};
75-
76-
// NMEA sentence
77-
typedef struct {
78-
uint8_t *start; // Pointer to the first byte of sentence
79-
uint8_t *data; // Pointer to the first term of sentence
80-
uint8_t *end; // Pointer to the last byte of sentence
81-
uint8_t type; // Sentence type
82-
} NMEASentence_TypeDef;
83-
84-
// Structure to hold NMEA time
85-
typedef struct {
86-
uint8_t Hours; // 0..23
87-
uint8_t Minutes; // 0..59
88-
uint8_t Seconds; // 0..59
89-
} NMEATime;
90-
91-
// Structure to hold NMEA date
92-
typedef struct {
93-
uint8_t Date; // 1..31
94-
uint8_t Month; // 1..12
95-
uint16_t Year; // e.g. 2015
96-
} NMEADate;
97-
98-
// Structure to hold all parsed GPS data
99-
typedef struct {
100-
int32_t latitude; // Latitude (microdegrees), e.g. 89123456 = 89.123456 degrees
101-
uint8_t latitude_char; // Latitude N/S indicator (X if no valid data)
102-
int32_t longitude; // Longitude (microdegrees), e.g. 179123456 = 179.123456 degrees
103-
uint8_t longitude_char; // Longitude E/W indicator (X if no valid data)
104-
uint32_t speed_k; // Speed over ground (Knots, 1 knot = 1.85200km/h)
105-
uint32_t speed; // Speed over ground (km/h)
106-
uint32_t course; // Track angle relative to North (Degrees)
107-
uint32_t PDOP; // Dilution of precision
108-
uint32_t HDOP; // Horizontal dilution of precision
109-
uint32_t VDOP; // Vertical dilution of precision
110-
uint32_t accuracy; // Position accuracy (meters) [value of '500' represents 5.00m]
111-
uint8_t sats_used; // Satellites used for fix
112-
uint8_t sats_view; // Satellites in view
113-
int32_t altitude; // Mean-sea-level altitude (meters)
114-
int32_t geoid_separation; // Geoid-to-ellipsoid separation (meters)
115-
uint8_t fix; // Fix indicator (1 = fix not available, 2 = 2D fix, 3 = 3D fix)
116-
NMEATime fix_time; // Time of fix
117-
NMEADate fix_date; // Date of fix
118-
NMEATime time; // UTC time
119-
NMEADate date; // UTC date
120-
bool datetime_valid; // Have valid date and time
121-
uint8_t fix_quality; // Position fix indicator:
122-
// 0 = invalid
123-
// 1 = GPS fix (SPS)
124-
// 2 = DGPS fix
125-
// 3 = PPS fix (Encrypted military signal)
126-
// 4 = RTK (Real Time Kinematic)
127-
// 5 = Floating RTK
128-
// 6 = Estimated (dead reckoning) (2.3 feature)
129-
// 7 = Manual input mode
130-
// 8 = Simulation mode
131-
uint8_t mode; // Mode indicator:
132-
// A = Autonomous
133-
// D = Differential(DGPS)
134-
// E = Estimated(DR),
135-
// R = Coarse position
136-
// S = Simulator
137-
// N = Data not valid
138-
uint32_t dgps_age; // Time since last DGPS update (seconds)
139-
uint32_t dgps_id; // DGPS station ID number
140-
bool valid; // GPS status: TRUE if data valid
141-
} GPS_Data_TypeDef;
142-
143-
// Structure describes the GPS satellite
144-
typedef struct {
145-
uint8_t PRN; // Satellite PRN number
146-
uint8_t elevation; // Elevation, degrees (max 90)
147-
uint16_t azimuth; // Azimuth, degrees from true north (0..359)
148-
uint8_t SNR; // SNR, dB (0..99, 255 when not tracking)
149-
bool used; // TRUE if satellite used in location fix
150-
} GPS_Satellite_TypeDef;
151-
152-
// PMTK sentences parse result
153-
typedef struct {
154-
bool PMTK_BOOT; // TRUE when "$PMTK011,MTKGPS*08" sentence parsed
155-
uint8_t PMTK010; // Last parsed $PMTK010 sentence:
156-
// 0 = unknown
157-
// 1 = startup
158-
// 2 = notification for the host aiding EPO
159-
// 3 = notification for the transition to normal mode is successfully done
160-
uint16_t PMTK001_CMD; // Cmd field from last parsed $PMTK001 sentence
161-
uint8_t PMTK001_FLAG; // Flag field from last parsed $PMTK001 sentence:
162-
// 0 = invalid packet
163-
// 1 = unsupported packet type
164-
// 2 = valid packet, but action failed
165-
// 3 = valid packet, action succeeded
166-
} GPS_PMTK_TypeDef;
167-
16841

16942
// Public variables
170-
extern GPS_Data_TypeDef GPSData; // Parsed GPS information
171-
extern bool GPS_new_data; // TRUE if received new GPS packet
172-
extern bool GPS_parsed; // TRUE if GPS packets was parsed
17343
extern uint16_t GPS_buf_cntr; // Number of actual bytes in GPS buffer
174-
extern uint8_t GPS_sentences_parsed; // Parsed NMEA sentences counter
175-
extern uint8_t GPS_sentences_unknown; // Unsupported NMEA sentences counter
176-
extern uint8_t GPS_sentences_invalid; // Invalid NMEA sentences counter
17744
extern uint8_t GPS_buf[]; // Buffer for GPS data
178-
extern uint8_t GPS_sats[]; // IDs of satellites used in position fix
179-
extern GPS_Satellite_TypeDef GPS_sats_view[]; // Information about satellites in view
45+
extern bool GPS_new_data; // TRUE if received new GPS packet
46+
extern bool GPS_parsed; // TRUE if GPS packets was parsed
18047

18148

18249
// Function prototypes
18350
void GPS_Send(char *cmd);
184-
void GPS_InitData(void);
185-
void GPS_CheckUsedSats(void);
186-
void GPS_ParseBuf(uint8_t *buf, uint32_t length);
18751
void GPS_Init(void);
18852

18953
#endif // __GPS_H

‎stm32l151rdt6-dev/NMEA.c

+782
Large diffs are not rendered by default.

‎stm32l151rdt6-dev/NMEA.h

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Define to prevent recursive inclusion -------------------------------------
2+
#ifndef __NMEA_H
3+
#define __NMEA_H
4+
5+
6+
// Size constants
7+
#define MAX_SATELLITES_VIEW 12 // Maximum number of satellites in view to handle
8+
9+
// Factor for translating PDOP to accuracy in meters
10+
// This is very rough value representing GPS horizontal position accuracy
11+
#define GPS_DOP_FACTOR 5
12+
13+
14+
// Simple boolean
15+
#ifndef BOOL
16+
#define BOOL
17+
typedef enum {
18+
FALSE = 0,
19+
TRUE = !FALSE
20+
} bool;
21+
#endif
22+
23+
24+
// Types of NMEA sentences
25+
enum {
26+
// Status sentences
27+
NMEA_NOTFOUND = 1, // No sentence has been found
28+
NMEA_UNKNOWN, // Unsupported sentence found
29+
NMEA_INVALID, // Sentence validation failed
30+
// GPS sentences
31+
NMEA_GPGLL,
32+
NMEA_GPRMC,
33+
NMEA_GPVTG,
34+
NMEA_GPGGA,
35+
NMEA_GPGSA,
36+
NMEA_GPGSV,
37+
NMEA_GPZDA,
38+
// MTK sentences
39+
NMEA_PMTK001,
40+
NMEA_PMTK010,
41+
NMEA_PMTK011
42+
};
43+
44+
// Structure describes NMEA sentence in the data buffer
45+
typedef struct {
46+
uint8_t *start; // Pointer to the first byte of sentence
47+
uint8_t *data; // Pointer to the first term of sentence
48+
uint8_t *end; // Pointer to the last byte of sentence
49+
uint8_t type; // Sentence type
50+
} NMEASentence_TypeDef;
51+
52+
// Structure to hold NMEA time
53+
typedef struct {
54+
uint8_t Hours; // Hours (0..23)
55+
uint8_t Minutes; // Minutes (0..59)
56+
uint8_t Seconds; // Seconds (0..59)
57+
} NMEATime;
58+
59+
// Structure to hold NMEA date
60+
typedef struct {
61+
uint8_t Date; // Day of month (1..31)
62+
uint8_t Month; // Month (1..12)
63+
uint16_t Year; // Year four-digit number (e.g. 2015)
64+
} NMEADate;
65+
66+
// Structure to hold all parsed GPS data
67+
typedef struct {
68+
int32_t latitude; // Latitude (microdegrees), e.g. 89123456 = 89.123456 degrees
69+
uint8_t latitude_char; // Latitude N/S indicator (X if no valid data)
70+
int32_t longitude; // Longitude (microdegrees), e.g. 179123456 = 179.123456 degrees
71+
uint8_t longitude_char; // Longitude E/W indicator (X if no valid data)
72+
uint32_t speed_k; // Speed over ground (Knots, 1 knot = 1.85200km/h)
73+
uint32_t speed; // Speed over ground (km/h)
74+
uint32_t course; // Track angle relative to North (Degrees)
75+
uint32_t PDOP; // Dilution of precision
76+
uint32_t HDOP; // Horizontal dilution of precision
77+
uint32_t VDOP; // Vertical dilution of precision
78+
uint32_t accuracy; // Position accuracy (meters) [value of '500' represents 5.00m]
79+
uint8_t sats_used; // Satellites used for fix
80+
uint8_t sats_view; // Satellites in view
81+
int32_t altitude; // Mean-sea-level altitude (meters)
82+
int32_t geoid_separation; // Geoid-to-ellipsoid separation (meters)
83+
uint8_t fix; // Fix indicator (1 = fix not available, 2 = 2D fix, 3 = 3D fix)
84+
NMEATime fix_time; // Time of fix
85+
NMEADate fix_date; // Date of fix
86+
NMEATime time; // UTC time
87+
NMEADate date; // UTC date
88+
bool datetime_valid; // Have valid date and time
89+
uint8_t fix_quality; // Position fix indicator:
90+
// 0 = invalid
91+
// 1 = GPS fix (SPS)
92+
// 2 = DGPS fix
93+
// 3 = PPS fix (Encrypted military signal)
94+
// 4 = RTK (Real Time Kinematic)
95+
// 5 = Floating RTK
96+
// 6 = Estimated (dead reckoning) (2.3 feature)
97+
// 7 = Manual input mode
98+
// 8 = Simulation mode
99+
uint8_t mode; // Mode indicator:
100+
// A = Autonomous
101+
// D = Differential(DGPS)
102+
// E = Estimated(DR),
103+
// R = Coarse position
104+
// S = Simulator
105+
// N = Data not valid
106+
uint32_t dgps_age; // Time since last DGPS update (seconds)
107+
uint32_t dgps_id; // DGPS station ID number
108+
bool valid; // GPS status: TRUE if data valid
109+
} GPS_Data_TypeDef;
110+
111+
// Structure describes the satellite parameters
112+
typedef struct {
113+
uint8_t PRN; // Satellite PRN number
114+
uint8_t elevation; // Elevation, degrees (max 90)
115+
uint16_t azimuth; // Azimuth, degrees from true north (0..359)
116+
uint8_t SNR; // SNR, dB (0..99, 255 when not tracking)
117+
bool used; // TRUE if satellite used in location fix
118+
} NMEA_Sat_TypeDef;
119+
120+
// Structure to hold data from PMTK sentences
121+
typedef struct {
122+
bool PMTK_BOOT; // TRUE when "$PMTK011,MTKGPS*08" sentence parsed
123+
uint8_t PMTK010; // Last parsed $PMTK010 sentence:
124+
// 0 = unknown
125+
// 1 = startup
126+
// 2 = notification for the host aiding EPO
127+
// 3 = notification for the transition to normal mode is successfully done
128+
uint16_t PMTK001_CMD; // CMD field from last parsed $PMTK001 sentence
129+
uint8_t PMTK001_FLAG; // FLAG field from last parsed $PMTK001 sentence:
130+
// 0 = invalid packet
131+
// 1 = unsupported packet type
132+
// 2 = valid packet, but action failed
133+
// 3 = valid packet, action succeeded
134+
} NMEA_PMTK_TypeDef;
135+
136+
137+
// Public variables
138+
// Structures for parsed data
139+
extern GPS_Data_TypeDef GPSData; // Data from GNSS sentences
140+
extern NMEA_PMTK_TypeDef PMTKData; // Data from PMTK sentences
141+
142+
// Sentences counters
143+
extern uint8_t NMEA_sentences_parsed; // Parsed
144+
extern uint8_t NMEA_sentences_unknown; // Unsupported
145+
extern uint8_t NMEA_sentences_invalid; // Invalid
146+
147+
// Information about satellites in view
148+
extern NMEA_Sat_TypeDef GPS_sats_view[];
149+
150+
151+
// Function prototypes
152+
uint8_t NMEA_CalcCRC(char *str);
153+
void NMEA_InitData(void);
154+
void NMEA_CheckUsedSats(void);
155+
void NMEA_ParseBuf(uint8_t *buf, uint16_t *length);
156+
157+
#endif // __NMEA_H

‎stm32l151rdt6-dev/main.c

+18-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "nRF24.h"
2424
#include "uart.h"
2525
#include "ST7541.h"
26+
#include "NMEA.h"
2627
#include "GPS.h"
2728

2829
// USB stuff
@@ -1794,7 +1795,7 @@ int main(void) {
17941795
_NMEA_total_count = 0;
17951796
GPS_new_data = FALSE;
17961797
GPS_parsed = FALSE;
1797-
GPS_InitData();
1798+
NMEA_InitData();
17981799

17991800
// The GPS USART port initialization
18001801
UARTx_Init(GPS_USART_PORT,USART_TX | USART_RX,9600); // Use slow speed at startup
@@ -1938,11 +1939,11 @@ int main(void) {
19381939
// GPS info
19391940
i = 0;
19401941
i += PutStr(i,30,"NMEA:",fnt5x7) - 1;
1941-
i += PutIntU(i,30,GPS_sentences_parsed,fnt5x7) - 1;
1942+
i += PutIntU(i,30,NMEA_sentences_parsed,fnt5x7) - 1;
19421943
i += DrawChar(i,30,'/',fnt5x7) - 1;
1943-
i += PutIntU(i,30,GPS_sentences_unknown,fnt5x7) - 1;
1944+
i += PutIntU(i,30,NMEA_sentences_unknown,fnt5x7) - 1;
19441945
i += DrawChar(i,30,'/',fnt5x7) - 1;
1945-
i += PutIntU(i,30,GPS_sentences_invalid,fnt5x7) + 5;
1946+
i += PutIntU(i,30,NMEA_sentences_invalid,fnt5x7) + 5;
19461947
i += PutStr(i,30,"Size:",fnt5x7) - 1;
19471948
i += PutIntU(i,30,GPS_buf_cntr,fnt5x7);
19481949

@@ -2285,18 +2286,24 @@ int main(void) {
22852286
_NMEA_total_size += GPS_buf_cntr;
22862287

22872288
// Parse data received from GPS receiver
2288-
GPS_ParseBuf(GPS_buf,GPS_buf_cntr);
2289+
NMEA_ParseBuf(GPS_buf,&GPS_buf_cntr);
2290+
2291+
// Reset the new GPS data flag (data were parsed)
2292+
GPS_new_data = FALSE;
2293+
2294+
// Set flag indicating what GPS data was parsed
2295+
GPS_parsed = TRUE;
22892296

22902297
// Update NMEA sentences counter
2291-
_NMEA_total_count += GPS_sentences_parsed + GPS_sentences_unknown;
2298+
_NMEA_total_count += NMEA_sentences_parsed + NMEA_sentences_invalid + NMEA_sentences_unknown;
22922299
}
22932300

22942301
if (GPS_parsed) {
22952302
// GPS data parsed
22962303

22972304
// Update related variables if at least one sentence was parsed
2298-
if (GPS_sentences_parsed) {
2299-
GPS_CheckUsedSats();
2305+
if (NMEA_sentences_parsed) {
2306+
NMEA_CheckUsedSats();
23002307
if (GPSData.fix == 3) {
23012308
// GPS altitude makes sense only in case of 3D fix
23022309
CurData.GPSAlt = GPSData.altitude;
@@ -2312,9 +2319,9 @@ int main(void) {
23122319

23132320
///*
23142321
printf("GPS: NMEA=%u/%u/%u SAT=%u/%u FIX=%u MODE=\"%c\" FIX=\"%sVALID\"\r\n",
2315-
GPS_sentences_parsed,
2316-
GPS_sentences_unknown,
2317-
GPS_sentences_invalid,
2322+
NMEA_sentences_parsed,
2323+
NMEA_sentences_unknown,
2324+
NMEA_sentences_invalid,
23182325
GPSData.sats_used,
23192326
GPSData.sats_view,
23202327
GPSData.fix,

0 commit comments

Comments
 (0)
Please sign in to comment.