Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FileManager GPSGms6 SDFileSystem mbed
Fork of 2545_SD_Card by
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);
}
