'****************************************************************
'                                                               *
'    Filename:	     GPS_LCD.bas                                *
'    Date:           11/18/2008                                 *
'    File Version:   0.01                                       *
'                                                               *
'    Author:         Peter Putnam                               *
'    email:          peter@ni6e.com                             *
'                                                               *
'****************************************************************
'
'This project decodes the RS-232 output from a GPS receiver and 
'displays the time and date values from the $GPRMC string on
'a 2-line x 8-character LCD.

'The top line displays hours, minutes and seconds of UTC time.

'If the GPS data is valid, denoted by the character "A" in array
'position 14, the lower line displays the UTC date. It displays 
'the warning "No Fix" if the fix data is invalid.

'The "No Fix" pin is reset to low if the fix is valid. If the fix
'becomes invalid, the LED pin is set high to turn on a warning LED.

'The message "No Data" is posted if the RS232 input fails at 
' any time.

' Compiled with SourceBoost BASIC for the PIC microprocessor

'****************************************************************
'                         16F688                                *
'                       +---------+                             *
'                     1 |         | 14                          *
'            5.0 V  ----+         +----  GND                    *
'                     2 |         | 13                          *
'           xtal    ----+         +----  RA0   "No Fix" LED     *
'                     3 |         | 12                          *
'           xtal    ----+         +----  RA1    RS              *
'                     4 |         | 11                          *
'              RA3  ----+         +----  RA2    E               *
'                     5 |         | 10                          *
'               RX  ->--+         +----  RC0    DB4             *
'                     6 |         | 9                           *
'               TX  -<--+         +----  RC1    DB5             *
'                     7 |         | 8                           *
'       DB7    RC3  ----+         +----  RC2    DB6             *
'                       |         |                             *
'                       +---------+                             *
'                                                               *
'****************************************************************


'	processor   now      16F917 for test
'   soon to be ported to   16F688


#pragma DATA 0x2007, _XT_OSC & _WDT_ON & _MCLRE_ON

'#pragma DATA 0x2007, _XT_OSC & _WDT_OFF & _MCLRE_OFF   for 16F688

#pragma CLOCK_FREQ 3686400


Sub main()

	call lcd_init()		                'Initialize the LCD to 4-bit format
	call lcd_clear()	                'Clear the LCD
	call usart_init()                   'Initialize the UART to 4800,n,8,1

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

	call lcd_putch(32)	                'Prints ASCII char " "
 	call lcd_putch(32)	                'Prints ASCII char " "
 	call lcd_putch(32)	                'Prints ASCII char " "	
  	call lcd_putch(78)	                'Prints ASCII char "N"
  	call lcd_putch(111)	                'Prints ASCII char "o"
	call lcd_line2()  	
 	call lcd_putch(32)	                'Prints ASCII char " "
 	call lcd_putch(32)	                'Prints ASCII char " " 	
 	call lcd_putch(68)	                'Prints ASCII char "D"
 	call lcd_putch(97)	                'Prints ASCII char "a"
 	call lcd_putch(116)	                'Prints ASCII char "t"
 	call lcd_putch(97)	                'Prints ASCII char "a"

loop1:

    v(0) = (call usart_rx())            '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 3                ' take next three characters after "$"
          v(i) = (call usart_rx())
          next i
    else goto loop1                     'Start over if first character is not "$"
    end if
'                                        If string "GPRMC" is found
'                                         then gather rest of string
'                                          only "P" and "R" are tested here
'
    if v(2) = 80 and v(3)= 82 then  'If this string is "GPRMC"
          for i = 4 to 58                   ' collect a total of 58 bytes
          v(i) = (call usart_rx())
          next i
    else goto loop1                     'Start over if string in not "GPRMC"
    end if


	call lcd_clear()	                'Clears the LCD

	call lcd_putch(v(7))	            'Print 10s of hours
	call lcd_putch(v(8))	            'Print  1s of hours
	call lcd_putch(58)	                'Print ASCII char ":"
	call lcd_putch(v(9))	            'Print 10s of minutes
	call lcd_putch(v(10))	            'Print  1s of minutes
	call lcd_putch(58)	                'Print ASCII char ":"
	call lcd_putch(v(11))	            'Print 10s of seconds
	call lcd_putch(v(12))	            'Print  1s of seconds


	call lcd_line2()	                'Put cursor at begining of LCD line 2

    if v (14) = 65 then                 'Array element 14 contains "A" if the fix is valid
          goto loop2                   ' for a valid fix, display the date on line 2
          else goto loop3              ' for an invalid fix, display "No Fix"
    end if    

loop2:

'    porta.2 = 0                         'Drives Port A.0 pin low, turns warning LED off
  	call lcd_putch(v(55))	            'Print 10s of months
  	call lcd_putch(v(56))	            'Print  1s of months
 	call lcd_putch(46)	                'Print ASCII char "."
 	call lcd_putch(v(53))	            'Print 10s of days
 	call lcd_putch(v(54))	            'Print  1s of days	
 	call lcd_putch(46)	                'Print ASCII char "."
	call lcd_putch(v(57))	            'Print 10s of year
	call lcd_putch(v(58))	            'Print  1s of year
	goto loop1

loop3:

'    porta.2 = 1                         'Drives Port A.0 pin high, turns warning LED on
 	call lcd_putch(32)	                'Prints ASCII char " "	
  	call lcd_putch(78)	                'Prints ASCII char "N"
  	call lcd_putch(111)	                'Prints ASCII char "o"
 	call lcd_putch(32)	                'Prints ASCII char " "
 	call lcd_putch(70)	                'Prints ASCII char "F"
 	call lcd_putch(105)	                'Prints ASCII char "i"
 	call lcd_putch(120)	                'Prints ASCII char "x"	
	goto loop1

End Sub