'****************************************************************
'                                                               *
'    Filename:	     GPS_LED.bas                                *
'    Date:           11/20/2008                                 *
'    File Version:   0.01                                       *
'                                                               *
'    Author:         Peter Putnam                               *
'    email:          peter@ni6e.com                             *
'                                                               *
'****************************************************************
'
'This project decodes the RS-232 output from a GPS receiver, using
' a sofware UART, and determines if the fix is valid.
'
'If the GPS data is valid, denoted by the character "A" in string
' $GPRMC, position 14, the "OK Fix" pin is set high to illuminate
' a green LED.
'
'If the receiver is providing serial data, but has not yet declared
' it valid or if a valid fix changes to invalid, a yellow "No Fix" 
' warning LED is illuminated.

'If the serial data stream is lost for more than two seconds, the
' watchdog timer resets the chip, setting the "No Data" pin to 
' illuminate a red LED.
'
'Compiled with SourceBoost BASIC for the PIC 12F629 microprocessor.
'
' GPIO.5 (pin 2) is used as the serial data input.
' GPIO.0 (pin 7) is used as the "No Data" LED output pin.
' GPIO.1 (pin 6) is used as the "No Fix"  LED output pin.
' GPIO.2 (pin 5) is used as the "OK Fix"  LED output pin.
'
'****************************************************************
'                                                               *
'                         12F629                                *
'                       +---------+                             *
'                     1 |         | 8                           *
'           +5.0 V  ----+         +----  GND                    *
'                     2 |         | 7                           *
'    Serial In GP5  >---+         +--->  GP0 "No Data" LED Out  *
'                     3 |         | 6                           *
'              GP4  <---+         +--->  GP1 "No Fix" LED Out   *
'                     4 |         | 5                           *
'              GP3  >---+         +--->  GP2 "OK Fix" LED Out   *
'                       |         |                             *
'                       +---------+                             *
'                                                               *
'****************************************************************
'Connect the anodes of the LEDs through 1K ohm resistors. The
' cathodes go to ground.
'
'Use of an input inverter such as an MC1489 or MAX232 is required 
' if true bipolar RS232 data is supplied.
'
' The simple inverter below provides that function.
'
'****************************************************************
'                                                               *
'                                 | +5 VDC      __    __ +5     *
'       __                        >               |  |          *
'      |  |    +V                 >  22K ohms     |__|   0V     *
'      |  |<-  0V                 >                             *
'    __|  |__  -V                 |--------> to GP5 (pin 2)     *
'                  10K ohms     |/ c                            *
'  RS232 From  >-----^^^^--.----|                               *
'   GPS RX                 |  b |\ e   2N3904 or Generic NPN    *
'                   |-->|--|      |                             *
'                   | 1N914       |                             *
'                   |             |                             *
'                  Gnd           Gnd                            *
'                                                               *
'                                                               *
'****************************************************************
'
'
'
#pragma DATA 0x2007, _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF

#pragma CLOCK_FREQ 4000000

Sub main()
'                                       'Each PIC processor has a unique
'                                       ' oscillator calibration byte. 
'                                       'This routine retrieves that byte
'                                       ' to assure 1% clock accuracy.
asm
{
call      0x3ff
movwf     _osccal
}

    dim i as byte                       'Array pointer
    dim v(15) as byte                   'Data array

    option_reg.7 = 0                    'Enable Global Weak Pull-Ups
    gpio = 00000001b                    'Start with "No Data" Red LED on
    cmcon = 0x07                        'Set GPIO<2:0> to digital IO                             
    trisio = 00101000b                  'Set GPIO<5,3> as inputs


loop1:

     v(0) = (call rs232_getch())        'Take any character into array

'                                       'Clear watchdog timer, data is flowing
asm
{
clrwdt
}

    if v(0) = 36 then                   'Search for "$" at beginning of string
          for i = 1 to 14               ' take next 14 characters if it is
          v(i) = (call rs232_getch())
          next i
    else goto loop1                     'Start over if first character is not "$"
    end if

'                                       '  Only "P" and "R" are tested
    if v(2) = 80 and v(3)= 82 then      'If this string is "GPRMC" and if
         if v (14) = 65 then            ' array element 14 contains "A" the fix is valid
             gpio = 00000100b           '  for a valid fix, turn on the "OK Fix" Green LED
             else gpio=00000010b        '  for an invalid fix, turn on the "No Fix" Yellow LED
         end if 
    else goto loop1                     'Start over if string is not "GPRMC"
    end if     

   goto loop1

End Sub