BeRTOS
wingps.c
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 }