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
Revision 6:56eda66d585b, committed 2017-06-14
- 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
--- 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.