A controller-neutral API for working with GPS devices.
Dependents: CsrLocationDemo CsrLocationDemo
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__*/
Generated on Fri Jul 15 2022 07:53:07 by
![doxygen](doxygen.png)