An extension of original API for working with GPS devices.
Diff: GPSProvider.h
- Revision:
- 0:792e9343fd39
- Child:
- 1:c1122f8eec82
diff -r 000000000000 -r 792e9343fd39 GPSProvider.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPSProvider.h Thu Oct 30 14:42:27 2014 +0000 @@ -0,0 +1,242 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GPS_PROVIDER_H__ +#define __GPS_PROVIDER_H__ + +class GPSProviderImplBase; /* forward declaration */ +extern GPSProviderImplBase *createGPSProviderInstance(void); + +// +// Here's a snippet showing how this API can be used. Please note that this is +// an asynchronous API--users can setup an asynchronous handler to receive +// location updates. The handler gets invoked from interrupt context. Users +// *should not* do any long running or blocking operations in the handler. +// +// void handleGPSData(const LocationUpdateParams_t *newData) { +// /* Do something with the location update; but please don't make any +// * blocking calls or invoke long-running operations. */ +// } +// +// GPSProvider gps; +// +// gps.setPowerMode(LOW_POWER); +// gps.onLocationUpdate(handleGPSData); +// +// gps.reset(); // implicitly calls powerOn(). +// gps.start(); +// +// wait(/* some duration to allow controller to stabilize */); +// if (gps.haveDeviceInfo()) { +// printf("%s", gps.getDeviceInfo()); +// } +// +// ... +// /* Period where the gps locationHandler gets invoked asynchronously. */ +// ... +// +// /* at some point in the future, either the following.. */ +// gps.stop(); +// gps.powerOff(); +// /* or simply destroy the gps object to achieve the same. */ +// + +class GPSProvider { +public: + /** Power mode selection */ + enum PowerMode_t { + POWER_FULL, + POWER_LOW, + }; + + /** + * GPS time starts from UTC 01/06/1980(MM/DD/YYYY) and includes 2 fields: + * week and tow. For a given GPS time, week is the passed week number since + * the GPS start time, and tow(time of week) is the passed seconds since the + * last Sunday. For example, a given UTC time [10/30/3014 + * 01:10:00](MM/DD/YYYY HH:MM:SS) can be converted into GPS time [1816, + * 4200](week, seconds). + * + * GPS time can be used as a quite accurate time once position is fixed. + */ + struct GPSTime_t { + uint16_t gps_week; + uint32_t tow; /* time of week (in seconds) */ + }; + + typedef float LocationType_t; + typedef float Altitude_t; + struct LocationUpdateParams_t { + uint32_t version; /* Layout-version for the following structure; + * this is to accommodate changes over time. */ + LocationType_t lat; + LocationType_t lon; + Altitude_t altitude; + + union { + GPSTime_t gpsTime; + float utcTime; + } u; + }; + +public: + /** + * Set the operating mode for power. Typically this allows the user to + * choose between various low-power modes. Entering low-power modes often + * results in a trade-off between accuracy and power consumption. + * + * The new mode takes effect upon calling start(). + * + * @param power The new power mode. + * @return true if the update was successful. + */ + bool setPowerMode(PowerMode_t power); + + /** + * HW reset to get location chip into hibernation mode, but in readiness for + * starting operation. The GPS controller emerges from hibernation when + * start() is called. + * + * The typical initialization sequence is: + * reset(); + * start(); // and thereafter receive location-update callbacks. + */ + void reset(void); + + /** + * Start the GPS operation, taking into account the operation mode set + * previously. Following this call, the user may expect to receive location + * notifications in interrupt context if a handler has previously been set. + * + * @note: calling start repeatedly doesn't hurt. + */ + void start(void); + + /** + * Stop active operation of the GPS; and put it to hibernation. + * + * @note: You don't need to call reset() afterwards to enter hibernation. + * @note: Calling stop() repeatedly doesn't hurt. + */ + void stop(void); + + /** + * @return true if the initialization process has received enough + * information to determine the hardware's version/device-info. + */ + bool haveDeviceInfo(void) const { + return discoveredDeviceInfo; + } + + /** + * Fetch the device information string. This is expected to contain the + * version number or any other device identifier. + */ + const char *getDeviceInfo(void) const { + return deviceInfo; + } + + /** + * This is a wildcard API for sending controller specific commands. Use of + * this API will make programs non-portable, but then there may arise a + * genuine need to access special functionality. + * + * @param command A controller specific command. + * @param arg Argument to the command; interpreted according to the command. + * @return any return from the command. + */ + uint32_t ioctl(uint32_t command, void *arg); + + /** + * @return true if we've obtained at least one valid location since last + * calling start(). + * + * @Note: This is cleared after reset(). + */ + bool locationAvailable(void) const { + return haveValidLocation; + } + + /** + * @return the last valid location if there is any; else NULL. + */ + const LocationUpdateParams_t *getLastLocation(void) const { + return haveValidLocation ? &lastLocation : NULL; + } + + /** + * Type declaration for a callback to be invoked from interrupt context upon + * receiving new location data. + * + * @Note: Please note that the handler gets invoked from interrupt context. + * Users *should not* do any long running or blocking operations in the + * handler. + */ + typedef void (* LocationUpdateCallback_t)(const LocationUpdateParams_t *params); + + /** + * Setup the locationUpdate callback. + * + * @Note: Please note that the handler gets invoked from interrupt context. + * Users *should not* do any long running or blocking operations in the + * handler. + */ + void onLocationUpdate(LocationUpdateCallback_t callback); + +public: + /** + * Default constructor. + */ + GPSProvider() : + impl(createGPSProviderInstance()), + havePoweredOn(false), + discoveredDeviceInfo(false), + haveValidLocation(false), + deviceInfo(NULL), + updateCallback(NULL) { + /* empty */ + } + + virtual ~GPSProvider() { + stop(); + } + +private: + /** + * We use 'composition' to combine a driver-implementation object to the + * GPSProvider interface. The implementation object will come to life + * through the createGPSProviderInstance(), which must be defined by the + * driver library. The mechanics of the implementation are to be hidden + * behind the abstract interface provided by GPSProvider. + */ + GPSProviderImplBase *const impl; + +private: + bool havePoweredOn; + bool discoveredDeviceInfo; + bool haveValidLocation; + + const char *deviceInfo; + LocationUpdateParams_t lastLocation; + LocationUpdateCallback_t *updateCallback; + + /* disallow copy constructor and assignment operators */ +private: + GPSProvider(const GPSProvider&); + GPSProvider & operator= (const GPSProvider&); +}; + +#endif /*__GPS_PROVIDER_H__*/