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