An extension of original API for working with GPS devices.

Committer:
apalmieri
Date:
Mon Jun 19 13:48:56 2017 +0000
Revision:
10:013af7b8c22a
Parent:
8:47fa213225c3
Typo in header comment

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 0:792e9343fd39 1 /* mbed Microcontroller Library
rgrover1 0:792e9343fd39 2 * Copyright (c) 2006-2014 ARM Limited
rgrover1 0:792e9343fd39 3 *
rgrover1 0:792e9343fd39 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 0:792e9343fd39 5 * you may not use this file except in compliance with the License.
rgrover1 0:792e9343fd39 6 * You may obtain a copy of the License at
rgrover1 0:792e9343fd39 7 *
rgrover1 0:792e9343fd39 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 0:792e9343fd39 9 *
rgrover1 0:792e9343fd39 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 0:792e9343fd39 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 0:792e9343fd39 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 0:792e9343fd39 13 * See the License for the specific language governing permissions and
rgrover1 0:792e9343fd39 14 * limitations under the License.
rgrover1 0:792e9343fd39 15 */
rgrover1 0:792e9343fd39 16
rgrover1 0:792e9343fd39 17 #ifndef __GPS_PROVIDER_H__
rgrover1 0:792e9343fd39 18 #define __GPS_PROVIDER_H__
rgrover1 0:792e9343fd39 19
apalmieri 8:47fa213225c3 20 // [ST-GNSS] - Geofencing API
apalmieri 8:47fa213225c3 21 class GPSGeofence; /* forward declaration */
apalmieri 8:47fa213225c3 22
rgrover1 0:792e9343fd39 23 class GPSProviderImplBase; /* forward declaration */
rgrover1 0:792e9343fd39 24 extern GPSProviderImplBase *createGPSProviderInstance(void);
rgrover1 0:792e9343fd39 25
rgrover1 0:792e9343fd39 26 //
rgrover1 1:c1122f8eec82 27 // Here's a snippet showing how this API can be used. The handler gets invoked
rgrover1 1:c1122f8eec82 28 // from thread context--i.e. from the main application.
rgrover1 0:792e9343fd39 29 //
rgrover1 1:c1122f8eec82 30 // void handleGPSData(const LocationUpdateParams_t *newLocation) {
rgrover1 1:c1122f8eec82 31 // ...
rgrover1 0:792e9343fd39 32 // }
rgrover1 0:792e9343fd39 33 //
rgrover1 0:792e9343fd39 34 // GPSProvider gps;
rgrover1 0:792e9343fd39 35 //
rgrover1 0:792e9343fd39 36 // gps.setPowerMode(LOW_POWER);
rgrover1 0:792e9343fd39 37 // gps.onLocationUpdate(handleGPSData);
rgrover1 0:792e9343fd39 38 //
rgrover1 1:c1122f8eec82 39 // gps.reset();
rgrover1 0:792e9343fd39 40 // gps.start();
rgrover1 0:792e9343fd39 41 //
rgrover1 1:c1122f8eec82 42 // while (true) {
rgrover1 1:c1122f8eec82 43 // /* purely optional */
rgrover1 1:c1122f8eec82 44 // static bool printedDeviceInfo = false;
rgrover1 1:c1122f8eec82 45 // if (!printedDeviceInfo && gps.haveDeviceInfo()) {
rgrover1 1:c1122f8eec82 46 // printf("%s", gps.getDeviceInfo());
rgrover1 1:c1122f8eec82 47 // printedDeviceInfo = true;
rgrover1 1:c1122f8eec82 48 // }
rgrover1 0:792e9343fd39 49 //
rgrover1 1:c1122f8eec82 50 // /* Main message processing activity; location callbacks are called
rgrover1 1:c1122f8eec82 51 // * as a result of message processing. */
rgrover1 1:c1122f8eec82 52 // gps.process();
rgrover1 1:c1122f8eec82 53 // /* sleep(); */
rgrover1 0:792e9343fd39 54 //
rgrover1 1:c1122f8eec82 55 // if (/* at some point in the future */) {
rgrover1 1:c1122f8eec82 56 // break;
rgrover1 1:c1122f8eec82 57 // }
rgrover1 1:c1122f8eec82 58 // }
rgrover1 0:792e9343fd39 59 // gps.stop();
rgrover1 0:792e9343fd39 60 //
rgrover1 0:792e9343fd39 61
rgrover1 0:792e9343fd39 62 class GPSProvider {
rgrover1 0:792e9343fd39 63 public:
rgrover1 0:792e9343fd39 64 /** Power mode selection */
rgrover1 0:792e9343fd39 65 enum PowerMode_t {
rgrover1 1:c1122f8eec82 66 POWER_FULL, /**< full-power mode typically results in high-accuracy location data updated at 1Hz. */
rgrover1 1:c1122f8eec82 67 POWER_LOW, /**< low-power mode involves longer periods of hibernation in between location updates. */
rgrover1 0:792e9343fd39 68 };
rgrover1 0:792e9343fd39 69
rgrover1 0:792e9343fd39 70 /**
rgrover1 0:792e9343fd39 71 * GPS time starts from UTC 01/06/1980(MM/DD/YYYY) and includes 2 fields:
rgrover1 0:792e9343fd39 72 * week and tow. For a given GPS time, week is the passed week number since
rgrover1 0:792e9343fd39 73 * the GPS start time, and tow(time of week) is the passed seconds since the
rgrover1 0:792e9343fd39 74 * last Sunday. For example, a given UTC time [10/30/3014
rgrover1 0:792e9343fd39 75 * 01:10:00](MM/DD/YYYY HH:MM:SS) can be converted into GPS time [1816,
rgrover1 0:792e9343fd39 76 * 4200](week, seconds).
rgrover1 0:792e9343fd39 77 *
rgrover1 0:792e9343fd39 78 * GPS time can be used as a quite accurate time once position is fixed.
rgrover1 0:792e9343fd39 79 */
rgrover1 0:792e9343fd39 80 struct GPSTime_t {
rgrover1 0:792e9343fd39 81 uint16_t gps_week;
zhjcpi 7:820997be26cb 82 uint32_t tow; /* time of week (in millisecond) */
rgrover1 0:792e9343fd39 83 };
rgrover1 0:792e9343fd39 84
rgrover1 0:792e9343fd39 85 typedef float LocationType_t;
rgrover1 0:792e9343fd39 86 typedef float Altitude_t;
rgrover1 0:792e9343fd39 87 struct LocationUpdateParams_t {
rgrover1 0:792e9343fd39 88 uint32_t version; /* Layout-version for the following structure;
rgrover1 0:792e9343fd39 89 * this is to accommodate changes over time. */
rgrover1 1:c1122f8eec82 90 bool valid; /* Does this update contain a valid location. */
rgrover1 0:792e9343fd39 91 LocationType_t lat;
rgrover1 0:792e9343fd39 92 LocationType_t lon;
rgrover1 0:792e9343fd39 93 Altitude_t altitude;
rgrover1 0:792e9343fd39 94
rgrover1 1:c1122f8eec82 95 unsigned numGPSSVs; /* num GPS Satellites */
rgrover1 1:c1122f8eec82 96 unsigned numGLOSVs; /* num GLONASS Satellites */
rgrover1 1:c1122f8eec82 97
zhjcpi 7:820997be26cb 98 GPSTime_t gpsTime; /* gps time */
zhjcpi 7:820997be26cb 99 uint64_t utcTime; /* UTC time in millisecond */
rgrover1 0:792e9343fd39 100 };
rgrover1 0:792e9343fd39 101
apalmieri 8:47fa213225c3 102 // [ST-GNSS] - Geofencing API
apalmieri 8:47fa213225c3 103 struct GeofencesTriggerParams_t {
apalmieri 8:47fa213225c3 104 int geofenceTransition;
apalmieri 8:47fa213225c3 105 GPSGeofence **triggeringGeofences;
apalmieri 8:47fa213225c3 106 };
apalmieri 8:47fa213225c3 107
rgrover1 0:792e9343fd39 108 public:
rgrover1 0:792e9343fd39 109 /**
rgrover1 0:792e9343fd39 110 * Set the operating mode for power. Typically this allows the user to
rgrover1 0:792e9343fd39 111 * choose between various low-power modes. Entering low-power modes often
rgrover1 0:792e9343fd39 112 * results in a trade-off between accuracy and power consumption.
rgrover1 0:792e9343fd39 113 *
rgrover1 0:792e9343fd39 114 * The new mode takes effect upon calling start().
rgrover1 0:792e9343fd39 115 *
rgrover1 0:792e9343fd39 116 * @param power The new power mode.
rgrover1 0:792e9343fd39 117 * @return true if the update was successful.
rgrover1 0:792e9343fd39 118 */
rgrover1 0:792e9343fd39 119 bool setPowerMode(PowerMode_t power);
rgrover1 0:792e9343fd39 120
rgrover1 0:792e9343fd39 121 /**
rgrover1 0:792e9343fd39 122 * HW reset to get location chip into hibernation mode, but in readiness for
rgrover1 0:792e9343fd39 123 * starting operation. The GPS controller emerges from hibernation when
rgrover1 0:792e9343fd39 124 * start() is called.
rgrover1 0:792e9343fd39 125 *
rgrover1 0:792e9343fd39 126 * The typical initialization sequence is:
rgrover1 0:792e9343fd39 127 * reset();
rgrover1 0:792e9343fd39 128 * start(); // and thereafter receive location-update callbacks.
rgrover1 0:792e9343fd39 129 */
rgrover1 0:792e9343fd39 130 void reset(void);
rgrover1 0:792e9343fd39 131
rgrover1 0:792e9343fd39 132 /**
rgrover1 0:792e9343fd39 133 * Start the GPS operation, taking into account the operation mode set
rgrover1 0:792e9343fd39 134 * previously. Following this call, the user may expect to receive location
rgrover1 0:792e9343fd39 135 * notifications in interrupt context if a handler has previously been set.
rgrover1 0:792e9343fd39 136 *
rgrover1 0:792e9343fd39 137 * @note: calling start repeatedly doesn't hurt.
rgrover1 0:792e9343fd39 138 */
rgrover1 0:792e9343fd39 139 void start(void);
rgrover1 0:792e9343fd39 140
rgrover1 0:792e9343fd39 141 /**
rgrover1 0:792e9343fd39 142 * Stop active operation of the GPS; and put it to hibernation.
rgrover1 0:792e9343fd39 143 *
rgrover1 0:792e9343fd39 144 * @note: You don't need to call reset() afterwards to enter hibernation.
rgrover1 0:792e9343fd39 145 * @note: Calling stop() repeatedly doesn't hurt.
rgrover1 0:792e9343fd39 146 */
rgrover1 0:792e9343fd39 147 void stop(void);
rgrover1 0:792e9343fd39 148
rgrover1 0:792e9343fd39 149 /**
rgrover1 1:c1122f8eec82 150 * Process location data from chip and update location and satellite
rgrover1 1:c1122f8eec82 151 * information. This API is supposed to be called repeatedly from the
rgrover1 1:c1122f8eec82 152 * application in thread mode to process incoming messages as they are
rgrover1 1:c1122f8eec82 153 * received from the GPS controller. Arriving data is first appended to
rgrover1 1:c1122f8eec82 154 * something like a circular buffer by interrupts, and then parsed as
rgrover1 1:c1122f8eec82 155 * messages in thread mode.
rgrover1 1:c1122f8eec82 156 *
rgrover1 1:c1122f8eec82 157 * The application typically enters a loop calling process() after
rgrover1 1:c1122f8eec82 158 * initializing the GPS controller with start(). process() returns
rgrover1 1:c1122f8eec82 159 * immediately if there is no work to be done, but it must get invoked
rgrover1 1:c1122f8eec82 160 * frequently in order to keep pace with arriving data.
rgrover1 1:c1122f8eec82 161 *
rgrover1 1:c1122f8eec82 162 * Mbed's sleep() may be usefully thrown into the application's process()
rgrover1 1:c1122f8eec82 163 * loop to save power--sleep() has the effect of putting the processor to
rgrover1 1:c1122f8eec82 164 * sleep while waiting for an event (such as an interrupt). As always, some
rgrover1 1:c1122f8eec82 165 * care must be taken in employing sleep(), because there is a small
rgrover1 1:c1122f8eec82 166 * synchronization window where an interrupt may arrive and pend data which
rgrover1 1:c1122f8eec82 167 * doesn't get processed (as illustrated below).
rgrover1 1:c1122f8eec82 168 *
rgrover1 1:c1122f8eec82 169 * while (true) {
rgrover1 1:c1122f8eec82 170 * process();
rgrover1 1:c1122f8eec82 171 * <-- interrupt arrives now and appends new data
rgrover1 1:c1122f8eec82 172 * sleep(); // but then we go to sleep without processing it.
rgrover1 1:c1122f8eec82 173 * }
rgrover1 1:c1122f8eec82 174 *
rgrover1 1:c1122f8eec82 175 * There is a way around it: if sleep() boils down to the use of ARM's WFE
rgrover1 1:c1122f8eec82 176 * instruction (as opposed to WFI), then its safe from the above-mentioned
rgrover1 1:c1122f8eec82 177 * synchronization window.
rgrover1 1:c1122f8eec82 178 */
rgrover1 1:c1122f8eec82 179 void process(void);
rgrover1 1:c1122f8eec82 180
rgrover1 1:c1122f8eec82 181 /**
rgrover1 0:792e9343fd39 182 * @return true if the initialization process has received enough
rgrover1 0:792e9343fd39 183 * information to determine the hardware's version/device-info.
rgrover1 0:792e9343fd39 184 */
rgrover1 1:c1122f8eec82 185 bool haveDeviceInfo(void) const;
rgrover1 0:792e9343fd39 186
rgrover1 0:792e9343fd39 187 /**
rgrover1 0:792e9343fd39 188 * Fetch the device information string. This is expected to contain the
rgrover1 0:792e9343fd39 189 * version number or any other device identifier.
rgrover1 0:792e9343fd39 190 */
rgrover1 1:c1122f8eec82 191 const char *getDeviceInfo(void) const;
rgrover1 0:792e9343fd39 192
rgrover1 0:792e9343fd39 193 /**
rgrover1 0:792e9343fd39 194 * This is a wildcard API for sending controller specific commands. Use of
rgrover1 0:792e9343fd39 195 * this API will make programs non-portable, but then there may arise a
rgrover1 0:792e9343fd39 196 * genuine need to access special functionality.
rgrover1 0:792e9343fd39 197 *
rgrover1 0:792e9343fd39 198 * @param command A controller specific command.
rgrover1 0:792e9343fd39 199 * @param arg Argument to the command; interpreted according to the command.
rgrover1 0:792e9343fd39 200 * @return any return from the command.
rgrover1 0:792e9343fd39 201 */
rgrover1 0:792e9343fd39 202 uint32_t ioctl(uint32_t command, void *arg);
rgrover1 0:792e9343fd39 203
rgrover1 0:792e9343fd39 204 /**
rgrover1 0:792e9343fd39 205 * @return true if we've obtained at least one valid location since last
rgrover1 0:792e9343fd39 206 * calling start().
rgrover1 0:792e9343fd39 207 *
rgrover1 0:792e9343fd39 208 * @Note: This is cleared after reset().
rgrover1 0:792e9343fd39 209 */
rgrover1 1:c1122f8eec82 210 bool locationAvailable(void) const;
rgrover1 0:792e9343fd39 211
rgrover1 0:792e9343fd39 212 /**
rgrover1 0:792e9343fd39 213 * @return the last valid location if there is any; else NULL.
rgrover1 0:792e9343fd39 214 */
rgrover1 1:c1122f8eec82 215 const LocationUpdateParams_t *getLastLocation(void) const;
rgrover1 0:792e9343fd39 216
rgrover1 0:792e9343fd39 217 /**
rgrover1 0:792e9343fd39 218 * Type declaration for a callback to be invoked from interrupt context upon
rgrover1 0:792e9343fd39 219 * receiving new location data.
rgrover1 0:792e9343fd39 220 *
rgrover1 0:792e9343fd39 221 * @Note: Please note that the handler gets invoked from interrupt context.
rgrover1 0:792e9343fd39 222 * Users *should not* do any long running or blocking operations in the
rgrover1 0:792e9343fd39 223 * handler.
rgrover1 0:792e9343fd39 224 */
rgrover1 0:792e9343fd39 225 typedef void (* LocationUpdateCallback_t)(const LocationUpdateParams_t *params);
rgrover1 0:792e9343fd39 226
rgrover1 0:792e9343fd39 227 /**
rgrover1 0:792e9343fd39 228 * Setup the locationUpdate callback.
rgrover1 0:792e9343fd39 229 *
rgrover1 0:792e9343fd39 230 * @Note: Please note that the handler gets invoked from interrupt context.
rgrover1 0:792e9343fd39 231 * Users *should not* do any long running or blocking operations in the
rgrover1 0:792e9343fd39 232 * handler.
rgrover1 0:792e9343fd39 233 */
rgrover1 0:792e9343fd39 234 void onLocationUpdate(LocationUpdateCallback_t callback);
rgrover1 0:792e9343fd39 235
rgrover1 1:c1122f8eec82 236 /**
rgrover1 1:c1122f8eec82 237 * In low-power operation, the GPS controller may be expected to hibernate
rgrover1 1:c1122f8eec82 238 * for extended periods and location updates may be infrequent. It should
rgrover1 1:c1122f8eec82 239 * then be possible for an application to demand location data when needed.
rgrover1 1:c1122f8eec82 240 *
rgrover1 1:c1122f8eec82 241 * This calls results in a locationCallback if there is a useful location to
rgrover1 1:c1122f8eec82 242 * report.
rgrover1 1:c1122f8eec82 243 */
rgrover1 1:c1122f8eec82 244 void lpmGetImmediateLocation(void);
rgrover1 1:c1122f8eec82 245
apalmieri 8:47fa213225c3 246 // [ST-GNSS] - Geofencing API
apalmieri 8:47fa213225c3 247 bool isGeofencingSupported(void) const;
apalmieri 8:47fa213225c3 248 // [ST-GNSS] - Geofencing API
apalmieri 8:47fa213225c3 249 typedef void (* GeofencesTriggerCallback_t)(const GeofencesTriggerParams_t *params);
apalmieri 8:47fa213225c3 250 // [ST-GNSS] - Geofencing API
apalmieri 8:47fa213225c3 251 void onGeofencesTrigger(GeofencesTriggerCallback_t callback);
apalmieri 8:47fa213225c3 252
rgrover1 0:792e9343fd39 253 public:
rgrover1 0:792e9343fd39 254 /**
rgrover1 0:792e9343fd39 255 * Default constructor.
rgrover1 0:792e9343fd39 256 */
rgrover1 1:c1122f8eec82 257 GPSProvider() : impl(createGPSProviderInstance()) {
rgrover1 0:792e9343fd39 258 /* empty */
rgrover1 0:792e9343fd39 259 }
rgrover1 0:792e9343fd39 260
rgrover1 0:792e9343fd39 261 virtual ~GPSProvider() {
rgrover1 0:792e9343fd39 262 stop();
rgrover1 0:792e9343fd39 263 }
rgrover1 0:792e9343fd39 264
rgrover1 0:792e9343fd39 265 private:
rgrover1 0:792e9343fd39 266 /**
rgrover1 0:792e9343fd39 267 * We use 'composition' to combine a driver-implementation object to the
rgrover1 0:792e9343fd39 268 * GPSProvider interface. The implementation object will come to life
rgrover1 0:792e9343fd39 269 * through the createGPSProviderInstance(), which must be defined by the
rgrover1 0:792e9343fd39 270 * driver library. The mechanics of the implementation are to be hidden
rgrover1 0:792e9343fd39 271 * behind the abstract interface provided by GPSProvider.
rgrover1 0:792e9343fd39 272 */
rgrover1 0:792e9343fd39 273 GPSProviderImplBase *const impl;
rgrover1 0:792e9343fd39 274
rgrover1 0:792e9343fd39 275 /* disallow copy constructor and assignment operators */
rgrover1 0:792e9343fd39 276 private:
rgrover1 0:792e9343fd39 277 GPSProvider(const GPSProvider&);
rgrover1 0:792e9343fd39 278 GPSProvider & operator= (const GPSProvider&);
rgrover1 0:792e9343fd39 279 };
rgrover1 0:792e9343fd39 280
rgrover1 0:792e9343fd39 281 #endif /*__GPS_PROVIDER_H__*/