A controller-neutral API for working with GPS devices.

Dependents:   CsrLocationDemo CsrLocationDemo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GPSProvider.h Source File

GPSProvider.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2014 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef __GPS_PROVIDER_H__
00018 #define __GPS_PROVIDER_H__
00019 
00020 class GPSProviderImplBase; /* forward declaration */
00021 extern GPSProviderImplBase *createGPSProviderInstance(void);
00022 
00023 //
00024 // Here's a snippet showing how this API can be used. The handler gets invoked
00025 // from thread context--i.e. from the main application.
00026 //
00027 //      void handleGPSData(const LocationUpdateParams_t *newLocation) {
00028 //          ...
00029 //      }
00030 //
00031 //      GPSProvider gps;
00032 //
00033 //      gps.setPowerMode(LOW_POWER);
00034 //      gps.onLocationUpdate(handleGPSData);
00035 //
00036 //      gps.reset();
00037 //      gps.start();
00038 //
00039 //      while (true) {
00040 //          /* purely optional */
00041 //          static bool printedDeviceInfo = false;
00042 //          if (!printedDeviceInfo && gps.haveDeviceInfo()) {
00043 //              printf("%s", gps.getDeviceInfo());
00044 //              printedDeviceInfo = true;
00045 //          }
00046 //
00047 //          /* Main message processing activity; location callbacks are called
00048 //           * as a result of message processing. */
00049 //          gps.process();
00050 //          /* sleep(); */
00051 //
00052 //          if (/* at some point in the future */) {
00053 //              break;
00054 //          }
00055 //      }
00056 //      gps.stop();
00057 //
00058 
00059 class GPSProvider {
00060 public:
00061     /** Power mode selection */
00062     enum PowerMode_t {
00063          POWER_FULL, /**< full-power mode typically results in high-accuracy location data updated at 1Hz. */
00064          POWER_LOW,  /**< low-power mode involves longer periods of hibernation in between location updates. */
00065     };
00066 
00067     /**
00068      * GPS time starts from UTC 01/06/1980(MM/DD/YYYY) and includes 2 fields:
00069      * week and tow. For a given GPS time, week is the passed week number since
00070      * the GPS start time, and tow(time of week) is the passed seconds since the
00071      * last Sunday. For example, a given UTC time [10/30/3014
00072      * 01:10:00](MM/DD/YYYY HH:MM:SS) can be converted into GPS time [1816,
00073      * 4200](week, seconds).
00074      *
00075      * GPS time can be used as a quite accurate time once position is fixed.
00076      */
00077     struct GPSTime_t {
00078         uint16_t gps_week;
00079         uint32_t tow;       /* time of week (in millisecond) */
00080     };
00081 
00082     typedef float LocationType_t;
00083     typedef float Altitude_t;
00084     struct LocationUpdateParams_t {
00085         uint32_t       version; /* Layout-version for the following structure;
00086                                  * this is to accommodate changes over time. */
00087         bool           valid;   /* Does this update contain a valid location. */
00088         LocationType_t lat;
00089         LocationType_t lon;
00090         Altitude_t     altitude;
00091 
00092         unsigned       numGPSSVs; /* num GPS Satellites */
00093         unsigned       numGLOSVs; /* num GLONASS Satellites */
00094 
00095         GPSTime_t      gpsTime; /* gps time */
00096         uint64_t       utcTime; /* UTC time in millisecond */
00097     };
00098 
00099 public:
00100     /**
00101      * Set the operating mode for power. Typically this allows the user to
00102      * choose between various low-power modes. Entering low-power modes often
00103      * results in a trade-off between accuracy and power consumption.
00104      *
00105      * The new mode takes effect upon calling start().
00106      *
00107      * @param power The new power mode.
00108      * @return      true if the update was successful.
00109      */
00110     bool setPowerMode(PowerMode_t power);
00111 
00112     /**
00113      * HW reset to get location chip into hibernation mode, but in readiness for
00114      * starting operation. The GPS controller emerges from hibernation when
00115      * start() is called.
00116      *
00117      * The typical initialization sequence is:
00118      *   reset();
00119      *   start(); // and thereafter receive location-update callbacks.
00120      */
00121     void reset(void);
00122 
00123     /**
00124      * Start the GPS operation, taking into account the operation mode set
00125      * previously. Following this call, the user may expect to receive location
00126      * notifications in interrupt context if a handler has previously been set.
00127      *
00128      * @note: calling start repeatedly doesn't hurt.
00129      */
00130     void start(void);
00131 
00132     /**
00133      * Stop active operation of the GPS; and put it to hibernation.
00134      *
00135      * @note: You don't need to call reset() afterwards to enter hibernation.
00136      * @note: Calling stop() repeatedly doesn't hurt.
00137      */
00138     void stop(void);
00139 
00140     /**
00141      * Process location data from chip and update location and satellite
00142      * information. This API is supposed to be called repeatedly from the
00143      * application in thread mode to process incoming messages as they are
00144      * received from the GPS controller. Arriving data is first appended to
00145      * something like a circular buffer by interrupts, and then parsed as
00146      * messages in thread mode.
00147      *
00148      * The application typically enters a loop calling process() after
00149      * initializing the GPS controller with start(). process() returns
00150      * immediately if there is no work to be done, but it must get invoked
00151      * frequently in order to keep pace with arriving data.
00152      *
00153      * Mbed's sleep() may be usefully thrown into the application's process()
00154      * loop to save power--sleep() has the effect of putting the processor to
00155      * sleep while waiting for an event (such as an interrupt). As always, some
00156      * care must be taken in employing sleep(), because there is a small
00157      * synchronization window where an interrupt may arrive and pend data which
00158      * doesn't get processed (as illustrated below).
00159      *
00160      *  while (true) {
00161      *      process();
00162      *        <--  interrupt arrives now and appends new data
00163      *      sleep(); // but then we go to sleep without processing it.
00164      *  }
00165      *
00166      * There is a way around it: if sleep() boils down to the use of ARM's WFE
00167      * instruction (as opposed to WFI), then its safe from the above-mentioned
00168      * synchronization window.
00169      */
00170     void process(void);
00171 
00172     /**
00173      * @return  true if the initialization process has received enough
00174      *     information to determine the hardware's version/device-info.
00175      */
00176     bool haveDeviceInfo(void) const;
00177 
00178     /**
00179      * Fetch the device information string. This is expected to contain the
00180      * version number or any other device identifier.
00181      */
00182     const char *getDeviceInfo(void) const;
00183 
00184     /**
00185      * This is a wildcard API for sending controller specific commands. Use of
00186      * this API will make programs non-portable, but then there may arise a
00187      * genuine need to access special functionality.
00188      *
00189      * @param  command   A controller specific command.
00190      * @param  arg       Argument to the command; interpreted according to the command.
00191      * @return           any return from the command.
00192      */
00193     uint32_t ioctl(uint32_t command, void *arg);
00194 
00195     /**
00196      * @return  true if we've obtained at least one valid location since last
00197      *     calling start().
00198      *
00199      * @Note: This is cleared after reset().
00200      */
00201     bool locationAvailable(void) const;
00202 
00203     /**
00204      * @return  the last valid location if there is any; else NULL.
00205      */
00206     const LocationUpdateParams_t *getLastLocation(void) const;
00207 
00208     /**
00209      * Type declaration for a callback to be invoked from interrupt context upon
00210      * receiving new location data.
00211      *
00212      * @Note: Please note that the handler gets invoked from interrupt context.
00213      * Users *should not* do any long running or blocking operations in the
00214      * handler.
00215      */
00216     typedef void (* LocationUpdateCallback_t)(const LocationUpdateParams_t *params);
00217 
00218     /**
00219      * Setup the locationUpdate callback.
00220      *
00221      * @Note: Please note that the handler gets invoked from interrupt context.
00222      * Users *should not* do any long running or blocking operations in the
00223      * handler.
00224      */
00225     void onLocationUpdate(LocationUpdateCallback_t callback);
00226 
00227     /**
00228      * In low-power operation, the GPS controller may be expected to hibernate
00229      * for extended periods and location updates may be infrequent. It should
00230      * then be possible for an application to demand location data when needed.
00231      *
00232      * This calls results in a locationCallback if there is a useful location to
00233      * report.
00234      */
00235     void lpmGetImmediateLocation(void);
00236 
00237 public:
00238     /**
00239      * Default constructor.
00240      */
00241     GPSProvider() : impl(createGPSProviderInstance()) {
00242         /* empty */
00243     }
00244 
00245     virtual ~GPSProvider() {
00246         stop();
00247     }
00248 
00249 private:
00250     /**
00251      * We use 'composition' to combine a driver-implementation object to the
00252      * GPSProvider interface. The implementation object will come to life
00253      * through the createGPSProviderInstance(), which must be defined by the
00254      * driver library. The mechanics of the implementation are to be hidden
00255      * behind the abstract interface provided by GPSProvider.
00256      */
00257     GPSProviderImplBase *const impl;
00258 
00259     /* disallow copy constructor and assignment operators */
00260 private:
00261     GPSProvider(const GPSProvider&);
00262     GPSProvider & operator= (const GPSProvider&);
00263 };
00264 
00265 #endif /*__GPS_PROVIDER_H__*/