A controller-neutral API for working with GPS devices.

Dependents:   CsrLocationDemo CsrLocationDemo

Committer:
rgrover1
Date:
Thu Oct 30 14:42:27 2014 +0000
Revision:
0:792e9343fd39
Child:
1:c1122f8eec82
GPS API

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
rgrover1 0:792e9343fd39 20 class GPSProviderImplBase; /* forward declaration */
rgrover1 0:792e9343fd39 21 extern GPSProviderImplBase *createGPSProviderInstance(void);
rgrover1 0:792e9343fd39 22
rgrover1 0:792e9343fd39 23 //
rgrover1 0:792e9343fd39 24 // Here's a snippet showing how this API can be used. Please note that this is
rgrover1 0:792e9343fd39 25 // an asynchronous API--users can setup an asynchronous handler to receive
rgrover1 0:792e9343fd39 26 // location updates. The handler gets invoked from interrupt context. Users
rgrover1 0:792e9343fd39 27 // *should not* do any long running or blocking operations in the handler.
rgrover1 0:792e9343fd39 28 //
rgrover1 0:792e9343fd39 29 // void handleGPSData(const LocationUpdateParams_t *newData) {
rgrover1 0:792e9343fd39 30 // /* Do something with the location update; but please don't make any
rgrover1 0:792e9343fd39 31 // * blocking calls or invoke long-running operations. */
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 0:792e9343fd39 39 // gps.reset(); // implicitly calls powerOn().
rgrover1 0:792e9343fd39 40 // gps.start();
rgrover1 0:792e9343fd39 41 //
rgrover1 0:792e9343fd39 42 // wait(/* some duration to allow controller to stabilize */);
rgrover1 0:792e9343fd39 43 // if (gps.haveDeviceInfo()) {
rgrover1 0:792e9343fd39 44 // printf("%s", gps.getDeviceInfo());
rgrover1 0:792e9343fd39 45 // }
rgrover1 0:792e9343fd39 46 //
rgrover1 0:792e9343fd39 47 // ...
rgrover1 0:792e9343fd39 48 // /* Period where the gps locationHandler gets invoked asynchronously. */
rgrover1 0:792e9343fd39 49 // ...
rgrover1 0:792e9343fd39 50 //
rgrover1 0:792e9343fd39 51 // /* at some point in the future, either the following.. */
rgrover1 0:792e9343fd39 52 // gps.stop();
rgrover1 0:792e9343fd39 53 // gps.powerOff();
rgrover1 0:792e9343fd39 54 // /* or simply destroy the gps object to achieve the same. */
rgrover1 0:792e9343fd39 55 //
rgrover1 0:792e9343fd39 56
rgrover1 0:792e9343fd39 57 class GPSProvider {
rgrover1 0:792e9343fd39 58 public:
rgrover1 0:792e9343fd39 59 /** Power mode selection */
rgrover1 0:792e9343fd39 60 enum PowerMode_t {
rgrover1 0:792e9343fd39 61 POWER_FULL,
rgrover1 0:792e9343fd39 62 POWER_LOW,
rgrover1 0:792e9343fd39 63 };
rgrover1 0:792e9343fd39 64
rgrover1 0:792e9343fd39 65 /**
rgrover1 0:792e9343fd39 66 * GPS time starts from UTC 01/06/1980(MM/DD/YYYY) and includes 2 fields:
rgrover1 0:792e9343fd39 67 * week and tow. For a given GPS time, week is the passed week number since
rgrover1 0:792e9343fd39 68 * the GPS start time, and tow(time of week) is the passed seconds since the
rgrover1 0:792e9343fd39 69 * last Sunday. For example, a given UTC time [10/30/3014
rgrover1 0:792e9343fd39 70 * 01:10:00](MM/DD/YYYY HH:MM:SS) can be converted into GPS time [1816,
rgrover1 0:792e9343fd39 71 * 4200](week, seconds).
rgrover1 0:792e9343fd39 72 *
rgrover1 0:792e9343fd39 73 * GPS time can be used as a quite accurate time once position is fixed.
rgrover1 0:792e9343fd39 74 */
rgrover1 0:792e9343fd39 75 struct GPSTime_t {
rgrover1 0:792e9343fd39 76 uint16_t gps_week;
rgrover1 0:792e9343fd39 77 uint32_t tow; /* time of week (in seconds) */
rgrover1 0:792e9343fd39 78 };
rgrover1 0:792e9343fd39 79
rgrover1 0:792e9343fd39 80 typedef float LocationType_t;
rgrover1 0:792e9343fd39 81 typedef float Altitude_t;
rgrover1 0:792e9343fd39 82 struct LocationUpdateParams_t {
rgrover1 0:792e9343fd39 83 uint32_t version; /* Layout-version for the following structure;
rgrover1 0:792e9343fd39 84 * this is to accommodate changes over time. */
rgrover1 0:792e9343fd39 85 LocationType_t lat;
rgrover1 0:792e9343fd39 86 LocationType_t lon;
rgrover1 0:792e9343fd39 87 Altitude_t altitude;
rgrover1 0:792e9343fd39 88
rgrover1 0:792e9343fd39 89 union {
rgrover1 0:792e9343fd39 90 GPSTime_t gpsTime;
rgrover1 0:792e9343fd39 91 float utcTime;
rgrover1 0:792e9343fd39 92 } u;
rgrover1 0:792e9343fd39 93 };
rgrover1 0:792e9343fd39 94
rgrover1 0:792e9343fd39 95 public:
rgrover1 0:792e9343fd39 96 /**
rgrover1 0:792e9343fd39 97 * Set the operating mode for power. Typically this allows the user to
rgrover1 0:792e9343fd39 98 * choose between various low-power modes. Entering low-power modes often
rgrover1 0:792e9343fd39 99 * results in a trade-off between accuracy and power consumption.
rgrover1 0:792e9343fd39 100 *
rgrover1 0:792e9343fd39 101 * The new mode takes effect upon calling start().
rgrover1 0:792e9343fd39 102 *
rgrover1 0:792e9343fd39 103 * @param power The new power mode.
rgrover1 0:792e9343fd39 104 * @return true if the update was successful.
rgrover1 0:792e9343fd39 105 */
rgrover1 0:792e9343fd39 106 bool setPowerMode(PowerMode_t power);
rgrover1 0:792e9343fd39 107
rgrover1 0:792e9343fd39 108 /**
rgrover1 0:792e9343fd39 109 * HW reset to get location chip into hibernation mode, but in readiness for
rgrover1 0:792e9343fd39 110 * starting operation. The GPS controller emerges from hibernation when
rgrover1 0:792e9343fd39 111 * start() is called.
rgrover1 0:792e9343fd39 112 *
rgrover1 0:792e9343fd39 113 * The typical initialization sequence is:
rgrover1 0:792e9343fd39 114 * reset();
rgrover1 0:792e9343fd39 115 * start(); // and thereafter receive location-update callbacks.
rgrover1 0:792e9343fd39 116 */
rgrover1 0:792e9343fd39 117 void reset(void);
rgrover1 0:792e9343fd39 118
rgrover1 0:792e9343fd39 119 /**
rgrover1 0:792e9343fd39 120 * Start the GPS operation, taking into account the operation mode set
rgrover1 0:792e9343fd39 121 * previously. Following this call, the user may expect to receive location
rgrover1 0:792e9343fd39 122 * notifications in interrupt context if a handler has previously been set.
rgrover1 0:792e9343fd39 123 *
rgrover1 0:792e9343fd39 124 * @note: calling start repeatedly doesn't hurt.
rgrover1 0:792e9343fd39 125 */
rgrover1 0:792e9343fd39 126 void start(void);
rgrover1 0:792e9343fd39 127
rgrover1 0:792e9343fd39 128 /**
rgrover1 0:792e9343fd39 129 * Stop active operation of the GPS; and put it to hibernation.
rgrover1 0:792e9343fd39 130 *
rgrover1 0:792e9343fd39 131 * @note: You don't need to call reset() afterwards to enter hibernation.
rgrover1 0:792e9343fd39 132 * @note: Calling stop() repeatedly doesn't hurt.
rgrover1 0:792e9343fd39 133 */
rgrover1 0:792e9343fd39 134 void stop(void);
rgrover1 0:792e9343fd39 135
rgrover1 0:792e9343fd39 136 /**
rgrover1 0:792e9343fd39 137 * @return true if the initialization process has received enough
rgrover1 0:792e9343fd39 138 * information to determine the hardware's version/device-info.
rgrover1 0:792e9343fd39 139 */
rgrover1 0:792e9343fd39 140 bool haveDeviceInfo(void) const {
rgrover1 0:792e9343fd39 141 return discoveredDeviceInfo;
rgrover1 0:792e9343fd39 142 }
rgrover1 0:792e9343fd39 143
rgrover1 0:792e9343fd39 144 /**
rgrover1 0:792e9343fd39 145 * Fetch the device information string. This is expected to contain the
rgrover1 0:792e9343fd39 146 * version number or any other device identifier.
rgrover1 0:792e9343fd39 147 */
rgrover1 0:792e9343fd39 148 const char *getDeviceInfo(void) const {
rgrover1 0:792e9343fd39 149 return deviceInfo;
rgrover1 0:792e9343fd39 150 }
rgrover1 0:792e9343fd39 151
rgrover1 0:792e9343fd39 152 /**
rgrover1 0:792e9343fd39 153 * This is a wildcard API for sending controller specific commands. Use of
rgrover1 0:792e9343fd39 154 * this API will make programs non-portable, but then there may arise a
rgrover1 0:792e9343fd39 155 * genuine need to access special functionality.
rgrover1 0:792e9343fd39 156 *
rgrover1 0:792e9343fd39 157 * @param command A controller specific command.
rgrover1 0:792e9343fd39 158 * @param arg Argument to the command; interpreted according to the command.
rgrover1 0:792e9343fd39 159 * @return any return from the command.
rgrover1 0:792e9343fd39 160 */
rgrover1 0:792e9343fd39 161 uint32_t ioctl(uint32_t command, void *arg);
rgrover1 0:792e9343fd39 162
rgrover1 0:792e9343fd39 163 /**
rgrover1 0:792e9343fd39 164 * @return true if we've obtained at least one valid location since last
rgrover1 0:792e9343fd39 165 * calling start().
rgrover1 0:792e9343fd39 166 *
rgrover1 0:792e9343fd39 167 * @Note: This is cleared after reset().
rgrover1 0:792e9343fd39 168 */
rgrover1 0:792e9343fd39 169 bool locationAvailable(void) const {
rgrover1 0:792e9343fd39 170 return haveValidLocation;
rgrover1 0:792e9343fd39 171 }
rgrover1 0:792e9343fd39 172
rgrover1 0:792e9343fd39 173 /**
rgrover1 0:792e9343fd39 174 * @return the last valid location if there is any; else NULL.
rgrover1 0:792e9343fd39 175 */
rgrover1 0:792e9343fd39 176 const LocationUpdateParams_t *getLastLocation(void) const {
rgrover1 0:792e9343fd39 177 return haveValidLocation ? &lastLocation : NULL;
rgrover1 0:792e9343fd39 178 }
rgrover1 0:792e9343fd39 179
rgrover1 0:792e9343fd39 180 /**
rgrover1 0:792e9343fd39 181 * Type declaration for a callback to be invoked from interrupt context upon
rgrover1 0:792e9343fd39 182 * receiving new location data.
rgrover1 0:792e9343fd39 183 *
rgrover1 0:792e9343fd39 184 * @Note: Please note that the handler gets invoked from interrupt context.
rgrover1 0:792e9343fd39 185 * Users *should not* do any long running or blocking operations in the
rgrover1 0:792e9343fd39 186 * handler.
rgrover1 0:792e9343fd39 187 */
rgrover1 0:792e9343fd39 188 typedef void (* LocationUpdateCallback_t)(const LocationUpdateParams_t *params);
rgrover1 0:792e9343fd39 189
rgrover1 0:792e9343fd39 190 /**
rgrover1 0:792e9343fd39 191 * Setup the locationUpdate callback.
rgrover1 0:792e9343fd39 192 *
rgrover1 0:792e9343fd39 193 * @Note: Please note that the handler gets invoked from interrupt context.
rgrover1 0:792e9343fd39 194 * Users *should not* do any long running or blocking operations in the
rgrover1 0:792e9343fd39 195 * handler.
rgrover1 0:792e9343fd39 196 */
rgrover1 0:792e9343fd39 197 void onLocationUpdate(LocationUpdateCallback_t callback);
rgrover1 0:792e9343fd39 198
rgrover1 0:792e9343fd39 199 public:
rgrover1 0:792e9343fd39 200 /**
rgrover1 0:792e9343fd39 201 * Default constructor.
rgrover1 0:792e9343fd39 202 */
rgrover1 0:792e9343fd39 203 GPSProvider() :
rgrover1 0:792e9343fd39 204 impl(createGPSProviderInstance()),
rgrover1 0:792e9343fd39 205 havePoweredOn(false),
rgrover1 0:792e9343fd39 206 discoveredDeviceInfo(false),
rgrover1 0:792e9343fd39 207 haveValidLocation(false),
rgrover1 0:792e9343fd39 208 deviceInfo(NULL),
rgrover1 0:792e9343fd39 209 updateCallback(NULL) {
rgrover1 0:792e9343fd39 210 /* empty */
rgrover1 0:792e9343fd39 211 }
rgrover1 0:792e9343fd39 212
rgrover1 0:792e9343fd39 213 virtual ~GPSProvider() {
rgrover1 0:792e9343fd39 214 stop();
rgrover1 0:792e9343fd39 215 }
rgrover1 0:792e9343fd39 216
rgrover1 0:792e9343fd39 217 private:
rgrover1 0:792e9343fd39 218 /**
rgrover1 0:792e9343fd39 219 * We use 'composition' to combine a driver-implementation object to the
rgrover1 0:792e9343fd39 220 * GPSProvider interface. The implementation object will come to life
rgrover1 0:792e9343fd39 221 * through the createGPSProviderInstance(), which must be defined by the
rgrover1 0:792e9343fd39 222 * driver library. The mechanics of the implementation are to be hidden
rgrover1 0:792e9343fd39 223 * behind the abstract interface provided by GPSProvider.
rgrover1 0:792e9343fd39 224 */
rgrover1 0:792e9343fd39 225 GPSProviderImplBase *const impl;
rgrover1 0:792e9343fd39 226
rgrover1 0:792e9343fd39 227 private:
rgrover1 0:792e9343fd39 228 bool havePoweredOn;
rgrover1 0:792e9343fd39 229 bool discoveredDeviceInfo;
rgrover1 0:792e9343fd39 230 bool haveValidLocation;
rgrover1 0:792e9343fd39 231
rgrover1 0:792e9343fd39 232 const char *deviceInfo;
rgrover1 0:792e9343fd39 233 LocationUpdateParams_t lastLocation;
rgrover1 0:792e9343fd39 234 LocationUpdateCallback_t *updateCallback;
rgrover1 0:792e9343fd39 235
rgrover1 0:792e9343fd39 236 /* disallow copy constructor and assignment operators */
rgrover1 0:792e9343fd39 237 private:
rgrover1 0:792e9343fd39 238 GPSProvider(const GPSProvider&);
rgrover1 0:792e9343fd39 239 GPSProvider & operator= (const GPSProvider&);
rgrover1 0:792e9343fd39 240 };
rgrover1 0:792e9343fd39 241
rgrover1 0:792e9343fd39 242 #endif /*__GPS_PROVIDER_H__*/