This class provides an API to communicate with a u-blox GNSS chip. The files here were originally part of the C027_Support library (https://developer.mbed.org/teams/ublox/code/C027_Support/ at revision 138:dafbbf31bf76) but have been separated out, primarily for use on the u-blox C030 board where the cellular interace portion of the C027_Support library will instead be provided through the new mbed Cellular API.

Dependents:   example-ublox-at-cellular-interface-ext example-low-power-sleep example-C030-out-of-box-demo example-C030-out-of-box-demo ... more

Files at this revision

API Documentation at this revision

Comitter:
rob.meades@u-blox.com
Date:
Wed Jun 14 20:44:42 2017 +0100
Parent:
5:af4baf3c67f3
Child:
7:bfbe9d5d6f56
Child:
8:720841961804
Commit message:
Test passing on C027 and C030 platforms.

Changed in this revision

TESTS/unit_tests/default/main.cpp Show annotated file Show diff for this revision Revisions of this file
gnss.cpp Show annotated file Show diff for this revision Revisions of this file
gnss.h Show annotated file Show diff for this revision Revisions of this file
--- a/TESTS/unit_tests/default/main.cpp	Sun Jun 11 13:45:56 2017 +0000
+++ b/TESTS/unit_tests/default/main.cpp	Wed Jun 14 20:44:42 2017 +0100
@@ -3,9 +3,6 @@
 #include "unity.h"
 #include "utest.h"
 #include "gnss.h"
-extern "C" {
-#include "c030_api.h"
-}
  
 using namespace utest::v1;
 
@@ -58,47 +55,55 @@
     char buffer[64];
     int responseLength = 0;
     int returnCode;
+    bool gotAck = false;
+    Timer timer;
 
     GnssSerial *pGnss = new GnssSerial();
 
-    // Initialise the GNSS chip and wait for it to start up
+    // Initialise the GNSS chip
     pGnss->init(NC);
-    wait_ms(1000);
 
-    // See ublox7-V14_ReceiverDescrProtSpec section 30.11.15 (CFG-NAV5)
-    // Set automotive mode, which should be acknowledged
-    memset (buffer, 0, sizeof (buffer));
-    buffer[0] = 0x00;
-    buffer[1] = 0x01; // Set dynamic config only
-    buffer[2] = 0x04; // Automotive
-    // Send length is 32 bytes of payload + 6 bytes header + 2 bytes CRC
-    TEST_ASSERT_EQUAL_INT (40, pGnss->sendUbx(0x06, 0x24, buffer, 32));
-    while (responseLength == 0) {
-        // Wait for the required Ack
-        returnCode = pGnss->getMessage(buffer, sizeof(buffer));
-        if ((returnCode != GnssSerial::WAIT) && (returnCode != GnssSerial::NOT_FOUND)) {
-            responseLength = LENGTH(returnCode);
-            if ((PROTOCOL(returnCode) == GnssSerial::UBX)) {
-                printHex(buffer, responseLength);
-                // Ack is  0xb5-62-05-00-02-00-msgclass-msgid-crcA-crcB
-                // Nack is 0xb5-62-05-01-02-00-msgclass-msgid-crcA-crcB
-                TEST_ASSERT_EQUAL_UINT8(0xb5, buffer[0]);
-                TEST_ASSERT_EQUAL_UINT8(0x62, buffer[1]);
-                TEST_ASSERT_EQUAL_UINT8(0x05, buffer[2]);
-                TEST_ASSERT_EQUAL_UINT8(0x00, buffer[3]);
-                TEST_ASSERT_EQUAL_UINT8(0x02, buffer[4]);
-                TEST_ASSERT_EQUAL_UINT8(0x00, buffer[5]);
-                TEST_ASSERT_EQUAL_UINT8(0x06, buffer[6]);
-                TEST_ASSERT_EQUAL_UINT8(0x24, buffer[7]);
-            } else if ((PROTOCOL(returnCode) == GnssSerial::NMEA)) {
-                printf ("%.*s", responseLength, buffer);
-                responseLength = 0;
-            } else {
-                printHex(buffer, responseLength);
-                responseLength = 0;
+    // Try this a few times as we might get no response
+    // if the GNSS chip is busy
+    for (int x = 0; (x < 3) && !gotAck; x++) {
+        // See ublox7-V14_ReceiverDescrProtSpec section 30.11.15 (CFG-NAV5)
+        // Set automotive mode, which should be acknowledged
+        memset (buffer, 0, sizeof (buffer));
+        buffer[0] = 0x00;
+        buffer[1] = 0x01; // Mask: set dynamic config only
+        buffer[2] = 0x04; // Dynamic platform model: automotive
+        // Send length is 32 bytes of payload + 6 bytes header + 2 bytes CRC
+        TEST_ASSERT_EQUAL_INT (40, pGnss->sendUbx(0x06, 0x24, buffer, 32));
+        printf ("CFG_NAV5 command sent, try %d.\n", x);
+        timer.start();
+        while ((!gotAck) && (timer.read_ms() < 1000)) {
+            // Wait for the required Ack
+            returnCode = pGnss->getMessage(buffer, sizeof(buffer));
+            if ((returnCode != GnssSerial::WAIT) && (returnCode != GnssSerial::NOT_FOUND)) {
+                responseLength = LENGTH(returnCode);
+                if ((PROTOCOL(returnCode) == GnssSerial::UBX)) {
+                    printHex(buffer, responseLength);
+                    // Ack is  0xb5-62-05-00-02-00-msgclass-msgid-crcA-crcB
+                    // Nack is 0xb5-62-05-01-02-00-msgclass-msgid-crcA-crcB
+                    TEST_ASSERT_EQUAL_UINT8(0xb5, buffer[0]);
+                    TEST_ASSERT_EQUAL_UINT8(0x62, buffer[1]);
+                    TEST_ASSERT_EQUAL_UINT8(0x05, buffer[2]);
+                    TEST_ASSERT_EQUAL_UINT8(0x00, buffer[3]);
+                    TEST_ASSERT_EQUAL_UINT8(0x02, buffer[4]);
+                    TEST_ASSERT_EQUAL_UINT8(0x00, buffer[5]);
+                    TEST_ASSERT_EQUAL_UINT8(0x06, buffer[6]);
+                    TEST_ASSERT_EQUAL_UINT8(0x24, buffer[7]);
+                    gotAck = true;
+                } else if ((PROTOCOL(returnCode) == GnssSerial::NMEA)) {
+                    printf ("%.*s", responseLength, buffer);
+                } else {
+                    printHex(buffer, responseLength);
+                }
             }
+            wait_ms (100);
         }
-        wait_ms (100);
+        timer.stop();
+        timer.reset();
     }
 }
 
@@ -216,8 +221,6 @@
 
 int main() {
 
-    c030_init(); // HACK
-
     return !Harness::run(specification);
 }
 
--- a/gnss.cpp	Sun Jun 11 13:45:56 2017 +0000
+++ b/gnss.cpp	Wed Jun 14 20:44:42 2017 +0100
@@ -45,7 +45,7 @@
 
 void GnssParser::powerOff(void)
 {
-    // set the GNSS into backup mode using the command RMX-LPREQ
+    // Set the GNSS into backup mode using the command RMX-LPREQ
     struct { unsigned long dur; unsigned long flags; } msg = {0/*endless*/,0/*backup*/};
     sendUbx(0x02, 0x41, &msg, sizeof(msg));
 }
@@ -103,7 +103,7 @@
     char ch;
     if (++o > len)                      return WAIT;
     if ('$' != pipe->next())            return NOT_FOUND;
-    // this needs to be extended by crc checking 
+    // This needs to be extended by crc checking 
     for (;;)
     {
         if (++o > len)                  return WAIT;
@@ -203,13 +203,13 @@
 
 const char* GnssParser::findNmeaItemPos(int ix, const char* start, const char* end)
 {
-    // find the start
+    // Find the start
     for (; (start < end) && (ix > 0); start ++)
     {
         if (*start == ',')
             ix --;
     }
-    // found and check bounds
+    // Found and check bounds
     if ((ix == 0) && (start < end) && 
         (*start != ',') && (*start != '*') && (*start != '\r') && (*start != '\n'))
         return start;
@@ -221,11 +221,11 @@
 {
     char* end = &buf[len];
     const char* pos = findNmeaItemPos(ix, buf, end);
-    // find the start
+    // Find the start
     if (!pos)
         return false;
     val = strtod(pos, &end);
-    // restore the last character
+    // Restore the last character
     return (end > pos);
 }
 
@@ -233,7 +233,7 @@
 {
     char* end = &buf[len];
     const char* pos = findNmeaItemPos(ix, buf, end);
-    // find the start
+    // Find the start
     if (!pos)
         return false;
     val = (int)strtol(pos, &end, base);
@@ -244,13 +244,13 @@
 {
     const char* end = &buf[len];
     const char* pos = findNmeaItemPos(ix, buf, end);
-    // find the start
+    // Find the start
     if (!pos)
         return false;
-    // skip leading spaces
+    // Skip leading spaces
     while ((pos < end) && isspace(*pos))
         pos++;
-    // check bound
+    // Check bound
     if ((pos < end) && 
         (*pos != ',') && (*pos != '*') && (*pos != '\r') && (*pos != '\n'))
     {
@@ -296,20 +296,25 @@
 
 bool GnssSerial::init(PinName pn)
 {
+    Timer timer;
+    int size;
+    
     // Unused (kept only for compatibility with the I2C version)
     (void)pn;
     
     // Power up and enable the module
     _powerOn();
 
-    // send a byte to wakup the device again
+    // Send a byte to wakup the device again
     putc(0xFF);
-    // wait until we get some bytes
-    int size = _pipeRx.size();
-    Timer timer;
+    // Wait until we get some bytes
+    size = _pipeRx.size();
     timer.start();
-    while ((100 > timer.read_ms()) && (size == _pipeRx.size()))
-        /* nothing / just wait */;
+    while ((timer.read_ms() < 1000) && (size == _pipeRx.size())) {
+        /* Nothing, just wait */
+    }
+    timer.stop();
+    
     return (size != _pipeRx.size());
 }
 
@@ -357,13 +362,13 @@
 
 int GnssI2C::getMessage(char* buf, int len)
 {
-    // fill the pipe
+    // Fill the pipe
     int sz = _pipe.free();
     if (sz) 
         sz = _get(buf, sz);
     if (sz) 
         _pipe.put(buf, sz);
-    // now parse it
+    // Now parse it
     return _getMessage(&_pipe, buf, len);   
 }
 
--- a/gnss.h	Sun Jun 11 13:45:56 2017 +0000
+++ b/gnss.h	Wed Jun 14 20:44:42 2017 +0100
@@ -33,10 +33,10 @@
 #endif
 
 #ifdef TARGET_UBLOX_C027
-#define GNSSEN   GPSEN
-#define GNSSTXD  GPSTXD
-#define GNSSRXD  GPSRXD
-#define GNSSBAUD GPSBAUD
+# define GNSSEN   GPSEN
+# define GNSSTXD  GPSTXD
+# define GNSSRXD  GPSRXD
+# define GNSSBAUD GPSBAUD
 #endif
 
 /** Basic GNSS parser class.