GPS GMS-6 Module
GPSGms6.cpp
- Committer:
- nsrwsurasak
- Date:
- 2016-05-10
- Revision:
- 0:7ef27b349b37
- Child:
- 1:dceb4eaf697e
File content as of revision 0:7ef27b349b37:
#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); }