GPS GMS-6 Module

Dependents:   RwSDCard_Xml_GPS

Revision:
0:7ef27b349b37
Child:
1:dceb4eaf697e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPSGms6.cpp	Tue May 10 06:33:57 2016 +0000
@@ -0,0 +1,184 @@
+#include "mbed.h"
+#include "GPSGms6.h"
+#include <string>
+
+#define GET_GPRMC_SECTION_SIZE(state)                   (unsigned int)gprms_tbl[state].size
+#define GET_GPRMC_VARIABLE_ADDR(state)                  gprms_tbl[state].p_val
+#define GET_GPRMC_NEXT_STATE(state)                     (GPS_ProcessState)gprms_tbl[state+1].state
+
+
+GPRMC_Data_TypeDef m_gprmc;
+GPRMC_Data_TypeDef m_valid_gprmc;
+char m_RxBuf[RX_BUF_SIZE];
+bool m_available;
+int m_index;
+Serial serial_gps(PA_9, PA_10);
+GPRMC_Tbl_TypeDef gprms_tbl[] = {
+    //          index                       , section size                       , variable
+    {GPS_Process_Start              , INVALID_VALUE              ,(char *)INVALID_VALUE},
+    {GPS_Process_Header             , HEADER_SIZE                , m_gprmc.header},
+    {GPS_Process_Time               , GPRMC_TIME_SIZE            , m_gprmc.time},
+    {GPS_Process_Status             , GPRMC_STATUS_SIZE          , m_gprmc.status},
+    {GPS_Process_Latitude           , GPRMC_LATITUDE_SIZE        , m_gprmc.latitude},
+    {GPS_Process_Latitude_hemis     , GPRMC_LATITUDE_HEMI_SIZE   , m_gprmc.latitude_hemi},
+    {GPS_Process_Longitude          , GPRMC_LONGITUDE_SIZE       , m_gprmc.longitude},
+    {GPS_Process_Longitude_hemis    , GPRMC_LONGITUDE_HEMI_SIZE  , m_gprmc.longitude_hemi},
+    {GPS_Process_Speed              , GPRMC_SPEED_SIZE           , m_gprmc.speed},
+    {GPS_Process_Course             , GPRMC_COURSE_SIZE          , m_gprmc.course},
+    {GPS_Process_Date               , GPRMC_DATE_SIZE            , m_gprmc.date},
+    {GPS_Process_Magnetic           , GPRMC_MAGNETIC_SIZE        , m_gprmc.magnetic},
+    {GPS_Process_Magnetic_Dir       , GPRMC_MAGNETIC_DIR_SIZE    , m_gprmc.magnetic_dir},
+    {GPS_Process_Indicator          , GPRMC_INDICATOR_SIZE       , m_gprmc.indicator},
+    {GPS_Process_Complete           ,INVALID_VALUE              ,(char *)INVALID_VALUE}
+
+};
+static GPS_ProcessStatus GPS_ProcessGprmcSection(GPS_ProcessState state,char * buf , unsigned int buf_index,unsigned int buf_size, unsigned int section_size, char * ret_value)
+{
+    GPS_ProcessStatus status = GPS_Status_Valid;
+    if (buf_index >= (buf_size - section_size)) {
+        status = GPS_Status_NotEnough;
+    } else if (buf[buf_index] == ',') {
+        status = GPS_Status_Empty;
+        memset(ret_value,' ', section_size);
+    } else {
+        unsigned int idx;
+//        printf("\r\n state = %d =",state);
+        for(idx = 0; idx < section_size; idx++) {
+            ret_value[idx] = buf[buf_index + idx];
+        }
+
+    }
+    return status;
+
+}
+static void GPS_ProcessGpsData(char * buf, unsigned int size)
+{
+    unsigned int index;
+    unsigned int adv_index = 0;
+    GPS_ProcessStatus status = GPS_Status_Valid;
+    GPS_ProcessState state = GPS_Process_Start;
+    for(index = 0; index < size; index++) {
+        if (state == GPS_Process_Start) {
+            if (buf[index] == '$') {
+                state = GPS_Process_Header;
+            } else {
+                continue;
+            }
+        } else if (state == GPS_Process_Header) {
+            if (index < (size - HEADER_SIZE)) {
+                if (buf[index] == 'G' &&
+                        buf[index+1] == 'P' &&
+                        buf[index+2] == 'R' &&
+                        buf[index+3] == 'M' &&
+                        buf[index+4] == 'C'
+                   ) {
+                    unsigned int h_index;
+                    for(h_index = 0; h_index < HEADER_SIZE; h_index++) {
+                        m_gprmc.header[h_index] = buf[index + h_index];
+                    }
+                    index += HEADER_SIZE;
+                    state = GPS_Process_Time;
+                }
+            } else {
+                break;
+            }
+
+        } else {
+            status = GPS_ProcessGprmcSection(state, buf ,index, size, GET_GPRMC_SECTION_SIZE(state), GET_GPRMC_VARIABLE_ADDR(state));
+            adv_index = GET_GPRMC_SECTION_SIZE(state);
+            state = GET_GPRMC_NEXT_STATE(state) ;
+        }
+
+
+        if (status == GPS_Status_NotEnough || state == GPS_Process_Complete) {
+            break;
+        } else if (status == GPS_Status_Valid) {
+            index += adv_index;
+        }
+    }
+
+    if (m_gprmc.indicator[0] == (char)'A' &&
+            m_gprmc.indicator[0] == (char)'D' &&
+            m_gprmc.indicator[0] == (char)'E'
+       ) {
+        m_available= true;
+        memcpy(&m_valid_gprmc, &m_gprmc , sizeof(m_gprmc));
+    }
+}
+
+
+void complete_callback()
+{
+    GPS_ProcessGpsData(m_RxBuf, RX_BUF_SIZE);
+
+}
+void byte_callback()
+{
+    // Note: you need to actually read from the serial to clear the RX interrupt
+    //printf("%c", gps.getc());
+    m_RxBuf[m_index] = serial_gps.getc();
+    //printf("%c", m_RxBuf[m_index]);
+    m_index++;
+    if (m_index == RX_BUF_SIZE) {
+        m_index = 0;
+        complete_callback();
+    }
+//    myled = !myled;
+}
+GPSGms6::GPSGms6()
+{
+
+    m_index = 0;
+    m_available = false;
+
+    serial_gps.baud(9600);
+
+}
+void GPSGms6::start_GPS()
+{
+    serial_gps.attach(&byte_callback);
+}
+GPRMC_Data_TypeDef GPSGms6::latestGPRMC()
+{
+    return (m_gprmc);
+}
+GPRMC_Data_TypeDef GPSGms6::validGPRMC()
+{
+    m_available = false;
+    return (m_valid_gprmc);
+}
+bool GPSGms6::available()
+{
+    return (m_available);
+}
+tm GPSGms6::UTCTime()
+{
+    struct tm t;
+    if (m_gprmc.date[0] != ' ' && m_gprmc.time[0] != ' ' )
+    {
+        char str[3];
+        
+        memcpy( str, &m_gprmc.time[4], 2 );
+        t.tm_sec =  atoi(str);
+        memcpy( str, &m_gprmc.time[2], 2 );
+        t.tm_min =  atoi(str);
+        memcpy( str, &m_gprmc.time[0], 2 );
+        t.tm_hour =  atoi(str);
+        
+        memcpy( str, &m_gprmc.date[0], 2 );
+        t.tm_mday =  atoi(str);
+        
+        memcpy( str, &m_gprmc.date[2], 2 );
+        t.tm_mon =  atoi(str);
+        
+        memcpy( str, &m_gprmc.date[4], 2 );
+        t.tm_year =  atoi(str);
+    }
+    else
+    {
+        t.tm_mday = 0;
+        t.tm_mon  = 0;
+        t.tm_year = 0;
+    }
+    return (t);
+}
\ No newline at end of file