Lucy Luz / Mbed 2 deprecated RwSDCard_Xml_GPS

Dependencies:   FileManager GPSGms6 SDFileSystem mbed

Fork of 2545_SD_Card by Craig Evans

GPSGms6.cpp

Committer:
Lucyjungz
Date:
2016-05-09
Revision:
4:aa7ac2ac6913
Parent:
1:f911149acd35
Child:
6:a05ec997c496

File content as of revision 4:aa7ac2ac6913:

#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);
}