This code holds the complete demo set for the sx1280: PingPong, PER and Ranging Outdoor demo application. >>>>> This code MUST run on the mbed library release 127 or everything will be painfully slow.

Dependencies:   mbed SX1280Lib DmTftLibrary

* This code MUST run on the mbed library release 127 or everything will be painfully slow.*
Committer:
mverdy
Date:
Thu Nov 08 10:14:39 2018 +0000
Revision:
20:626b92b70bf7
Addition of missing modules to synchronize with v1.5.2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mverdy 20:626b92b70bf7 1 /*
mverdy 20:626b92b70bf7 2 ______ _
mverdy 20:626b92b70bf7 3 / _____) _ | |
mverdy 20:626b92b70bf7 4 ( (____ _____ ____ _| |_ _____ ____| |__
mverdy 20:626b92b70bf7 5 \____ \| ___ | (_ _) ___ |/ ___) _ \
mverdy 20:626b92b70bf7 6 _____) ) ____| | | || |_| ____( (___| | | |
mverdy 20:626b92b70bf7 7 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mverdy 20:626b92b70bf7 8 (C)2016 Semtech
mverdy 20:626b92b70bf7 9
mverdy 20:626b92b70bf7 10 Description: uBlox MAX7 GPS
mverdy 20:626b92b70bf7 11
mverdy 20:626b92b70bf7 12 Maintainer: Gregory Cristian & Gilbert Menth
mverdy 20:626b92b70bf7 13 */
mverdy 20:626b92b70bf7 14
mverdy 20:626b92b70bf7 15 #include <stdio.h>
mverdy 20:626b92b70bf7 16 #include "mbed.h"
mverdy 20:626b92b70bf7 17 #include "Timers.h"
mverdy 20:626b92b70bf7 18 #include "GpsMax7.h"
mverdy 20:626b92b70bf7 19
mverdy 20:626b92b70bf7 20
mverdy 20:626b92b70bf7 21 #define MAX_NMEA_SENTENCE_LENGTH 100
mverdy 20:626b92b70bf7 22 #define GPS_I2C_ADDR ( 0x84 ) // GPS IC I2C address
mverdy 20:626b92b70bf7 23 #define NUM_SETUP_COMMANDS 7
mverdy 20:626b92b70bf7 24 #define SETUP_COMMAND_LENGTH 16
mverdy 20:626b92b70bf7 25 #define DATA_STREAM_ADDRESS 0xFF
mverdy 20:626b92b70bf7 26 #define I2C_FREQUENCY 100000 //100 kHz
mverdy 20:626b92b70bf7 27
mverdy 20:626b92b70bf7 28
mverdy 20:626b92b70bf7 29 typedef enum
mverdy 20:626b92b70bf7 30 {
mverdy 20:626b92b70bf7 31 GPGGA_NMEA_DOLLAR,
mverdy 20:626b92b70bf7 32 GPGGA_NMEA_G1,
mverdy 20:626b92b70bf7 33 GPGGA_NMEA_P,
mverdy 20:626b92b70bf7 34 GPGGA_NMEA_G2,
mverdy 20:626b92b70bf7 35 GPGGA_NMEA_G3,
mverdy 20:626b92b70bf7 36 GPGGA_NMEA_A,
mverdy 20:626b92b70bf7 37 GPGGA_NMEA_CR,
mverdy 20:626b92b70bf7 38 GPGGA_NMEA_LF
mverdy 20:626b92b70bf7 39 }GpggaNmeaFields_t;
mverdy 20:626b92b70bf7 40
mverdy 20:626b92b70bf7 41 typedef enum
mverdy 20:626b92b70bf7 42 {
mverdy 20:626b92b70bf7 43 GPZDA_NMEA_DOLLAR,
mverdy 20:626b92b70bf7 44 GPZDA_NMEA_G1,
mverdy 20:626b92b70bf7 45 GPZDA_NMEA_P,
mverdy 20:626b92b70bf7 46 GPZDA_NMEA_G2,
mverdy 20:626b92b70bf7 47 GPZDA_NMEA_G3,
mverdy 20:626b92b70bf7 48 GPZDA_NMEA_A,
mverdy 20:626b92b70bf7 49 GPZDA_NMEA_CR,
mverdy 20:626b92b70bf7 50 GPZDA_NMEA_LF
mverdy 20:626b92b70bf7 51 }GpzdaNmeaFields_t;
mverdy 20:626b92b70bf7 52
mverdy 20:626b92b70bf7 53 typedef enum
mverdy 20:626b92b70bf7 54 {
mverdy 20:626b92b70bf7 55 GPS_COMMS_INIT,
mverdy 20:626b92b70bf7 56 GPS_COMMS_WRITE_SETUP,
mverdy 20:626b92b70bf7 57 GPS_COMMS_WAIT_WRITE_SETUP,
mverdy 20:626b92b70bf7 58 GPS_COMMS_READ_DATA_BUFFER,
mverdy 20:626b92b70bf7 59 GPS_COMMS_WAIT_NEXT_READ
mverdy 20:626b92b70bf7 60 }GpsCommsState_t;
mverdy 20:626b92b70bf7 61
mverdy 20:626b92b70bf7 62 union GpsBufferSize
mverdy 20:626b92b70bf7 63 {
mverdy 20:626b92b70bf7 64 uint16_t NumBytes;
mverdy 20:626b92b70bf7 65 char NumBytesBuffer[2];
mverdy 20:626b92b70bf7 66 };
mverdy 20:626b92b70bf7 67
mverdy 20:626b92b70bf7 68
mverdy 20:626b92b70bf7 69 //MAX7 initialisation commands
mverdy 20:626b92b70bf7 70 const char SetupArray[NUM_SETUP_COMMANDS][SETUP_COMMAND_LENGTH] =
mverdy 20:626b92b70bf7 71 {
mverdy 20:626b92b70bf7 72 { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29 }, // GxGGA on to I2C
mverdy 20:626b92b70bf7 73 { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x62 }, // GxZDA on to I2C
mverdy 20:626b92b70bf7 74 { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B }, // GxGLL not on the I2C
mverdy 20:626b92b70bf7 75 { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40 }, // GxRMC not on the I2C
mverdy 20:626b92b70bf7 76 { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x05, 0x47 }, // GxVTG not on the I2C
mverdy 20:626b92b70bf7 77 { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32 }, // GxGSA not on the I2C
mverdy 20:626b92b70bf7 78 { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39 } // GxGSV not on the I2C
mverdy 20:626b92b70bf7 79 };
mverdy 20:626b92b70bf7 80
mverdy 20:626b92b70bf7 81 I2C GpsI2C( I2C_SDA, I2C_SCL );
mverdy 20:626b92b70bf7 82
mverdy 20:626b92b70bf7 83 GpsStruct Gps;
mverdy 20:626b92b70bf7 84
mverdy 20:626b92b70bf7 85 static uint8_t GpggaSentenceBuffer[MAX_NMEA_SENTENCE_LENGTH];
mverdy 20:626b92b70bf7 86 static int GpggaSentenceBufferPtr = 0;
mverdy 20:626b92b70bf7 87 static uint8_t GpzdaSentenceBuffer[MAX_NMEA_SENTENCE_LENGTH];
mverdy 20:626b92b70bf7 88 static int GpzdaSentenceBufferPtr = 0;
mverdy 20:626b92b70bf7 89
mverdy 20:626b92b70bf7 90 static GpggaNmeaFields_t GpggaNmeaField;
mverdy 20:626b92b70bf7 91 static GpzdaNmeaFields_t GpzdaNmeaField;
mverdy 20:626b92b70bf7 92 static GpsCommsState_t GpsCommsState;
mverdy 20:626b92b70bf7 93 static uint32_t GpsCommsTimer;
mverdy 20:626b92b70bf7 94
mverdy 20:626b92b70bf7 95
mverdy 20:626b92b70bf7 96 static void GpsCheckCommandBufferForGpgga( uint8_t thisChar );
mverdy 20:626b92b70bf7 97 static void GpsCheckCommandBufferForGpzda( uint8_t thisChar );
mverdy 20:626b92b70bf7 98 static void ParseNmeaGpggaSentence( void );
mverdy 20:626b92b70bf7 99 static void ParseNmeaGpzdaSentence( void );
mverdy 20:626b92b70bf7 100 static bool Max7GpsWriteSetupOK( void );
mverdy 20:626b92b70bf7 101 static bool Max7GpsReadDataBuffer( void );
mverdy 20:626b92b70bf7 102 static uint8_t Max7GpsReadRegister( char thisRegAddress );
mverdy 20:626b92b70bf7 103
mverdy 20:626b92b70bf7 104
mverdy 20:626b92b70bf7 105 void Max7GpsInit( void )
mverdy 20:626b92b70bf7 106 {
mverdy 20:626b92b70bf7 107 GpsI2C.frequency( I2C_FREQUENCY );
mverdy 20:626b92b70bf7 108 }
mverdy 20:626b92b70bf7 109
mverdy 20:626b92b70bf7 110 void Max7GpsHandle( void )
mverdy 20:626b92b70bf7 111 {
mverdy 20:626b92b70bf7 112 switch( GpsCommsState )
mverdy 20:626b92b70bf7 113 {
mverdy 20:626b92b70bf7 114 case GPS_COMMS_INIT:
mverdy 20:626b92b70bf7 115 GpsCommsState = GPS_COMMS_WRITE_SETUP;
mverdy 20:626b92b70bf7 116 break;
mverdy 20:626b92b70bf7 117
mverdy 20:626b92b70bf7 118 case GPS_COMMS_WRITE_SETUP:
mverdy 20:626b92b70bf7 119 if( Max7GpsWriteSetupOK( ) )
mverdy 20:626b92b70bf7 120 {
mverdy 20:626b92b70bf7 121 GpsCommsState = GPS_COMMS_READ_DATA_BUFFER;
mverdy 20:626b92b70bf7 122 }
mverdy 20:626b92b70bf7 123 else
mverdy 20:626b92b70bf7 124 {
mverdy 20:626b92b70bf7 125 TimersSetTimer( &GpsCommsTimer, 1 * TIM_SEC );
mverdy 20:626b92b70bf7 126 GpsCommsState = GPS_COMMS_WAIT_WRITE_SETUP;
mverdy 20:626b92b70bf7 127 }
mverdy 20:626b92b70bf7 128 break;
mverdy 20:626b92b70bf7 129
mverdy 20:626b92b70bf7 130 case GPS_COMMS_WAIT_WRITE_SETUP:
mverdy 20:626b92b70bf7 131 if( TimersTimerHasExpired( &GpsCommsTimer ) )
mverdy 20:626b92b70bf7 132 {
mverdy 20:626b92b70bf7 133 GpsCommsState = GPS_COMMS_WRITE_SETUP;
mverdy 20:626b92b70bf7 134 }
mverdy 20:626b92b70bf7 135 break;
mverdy 20:626b92b70bf7 136
mverdy 20:626b92b70bf7 137 case GPS_COMMS_READ_DATA_BUFFER:
mverdy 20:626b92b70bf7 138 Max7GpsReadDataBuffer( );
mverdy 20:626b92b70bf7 139 TimersSetTimer( &GpsCommsTimer, 100 * TIM_MSEC );
mverdy 20:626b92b70bf7 140 GpsCommsState = GPS_COMMS_WAIT_NEXT_READ;
mverdy 20:626b92b70bf7 141 break;
mverdy 20:626b92b70bf7 142
mverdy 20:626b92b70bf7 143 case GPS_COMMS_WAIT_NEXT_READ:
mverdy 20:626b92b70bf7 144 if( TimersTimerHasExpired( &GpsCommsTimer ) )
mverdy 20:626b92b70bf7 145 {
mverdy 20:626b92b70bf7 146 GpsCommsState = GPS_COMMS_READ_DATA_BUFFER;
mverdy 20:626b92b70bf7 147 }
mverdy 20:626b92b70bf7 148 break;
mverdy 20:626b92b70bf7 149 }
mverdy 20:626b92b70bf7 150 }
mverdy 20:626b92b70bf7 151
mverdy 20:626b92b70bf7 152 static bool Max7GpsWriteSetupOK( void )
mverdy 20:626b92b70bf7 153 {
mverdy 20:626b92b70bf7 154 int lineCount;
mverdy 20:626b92b70bf7 155
mverdy 20:626b92b70bf7 156 for( lineCount = 0; lineCount < NUM_SETUP_COMMANDS; lineCount++ )
mverdy 20:626b92b70bf7 157 {
mverdy 20:626b92b70bf7 158 if( GpsI2C.write( GPS_I2C_ADDR, &SetupArray[lineCount][0], \
mverdy 20:626b92b70bf7 159 SETUP_COMMAND_LENGTH, 0 ) )
mverdy 20:626b92b70bf7 160 {
mverdy 20:626b92b70bf7 161 return false;
mverdy 20:626b92b70bf7 162 }
mverdy 20:626b92b70bf7 163 }
mverdy 20:626b92b70bf7 164 return true;
mverdy 20:626b92b70bf7 165 }
mverdy 20:626b92b70bf7 166
mverdy 20:626b92b70bf7 167 static bool Max7GpsReadDataBuffer( void )
mverdy 20:626b92b70bf7 168 {
mverdy 20:626b92b70bf7 169 uint8_t incomingCheck;
mverdy 20:626b92b70bf7 170 bool contFlag = true;
mverdy 20:626b92b70bf7 171
mverdy 20:626b92b70bf7 172 while( contFlag )
mverdy 20:626b92b70bf7 173 {
mverdy 20:626b92b70bf7 174 incomingCheck = Max7GpsReadRegister( DATA_STREAM_ADDRESS );
mverdy 20:626b92b70bf7 175 if( incomingCheck == 0xFF )
mverdy 20:626b92b70bf7 176 {
mverdy 20:626b92b70bf7 177 contFlag = false;
mverdy 20:626b92b70bf7 178 }
mverdy 20:626b92b70bf7 179 else
mverdy 20:626b92b70bf7 180 {
mverdy 20:626b92b70bf7 181 GpsCheckCommandBufferForGpgga( incomingCheck );
mverdy 20:626b92b70bf7 182 GpsCheckCommandBufferForGpzda( incomingCheck );
mverdy 20:626b92b70bf7 183 }
mverdy 20:626b92b70bf7 184 }
mverdy 20:626b92b70bf7 185 return false;
mverdy 20:626b92b70bf7 186 }
mverdy 20:626b92b70bf7 187
mverdy 20:626b92b70bf7 188 static uint8_t Max7GpsReadRegister( char thisRegAddress )
mverdy 20:626b92b70bf7 189 {
mverdy 20:626b92b70bf7 190 char thisValue;
mverdy 20:626b92b70bf7 191 uint8_t retVal;
mverdy 20:626b92b70bf7 192
mverdy 20:626b92b70bf7 193 thisValue = thisRegAddress;
mverdy 20:626b92b70bf7 194 GpsI2C.write( GPS_I2C_ADDR, &thisValue, 1, 0 );
mverdy 20:626b92b70bf7 195 GpsI2C.read( GPS_I2C_ADDR, &thisValue, 1, 0 );
mverdy 20:626b92b70bf7 196 retVal = ( uint8_t )thisValue;
mverdy 20:626b92b70bf7 197 return retVal;
mverdy 20:626b92b70bf7 198 }
mverdy 20:626b92b70bf7 199
mverdy 20:626b92b70bf7 200 static void GpsCheckCommandBufferForGpgga( uint8_t thisChar )
mverdy 20:626b92b70bf7 201 {
mverdy 20:626b92b70bf7 202 switch( GpggaNmeaField )
mverdy 20:626b92b70bf7 203 {
mverdy 20:626b92b70bf7 204 default:
mverdy 20:626b92b70bf7 205 case GPGGA_NMEA_DOLLAR:
mverdy 20:626b92b70bf7 206 if( thisChar == '$' )
mverdy 20:626b92b70bf7 207 {
mverdy 20:626b92b70bf7 208 GpggaSentenceBufferPtr = 0;
mverdy 20:626b92b70bf7 209 GpggaSentenceBuffer[GpggaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 210 GpggaNmeaField = GPGGA_NMEA_G1;
mverdy 20:626b92b70bf7 211 }
mverdy 20:626b92b70bf7 212 break;
mverdy 20:626b92b70bf7 213
mverdy 20:626b92b70bf7 214 case GPGGA_NMEA_G1:
mverdy 20:626b92b70bf7 215 if( thisChar == 'G' )
mverdy 20:626b92b70bf7 216 {
mverdy 20:626b92b70bf7 217 GpggaSentenceBuffer[GpggaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 218 GpggaNmeaField = GPGGA_NMEA_P;
mverdy 20:626b92b70bf7 219 }
mverdy 20:626b92b70bf7 220 else
mverdy 20:626b92b70bf7 221 {
mverdy 20:626b92b70bf7 222 GpggaNmeaField = GPGGA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 223 }
mverdy 20:626b92b70bf7 224 break;
mverdy 20:626b92b70bf7 225
mverdy 20:626b92b70bf7 226 case GPGGA_NMEA_P:
mverdy 20:626b92b70bf7 227 if( thisChar == 'P' )
mverdy 20:626b92b70bf7 228 {
mverdy 20:626b92b70bf7 229 GpggaSentenceBuffer[GpggaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 230 GpggaNmeaField = GPGGA_NMEA_G2;
mverdy 20:626b92b70bf7 231 }
mverdy 20:626b92b70bf7 232 else
mverdy 20:626b92b70bf7 233 {
mverdy 20:626b92b70bf7 234 GpggaNmeaField = GPGGA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 235 }
mverdy 20:626b92b70bf7 236 break;
mverdy 20:626b92b70bf7 237
mverdy 20:626b92b70bf7 238 case GPGGA_NMEA_G2:
mverdy 20:626b92b70bf7 239 if( thisChar == 'G' )
mverdy 20:626b92b70bf7 240 {
mverdy 20:626b92b70bf7 241 GpggaSentenceBuffer[GpggaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 242 GpggaNmeaField = GPGGA_NMEA_G3;
mverdy 20:626b92b70bf7 243 }
mverdy 20:626b92b70bf7 244 else
mverdy 20:626b92b70bf7 245 {
mverdy 20:626b92b70bf7 246 GpggaNmeaField = GPGGA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 247 }
mverdy 20:626b92b70bf7 248 break;
mverdy 20:626b92b70bf7 249
mverdy 20:626b92b70bf7 250 case GPGGA_NMEA_G3:
mverdy 20:626b92b70bf7 251 if( thisChar == 'G' )
mverdy 20:626b92b70bf7 252 {
mverdy 20:626b92b70bf7 253 GpggaSentenceBuffer[GpggaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 254 GpggaNmeaField = GPGGA_NMEA_A;
mverdy 20:626b92b70bf7 255 }
mverdy 20:626b92b70bf7 256 else
mverdy 20:626b92b70bf7 257 {
mverdy 20:626b92b70bf7 258 GpggaNmeaField = GPGGA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 259 }
mverdy 20:626b92b70bf7 260 break;
mverdy 20:626b92b70bf7 261
mverdy 20:626b92b70bf7 262 case GPGGA_NMEA_A:
mverdy 20:626b92b70bf7 263 if( thisChar == 'A' )
mverdy 20:626b92b70bf7 264 {
mverdy 20:626b92b70bf7 265 GpggaSentenceBuffer[GpggaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 266 GpggaNmeaField = GPGGA_NMEA_CR;
mverdy 20:626b92b70bf7 267 }
mverdy 20:626b92b70bf7 268 else
mverdy 20:626b92b70bf7 269 {
mverdy 20:626b92b70bf7 270 GpggaNmeaField = GPGGA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 271 }
mverdy 20:626b92b70bf7 272 break;
mverdy 20:626b92b70bf7 273
mverdy 20:626b92b70bf7 274 case GPGGA_NMEA_CR:
mverdy 20:626b92b70bf7 275 GpggaSentenceBuffer[GpggaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 276 if( GpggaSentenceBufferPtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 277 {
mverdy 20:626b92b70bf7 278 GpggaNmeaField = GPGGA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 279 }
mverdy 20:626b92b70bf7 280 if( thisChar == 0x0A )
mverdy 20:626b92b70bf7 281 {
mverdy 20:626b92b70bf7 282 ParseNmeaGpggaSentence( );
mverdy 20:626b92b70bf7 283 }
mverdy 20:626b92b70bf7 284 break;
mverdy 20:626b92b70bf7 285
mverdy 20:626b92b70bf7 286 case GPGGA_NMEA_LF:
mverdy 20:626b92b70bf7 287 break;
mverdy 20:626b92b70bf7 288 }
mverdy 20:626b92b70bf7 289 }
mverdy 20:626b92b70bf7 290
mverdy 20:626b92b70bf7 291 static void GpsCheckCommandBufferForGpzda( uint8_t thisChar )
mverdy 20:626b92b70bf7 292 {
mverdy 20:626b92b70bf7 293 switch( GpzdaNmeaField )
mverdy 20:626b92b70bf7 294 {
mverdy 20:626b92b70bf7 295 default:
mverdy 20:626b92b70bf7 296 case GPZDA_NMEA_DOLLAR:
mverdy 20:626b92b70bf7 297 if( thisChar == '$' )
mverdy 20:626b92b70bf7 298 {
mverdy 20:626b92b70bf7 299 GpzdaSentenceBufferPtr = 0;
mverdy 20:626b92b70bf7 300 GpzdaSentenceBuffer[GpzdaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 301 GpzdaNmeaField = GPZDA_NMEA_G1;
mverdy 20:626b92b70bf7 302 }
mverdy 20:626b92b70bf7 303 break;
mverdy 20:626b92b70bf7 304
mverdy 20:626b92b70bf7 305 case GPZDA_NMEA_G1:
mverdy 20:626b92b70bf7 306 if( thisChar == 'G' )
mverdy 20:626b92b70bf7 307 {
mverdy 20:626b92b70bf7 308 GpzdaSentenceBuffer[GpzdaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 309 GpzdaNmeaField = GPZDA_NMEA_P;
mverdy 20:626b92b70bf7 310 }
mverdy 20:626b92b70bf7 311 else
mverdy 20:626b92b70bf7 312 {
mverdy 20:626b92b70bf7 313 GpzdaNmeaField = GPZDA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 314 }
mverdy 20:626b92b70bf7 315 break;
mverdy 20:626b92b70bf7 316
mverdy 20:626b92b70bf7 317 case GPZDA_NMEA_P:
mverdy 20:626b92b70bf7 318 if( thisChar == 'P' )
mverdy 20:626b92b70bf7 319 {
mverdy 20:626b92b70bf7 320 GpzdaSentenceBuffer[GpzdaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 321 GpzdaNmeaField = GPZDA_NMEA_G2;
mverdy 20:626b92b70bf7 322 }
mverdy 20:626b92b70bf7 323 else
mverdy 20:626b92b70bf7 324 {
mverdy 20:626b92b70bf7 325 GpzdaNmeaField = GPZDA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 326 }
mverdy 20:626b92b70bf7 327 break;
mverdy 20:626b92b70bf7 328
mverdy 20:626b92b70bf7 329 case GPZDA_NMEA_G2:
mverdy 20:626b92b70bf7 330 if( thisChar == 'Z' )
mverdy 20:626b92b70bf7 331 {
mverdy 20:626b92b70bf7 332 GpzdaSentenceBuffer[GpzdaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 333 GpzdaNmeaField = GPZDA_NMEA_G3;
mverdy 20:626b92b70bf7 334 }
mverdy 20:626b92b70bf7 335 else
mverdy 20:626b92b70bf7 336 {
mverdy 20:626b92b70bf7 337 GpzdaNmeaField = GPZDA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 338 }
mverdy 20:626b92b70bf7 339 break;
mverdy 20:626b92b70bf7 340
mverdy 20:626b92b70bf7 341 case GPZDA_NMEA_G3:
mverdy 20:626b92b70bf7 342 if( thisChar == 'D' )
mverdy 20:626b92b70bf7 343 {
mverdy 20:626b92b70bf7 344 GpzdaSentenceBuffer[GpzdaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 345 GpzdaNmeaField = GPZDA_NMEA_A;
mverdy 20:626b92b70bf7 346 }
mverdy 20:626b92b70bf7 347 else
mverdy 20:626b92b70bf7 348 {
mverdy 20:626b92b70bf7 349 GpzdaNmeaField = GPZDA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 350 }
mverdy 20:626b92b70bf7 351 break;
mverdy 20:626b92b70bf7 352
mverdy 20:626b92b70bf7 353 case GPZDA_NMEA_A:
mverdy 20:626b92b70bf7 354 if( thisChar == 'A' )
mverdy 20:626b92b70bf7 355 {
mverdy 20:626b92b70bf7 356 GpzdaSentenceBuffer[GpzdaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 357 GpzdaNmeaField = GPZDA_NMEA_CR;
mverdy 20:626b92b70bf7 358 }
mverdy 20:626b92b70bf7 359 else
mverdy 20:626b92b70bf7 360 {
mverdy 20:626b92b70bf7 361 GpzdaNmeaField = GPZDA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 362 }
mverdy 20:626b92b70bf7 363 break;
mverdy 20:626b92b70bf7 364
mverdy 20:626b92b70bf7 365 case GPZDA_NMEA_CR:
mverdy 20:626b92b70bf7 366 GpzdaSentenceBuffer[GpzdaSentenceBufferPtr++] = thisChar;
mverdy 20:626b92b70bf7 367 if( GpzdaSentenceBufferPtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 368 {
mverdy 20:626b92b70bf7 369 GpzdaNmeaField = GPZDA_NMEA_DOLLAR;
mverdy 20:626b92b70bf7 370 }
mverdy 20:626b92b70bf7 371 if( thisChar == 0x0A )
mverdy 20:626b92b70bf7 372 {
mverdy 20:626b92b70bf7 373 ParseNmeaGpzdaSentence( );
mverdy 20:626b92b70bf7 374 }
mverdy 20:626b92b70bf7 375 break;
mverdy 20:626b92b70bf7 376
mverdy 20:626b92b70bf7 377 case GPZDA_NMEA_LF:
mverdy 20:626b92b70bf7 378 break;
mverdy 20:626b92b70bf7 379 }
mverdy 20:626b92b70bf7 380 }
mverdy 20:626b92b70bf7 381
mverdy 20:626b92b70bf7 382 static void ParseNmeaGpggaSentence( void )
mverdy 20:626b92b70bf7 383 {
mverdy 20:626b92b70bf7 384 GpggaStruct thisFix;
mverdy 20:626b92b70bf7 385 int sentencePtr = 1;
mverdy 20:626b92b70bf7 386 int subStrPtr = 0;
mverdy 20:626b92b70bf7 387 int commaCount = 0;
mverdy 20:626b92b70bf7 388 uint8_t checkSum = 0;
mverdy 20:626b92b70bf7 389 uint8_t thisChar;
mverdy 20:626b92b70bf7 390 bool contFlag = true;
mverdy 20:626b92b70bf7 391 char tArray[3];
mverdy 20:626b92b70bf7 392 char compArray[3];
mverdy 20:626b92b70bf7 393
mverdy 20:626b92b70bf7 394 while( contFlag ) //Get the checksum
mverdy 20:626b92b70bf7 395 {
mverdy 20:626b92b70bf7 396 thisChar = GpggaSentenceBuffer[sentencePtr];
mverdy 20:626b92b70bf7 397 if( thisChar == '*' )
mverdy 20:626b92b70bf7 398 {
mverdy 20:626b92b70bf7 399 contFlag = false;
mverdy 20:626b92b70bf7 400 }
mverdy 20:626b92b70bf7 401 else
mverdy 20:626b92b70bf7 402 {
mverdy 20:626b92b70bf7 403 checkSum ^= thisChar;
mverdy 20:626b92b70bf7 404 }
mverdy 20:626b92b70bf7 405 sentencePtr++;
mverdy 20:626b92b70bf7 406 if( sentencePtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 407 {
mverdy 20:626b92b70bf7 408 thisFix.Fixed = false;
mverdy 20:626b92b70bf7 409 return;
mverdy 20:626b92b70bf7 410 }
mverdy 20:626b92b70bf7 411 }
mverdy 20:626b92b70bf7 412 compArray[0] = GpggaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 413 compArray[1] = GpggaSentenceBuffer[sentencePtr];
mverdy 20:626b92b70bf7 414 compArray[2] = 0x00;
mverdy 20:626b92b70bf7 415 sentencePtr = 0;
mverdy 20:626b92b70bf7 416 sprintf( tArray, "%02X", checkSum );
mverdy 20:626b92b70bf7 417 if( strcmp( tArray, compArray ) != 0 ) //Fails checksum
mverdy 20:626b92b70bf7 418 {
mverdy 20:626b92b70bf7 419 thisFix.Fixed = false;
mverdy 20:626b92b70bf7 420 return;
mverdy 20:626b92b70bf7 421 }
mverdy 20:626b92b70bf7 422 while( commaCount < 6 ) //Find fix quality
mverdy 20:626b92b70bf7 423 {
mverdy 20:626b92b70bf7 424 if( GpggaSentenceBuffer[sentencePtr++] == ',' )
mverdy 20:626b92b70bf7 425 {
mverdy 20:626b92b70bf7 426 commaCount++;
mverdy 20:626b92b70bf7 427 }
mverdy 20:626b92b70bf7 428 if( sentencePtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 429 {
mverdy 20:626b92b70bf7 430 thisFix.Fixed = false;
mverdy 20:626b92b70bf7 431 return;
mverdy 20:626b92b70bf7 432 }
mverdy 20:626b92b70bf7 433 }
mverdy 20:626b92b70bf7 434 switch( GpggaSentenceBuffer[sentencePtr++] )
mverdy 20:626b92b70bf7 435 {
mverdy 20:626b92b70bf7 436 case '1':
mverdy 20:626b92b70bf7 437 case '2':
mverdy 20:626b92b70bf7 438 case '3':
mverdy 20:626b92b70bf7 439 case '4':
mverdy 20:626b92b70bf7 440 thisFix.Fixed = true;
mverdy 20:626b92b70bf7 441 break;
mverdy 20:626b92b70bf7 442
mverdy 20:626b92b70bf7 443 default:
mverdy 20:626b92b70bf7 444 thisFix.Fixed = false;
mverdy 20:626b92b70bf7 445 break;
mverdy 20:626b92b70bf7 446 }
mverdy 20:626b92b70bf7 447 sentencePtr++; //Skip comma after fix
mverdy 20:626b92b70bf7 448 thisFix.NumSats[subStrPtr++] = GpggaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 449 thisFix.NumSats[subStrPtr++] = GpggaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 450 thisFix.NumSats[subStrPtr] = 0;
mverdy 20:626b92b70bf7 451 if( thisFix.Fixed )
mverdy 20:626b92b70bf7 452 {
mverdy 20:626b92b70bf7 453 sentencePtr = 0;
mverdy 20:626b92b70bf7 454 commaCount = 0;
mverdy 20:626b92b70bf7 455 while( commaCount < 1 ) //Find fix time
mverdy 20:626b92b70bf7 456 {
mverdy 20:626b92b70bf7 457 if( GpggaSentenceBuffer[sentencePtr++] == ',' )
mverdy 20:626b92b70bf7 458 {
mverdy 20:626b92b70bf7 459 commaCount++;
mverdy 20:626b92b70bf7 460 }
mverdy 20:626b92b70bf7 461 if( sentencePtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 462 {
mverdy 20:626b92b70bf7 463 thisFix.Fixed = false;
mverdy 20:626b92b70bf7 464 return;
mverdy 20:626b92b70bf7 465 }
mverdy 20:626b92b70bf7 466 }
mverdy 20:626b92b70bf7 467 subStrPtr = 0;
mverdy 20:626b92b70bf7 468 // Skip over time field as this can be picked up from the other sentence
mverdy 20:626b92b70bf7 469 sentencePtr += 6;
mverdy 20:626b92b70bf7 470 while( commaCount < 2 ) //Find Latitude
mverdy 20:626b92b70bf7 471 {
mverdy 20:626b92b70bf7 472 if( GpzdaSentenceBuffer[sentencePtr++] == ',' )
mverdy 20:626b92b70bf7 473 {
mverdy 20:626b92b70bf7 474 commaCount++;
mverdy 20:626b92b70bf7 475 }
mverdy 20:626b92b70bf7 476 if( sentencePtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 477 {
mverdy 20:626b92b70bf7 478 thisFix.Fixed = false;
mverdy 20:626b92b70bf7 479 return;
mverdy 20:626b92b70bf7 480 }
mverdy 20:626b92b70bf7 481 }
mverdy 20:626b92b70bf7 482 subStrPtr = 0;
mverdy 20:626b92b70bf7 483 for( commaCount = 0; commaCount < 10; commaCount++ )
mverdy 20:626b92b70bf7 484 {
mverdy 20:626b92b70bf7 485 thisFix.Lat[subStrPtr++] = GpggaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 486 }
mverdy 20:626b92b70bf7 487 sentencePtr++; // Skip next comma
mverdy 20:626b92b70bf7 488 thisFix.Lat[subStrPtr++] = ' '; //Add a space
mverdy 20:626b92b70bf7 489 thisFix.Lat[subStrPtr++] = GpggaSentenceBuffer[sentencePtr++]; //N or S
mverdy 20:626b92b70bf7 490 thisFix.Lat[subStrPtr] = 0x00; //String terminate
mverdy 20:626b92b70bf7 491
mverdy 20:626b92b70bf7 492 while( commaCount < 4 ) //Find Longitude
mverdy 20:626b92b70bf7 493 {
mverdy 20:626b92b70bf7 494 if( GpggaSentenceBuffer[sentencePtr++] == ',' )
mverdy 20:626b92b70bf7 495 {
mverdy 20:626b92b70bf7 496 commaCount++;
mverdy 20:626b92b70bf7 497 }
mverdy 20:626b92b70bf7 498 if( sentencePtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 499 {
mverdy 20:626b92b70bf7 500 thisFix.Fixed = false;
mverdy 20:626b92b70bf7 501 return;
mverdy 20:626b92b70bf7 502 }
mverdy 20:626b92b70bf7 503 }
mverdy 20:626b92b70bf7 504 sentencePtr++; // Skip this comma
mverdy 20:626b92b70bf7 505 subStrPtr = 0;
mverdy 20:626b92b70bf7 506 for( commaCount = 0; commaCount < 11; commaCount++ )
mverdy 20:626b92b70bf7 507 {
mverdy 20:626b92b70bf7 508 thisFix.Long[subStrPtr++] = GpggaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 509 }
mverdy 20:626b92b70bf7 510 sentencePtr++; // Skip next comma
mverdy 20:626b92b70bf7 511 thisFix.Long[subStrPtr++] = ' '; //Add a space
mverdy 20:626b92b70bf7 512 thisFix.Long[subStrPtr++] = GpggaSentenceBuffer[sentencePtr++]; //E or W
mverdy 20:626b92b70bf7 513 thisFix.Long[subStrPtr] = 0x00; //String terminate
mverdy 20:626b92b70bf7 514 }
mverdy 20:626b92b70bf7 515 thisFix.Updated = true;
mverdy 20:626b92b70bf7 516 Gps.Position = thisFix;
mverdy 20:626b92b70bf7 517 }
mverdy 20:626b92b70bf7 518
mverdy 20:626b92b70bf7 519 static void ParseNmeaGpzdaSentence( void )
mverdy 20:626b92b70bf7 520 {
mverdy 20:626b92b70bf7 521 GpzdaStruct thisTime;
mverdy 20:626b92b70bf7 522 int sentencePtr = 1;
mverdy 20:626b92b70bf7 523 int commaCount = 0;
mverdy 20:626b92b70bf7 524 uint8_t checkSum = 0;
mverdy 20:626b92b70bf7 525 uint8_t thisChar;
mverdy 20:626b92b70bf7 526 bool contFlag = true;
mverdy 20:626b92b70bf7 527 char tArray[3];
mverdy 20:626b92b70bf7 528 char compArray[3];
mverdy 20:626b92b70bf7 529
mverdy 20:626b92b70bf7 530 while( contFlag ) //Get the checksum
mverdy 20:626b92b70bf7 531 {
mverdy 20:626b92b70bf7 532 thisChar = GpzdaSentenceBuffer[sentencePtr];
mverdy 20:626b92b70bf7 533 if( thisChar == '*' )
mverdy 20:626b92b70bf7 534 {
mverdy 20:626b92b70bf7 535 contFlag = false;
mverdy 20:626b92b70bf7 536 }
mverdy 20:626b92b70bf7 537 else
mverdy 20:626b92b70bf7 538 {
mverdy 20:626b92b70bf7 539 checkSum ^= thisChar;
mverdy 20:626b92b70bf7 540 }
mverdy 20:626b92b70bf7 541 sentencePtr++;
mverdy 20:626b92b70bf7 542 if( sentencePtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 543 {
mverdy 20:626b92b70bf7 544 return;
mverdy 20:626b92b70bf7 545 }
mverdy 20:626b92b70bf7 546 }
mverdy 20:626b92b70bf7 547 compArray[0] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 548 compArray[1] = GpzdaSentenceBuffer[sentencePtr];
mverdy 20:626b92b70bf7 549 compArray[2] = 0x00;
mverdy 20:626b92b70bf7 550 sentencePtr = 0;
mverdy 20:626b92b70bf7 551 sprintf( tArray, "%02X", checkSum );
mverdy 20:626b92b70bf7 552 if( strcmp( tArray, compArray ) != 0 ) //Fails checksum
mverdy 20:626b92b70bf7 553 {
mverdy 20:626b92b70bf7 554 return;
mverdy 20:626b92b70bf7 555 }
mverdy 20:626b92b70bf7 556 while( commaCount < 1 ) //Start with hours (first field)
mverdy 20:626b92b70bf7 557 {
mverdy 20:626b92b70bf7 558 if( GpzdaSentenceBuffer[sentencePtr++] == ',' )
mverdy 20:626b92b70bf7 559 {
mverdy 20:626b92b70bf7 560 commaCount++;
mverdy 20:626b92b70bf7 561 }
mverdy 20:626b92b70bf7 562 if( sentencePtr >= MAX_NMEA_SENTENCE_LENGTH )
mverdy 20:626b92b70bf7 563 {
mverdy 20:626b92b70bf7 564 return;
mverdy 20:626b92b70bf7 565 }
mverdy 20:626b92b70bf7 566 }
mverdy 20:626b92b70bf7 567 thisTime.Hour[0] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 568 thisTime.Hour[1] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 569 thisTime.Hour[2] = 0x00;
mverdy 20:626b92b70bf7 570
mverdy 20:626b92b70bf7 571 thisTime.Minute[0] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 572 thisTime.Minute[1] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 573 thisTime.Minute[2] = 0x00;
mverdy 20:626b92b70bf7 574
mverdy 20:626b92b70bf7 575 thisTime.Second[0] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 576 thisTime.Second[1] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 577 thisTime.Second[2] = 0x00;
mverdy 20:626b92b70bf7 578 sentencePtr += 4;
mverdy 20:626b92b70bf7 579
mverdy 20:626b92b70bf7 580 thisTime.Day[0] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 581 thisTime.Day[1] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 582 thisTime.Day[2] = 0x00;
mverdy 20:626b92b70bf7 583 sentencePtr += 1;
mverdy 20:626b92b70bf7 584
mverdy 20:626b92b70bf7 585 thisTime.Month[0] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 586 thisTime.Month[1] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 587 thisTime.Month[2] = 0x00;
mverdy 20:626b92b70bf7 588 sentencePtr += 1;
mverdy 20:626b92b70bf7 589
mverdy 20:626b92b70bf7 590 thisTime.Year[0] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 591 thisTime.Year[1] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 592 thisTime.Year[2] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 593 thisTime.Year[3] = GpzdaSentenceBuffer[sentencePtr++];
mverdy 20:626b92b70bf7 594 thisTime.Year[4] = 0x00;
mverdy 20:626b92b70bf7 595 thisTime.Updated = true;
mverdy 20:626b92b70bf7 596 Gps.Time = thisTime;
mverdy 20:626b92b70bf7 597 }
mverdy 20:626b92b70bf7 598
mverdy 20:626b92b70bf7 599 GpsStruct* Max7GpsgetData( void )
mverdy 20:626b92b70bf7 600 {
mverdy 20:626b92b70bf7 601 return &Gps ;
mverdy 20:626b92b70bf7 602 }
mverdy 20:626b92b70bf7 603