A driver for the MAX8U GPS by uBlox. Provides core functionality. Communicates through I2C.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX8U.h Source File

MAX8U.h

00001 #ifndef MAX8U_H
00002 #define MAX8U_H
00003 
00004 
00005 #include "mbed.h"
00006 #include "MAX8UConstants.h"
00007 
00008 #define MAX8U_I2C_DEF_ADDRESS 0x42 // this is the default address given in the databook
00009 
00010 
00011 /**
00012  * Class to use the MAX8U
00013  */ 
00014 class MAX8U
00015 {
00016 public:
00017 
00018     /**
00019      *  U-Blox GPS Fix Values
00020      */ 
00021     enum class GPSFix : uint8_t
00022     {
00023         NONE = 0,
00024         DEAD_RECKONING = 1,
00025         FIX_2D = 2,
00026         FIX_3D = 3,
00027         FIX_GPS_DEAD_RECKONING = 4,
00028         TIME_ONLY = 5
00029     };
00030 
00031     /**
00032      * U-Blox GNSS identifier
00033      */
00034     enum class GNSSID : uint8_t
00035     {
00036         GPS = 0,
00037         SBAS = 1,
00038         Galileo = 2,
00039         BeiDou = 3,
00040         IMES = 4,
00041         QZSS = 5,
00042         GLONASS = 6
00043     };
00044 
00045     /**
00046      * Used for AntennaPowerStatus, in the UBX_MON_HW message
00047      */
00048     enum class AntennaPowerStatus : uint8_t
00049     {
00050         OFF = 0,
00051         ON = 1,
00052         DONT_KNOW = 2,
00053         NO_MESSAGE_RCVD = 3
00054     };
00055 
00056     /**
00057      * Info about each sattelite, obtained from getSatelliteInfo()
00058      */
00059     struct SatelliteInfo
00060     {
00061         /**
00062          * GNSS that this satellite is from.
00063          */
00064         GNSSID gnss;
00065 
00066         /**
00067          * ID of this satellite in its GNSS
00068          */
00069         uint8_t satelliteID;
00070 
00071         /**
00072          * Carrier-noise ratio in dbHz
00073          */
00074         uint8_t signalStrength;
00075 
00076         /**
00077          * Signal quality indicator (see U-Blox protocol description section 32.17.17.1)
00078          */
00079          uint8_t signalQuality;
00080 
00081          /**
00082           * Get the string name of this satellite's GNSS.
00083           * @return
00084           */
00085          const char* getGNSSName();
00086 
00087          /**
00088           * True if this satellite is beign used to do navigation
00089           */
00090           bool svUsed;
00091     };
00092 
00093 private:
00094 
00095     Serial* _debugPort;
00096 
00097 
00098     /// buffer stores the data rcvd from reeading the stream on the MAX8U
00099     const static int bufferMaxLen = 256;
00100     char buffer[bufferMaxLen + 1];
00101 
00102     /// length of the message currently in the buffer.
00103     size_t currMessageLength = 0;
00104 
00105 
00106 
00107     /**
00108      * I2C port object.  Provides physical layer communications with the chip.
00109      */
00110     I2C _i2cPort;
00111 
00112     /// i2c address of IMU (7 bits)
00113     uint8_t _i2cAddress;
00114 
00115     /// user defined port speed
00116     int  _i2cPortSpeed;
00117 
00118     /// Reset pin -- resets GPS when held low.
00119     DigitalOut _rst;
00120 
00121     /**
00122      * sends header and data in the correct UBX protocol (adding sync chars, and checksums)
00123      * @returns true if command was sent sucessfully
00124      *
00125      */
00126     bool sendCommand(uint8_t messageClass, uint8_t messageID, uint8_t *data, uint16_t dataLen);
00127 
00128 
00129 public:
00130 
00131     // Data read from GPS
00132 
00133     /// Current latitude in decimal degrees.
00134     double latitude = 0;
00135 
00136     /// Current longitude in decimal degrees.
00137     double longitude = 0;
00138 
00139     /// Current height above earths surface (above ellipsoid) in meters
00140     float height = 0;
00141 
00142     /// Quality of the current fix
00143     GPSFix fixQuality = GPSFix::NONE;
00144 
00145     /// Estimate of the accuracy of the current position in meters
00146     float posAccuracy = 0;
00147 
00148     /// current number of sats used for navigation
00149     uint8_t numSatellites = 0;
00150 
00151     // Variables for Velocity Solution in NED, units: cm/s
00152     
00153     /// North Velocity Solution in NED, units: cm/s
00154     int32_t northVel = 0;
00155     
00156     /// East Velocity Solution in NED, units: cm/s
00157     int32_t eastVel = 0;
00158     
00159     /// Down Velocity Solution in NED, units: cm/s
00160     int32_t downVel = 0;
00161     
00162     /// 3D Speed Solution in NED, units: cm/s
00163     uint32_t speed3D = 0;
00164 
00165     //time as of the last message
00166     
00167     ///Month: time as of the last message
00168     uint8_t month;
00169     
00170     ///Day: time as of the last message
00171     uint8_t day;
00172     
00173     ///Hour: time as of the last message
00174     uint8_t hour;
00175     
00176     ///Minute: time as of the last message
00177     uint8_t minute;
00178     
00179     ///Second: time as of the last message
00180     uint8_t second;
00181     
00182     ///Year: time as of the last message
00183     uint16_t year;
00184 
00185     ///  is true, if the last msg was following the NMEA protocol, otherwise UBX
00186     bool isNMEASentence;
00187 
00188     /**
00189      * Construct a MAX8U, providing pins and parameters.
00190      *
00191      * This doesn't actually initialize the chip, you will need to call begin() for that.
00192      * @param debugPort DebugPort used to output debug information. Pass nullpntr otherwise.
00193      * @param user_SDApin Hardware I2C SDA pin connected to the MAX8
00194      * @param user_SCLpin Hardware I2C SCL pin connected to the MAX8
00195      * @param user_RSTPin Output pin connected to NRST
00196      * @param i2cAddress I2C address.  The MAX8 defaults to 0x42
00197      * @param i2cPortSpeed I2C frequency.  
00198      */
00199     MAX8U(Serial *debugPort, PinName user_SDApin, PinName user_SCLpin, PinName user_RSTPin,
00200           uint8_t i2cAddress = MAX8U_I2C_DEF_ADDRESS, int i2cPortSpeed = 100000);
00201 
00202 
00203 
00204 
00205 
00206     /**
00207      * resets the GPS. Configures the basic i2c settings. 
00208      * TODO: Verifies that it's connected, and reads out its version
00209      *
00210      * @return whether or not initialization was successful
00211      */
00212     bool begin();
00213 
00214     /**
00215      * Get the last message recieved from the GPS.  Could be binary or a string
00216      * depending on the protocol in use.
00217      * @return
00218      */
00219     char const * getLastMessageBuffer() { return buffer; }
00220 
00221     /**
00222      * If there is data to be read, then the function will read all queued data.
00223      * New data will be store in buffer array
00224      * @return true if got new data, false if there was an error or stream was empty
00225      */
00226     bool update();
00227 
00228     /**
00229      * Configure the GPS with the appropriate communications and message settings
00230      * for this driver.  Unless the driver has changed, you only need to call this once
00231      * for each new GPS (the config will be saved on the GPS)
00232      * @return
00233      */
00234     bool configure();
00235 
00236     /**
00237      * Receives a single MON_HW message and returns the power status
00238      * @return the status of the power of the antenna
00239      */
00240     AntennaPowerStatus antennaPowerStatus();
00241 
00242     /**
00243      * Reads and prints the current enabled GNSS Constellations and prints out the IDS for them
00244      */
00245     void readGNSSConfig();
00246 
00247     /**
00248      * Reads information from the GPS about all the satellites it can see and
00249      * fills it into the given array.
00250      * @param satelliteInfos Array of SatelliteInfos that the caller allocates.
00251      * @param infoLen Length of the info struct array.
00252      * @return The number of satellites the GPS returned info about.  If negative, there was
00253      * an error.  If <= the size of the array, then it's the number of valid array entries.
00254      * If greater than the size of the array, then the max number of array elements were filled in.
00255      */
00256     ssize_t readSatelliteInfo(SatelliteInfo * satelliteInfos, size_t infoLen);
00257 
00258     /**
00259      * Configures the time pulse. If enabled, it will send a pulse at the frequncy
00260      * @param timepulseId, 0 = timepulse, 1 = timepulse2
00261      * @param pulseLenRatio duty cycle.
00262      * @return
00263      */
00264     bool configureTimePulse(bool enabled, uint8_t timepulseId, uint32_t freq, uint32_t pulseLenRatio);
00265 
00266 
00267 
00268 private:
00269 
00270     /**
00271      * Helper function to read form the data buffer.
00272     * Numerical values can only be read from aligned memory addresses, but sometimes we need to not do that.
00273     * This function takes an address and an optional offset, and reads a value of the template type.
00274     */
00275     template<typename T>
00276     T readUnalignedValue(char* data, size_t offset = 0)
00277     {
00278         T value;
00279         memcpy(&value, data + offset, sizeof(value));
00280         return value;
00281     }
00282 
00283     /**
00284      * Tells the GPS to enable the message indicated by messageClass and messageID
00285      * This is done by sending a message to the GPS and then waiting for an ack message
00286      * @return true if an ack message has been recieved from the gps
00287      */
00288 
00289     bool setMessageEnabled(uint8_t messageClass, uint8_t messageID, bool enabled);
00290 
00291     /**
00292      * Processes the message currently in the buffer.
00293      * If this is data we are processing, parses it and stores it in class variables.
00294      * Otherwise, does nothing.
00295      */
00296     void processMessage();
00297 
00298     /**
00299      * Process a NAV_POSLLH message loaded into the buffer.
00300      */
00301     void processNAV_POSLLH();
00302 
00303     /**
00304      * Process a NAV_SOL message loaded into the buffer.
00305      */
00306     void processNAV_SOL();
00307 
00308     /**
00309      * Process a NAV_TIMEUTC message loaded into the buffer.
00310      */
00311     void processNAV_TIMEUTC();
00312 
00313     /**
00314      * Process a NAV_VELNED message loaded into the buffer.
00315      */
00316     void processNAV_VELNED();
00317 
00318     /**
00319      * Wait for a specific message to be received.
00320      * If we get another message that is not the one we're looking for during this time, then
00321      * we process that message using processMessage()
00322      * If the message is not received before the timeout, returns false.
00323      *
00324      *
00325      * @param messageClass Class of the message to wait for
00326      * @param messageID ID of the of the message to wait for
00327      * @param timeout How long to wait for the message.
00328      * @return
00329      */
00330     bool waitForMessage(uint8_t messageClass, uint8_t messageID, float timeout = 1.0f);
00331 
00332 
00333 
00334 
00335 
00336     /**
00337      * It will wait for a message of a specific kind.
00338      * NOTE: we assume that we wait for an ACK before sending another message,
00339      * so there should never be two ACKs in play at once.
00340      * @param sentMessageClass Class of the message expecting an ACK for
00341      * @param sentMessageID ID of the message expecting an ACK for
00342      * @param timeout How long to wait for the message
00343      * @return true if a correct ACK was received
00344      */
00345 
00346     bool waitForACK(uint8_t sentMessageClass, uint8_t sentMessageID, float timeout = 1.0f);
00347 
00348     /**
00349      * Configure the port settings appropriately for this driver.
00350      * @return
00351      */
00352     bool configureCommSettings();
00353 
00354     /**
00355      * Save all the current settings to the GPS's flash memory so that they will
00356      * be loaded when it boots.
00357      * @return
00358      */
00359     bool saveSettings();
00360 
00361     /**
00362      * Check the software version.  If not in debug mode, this will just return true if
00363      * it was able to talk to the device.  In debug mode, this will print all version info
00364      * to the console.
00365      * @return
00366      */
00367     bool checkVersion();
00368 
00369     /**
00370      * Reads exactly one command in the buffer, by accessing the 0xff register.
00371      * Stores the data in a global arr, buffer.
00372      */
00373     bool readNextMessage();
00374 
00375 
00376     /**
00377      * Returns length of buffer in the GPS module by reading the registers
00378      * @returns length of message. -1 if no ack is rcvd.
00379      */
00380     int32_t readLen();
00381 };
00382 #endif