Simple driver for GNSS functions on BG96 module.

Dependents:   mbed-os-example-cellular-gps-bg96

Note: this is early version

BG96 module needs to be already running to use this. Configuration only inside of this class. (hardcoded values)

Revision:
2:8b0663001935
Parent:
1:c3a5d3a0b437
Child:
3:98d27fc2eed5
--- a/BG96_GNSS.cpp	Wed Feb 19 16:34:28 2020 +0100
+++ b/BG96_GNSS.cpp	Tue Mar 03 14:27:09 2020 +0100
@@ -1,85 +1,133 @@
 #include "BG96_GNSS.h"
-#include "mbed.h"
-#include "mbed_debug.h"
 
 BG96_GNSS::BG96_GNSS()
 {
-    this->_serial = new UARTSerial(D1, D0, 115200); 
-
-    this->_parser = new ATCmdParser(_serial);
-    this->_parser->debug_on(false);
-    this->_parser->set_delimiter("\r\n");
-    this->_parser->set_timeout(1000);
+    _bg96_at_handler = CellularContext::get_default_instance()->get_device()->get_at_handler();
+    printf("[GPS] Created BG96 Object with AT HANDLER ADDR[%p].\r\n", _bg96_at_handler);
+    _bg96_instance = NULL;
 }
 
-int BG96_GNSS::check_if_ready(void)
-{
-    int counter = 0;
-    _parser->flush();
-
-    while ((counter++) < 10) {
-        if (_parser->recv("RDY")) {
-            printf("GPS ready\r\n");
-            return SUCCESS;
-        }
-        else if (_parser->send("AT") && _parser->recv("OK")) {
-            printf("GPS already available\r\n");
-            return SUCCESS;
-        }
-        thread_sleep_for(1);
+uint8_t BG96_GNSS::_get_instance()
+{   
+    if (_bg96_instance == NULL) {
+        _bg96_instance = _bg96_at_handler->get_instance(_bg96_at_handler->get_file_handle(), 
+                                    *_dummy_eventqueue, 1000, "\r\n", 100, false);
+        return SUCCESS;
     }
-
-    printf("GPS not ready\r\n");
-    return FAILURE;
+    else {
+        printf("[GPS] Failed while creating BG96 instance.\r\n");
+        return FAILURE;
+    }
 }
 
-int BG96_GNSS::set_gps_power(bool state)
+uint8_t BG96_GNSS::_close_instance()
 {
-    char _buf[32];
-
-    sprintf((char *)_buf, "%s", state ? "AT+QGPS=1" : "AT+QGPSEND");
-
-    if (_parser->send(_buf) && _parser->recv("OK")) {
-        printf("GPS Power: %s\r\n", state ? "On" : "Off");
+    if (_bg96_instance != NULL) {
+        _bg96_instance->close();
+        _bg96_instance = NULL;
+        printf("[GPS] Closed BG96 instance.\r\n");
         return SUCCESS;
-    } 
+    }
     else {
-        printf("Set GPS Power %s failed\r\n", state ? "On" : "Off");  
+        printf("[GPS] Failed while closing BG96 instance.\r\n");
         return FAILURE;
     }
 }
 
-int BG96_GNSS::get_gps_data(gps_data *data)
+uint8_t BG96_GNSS::set_gps_power(bool state)
+{
+    char _at_cmd[16];
+    uint8_t status = SUCCESS;
+
+    if (_get_instance() == SUCCESS) {
+        sprintf((char *)_at_cmd, "%s", state ? "AT+QGPS=1" : "AT+QGPSEND");
+        _bg96_instance->lock();
+        _bg96_instance->cmd_start(_at_cmd);
+        _bg96_instance->cmd_stop_read_resp();
+        if (_bg96_instance->get_last_error() != NSAPI_ERROR_OK) {
+            printf("[GPS] Failure while trying to change BG96 power.\r\n");
+            status = FAILURE;
+        } 
+        printf("[GPS] Powered ON the GPS module.\r\n");
+        _bg96_instance->unlock();
+        _close_instance();
+    }
+    else {
+        printf("[GPS] Failure while trying to get BG96 AT instance.\r\n");
+        status = FAILURE;
+    }
+    return status;
+}
+
+uint8_t BG96_GNSS::get_gps_data(gps_data *data)
 { 
-    bool ok = false;
-    char _buf[100];
-    int error;
+    uint8_t status = SUCCESS;
+
+    if (_get_instance() == SUCCESS) {
+        _bg96_instance->lock();
+        _bg96_instance->cmd_start("AT+QGPSLOC=2");
+        _bg96_instance->cmd_stop();
 
-    _parser->flush();
-    // first check if there is no error, possibly fixing is not done yet (error 516)
-    _parser->send((char*)"AT+QGPSLOC=2");
-    ok = _parser->recv("+CME ERROR: ");
-    if (ok) {
-        _parser->recv("%s\r\n", _buf);
-        sscanf(_buf,"%d", &error);   
-        printf("+CME ERROR: %d\r\n", error);
-        return FAILURE;
+        if (_bg96_instance->get_last_error() == NSAPI_ERROR_DEVICE_ERROR) {
+            printf("[GPS] Error while trying to get GPS data.\r\n");
+            status = FAILURE;
+        }
+        else {
+            _bg96_instance->set_stop_tag("OK");
+            _bg96_instance->resp_start();
+            if (_read_gps(data) == FAILURE) {
+                printf("[GPS] Error while trying to read GPS data.\r\n");
+                status = FAILURE;
+            }
+            _bg96_instance->resp_stop();
+        }
+        _bg96_instance->unlock();
+        _close_instance();
+    }
+    else {
+        printf("[GPS] Failure while trying to get BG96 AT instance.\r\n");
+        status = FAILURE;
+    }
+    return status;
+}
+
+uint8_t BG96_GNSS::_read_gps(gps_data *data)
+{
+    ssize_t bg96_read_size;
+    uint8_t status = SUCCESS;
+
+    bg96_read_size = _bg96_instance->read_string(data->utc, sizeof(data->utc)); // header
+    if (bg96_read_size == -1) {
+        status = FAILURE;
+    }
+    else {
+        // bg96_read_size = _bg96_instance->read_string(data->utc, sizeof(data->utc)); // time
+        bg96_read_size = _bg96_instance->read_string(data->lat, sizeof(data->lat)); // lat
+        bg96_read_size = _bg96_instance->read_string(data->lon, sizeof(data->lon)); // lon
+        bg96_read_size = _bg96_instance->read_string(data->hdop, sizeof(data->hdop)); // hdop
+        bg96_read_size = _bg96_instance->read_string(data->altitude, sizeof(data->altitude)); // altitude
+        bg96_read_size = _bg96_instance->read_string(data->fix, sizeof(data->fix)); // fix
+        bg96_read_size = _bg96_instance->read_string(data->cog, sizeof(data->cog)); // cog
+        bg96_read_size = _bg96_instance->read_string(data->spkm, sizeof(data->spkm)); // spkm
+        bg96_read_size = _bg96_instance->read_string(data->spkn, sizeof(data->spkn)); // spkn
+        bg96_read_size = _bg96_instance->read_string(data->date, sizeof(data->date)); // date
+        bg96_read_size = _bg96_instance->read_string(data->nsat, sizeof(data->nsat)); // nsat
     }
 
-    _parser->flush();
-    // if there is no error, repeat to save data
-    _parser->send((char*)"AT+QGPSLOC=2");
-    ok = _parser->recv("+QGPSLOC: ");
-    if (ok) {
-        _parser->recv("%s\r\n", _buf);
-        sscanf(_buf,"%f,%f,%f,%f,%f,%d,%f,%f,%f,%6s,%d",
-                &data->utc, &data->lat, &data->lon, &data->hdop,
-                &data->altitude, &data->fix, &data->cog,
-                &data->spkm, &data->spkn, data->date, &data->nsat);
-        ok = _parser->recv("OK");
-        return SUCCESS;
-    }
-    else {
-        return FAILURE;
-    }
+    return status;
 }
+
+void BG96_GNSS::print_gps_data(gps_data *data)
+{
+    printf("[GPS] Time: \tUTC:%s\r\n", data->utc);
+    printf("[GPS] Latitude: \tLAT:%s\r\n", data->lat);
+    printf("[GPS] Longitude: \tLON:%s\r\n", data->lon);
+    printf("[GPS] Horizontal: \tHDOP:%s\r\n", data->hdop);
+    printf("[GPS] Altitude: \tALT:%s\r\n", data->altitude);
+    printf("[GPS] Positioning: \tFIX:%s\r\n", data->fix);
+    printf("[GPS] Course over time: COG:%s\r\n", data->cog);
+    printf("[GPS] Speed km: \tSPKM:%s\r\n", data->spkm);
+    printf("[GPS] Speed knots: \tSPKN:%s\r\n", data->spkn);
+    printf("[GPS] Date: \t\tDATE:%s\r\n", data->date);
+    printf("[GPS] Satelites: \tNSAT:%s\r\n", data->nsat);
+}