BeRTOS
|
00001 /* 00002 Copyright (c) 2005, David M Howard (daveh at dmh2000.com) 00003 All rights reserved. 00004 00005 This product is licensed for use and distribution under the BSD Open Source License. 00006 see the file COPYING for more details. 00007 00008 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00009 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00010 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00011 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00012 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 00013 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00014 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00015 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00016 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00017 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00018 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00019 00020 */ 00021 00022 /* 00023 ======================================================================================================== 00024 EXAMPLE : SETUP FOR GGA AND RMC SENTENCES WITH SERIAL IO FOR WIN32 00025 ======================================================================================================= 00026 */ 00027 #define WIN32_LEAN_AND_MEAN 00028 #include <windows.h> 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include <string.h> 00032 #include "nmeap.h" 00033 00035 static HANDLE openPort(const char *port,int baud) 00036 { 00037 HANDLE h; 00038 DCB dcb; 00039 COMMTIMEOUTS tmo; 00040 int status; 00041 00042 /* open the port */ 00043 h = CreateFile( port, 00044 GENERIC_READ | GENERIC_WRITE, 00045 0, 00046 0, 00047 OPEN_EXISTING, 00048 0, 00049 0); 00050 if (h == INVALID_HANDLE_VALUE) { 00051 /* quit on error */ 00052 return h; 00053 } 00054 00055 00056 /* read current configuration */ 00057 status = GetCommState(h,&dcb); 00058 if (status == 0) { 00059 CloseHandle(h); 00060 return INVALID_HANDLE_VALUE; 00061 } 00062 00063 /* set the baud rate and other parameters */ 00064 dcb.BaudRate = baud; 00065 dcb.ByteSize = 8; 00066 dcb.Parity = NOPARITY; 00067 dcb.StopBits = ONESTOPBIT; 00068 00069 /* set configuration */ 00070 status = SetCommState(h, &dcb); 00071 if (status == 0) { 00072 CloseHandle(h); 00073 return INVALID_HANDLE_VALUE; 00074 } 00075 00076 /* read timeout configuration */ 00077 status = GetCommTimeouts(h,&tmo); 00078 if (status == 0) { 00079 CloseHandle(h); 00080 return INVALID_HANDLE_VALUE; 00081 } 00082 00083 /* set to indefinite blocking */ 00084 tmo.ReadIntervalTimeout = 0; 00085 tmo.ReadTotalTimeoutConstant = 0; 00086 tmo.ReadTotalTimeoutMultiplier = 0; 00087 status = SetCommTimeouts(h,&tmo); 00088 if (status == 0) { 00089 CloseHandle(h); 00090 return INVALID_HANDLE_VALUE; 00091 } 00092 00093 return h; 00094 } 00095 00097 static int readPort(HANDLE h) 00098 { 00099 BOOL status; 00100 char ch; 00101 DWORD count; 00102 status = ReadFile(h,&ch,1,&count,0); 00103 if (status == 0) { 00104 return -1; 00105 } 00106 00107 return (int)ch; 00108 } 00109 00110 00111 static void closePort(HANDLE h) 00112 { 00113 CloseHandle(h); 00114 } 00115 00116 00118 static void printGps(nmeap_gga_t *gga,nmeap_rmc_t *rmc) 00119 { 00120 printf("%lu %lu %.6f %.6f %.0f %f %f %d %d\n", 00121 gga->time, 00122 rmc->date, 00123 gga->latitude , 00124 gga->longitude, 00125 gga->altitude , 00126 rmc->course, 00127 rmc->speed, 00128 gga->satellites, 00129 gga->quality 00130 ); 00131 } 00132 00133 /* ---------------------------------------------------------------------------------------*/ 00134 /* STEP 1 : allocate the data structures. be careful if you put them on the stack because */ 00135 /* they need to be live for the duration of the parser */ 00136 /* ---------------------------------------------------------------------------------------*/ 00137 static nmeap_context_t nmea; /* parser context */ 00138 static nmeap_gga_t gga; /* this is where the data from GGA messages will show up */ 00139 static nmeap_rmc_t rmc; /* this is where the data from RMC messages will show up */ 00140 static int user_data; /* user can pass in anything. typically it will be a pointer to some user data */ 00141 00142 int main(int argc,char *argv[]) 00143 { 00144 int status; 00145 char ch; 00146 const char *port; 00147 int baud; 00148 HANDLE h; 00149 00150 /* require both arguments */ 00151 if (argc != 3) { 00152 printf("%s <comport> <baud>\n",argv[0]); 00153 return 1; 00154 } 00155 00156 /* serial port argument */ 00157 port = argv[1]; 00158 00159 /* baud rate argument */ 00160 status = sscanf(argv[2],"%d",&baud); 00161 if (status != 1) { 00162 printf("%s <comport> <baud>\n",argv[0]); 00163 printf("invalid <baud> : %s\n",argv[2]); 00164 return 1; 00165 } 00166 00168 h = openPort(port,baud); 00169 if (h == INVALID_HANDLE_VALUE) { 00170 printf("can't open port : %s\n",port); 00171 return 1; 00172 } 00173 00174 /* ---------------------------------------*/ 00175 /*STEP 2 : initialize the nmea context */ 00176 /* ---------------------------------------*/ 00177 status = nmeap_init(&nmea,(void *)&user_data); 00178 if (status != 0) { 00179 printf("nmeap_init %d\n",status); 00180 exit(1); 00181 } 00182 00183 /* ---------------------------------------*/ 00184 /*STEP 3 : add standard GPGGA parser */ 00185 /* -------------------------------------- */ 00186 status = nmeap_addParser(&nmea,"GPGGA",nmeap_gpgga,0,&gga); 00187 if (status != 0) { 00188 printf("nmeap_add %d\n",status); 00189 exit(1); 00190 } 00191 00192 /* ---------------------------------------*/ 00193 /*STEP 4 : add standard GPRMC parser */ 00194 /* -------------------------------------- */ 00195 status = nmeap_addParser(&nmea,"GPRMC",nmeap_gprmc,0,&rmc); 00196 if (status != 0) { 00197 printf("nmeap_add %d\n",status); 00198 exit(1); 00199 } 00200 00201 /* ---------------------------------------*/ 00202 /*STEP 5 : process input until done */ 00203 /* -------------------------------------- */ 00204 for(;;) { 00205 /* ---------------------------------------*/ 00206 /*STEP 6 : get a byte at a time */ 00207 /* -------------------------------------- */ 00208 ch = readPort(h); 00209 if (ch <= 0) { 00210 break; 00211 } 00212 00213 /* --------------------------------------- */ 00214 /*STEP 7 : pass it to the parser */ 00215 /* status indicates whether a complete msg */ 00216 /* arrived for this byte */ 00217 /* NOTE : in addition to the return status */ 00218 /* the message callout will be fired when */ 00219 /* a complete message is processed */ 00220 /* --------------------------------------- */ 00221 status = nmeap_parse(&nmea,ch); 00222 00223 /* ---------------------------------------*/ 00224 /*STEP 8 : process the return code */ 00225 /* -------------------------------------- */ 00226 switch(status) { 00227 case NMEAP_GPGGA: 00228 /* GOT A GPGGA MESSAGE */ 00229 printGps(&gga,&rmc); 00230 break; 00231 case NMEAP_GPRMC: 00232 /* GOT A GPRMC MESSAGE */ 00233 printGps(&gga,&rmc); 00234 break; 00235 default: 00236 break; 00237 } 00238 } 00239 00240 /* close and quit */ 00241 closePort(h); 00242 00243 return 0; 00244 }