⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gps.c

📁 Open DMT Client C Source code
💻 C
📖 第 1 页 / 共 4 页
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description://  Machine interface to GPS module.//  Abstraction layer for the machine interface to the GPS module.// Notes://  - The code included here is only an example of how to parse NMEA-0183 GPS records.//  This module should perform sufficient error checking to insure that the GPS module//  is functioning properly.//  - Ideally, GPS aquisition should occur in it's own thread in order to return//  the latest GPS fix to the requestor immediately (without blocking).  In non-thread//  mode, this implementation will block until a new GPS fix has been aquired (or if a //  timeout occurs).// ---// Change History://  2006/01/04  Martin D. Flynn//     -Initial release//  2006/02/09  Martin D. Flynn//     -This module now maintains its "stale" state.//     -"gpsGetDiagnostics" now returns a structure.//  2006/06/08  Martin D. Flynn//     -Added support for parsing "$GPGSA" //      (the DOP values are not currently used for fix discrimination).//  2007/01/28  Martin D. Flynn//     -WindowsCE port//     -Switched to generic thread access methods in 'tools/threads.h'//     -Initial implementation of a 'power-save' mode feature that closes the GPS //      comport if the sampling interval is greater than a minute (or so).  The HP //      hw6945 turns off the GPS receiver when the comport has been closed - to save //      power.  This feature allows GPS tracking on the HP hw6945 to conserve power//      (at the expense of some event accuracy).  Note: this feature is still under//      development and may not currently produce the desired results if used.// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#include "custom/defaults.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <time.h>#include <math.h>#include "custom/log.h"#include "custom/gps.h"#include "custom/gpsmods.h"#include "tools/stdtypes.h"#include "tools/utctools.h"#include "tools/strtools.h"#include "tools/checksum.h"#include "tools/comport.h"#include "base/events.h"#include "base/propman.h"#include "base/statcode.h"// ----------------------------------------------------------------------------#if !defined(GPS_COM_DATA_FORMAT)#  define GPS_COM_DATA_FORMAT           "8N1"#endif// ----------------------------------------------------------------------------/* compiling with thread support? */#if defined(GPS_THREAD)//#  warning GPS thread support enabled#  include "tools/threads.h"#else//#  warning GPS thread support disabled#endif// ----------------------------------------------------------------------------// References://   "GPS Hackery": http://www.ualberta.ca/~ckuethe/gps///   "GPS Applications": http://www.codeproject.com/vb/net/WritingGPSApplications1.asp// ----------------------------------------------------------------------------/* default GPS port */// This default value is not used if the GPS comport property is in effect.// The real default value is specified in 'propman.c'#if defined(TARGET_WINCE)#  define DEFAULT_GPS_PORT      ""#else#  define DEFAULT_GPS_PORT      "TTYS2"#endif/* simjulator port name */#define GPS_SIMULATOR_PORT      "sim"/* GPS bps */#define DEFAULT_GPS_SPEED       4800L // 8N1 assumed/* maximum out-of-sync seconds between GPS time and system time */// set this value to '0' to ignore sync'ing with system clock #define MAX_DELTA_CLOCK_TIME    20L/* minimum out-of-sync seconds between GPS time and system time */// delta must be at least this value to cause a system clock update#define MIN_DELTA_CLOCK_TIME    5L/* maximum number of allowed seconds in a $GP record 'cycle' */// In most GPS receivers, the default 'cycle' is 1 second#define GP_EXPIRE               5L/* power-save threshold */// if PROP_GPS_SAMPLE_RATE is >= this value, the GPS port will not be openned// until 'gpsAquire' is called, and will be closed after a GPS fix is aquired.#define POWER_SAVE_THRESHOLD    45L // seconds// ----------------------------------------------------------------------------/* control characters */#define ASCII_XON               17 // DC1, CTL_Q#define ASCII_XOFF              19 // DC3, CTL_S// ----------------------------------------------------------------------------#define SUPPORT_TYPE_GPRMC      0x0001 // should always be defined#define SUPPORT_TYPE_GPGGA      0x0002 // altitude, HDOP#define SUPPORT_TYPE_GPGSA      0x0004 // PDOP, HDOP, VDOP// ----------------------------------------------------------------------------#if defined(GPS_DEVICE_SIMULATOR)static utBool                   gpsSimulator = utFalse;#endifstatic ComPort_t                gpsComPort;static utBool                   gpsPortDebug;static GPS_t                    gpsFixLast;static GPS_t                    gpsFixUnsafe;static double                   gpsLastPDOP             = GPS_UNDEFINED_DOP;static double                   gpsLastHDOP             = GPS_UNDEFINED_DOP;static double                   gpsLastVDOP             = GPS_UNDEFINED_DOP;static TimerSec_t               gpsLastHDOPTimer        = 0L;static utBool                   gpsIsStale              = utFalse;static UInt32                   gpsSampleCount_A        = 0L; // validstatic UInt32                   gpsSampleCount_V        = 0L; // invalidstatic UInt32                   gpsRestartCount         = 0L;static TimerSec_t               gpsLastSampleTimer      = 0L;static TimerSec_t               gpsLastValidTimer       = 0L;static TimerSec_t               gpsLastReadErrorTimer   = 0L;static TimerSec_t               gpsLastLostErrorTimer   = 0L;static utBool                   gpsAquireRequest        = utFalse;static UInt32                   gpsAquireTimeoutMS      = 0L;#if defined(GPS_THREAD)static utBool                   gpsRunThread = utFalse;static threadThread_t           gpsThread;static threadMutex_t            gpsMutex;static threadMutex_t            gpsSampleMutex;static threadMutex_t            gpsAquireMutex;static threadCond_t             gpsAquireCond;#define SAMPLE_LOCK             MUTEX_LOCK(&gpsSampleMutex);#define SAMPLE_UNLOCK           MUTEX_UNLOCK(&gpsSampleMutex);#define GPS_LOCK                MUTEX_LOCK(&gpsMutex);#define GPS_UNLOCK              MUTEX_UNLOCK(&gpsMutex);#define AQUIRE_LOCK             MUTEX_LOCK(&gpsAquireMutex);#define AQUIRE_UNLOCK           MUTEX_UNLOCK(&gpsAquireMutex);#define AQUIRE_WAIT             CONDITION_WAIT(&gpsAquireCond, &gpsAquireMutex);#define AQUIRE_NOTIFY           CONDITION_NOTIFY(&gpsAquireCond);#else#define SAMPLE_LOCK     #define SAMPLE_UNLOCK   #define GPS_LOCK        #define GPS_UNLOCK      #define AQUIRE_LOCK             #define AQUIRE_UNLOCK           #define AQUIRE_WAIT             #define AQUIRE_NOTIFY           #endif// ----------------------------------------------------------------------------static GPSDiagnostics_t gpsStats = { 0L, 0L, 0L, 0L, 0L };GPSDiagnostics_t *gpsGetDiagnostics(GPSDiagnostics_t *stats){#if !defined(GPS_THREAD)// These values will not be accurate if not running in thread mode#  warning GPS is not running in thread mode, diagnostic values will not be accurate.#endif    GPSDiagnostics_t *s = stats? stats : &gpsStats;    SAMPLE_LOCK {        s->lastSampleTime = TIMER_TO_UTC(gpsLastSampleTimer);        s->lastValidTime  = TIMER_TO_UTC(gpsLastValidTimer);        s->sampleCount_A  = gpsSampleCount_A;        s->sampleCount_V  = gpsSampleCount_V;        s->restartCount   = gpsRestartCount;    } SAMPLE_UNLOCK    return s;}// ----------------------------------------------------------------------------#if defined(TARGET_WINCE)// skip handling of specific GPS receiver types#elsestatic void _gpsConfigGarmin(ComPort_t *com){    // This configures a Garmin receiver to send only GPRMC & GPGGA records,    // and send them only once every 2 seconds.        // disable all sentences    comPortWriteString(com, "$PGRMO,,2\r\r\n");    // "$PGRMO,,4" restores factory default sentences    comPortFlush(com, 100L);        // Fix mode: Automatic    // Differential mode: Automatic    comPortWriteString(com, "$PGRMC,A,,,,,,,,A\r\r\n");    comPortFlush(com, 100L);        // output every 2 seconds    // automatic position averaging when stopped    // NMEA-0183 v2.30 off    // enable WAAS    comPortWriteString(com, "$PGRMC1,2,,2,,,,1,W\r\r\n");    // "$PGRMC1,1" set it back to 1/sec    // "$PGRMC1E" queries current config    comPortFlush(com, 100L);    // enable GPRMC sentence    comPortWriteString(com, "$PGRMO,GPRMC,1\r\r\n");    comPortFlush(com, 100L);    // enable GPGGA sentence    comPortWriteString(com, "$PGRMO,GPGGA,1\r\r\n");    comPortFlush(com, 100L);    /* done */    logDEBUG(LOGSRC,"Garmin GPS configured");}#endif// ----------------------------------------------------------------------------/* open gps serial port */static utBool _gpsOpen(){    ComPort_t *com = &gpsComPort;    comPortInitStruct(com);    /* check port */    const char *portName = propGetString(PROP_CFG_GPS_PORT, "");    if (!portName || !*portName) { portName = DEFAULT_GPS_PORT; }        /* simulator mode? */#if defined(GPS_DEVICE_SIMULATOR)    gpsSimulator = strEqualsIgnoreCase(portName,GPS_SIMULATOR_PORT);    if (gpsSimulator) {        // should not be here if we are running in simulator mode        return utFalse;    }#endif    /* speed */    long bpsSpeed = (long)propGetUInt32(PROP_CFG_GPS_BPS, -1L);    if (bpsSpeed <= 0L) { bpsSpeed = DEFAULT_GPS_SPEED; }    /* open */    if (comPortOpen(com,portName,bpsSpeed,GPS_COM_DATA_FORMAT,utFalse) == (ComPort_t*)0) {        // The outer loop will retry the open later        // Generally, this should not occur on the GumStix        //logWARNING(LOGSRC,"Unable to open GPS port '%s' [%s]", portName, strerror(errno));        logWARNING(LOGSRC,"Unable to open GPS port '%s'", portName);        return utFalse;    }    logDEBUG(LOGSRC,"Opened GPS port: %s [%ld bps]", comPortName(com), bpsSpeed);    threadSleepMS(500L); // wait for connection to settle    /* comport logging */    gpsPortDebug = propGetBoolean(PROP_CFG_GPS_DEBUG,utFalse);#if defined(TARGET_WINCE)    // TODO: implement comport logging feature#else    if (gpsPortDebug) {        comPortSetDebugLogger(com, 0);    }#endif    /* specific GPS device configuration */#if defined(TARGET_WINCE)    // skip handling of specific GPS receiver types#else    const char *receiver = propGetString(PROP_CFG_GPS_MODEL,"");    if (strEqualsIgnoreCase(receiver,GPS_RECEIVER_GARMIN)) {        // Garmin 15, 18PC        _gpsConfigGarmin(com);    }#endif    /* return success */    return utTrue;}/* close gps serial port */static void _gpsClose(){    comPortClose(&gpsComPort);}// ----------------------------------------------------------------------------/* update system clock time */static utBool gpsUpdateSystemClock(long fixtime){    long delta = (long)propGetUInt32(PROP_GPS_CLOCK_DELTA, MAX_DELTA_CLOCK_TIME);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -