Frequency counter using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.
Dependencies: QEI DRV8830 PID ADT7410 TextLCD Frq_cuntr_Nucleo-F746ZG RingBuffer
Fork of Frequency_Counter_w_GPS_1PPS by
Please refer following.
/users/kenjiArai/notebook/frequency-counters/
GPS_rcvr/GPSrcvr.cpp@13:1041596c416c, 2016-11-23 (annotated)
- Committer:
- kenjiArai
- Date:
- Wed Nov 23 07:35:20 2016 +0000
- Revision:
- 13:1041596c416c
- Child:
- 15:ae0413277bc6
Frequency counter using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 13:1041596c416c | 1 | /* |
kenjiArai | 13:1041596c416c | 2 | * mbed Application program / GPS receiver control and 1PPS output |
kenjiArai | 13:1041596c416c | 3 | * |
kenjiArai | 13:1041596c416c | 4 | * Copyright (c) 2004,'09,'10,'16 Kenji Arai / JH1PJL |
kenjiArai | 13:1041596c416c | 5 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 13:1041596c416c | 6 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 13:1041596c416c | 7 | * Created: March 28th, 2004 Kenji Arai |
kenjiArai | 13:1041596c416c | 8 | * updated: July 25th, 2009 for PIC24USB |
kenjiArai | 13:1041596c416c | 9 | * updated: January 16th, 2010 change to GPS-GM318 |
kenjiArai | 13:1041596c416c | 10 | * updated: April 24th, 2010 for mbed / NXP LPC1768 |
kenjiArai | 13:1041596c416c | 11 | * Revised: Nomeber 20th, 2016 |
kenjiArai | 13:1041596c416c | 12 | */ |
kenjiArai | 13:1041596c416c | 13 | |
kenjiArai | 13:1041596c416c | 14 | // Include -------------------------------------------------------------------- |
kenjiArai | 13:1041596c416c | 15 | #include <string.h> |
kenjiArai | 13:1041596c416c | 16 | #include "mbed.h" |
kenjiArai | 13:1041596c416c | 17 | #include "RingBuffer.h" |
kenjiArai | 13:1041596c416c | 18 | #include "GPSrcvr.h" |
kenjiArai | 13:1041596c416c | 19 | |
kenjiArai | 13:1041596c416c | 20 | // Definition ----------------------------------------------------------------- |
kenjiArai | 13:1041596c416c | 21 | //#define USE_DEBUG |
kenjiArai | 13:1041596c416c | 22 | |
kenjiArai | 13:1041596c416c | 23 | #ifdef USE_DEBUG |
kenjiArai | 13:1041596c416c | 24 | #define U_DEBUGBAUD(x) pc.baud(x) |
kenjiArai | 13:1041596c416c | 25 | #define U_DEBUG(...) pc.printf(__VA_ARGS__) |
kenjiArai | 13:1041596c416c | 26 | #define DBG(c) pc.putc(c) |
kenjiArai | 13:1041596c416c | 27 | #else |
kenjiArai | 13:1041596c416c | 28 | #define U_DEBUGBAUD(x) {;} |
kenjiArai | 13:1041596c416c | 29 | #define U_DEBUG(...) {;} |
kenjiArai | 13:1041596c416c | 30 | #define DBG(c) {;} |
kenjiArai | 13:1041596c416c | 31 | #endif |
kenjiArai | 13:1041596c416c | 32 | |
kenjiArai | 13:1041596c416c | 33 | #define GSP_BUF_B (128 * 3) |
kenjiArai | 13:1041596c416c | 34 | #define GPS_BUF_S (128 * 2) |
kenjiArai | 13:1041596c416c | 35 | |
kenjiArai | 13:1041596c416c | 36 | // Object --------------------------------------------------------------------- |
kenjiArai | 13:1041596c416c | 37 | DigitalIn gps_rx(PD_2); // for checking GPS RX line |
kenjiArai | 13:1041596c416c | 38 | Serial gps(NC, PD_2); // GPS Data receive |
kenjiArai | 13:1041596c416c | 39 | RingBuffer rxbuf(1024); // can receive all information every one sec |
kenjiArai | 13:1041596c416c | 40 | |
kenjiArai | 13:1041596c416c | 41 | extern Serial pc; |
kenjiArai | 13:1041596c416c | 42 | |
kenjiArai | 13:1041596c416c | 43 | // RAM ------------------------------------------------------------------------ |
kenjiArai | 13:1041596c416c | 44 | bool gps_is_okay_flag; |
kenjiArai | 13:1041596c416c | 45 | uint8_t gps_ready; |
kenjiArai | 13:1041596c416c | 46 | uint8_t gps_status; |
kenjiArai | 13:1041596c416c | 47 | uint8_t gps_rmc_ready; |
kenjiArai | 13:1041596c416c | 48 | char GPS_Buffer[GSP_BUF_B]; //GPS data buffer |
kenjiArai | 13:1041596c416c | 49 | char MsgBuf_RMC[GPS_BUF_S]; |
kenjiArai | 13:1041596c416c | 50 | char MsgBuf_GSA[GPS_BUF_S]; |
kenjiArai | 13:1041596c416c | 51 | char MsgBuf_GGA[GPS_BUF_S]; |
kenjiArai | 13:1041596c416c | 52 | |
kenjiArai | 13:1041596c416c | 53 | // Function prototypes -------------------------------------------------------- |
kenjiArai | 13:1041596c416c | 54 | uint8_t check_gps_3d(void); |
kenjiArai | 13:1041596c416c | 55 | uint8_t check_gps_ready(void); |
kenjiArai | 13:1041596c416c | 56 | void get_time_and_date(struct tm *pt); |
kenjiArai | 13:1041596c416c | 57 | void getline_gps(void); |
kenjiArai | 13:1041596c416c | 58 | void gps_data_rcv(void); |
kenjiArai | 13:1041596c416c | 59 | void iGPSrcv_initialize(void); |
kenjiArai | 13:1041596c416c | 60 | int iGPS_readable(void); |
kenjiArai | 13:1041596c416c | 61 | int iGPS_getc(void); |
kenjiArai | 13:1041596c416c | 62 | |
kenjiArai | 13:1041596c416c | 63 | //////////////////////////////////////////////////////////////////////////////// |
kenjiArai | 13:1041596c416c | 64 | // Receive GPS data using Interrupt handler |
kenjiArai | 13:1041596c416c | 65 | // |
kenjiArai | 13:1041596c416c | 66 | // !!! Takes urgent and dirty solution by due to IRQ restriction |
kenjiArai | 13:1041596c416c | 67 | // on mbed library (reason is unknown as of today) |
kenjiArai | 13:1041596c416c | 68 | // reference source file:stm32f746xx.h |
kenjiArai | 13:1041596c416c | 69 | // under /mbed-dev/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F746ZG |
kenjiArai | 13:1041596c416c | 70 | //////////////////////////////////////////////////////////////////////////////// |
kenjiArai | 13:1041596c416c | 71 | // ------ Interrupt Function ------ |
kenjiArai | 13:1041596c416c | 72 | void rx_handler(void) |
kenjiArai | 13:1041596c416c | 73 | { |
kenjiArai | 13:1041596c416c | 74 | uint32_t reg = UART5->ISR; |
kenjiArai | 13:1041596c416c | 75 | if (reg && USART_ISR_RXNE){ // data is ready to read |
kenjiArai | 13:1041596c416c | 76 | UART5->ISR &= ~(USART_ISR_RXNE + USART_ISR_PE + USART_ISR_FE |
kenjiArai | 13:1041596c416c | 77 | + USART_ISR_NE + USART_ISR_ORE); |
kenjiArai | 13:1041596c416c | 78 | rxbuf.save((unsigned char)UART5->RDR); |
kenjiArai | 13:1041596c416c | 79 | } |
kenjiArai | 13:1041596c416c | 80 | } |
kenjiArai | 13:1041596c416c | 81 | |
kenjiArai | 13:1041596c416c | 82 | void iGPSrcv_initialize(void) |
kenjiArai | 13:1041596c416c | 83 | { |
kenjiArai | 13:1041596c416c | 84 | __disable_irq(); |
kenjiArai | 13:1041596c416c | 85 | UART5->CR1 &= ~(USART_CR1_TE + USART_CR1_TCIE + USART_CR1_TXEIE |
kenjiArai | 13:1041596c416c | 86 | + USART_CR1_PEIE + USART_CR1_IDLEIE); |
kenjiArai | 13:1041596c416c | 87 | UART5->CR1 |= (USART_CR1_RXNEIE + USART_CR1_RE + USART_CR1_UE); |
kenjiArai | 13:1041596c416c | 88 | NVIC_SetVector(UART5_IRQn, (uint32_t)rx_handler); |
kenjiArai | 13:1041596c416c | 89 | NVIC_ClearPendingIRQ(UART5_IRQn); |
kenjiArai | 13:1041596c416c | 90 | NVIC_EnableIRQ(UART5_IRQn); |
kenjiArai | 13:1041596c416c | 91 | __enable_irq(); |
kenjiArai | 13:1041596c416c | 92 | #if 0 |
kenjiArai | 13:1041596c416c | 93 | printf("UART5->CR1 0x%08x:0x%08x\r\n", &UART5->CR1, UART5->CR1); |
kenjiArai | 13:1041596c416c | 94 | printf("UART5->CR2 0x%08x:0x%08x\r\n", &UART5->CR2, UART5->CR2); |
kenjiArai | 13:1041596c416c | 95 | printf("UART5->CR3 0x%08x:0x%08x\r\n", &UART5->CR3, UART5->CR3); |
kenjiArai | 13:1041596c416c | 96 | printf("UART5->BRR 0x%08x:0x%08x\r\n", &UART5->BRR, UART5->BRR); |
kenjiArai | 13:1041596c416c | 97 | printf("UART5->GTPR 0x%08x:0x%08x\r\n", &UART5->GTPR, UART5->GTPR); |
kenjiArai | 13:1041596c416c | 98 | printf("UART5->RTOR 0x%08x:0x%08x\r\n", &UART5->RTOR, UART5->RTOR); |
kenjiArai | 13:1041596c416c | 99 | printf("UART5->RQR 0x%08x:0x%08x\r\n", &UART5->RQR, UART5->RQR); |
kenjiArai | 13:1041596c416c | 100 | printf("UART5->ISR 0x%08x:0x%08x\r\n", &UART5->ISR, UART5->ISR); |
kenjiArai | 13:1041596c416c | 101 | printf("UART5->ICR 0x%08x:0x%08x\r\n", &UART5->ICR, UART5->ICR); |
kenjiArai | 13:1041596c416c | 102 | #endif |
kenjiArai | 13:1041596c416c | 103 | } |
kenjiArai | 13:1041596c416c | 104 | |
kenjiArai | 13:1041596c416c | 105 | int iGPS_readable(void) |
kenjiArai | 13:1041596c416c | 106 | { |
kenjiArai | 13:1041596c416c | 107 | return rxbuf.check(); |
kenjiArai | 13:1041596c416c | 108 | } |
kenjiArai | 13:1041596c416c | 109 | |
kenjiArai | 13:1041596c416c | 110 | int iGPS_getc(void) |
kenjiArai | 13:1041596c416c | 111 | { |
kenjiArai | 13:1041596c416c | 112 | while(!rxbuf.check()){;} // wait receiving a character |
kenjiArai | 13:1041596c416c | 113 | return rxbuf.read(); |
kenjiArai | 13:1041596c416c | 114 | } |
kenjiArai | 13:1041596c416c | 115 | |
kenjiArai | 13:1041596c416c | 116 | //////////////////////////////////////////////////////////////////////////////// |
kenjiArai | 13:1041596c416c | 117 | // Parse GPS data |
kenjiArai | 13:1041596c416c | 118 | // Module Type: u-blux7 NEO-7M |
kenjiArai | 13:1041596c416c | 119 | //////////////////////////////////////////////////////////////////////////////// |
kenjiArai | 13:1041596c416c | 120 | // Get RMC & GAA data |
kenjiArai | 13:1041596c416c | 121 | void gps_data_rcv(void) |
kenjiArai | 13:1041596c416c | 122 | { |
kenjiArai | 13:1041596c416c | 123 | int8_t i; |
kenjiArai | 13:1041596c416c | 124 | time_t old_ave_sec[2]; |
kenjiArai | 13:1041596c416c | 125 | uint32_t diff = 0; |
kenjiArai | 13:1041596c416c | 126 | time_t seconds; |
kenjiArai | 13:1041596c416c | 127 | struct tm t_gps; |
kenjiArai | 13:1041596c416c | 128 | |
kenjiArai | 13:1041596c416c | 129 | seconds = time(NULL); |
kenjiArai | 13:1041596c416c | 130 | U_DEBUG("\r\nCurrent Time: %s\r\n", ctime(&seconds)); |
kenjiArai | 13:1041596c416c | 131 | old_ave_sec[0] = 0; |
kenjiArai | 13:1041596c416c | 132 | old_ave_sec[1] = 0; |
kenjiArai | 13:1041596c416c | 133 | // Wait long interval (every 1sec) |
kenjiArai | 13:1041596c416c | 134 | for (uint32_t i = 0; i < 100000; i++){ |
kenjiArai | 13:1041596c416c | 135 | if (gps_rx == 0){ |
kenjiArai | 13:1041596c416c | 136 | i = 0; |
kenjiArai | 13:1041596c416c | 137 | } |
kenjiArai | 13:1041596c416c | 138 | } |
kenjiArai | 13:1041596c416c | 139 | U_DEBUG("GPS line is Hi\r\n"); |
kenjiArai | 13:1041596c416c | 140 | // Clear GPS RX line errors(over run) |
kenjiArai | 13:1041596c416c | 141 | UART5->ICR = 0; |
kenjiArai | 13:1041596c416c | 142 | UART5->CR1 = 0; |
kenjiArai | 13:1041596c416c | 143 | UART5->CR1 = 5; |
kenjiArai | 13:1041596c416c | 144 | iGPSrcv_initialize(); |
kenjiArai | 13:1041596c416c | 145 | U_DEBUG("Start GPS!!"); |
kenjiArai | 13:1041596c416c | 146 | gps_is_okay_flag = false; |
kenjiArai | 13:1041596c416c | 147 | while(true) { |
kenjiArai | 13:1041596c416c | 148 | getline_gps(); // Get GPS data from UART |
kenjiArai | 13:1041596c416c | 149 | if (strncmp(GPS_Buffer, "$GPRMC",6) == 0) { |
kenjiArai | 13:1041596c416c | 150 | for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to RMC buffer |
kenjiArai | 13:1041596c416c | 151 | MsgBuf_RMC[i] = GPS_Buffer[i]; |
kenjiArai | 13:1041596c416c | 152 | } |
kenjiArai | 13:1041596c416c | 153 | MsgBuf_RMC[i+1] = 0; |
kenjiArai | 13:1041596c416c | 154 | #if 0 |
kenjiArai | 13:1041596c416c | 155 | U_DEBUG("Get GPRMC\r\n"); |
kenjiArai | 13:1041596c416c | 156 | #else |
kenjiArai | 13:1041596c416c | 157 | if (gps_is_okay_flag == false){ |
kenjiArai | 13:1041596c416c | 158 | pc.printf("GPRMC,"); |
kenjiArai | 13:1041596c416c | 159 | } |
kenjiArai | 13:1041596c416c | 160 | #endif |
kenjiArai | 13:1041596c416c | 161 | if (gps_ready == 3) { |
kenjiArai | 13:1041596c416c | 162 | U_DEBUG("3D condition\r\n"); |
kenjiArai | 13:1041596c416c | 163 | get_time_and_date(&t_gps); |
kenjiArai | 13:1041596c416c | 164 | seconds = mktime(&t_gps); |
kenjiArai | 13:1041596c416c | 165 | if (old_ave_sec[0] == 0){ |
kenjiArai | 13:1041596c416c | 166 | old_ave_sec[0] = seconds; |
kenjiArai | 13:1041596c416c | 167 | } else if (old_ave_sec[1] == 0){ |
kenjiArai | 13:1041596c416c | 168 | old_ave_sec[1] = seconds; |
kenjiArai | 13:1041596c416c | 169 | } else { |
kenjiArai | 13:1041596c416c | 170 | if (old_ave_sec[0] >= old_ave_sec[1]){ |
kenjiArai | 13:1041596c416c | 171 | diff = old_ave_sec[0] - old_ave_sec[1]; |
kenjiArai | 13:1041596c416c | 172 | } else { |
kenjiArai | 13:1041596c416c | 173 | diff = old_ave_sec[1] - old_ave_sec[0]; |
kenjiArai | 13:1041596c416c | 174 | } |
kenjiArai | 13:1041596c416c | 175 | if (diff > 100 ){ |
kenjiArai | 13:1041596c416c | 176 | old_ave_sec[0] = seconds; |
kenjiArai | 13:1041596c416c | 177 | old_ave_sec[1] = 0; |
kenjiArai | 13:1041596c416c | 178 | } else { |
kenjiArai | 13:1041596c416c | 179 | if (old_ave_sec[0] > old_ave_sec[1]){ |
kenjiArai | 13:1041596c416c | 180 | diff = seconds - old_ave_sec[0]; |
kenjiArai | 13:1041596c416c | 181 | if (diff < 100){ |
kenjiArai | 13:1041596c416c | 182 | old_ave_sec[1] = seconds; |
kenjiArai | 13:1041596c416c | 183 | } |
kenjiArai | 13:1041596c416c | 184 | } else { |
kenjiArai | 13:1041596c416c | 185 | diff = seconds - old_ave_sec[1]; |
kenjiArai | 13:1041596c416c | 186 | if (diff < 100){ |
kenjiArai | 13:1041596c416c | 187 | old_ave_sec[0] = seconds; |
kenjiArai | 13:1041596c416c | 188 | } |
kenjiArai | 13:1041596c416c | 189 | } |
kenjiArai | 13:1041596c416c | 190 | set_time(seconds); |
kenjiArai | 13:1041596c416c | 191 | U_DEBUG("Set time and GPS is okay!\r\n"); |
kenjiArai | 13:1041596c416c | 192 | gps_is_okay_flag = true; |
kenjiArai | 13:1041596c416c | 193 | } |
kenjiArai | 13:1041596c416c | 194 | } |
kenjiArai | 13:1041596c416c | 195 | } |
kenjiArai | 13:1041596c416c | 196 | } else if (strncmp(GPS_Buffer, "$GPGSA",6) == 0) { |
kenjiArai | 13:1041596c416c | 197 | for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to GSA buffer |
kenjiArai | 13:1041596c416c | 198 | MsgBuf_GSA[i] = GPS_Buffer[i]; |
kenjiArai | 13:1041596c416c | 199 | } |
kenjiArai | 13:1041596c416c | 200 | MsgBuf_GSA[i+1] = 0; |
kenjiArai | 13:1041596c416c | 201 | gps_ready = check_gps_3d(); |
kenjiArai | 13:1041596c416c | 202 | #if 0 |
kenjiArai | 13:1041596c416c | 203 | U_DEBUG("Get GPGSA\r\n"); |
kenjiArai | 13:1041596c416c | 204 | #else |
kenjiArai | 13:1041596c416c | 205 | if (gps_is_okay_flag == false){ |
kenjiArai | 13:1041596c416c | 206 | pc.printf("GPGSA,"); |
kenjiArai | 13:1041596c416c | 207 | } |
kenjiArai | 13:1041596c416c | 208 | #endif |
kenjiArai | 13:1041596c416c | 209 | } else if (strncmp(GPS_Buffer, "$GPGGA",6) == 0) { |
kenjiArai | 13:1041596c416c | 210 | for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to GGA buffer |
kenjiArai | 13:1041596c416c | 211 | MsgBuf_GGA[i] = GPS_Buffer[i]; |
kenjiArai | 13:1041596c416c | 212 | } |
kenjiArai | 13:1041596c416c | 213 | MsgBuf_GGA[i+1] = 0; |
kenjiArai | 13:1041596c416c | 214 | gps_status = check_gps_ready(); |
kenjiArai | 13:1041596c416c | 215 | #if 0 |
kenjiArai | 13:1041596c416c | 216 | U_DEBUG("Get GPGGA\r\n"); |
kenjiArai | 13:1041596c416c | 217 | #else |
kenjiArai | 13:1041596c416c | 218 | if (gps_is_okay_flag == false){ |
kenjiArai | 13:1041596c416c | 219 | pc.printf("GPGGA,"); |
kenjiArai | 13:1041596c416c | 220 | } |
kenjiArai | 13:1041596c416c | 221 | #endif |
kenjiArai | 13:1041596c416c | 222 | } |
kenjiArai | 13:1041596c416c | 223 | } |
kenjiArai | 13:1041596c416c | 224 | } |
kenjiArai | 13:1041596c416c | 225 | |
kenjiArai | 13:1041596c416c | 226 | bool check_gps_is_okay() |
kenjiArai | 13:1041596c416c | 227 | { |
kenjiArai | 13:1041596c416c | 228 | return gps_is_okay_flag; |
kenjiArai | 13:1041596c416c | 229 | } |
kenjiArai | 13:1041596c416c | 230 | |
kenjiArai | 13:1041596c416c | 231 | // Get line of data from GPS |
kenjiArai | 13:1041596c416c | 232 | void getline_gps(void) |
kenjiArai | 13:1041596c416c | 233 | { |
kenjiArai | 13:1041596c416c | 234 | char *p = GPS_Buffer; |
kenjiArai | 13:1041596c416c | 235 | |
kenjiArai | 13:1041596c416c | 236 | #if 1 |
kenjiArai | 13:1041596c416c | 237 | while (iGPS_getc() != '$'){;} |
kenjiArai | 13:1041596c416c | 238 | #else |
kenjiArai | 13:1041596c416c | 239 | while (iGPS_getc() != '$') { |
kenjiArai | 13:1041596c416c | 240 | Thread::yield(); |
kenjiArai | 13:1041596c416c | 241 | } |
kenjiArai | 13:1041596c416c | 242 | #endif |
kenjiArai | 13:1041596c416c | 243 | *p++ = '$'; |
kenjiArai | 13:1041596c416c | 244 | #if 1 |
kenjiArai | 13:1041596c416c | 245 | U_DEBUG("\r\n"); |
kenjiArai | 13:1041596c416c | 246 | #else |
kenjiArai | 13:1041596c416c | 247 | pc.printf("\r\n"); |
kenjiArai | 13:1041596c416c | 248 | #endif |
kenjiArai | 13:1041596c416c | 249 | for (char i= 0;i < 150;i++){ |
kenjiArai | 13:1041596c416c | 250 | *p = iGPS_getc(); |
kenjiArai | 13:1041596c416c | 251 | #if 1 |
kenjiArai | 13:1041596c416c | 252 | DBG(*p); |
kenjiArai | 13:1041596c416c | 253 | #else |
kenjiArai | 13:1041596c416c | 254 | pc.putc(*p); |
kenjiArai | 13:1041596c416c | 255 | #endif |
kenjiArai | 13:1041596c416c | 256 | if (*p == '\r'){ |
kenjiArai | 13:1041596c416c | 257 | *++p = '\n'; |
kenjiArai | 13:1041596c416c | 258 | *++p = 0; |
kenjiArai | 13:1041596c416c | 259 | *++p = 0; |
kenjiArai | 13:1041596c416c | 260 | U_DEBUG("Get one GPS data\r\n"); |
kenjiArai | 13:1041596c416c | 261 | return; |
kenjiArai | 13:1041596c416c | 262 | } else { |
kenjiArai | 13:1041596c416c | 263 | p++; |
kenjiArai | 13:1041596c416c | 264 | } |
kenjiArai | 13:1041596c416c | 265 | } |
kenjiArai | 13:1041596c416c | 266 | *++p = 0; |
kenjiArai | 13:1041596c416c | 267 | *++p = 0; |
kenjiArai | 13:1041596c416c | 268 | } |
kenjiArai | 13:1041596c416c | 269 | |
kenjiArai | 13:1041596c416c | 270 | // ASCII to hex |
kenjiArai | 13:1041596c416c | 271 | uint8_t hex(char c){ |
kenjiArai | 13:1041596c416c | 272 | if(c<= '/') return( ERR ); |
kenjiArai | 13:1041596c416c | 273 | if(((c -= '0')<= 9 || 10 <= ( c -= 'A' - '0' - 10)) && c <= 15) { |
kenjiArai | 13:1041596c416c | 274 | return((uint8_t)c); |
kenjiArai | 13:1041596c416c | 275 | } |
kenjiArai | 13:1041596c416c | 276 | return(ERR); |
kenjiArai | 13:1041596c416c | 277 | } |
kenjiArai | 13:1041596c416c | 278 | |
kenjiArai | 13:1041596c416c | 279 | // Search next ',' (comma) |
kenjiArai | 13:1041596c416c | 280 | char *next_comma( char *p ){ |
kenjiArai | 13:1041596c416c | 281 | while (1) { |
kenjiArai | 13:1041596c416c | 282 | if ( *p== ',' ) { |
kenjiArai | 13:1041596c416c | 283 | return ++p; |
kenjiArai | 13:1041596c416c | 284 | } else if ( *p == 0 ) { |
kenjiArai | 13:1041596c416c | 285 | return (char*)-1; |
kenjiArai | 13:1041596c416c | 286 | } else { |
kenjiArai | 13:1041596c416c | 287 | p++; |
kenjiArai | 13:1041596c416c | 288 | } |
kenjiArai | 13:1041596c416c | 289 | } |
kenjiArai | 13:1041596c416c | 290 | } |
kenjiArai | 13:1041596c416c | 291 | |
kenjiArai | 13:1041596c416c | 292 | // 2 digits ASCII char to one byte hex |
kenjiArai | 13:1041596c416c | 293 | unsigned char change_acii_hex( char*p ){ |
kenjiArai | 13:1041596c416c | 294 | unsigned char c; |
kenjiArai | 13:1041596c416c | 295 | |
kenjiArai | 13:1041596c416c | 296 | c = hex(*p++); /* No concern ERR condition! */ |
kenjiArai | 13:1041596c416c | 297 | c = (c * 10) + hex(*p++); |
kenjiArai | 13:1041596c416c | 298 | return c; |
kenjiArai | 13:1041596c416c | 299 | } |
kenjiArai | 13:1041596c416c | 300 | |
kenjiArai | 13:1041596c416c | 301 | // Skip number of comma |
kenjiArai | 13:1041596c416c | 302 | char *num_of_comma( char *p, int8_t n ){ |
kenjiArai | 13:1041596c416c | 303 | for (; n> 0; n--) { |
kenjiArai | 13:1041596c416c | 304 | if ( (p = next_comma(p)) == (char*) -1 ) { |
kenjiArai | 13:1041596c416c | 305 | return (char*)-1; |
kenjiArai | 13:1041596c416c | 306 | } |
kenjiArai | 13:1041596c416c | 307 | } |
kenjiArai | 13:1041596c416c | 308 | return p; |
kenjiArai | 13:1041596c416c | 309 | } |
kenjiArai | 13:1041596c416c | 310 | |
kenjiArai | 13:1041596c416c | 311 | // Get GPS status (1=Not fix, 2=2D, 3=3D) |
kenjiArai | 13:1041596c416c | 312 | uint8_t check_gps_3d(void){ |
kenjiArai | 13:1041596c416c | 313 | char *p; |
kenjiArai | 13:1041596c416c | 314 | uint8_t x; |
kenjiArai | 13:1041596c416c | 315 | uint8_t d; |
kenjiArai | 13:1041596c416c | 316 | |
kenjiArai | 13:1041596c416c | 317 | // pick-up time |
kenjiArai | 13:1041596c416c | 318 | p = MsgBuf_GSA; |
kenjiArai | 13:1041596c416c | 319 | p = num_of_comma(p,1); // skip ',' |
kenjiArai | 13:1041596c416c | 320 | // reach to "Position Fix Indicator" |
kenjiArai | 13:1041596c416c | 321 | if (*p == 'A') { |
kenjiArai | 13:1041596c416c | 322 | ++p; //',' |
kenjiArai | 13:1041596c416c | 323 | ++p; // 1 or 2 or 3 |
kenjiArai | 13:1041596c416c | 324 | d = hex(*p++); |
kenjiArai | 13:1041596c416c | 325 | if (d != ERR) { |
kenjiArai | 13:1041596c416c | 326 | x = d; |
kenjiArai | 13:1041596c416c | 327 | } else { |
kenjiArai | 13:1041596c416c | 328 | x = 1; |
kenjiArai | 13:1041596c416c | 329 | } |
kenjiArai | 13:1041596c416c | 330 | } else { |
kenjiArai | 13:1041596c416c | 331 | x = 1; |
kenjiArai | 13:1041596c416c | 332 | } |
kenjiArai | 13:1041596c416c | 333 | return x; |
kenjiArai | 13:1041596c416c | 334 | } |
kenjiArai | 13:1041596c416c | 335 | |
kenjiArai | 13:1041596c416c | 336 | // Get GPS status and number of satelites |
kenjiArai | 13:1041596c416c | 337 | uint8_t check_gps_ready(void){ |
kenjiArai | 13:1041596c416c | 338 | char *p; |
kenjiArai | 13:1041596c416c | 339 | uint8_t x; |
kenjiArai | 13:1041596c416c | 340 | uint8_t d; |
kenjiArai | 13:1041596c416c | 341 | |
kenjiArai | 13:1041596c416c | 342 | // pick-up time |
kenjiArai | 13:1041596c416c | 343 | p = MsgBuf_GGA; |
kenjiArai | 13:1041596c416c | 344 | p = num_of_comma(p,6); // skip ',' |
kenjiArai | 13:1041596c416c | 345 | // reach to "Position Fix Indicator" |
kenjiArai | 13:1041596c416c | 346 | if (*p == '1' || *p == '2') { |
kenjiArai | 13:1041596c416c | 347 | ++p; //',' |
kenjiArai | 13:1041596c416c | 348 | ++p; // Number |
kenjiArai | 13:1041596c416c | 349 | d = hex(*p++); |
kenjiArai | 13:1041596c416c | 350 | if (d != ERR) { |
kenjiArai | 13:1041596c416c | 351 | x = d * 10; |
kenjiArai | 13:1041596c416c | 352 | x += (uint32_t)hex(*p++); |
kenjiArai | 13:1041596c416c | 353 | if (*p != ',') { |
kenjiArai | 13:1041596c416c | 354 | x = 0; |
kenjiArai | 13:1041596c416c | 355 | } |
kenjiArai | 13:1041596c416c | 356 | } else { |
kenjiArai | 13:1041596c416c | 357 | x = 0; |
kenjiArai | 13:1041596c416c | 358 | } |
kenjiArai | 13:1041596c416c | 359 | } else { |
kenjiArai | 13:1041596c416c | 360 | x = 0; |
kenjiArai | 13:1041596c416c | 361 | } |
kenjiArai | 13:1041596c416c | 362 | return x; |
kenjiArai | 13:1041596c416c | 363 | } |
kenjiArai | 13:1041596c416c | 364 | |
kenjiArai | 13:1041596c416c | 365 | // Get time(UTC) from GPS data |
kenjiArai | 13:1041596c416c | 366 | void get_time_and_date(struct tm *pt){ |
kenjiArai | 13:1041596c416c | 367 | char *p; |
kenjiArai | 13:1041596c416c | 368 | |
kenjiArai | 13:1041596c416c | 369 | p = MsgBuf_RMC; |
kenjiArai | 13:1041596c416c | 370 | p = num_of_comma(p,1); /* skip one ',' */ |
kenjiArai | 13:1041596c416c | 371 | pt->tm_hour = change_acii_hex(p); |
kenjiArai | 13:1041596c416c | 372 | p += 2; |
kenjiArai | 13:1041596c416c | 373 | pt->tm_min = change_acii_hex(p); |
kenjiArai | 13:1041596c416c | 374 | p += 2; |
kenjiArai | 13:1041596c416c | 375 | pt->tm_sec = change_acii_hex(p); |
kenjiArai | 13:1041596c416c | 376 | p = MsgBuf_RMC; |
kenjiArai | 13:1041596c416c | 377 | p = num_of_comma(p,9); /* skip one ',' */ |
kenjiArai | 13:1041596c416c | 378 | pt->tm_mday = change_acii_hex(p); |
kenjiArai | 13:1041596c416c | 379 | p += 2; |
kenjiArai | 13:1041596c416c | 380 | pt->tm_mon = change_acii_hex(p) - 1; |
kenjiArai | 13:1041596c416c | 381 | p += 2; |
kenjiArai | 13:1041596c416c | 382 | pt->tm_year = change_acii_hex(p) + 100; |
kenjiArai | 13:1041596c416c | 383 | } |
kenjiArai | 13:1041596c416c | 384 |