GPS GMS-6 Module
GPSGms6.cpp@0:7ef27b349b37, 2016-05-10 (annotated)
- Committer:
- nsrwsurasak
- Date:
- Tue May 10 06:33:57 2016 +0000
- Revision:
- 0:7ef27b349b37
- Child:
- 1:dceb4eaf697e
GPSGms6
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nsrwsurasak | 0:7ef27b349b37 | 1 | #include "mbed.h" |
nsrwsurasak | 0:7ef27b349b37 | 2 | #include "GPSGms6.h" |
nsrwsurasak | 0:7ef27b349b37 | 3 | #include <string> |
nsrwsurasak | 0:7ef27b349b37 | 4 | |
nsrwsurasak | 0:7ef27b349b37 | 5 | #define GET_GPRMC_SECTION_SIZE(state) (unsigned int)gprms_tbl[state].size |
nsrwsurasak | 0:7ef27b349b37 | 6 | #define GET_GPRMC_VARIABLE_ADDR(state) gprms_tbl[state].p_val |
nsrwsurasak | 0:7ef27b349b37 | 7 | #define GET_GPRMC_NEXT_STATE(state) (GPS_ProcessState)gprms_tbl[state+1].state |
nsrwsurasak | 0:7ef27b349b37 | 8 | |
nsrwsurasak | 0:7ef27b349b37 | 9 | |
nsrwsurasak | 0:7ef27b349b37 | 10 | GPRMC_Data_TypeDef m_gprmc; |
nsrwsurasak | 0:7ef27b349b37 | 11 | GPRMC_Data_TypeDef m_valid_gprmc; |
nsrwsurasak | 0:7ef27b349b37 | 12 | char m_RxBuf[RX_BUF_SIZE]; |
nsrwsurasak | 0:7ef27b349b37 | 13 | bool m_available; |
nsrwsurasak | 0:7ef27b349b37 | 14 | int m_index; |
nsrwsurasak | 0:7ef27b349b37 | 15 | Serial serial_gps(PA_9, PA_10); |
nsrwsurasak | 0:7ef27b349b37 | 16 | GPRMC_Tbl_TypeDef gprms_tbl[] = { |
nsrwsurasak | 0:7ef27b349b37 | 17 | // index , section size , variable |
nsrwsurasak | 0:7ef27b349b37 | 18 | {GPS_Process_Start , INVALID_VALUE ,(char *)INVALID_VALUE}, |
nsrwsurasak | 0:7ef27b349b37 | 19 | {GPS_Process_Header , HEADER_SIZE , m_gprmc.header}, |
nsrwsurasak | 0:7ef27b349b37 | 20 | {GPS_Process_Time , GPRMC_TIME_SIZE , m_gprmc.time}, |
nsrwsurasak | 0:7ef27b349b37 | 21 | {GPS_Process_Status , GPRMC_STATUS_SIZE , m_gprmc.status}, |
nsrwsurasak | 0:7ef27b349b37 | 22 | {GPS_Process_Latitude , GPRMC_LATITUDE_SIZE , m_gprmc.latitude}, |
nsrwsurasak | 0:7ef27b349b37 | 23 | {GPS_Process_Latitude_hemis , GPRMC_LATITUDE_HEMI_SIZE , m_gprmc.latitude_hemi}, |
nsrwsurasak | 0:7ef27b349b37 | 24 | {GPS_Process_Longitude , GPRMC_LONGITUDE_SIZE , m_gprmc.longitude}, |
nsrwsurasak | 0:7ef27b349b37 | 25 | {GPS_Process_Longitude_hemis , GPRMC_LONGITUDE_HEMI_SIZE , m_gprmc.longitude_hemi}, |
nsrwsurasak | 0:7ef27b349b37 | 26 | {GPS_Process_Speed , GPRMC_SPEED_SIZE , m_gprmc.speed}, |
nsrwsurasak | 0:7ef27b349b37 | 27 | {GPS_Process_Course , GPRMC_COURSE_SIZE , m_gprmc.course}, |
nsrwsurasak | 0:7ef27b349b37 | 28 | {GPS_Process_Date , GPRMC_DATE_SIZE , m_gprmc.date}, |
nsrwsurasak | 0:7ef27b349b37 | 29 | {GPS_Process_Magnetic , GPRMC_MAGNETIC_SIZE , m_gprmc.magnetic}, |
nsrwsurasak | 0:7ef27b349b37 | 30 | {GPS_Process_Magnetic_Dir , GPRMC_MAGNETIC_DIR_SIZE , m_gprmc.magnetic_dir}, |
nsrwsurasak | 0:7ef27b349b37 | 31 | {GPS_Process_Indicator , GPRMC_INDICATOR_SIZE , m_gprmc.indicator}, |
nsrwsurasak | 0:7ef27b349b37 | 32 | {GPS_Process_Complete ,INVALID_VALUE ,(char *)INVALID_VALUE} |
nsrwsurasak | 0:7ef27b349b37 | 33 | |
nsrwsurasak | 0:7ef27b349b37 | 34 | }; |
nsrwsurasak | 0:7ef27b349b37 | 35 | 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) |
nsrwsurasak | 0:7ef27b349b37 | 36 | { |
nsrwsurasak | 0:7ef27b349b37 | 37 | GPS_ProcessStatus status = GPS_Status_Valid; |
nsrwsurasak | 0:7ef27b349b37 | 38 | if (buf_index >= (buf_size - section_size)) { |
nsrwsurasak | 0:7ef27b349b37 | 39 | status = GPS_Status_NotEnough; |
nsrwsurasak | 0:7ef27b349b37 | 40 | } else if (buf[buf_index] == ',') { |
nsrwsurasak | 0:7ef27b349b37 | 41 | status = GPS_Status_Empty; |
nsrwsurasak | 0:7ef27b349b37 | 42 | memset(ret_value,' ', section_size); |
nsrwsurasak | 0:7ef27b349b37 | 43 | } else { |
nsrwsurasak | 0:7ef27b349b37 | 44 | unsigned int idx; |
nsrwsurasak | 0:7ef27b349b37 | 45 | // printf("\r\n state = %d =",state); |
nsrwsurasak | 0:7ef27b349b37 | 46 | for(idx = 0; idx < section_size; idx++) { |
nsrwsurasak | 0:7ef27b349b37 | 47 | ret_value[idx] = buf[buf_index + idx]; |
nsrwsurasak | 0:7ef27b349b37 | 48 | } |
nsrwsurasak | 0:7ef27b349b37 | 49 | |
nsrwsurasak | 0:7ef27b349b37 | 50 | } |
nsrwsurasak | 0:7ef27b349b37 | 51 | return status; |
nsrwsurasak | 0:7ef27b349b37 | 52 | |
nsrwsurasak | 0:7ef27b349b37 | 53 | } |
nsrwsurasak | 0:7ef27b349b37 | 54 | static void GPS_ProcessGpsData(char * buf, unsigned int size) |
nsrwsurasak | 0:7ef27b349b37 | 55 | { |
nsrwsurasak | 0:7ef27b349b37 | 56 | unsigned int index; |
nsrwsurasak | 0:7ef27b349b37 | 57 | unsigned int adv_index = 0; |
nsrwsurasak | 0:7ef27b349b37 | 58 | GPS_ProcessStatus status = GPS_Status_Valid; |
nsrwsurasak | 0:7ef27b349b37 | 59 | GPS_ProcessState state = GPS_Process_Start; |
nsrwsurasak | 0:7ef27b349b37 | 60 | for(index = 0; index < size; index++) { |
nsrwsurasak | 0:7ef27b349b37 | 61 | if (state == GPS_Process_Start) { |
nsrwsurasak | 0:7ef27b349b37 | 62 | if (buf[index] == '$') { |
nsrwsurasak | 0:7ef27b349b37 | 63 | state = GPS_Process_Header; |
nsrwsurasak | 0:7ef27b349b37 | 64 | } else { |
nsrwsurasak | 0:7ef27b349b37 | 65 | continue; |
nsrwsurasak | 0:7ef27b349b37 | 66 | } |
nsrwsurasak | 0:7ef27b349b37 | 67 | } else if (state == GPS_Process_Header) { |
nsrwsurasak | 0:7ef27b349b37 | 68 | if (index < (size - HEADER_SIZE)) { |
nsrwsurasak | 0:7ef27b349b37 | 69 | if (buf[index] == 'G' && |
nsrwsurasak | 0:7ef27b349b37 | 70 | buf[index+1] == 'P' && |
nsrwsurasak | 0:7ef27b349b37 | 71 | buf[index+2] == 'R' && |
nsrwsurasak | 0:7ef27b349b37 | 72 | buf[index+3] == 'M' && |
nsrwsurasak | 0:7ef27b349b37 | 73 | buf[index+4] == 'C' |
nsrwsurasak | 0:7ef27b349b37 | 74 | ) { |
nsrwsurasak | 0:7ef27b349b37 | 75 | unsigned int h_index; |
nsrwsurasak | 0:7ef27b349b37 | 76 | for(h_index = 0; h_index < HEADER_SIZE; h_index++) { |
nsrwsurasak | 0:7ef27b349b37 | 77 | m_gprmc.header[h_index] = buf[index + h_index]; |
nsrwsurasak | 0:7ef27b349b37 | 78 | } |
nsrwsurasak | 0:7ef27b349b37 | 79 | index += HEADER_SIZE; |
nsrwsurasak | 0:7ef27b349b37 | 80 | state = GPS_Process_Time; |
nsrwsurasak | 0:7ef27b349b37 | 81 | } |
nsrwsurasak | 0:7ef27b349b37 | 82 | } else { |
nsrwsurasak | 0:7ef27b349b37 | 83 | break; |
nsrwsurasak | 0:7ef27b349b37 | 84 | } |
nsrwsurasak | 0:7ef27b349b37 | 85 | |
nsrwsurasak | 0:7ef27b349b37 | 86 | } else { |
nsrwsurasak | 0:7ef27b349b37 | 87 | status = GPS_ProcessGprmcSection(state, buf ,index, size, GET_GPRMC_SECTION_SIZE(state), GET_GPRMC_VARIABLE_ADDR(state)); |
nsrwsurasak | 0:7ef27b349b37 | 88 | adv_index = GET_GPRMC_SECTION_SIZE(state); |
nsrwsurasak | 0:7ef27b349b37 | 89 | state = GET_GPRMC_NEXT_STATE(state) ; |
nsrwsurasak | 0:7ef27b349b37 | 90 | } |
nsrwsurasak | 0:7ef27b349b37 | 91 | |
nsrwsurasak | 0:7ef27b349b37 | 92 | |
nsrwsurasak | 0:7ef27b349b37 | 93 | if (status == GPS_Status_NotEnough || state == GPS_Process_Complete) { |
nsrwsurasak | 0:7ef27b349b37 | 94 | break; |
nsrwsurasak | 0:7ef27b349b37 | 95 | } else if (status == GPS_Status_Valid) { |
nsrwsurasak | 0:7ef27b349b37 | 96 | index += adv_index; |
nsrwsurasak | 0:7ef27b349b37 | 97 | } |
nsrwsurasak | 0:7ef27b349b37 | 98 | } |
nsrwsurasak | 0:7ef27b349b37 | 99 | |
nsrwsurasak | 0:7ef27b349b37 | 100 | if (m_gprmc.indicator[0] == (char)'A' && |
nsrwsurasak | 0:7ef27b349b37 | 101 | m_gprmc.indicator[0] == (char)'D' && |
nsrwsurasak | 0:7ef27b349b37 | 102 | m_gprmc.indicator[0] == (char)'E' |
nsrwsurasak | 0:7ef27b349b37 | 103 | ) { |
nsrwsurasak | 0:7ef27b349b37 | 104 | m_available= true; |
nsrwsurasak | 0:7ef27b349b37 | 105 | memcpy(&m_valid_gprmc, &m_gprmc , sizeof(m_gprmc)); |
nsrwsurasak | 0:7ef27b349b37 | 106 | } |
nsrwsurasak | 0:7ef27b349b37 | 107 | } |
nsrwsurasak | 0:7ef27b349b37 | 108 | |
nsrwsurasak | 0:7ef27b349b37 | 109 | |
nsrwsurasak | 0:7ef27b349b37 | 110 | void complete_callback() |
nsrwsurasak | 0:7ef27b349b37 | 111 | { |
nsrwsurasak | 0:7ef27b349b37 | 112 | GPS_ProcessGpsData(m_RxBuf, RX_BUF_SIZE); |
nsrwsurasak | 0:7ef27b349b37 | 113 | |
nsrwsurasak | 0:7ef27b349b37 | 114 | } |
nsrwsurasak | 0:7ef27b349b37 | 115 | void byte_callback() |
nsrwsurasak | 0:7ef27b349b37 | 116 | { |
nsrwsurasak | 0:7ef27b349b37 | 117 | // Note: you need to actually read from the serial to clear the RX interrupt |
nsrwsurasak | 0:7ef27b349b37 | 118 | //printf("%c", gps.getc()); |
nsrwsurasak | 0:7ef27b349b37 | 119 | m_RxBuf[m_index] = serial_gps.getc(); |
nsrwsurasak | 0:7ef27b349b37 | 120 | //printf("%c", m_RxBuf[m_index]); |
nsrwsurasak | 0:7ef27b349b37 | 121 | m_index++; |
nsrwsurasak | 0:7ef27b349b37 | 122 | if (m_index == RX_BUF_SIZE) { |
nsrwsurasak | 0:7ef27b349b37 | 123 | m_index = 0; |
nsrwsurasak | 0:7ef27b349b37 | 124 | complete_callback(); |
nsrwsurasak | 0:7ef27b349b37 | 125 | } |
nsrwsurasak | 0:7ef27b349b37 | 126 | // myled = !myled; |
nsrwsurasak | 0:7ef27b349b37 | 127 | } |
nsrwsurasak | 0:7ef27b349b37 | 128 | GPSGms6::GPSGms6() |
nsrwsurasak | 0:7ef27b349b37 | 129 | { |
nsrwsurasak | 0:7ef27b349b37 | 130 | |
nsrwsurasak | 0:7ef27b349b37 | 131 | m_index = 0; |
nsrwsurasak | 0:7ef27b349b37 | 132 | m_available = false; |
nsrwsurasak | 0:7ef27b349b37 | 133 | |
nsrwsurasak | 0:7ef27b349b37 | 134 | serial_gps.baud(9600); |
nsrwsurasak | 0:7ef27b349b37 | 135 | |
nsrwsurasak | 0:7ef27b349b37 | 136 | } |
nsrwsurasak | 0:7ef27b349b37 | 137 | void GPSGms6::start_GPS() |
nsrwsurasak | 0:7ef27b349b37 | 138 | { |
nsrwsurasak | 0:7ef27b349b37 | 139 | serial_gps.attach(&byte_callback); |
nsrwsurasak | 0:7ef27b349b37 | 140 | } |
nsrwsurasak | 0:7ef27b349b37 | 141 | GPRMC_Data_TypeDef GPSGms6::latestGPRMC() |
nsrwsurasak | 0:7ef27b349b37 | 142 | { |
nsrwsurasak | 0:7ef27b349b37 | 143 | return (m_gprmc); |
nsrwsurasak | 0:7ef27b349b37 | 144 | } |
nsrwsurasak | 0:7ef27b349b37 | 145 | GPRMC_Data_TypeDef GPSGms6::validGPRMC() |
nsrwsurasak | 0:7ef27b349b37 | 146 | { |
nsrwsurasak | 0:7ef27b349b37 | 147 | m_available = false; |
nsrwsurasak | 0:7ef27b349b37 | 148 | return (m_valid_gprmc); |
nsrwsurasak | 0:7ef27b349b37 | 149 | } |
nsrwsurasak | 0:7ef27b349b37 | 150 | bool GPSGms6::available() |
nsrwsurasak | 0:7ef27b349b37 | 151 | { |
nsrwsurasak | 0:7ef27b349b37 | 152 | return (m_available); |
nsrwsurasak | 0:7ef27b349b37 | 153 | } |
nsrwsurasak | 0:7ef27b349b37 | 154 | tm GPSGms6::UTCTime() |
nsrwsurasak | 0:7ef27b349b37 | 155 | { |
nsrwsurasak | 0:7ef27b349b37 | 156 | struct tm t; |
nsrwsurasak | 0:7ef27b349b37 | 157 | if (m_gprmc.date[0] != ' ' && m_gprmc.time[0] != ' ' ) |
nsrwsurasak | 0:7ef27b349b37 | 158 | { |
nsrwsurasak | 0:7ef27b349b37 | 159 | char str[3]; |
nsrwsurasak | 0:7ef27b349b37 | 160 | |
nsrwsurasak | 0:7ef27b349b37 | 161 | memcpy( str, &m_gprmc.time[4], 2 ); |
nsrwsurasak | 0:7ef27b349b37 | 162 | t.tm_sec = atoi(str); |
nsrwsurasak | 0:7ef27b349b37 | 163 | memcpy( str, &m_gprmc.time[2], 2 ); |
nsrwsurasak | 0:7ef27b349b37 | 164 | t.tm_min = atoi(str); |
nsrwsurasak | 0:7ef27b349b37 | 165 | memcpy( str, &m_gprmc.time[0], 2 ); |
nsrwsurasak | 0:7ef27b349b37 | 166 | t.tm_hour = atoi(str); |
nsrwsurasak | 0:7ef27b349b37 | 167 | |
nsrwsurasak | 0:7ef27b349b37 | 168 | memcpy( str, &m_gprmc.date[0], 2 ); |
nsrwsurasak | 0:7ef27b349b37 | 169 | t.tm_mday = atoi(str); |
nsrwsurasak | 0:7ef27b349b37 | 170 | |
nsrwsurasak | 0:7ef27b349b37 | 171 | memcpy( str, &m_gprmc.date[2], 2 ); |
nsrwsurasak | 0:7ef27b349b37 | 172 | t.tm_mon = atoi(str); |
nsrwsurasak | 0:7ef27b349b37 | 173 | |
nsrwsurasak | 0:7ef27b349b37 | 174 | memcpy( str, &m_gprmc.date[4], 2 ); |
nsrwsurasak | 0:7ef27b349b37 | 175 | t.tm_year = atoi(str); |
nsrwsurasak | 0:7ef27b349b37 | 176 | } |
nsrwsurasak | 0:7ef27b349b37 | 177 | else |
nsrwsurasak | 0:7ef27b349b37 | 178 | { |
nsrwsurasak | 0:7ef27b349b37 | 179 | t.tm_mday = 0; |
nsrwsurasak | 0:7ef27b349b37 | 180 | t.tm_mon = 0; |
nsrwsurasak | 0:7ef27b349b37 | 181 | t.tm_year = 0; |
nsrwsurasak | 0:7ef27b349b37 | 182 | } |
nsrwsurasak | 0:7ef27b349b37 | 183 | return (t); |
nsrwsurasak | 0:7ef27b349b37 | 184 | } |