/**************************************************************
        Schemat podłączeń programowanego układu
                       +----v----+
                 MCLR [| 1     28|] VDD
                      [| 2     27|] VSS
                      [| 3     26|] RB15 -> DB4        
                      [| 4     25|] RB14 -> DB5
                      [| 5     24|] RB13 -> DB6
GPS TX -> RP2 (U2RXR) [| 6     23|] 
                      [| 7     22|] RB11 -> DB7
                  VSS [| 8     21|] RB10 -> RS
       (8 MHz) / OSCI [| 9     20|] VCAP/VDDCORE
               \ OSCO [|10     19|] DISVREG
                      [|11     18|] RB9 -> EN
                      [|12     17|] 
                  VDD [|13     16|]  
                      [|14     15|] 
                       +---------+
                     PIC24FJ64GB002
***************************************************************/
#include <p24Fxxxx.h>
//definiujemy szybkość oscylatora dla funkcji __delay_
#define FCY 16000000UL 
//biblioteka z funkcjami __delay_us i __delay_ms
#include <libpic30.h>

//ustawienia bitów konfiguracyjnych
//1. 
//FWDTEN_OFF - Watchdog wyłączony
//JTAGEN_OFF - JTAG wyłączony
_CONFIG1(FWDTEN_OFF & JTAGEN_OFF)
//2.
//FNOSC_PRIPLL - układ taktowany zewnętrznym oscylatorem z pętlą PLL
//POSCMOD_XT - częstotliwość taktowania oscylatora 8 MHz
//PLLDIV_DIV2 - konieczność podzielenia przez 2 dla modułu USB PLL
_CONFIG2(FNOSC_PRIPLL & POSCMOD_XT & PLLDIV_DIV2)
//////////////////////////////////////
#define TRIS_RS_LCD   TRISBbits.TRISB10
#define TRIS_EN_LCD   TRISBbits.TRISB9
#define TRIS_DB4_LCD  TRISBbits.TRISB15
#define TRIS_DB5_LCD  TRISBbits.TRISB14
#define TRIS_DB6_LCD  TRISBbits.TRISB13
#define TRIS_DB7_LCD  TRISBbits.TRISB11

#define RS_LCD   LATBbits.LATB10
#define EN_LCD   LATBbits.LATB9
#define DB4_LCD  LATBbits.LATB15
#define DB5_LCD  LATBbits.LATB14
#define DB6_LCD  LATBbits.LATB13
#define DB7_LCD  LATBbits.LATB11

#include "lcd.h"
//////////////////////////////////////
char tablica[128];				//tablica danych
//tablice znakowe dla funkcji LCD
char napis1[] = "Szukam...";	//9 znaków
char dane = 0, flaga = 0;		//zmienne modyfikowane w funkcji obsługi przerwania
int kursor;						//zmienna do obsługi tablicy

void __attribute__ ((interrupt, no_auto_psv)) _U2RXInterrupt(void) 
{
	dane = U2RXREG;				//odczytaj dane
	flaga = 1;					//ustaw flagę odebranego bajtu
	IFS1bits.U2RXIF = 0;		//czyść flagę przerwania
}

int main()
{
	/////////////////////////////////////////////////////
	AD1PCFGL = 0xFFFF;			//wszystkie linie cyfrowe

	/////////////////////////////////////////////////////
	//uruchomienie wyświetlacza LCD//////////////////////
	WlaczLCD();					//inicjalizacja wyświetlacza LCD
	WyswietlLCD(napis1, 9);		//wyświetl napis "Szukam..."

	/////////////////////////////////////////////////////
	// obsługa UART
	//remapowanie RP2 dla wejściowej linii U2RX modułu UART2
	//RP2 <- U2RX (linia nr 2)
	RPINR19bits.U2RXR = 2;
	//prędkość = 9600 (U2BRG = 16000000/16*9600 - 1)
	U2BRG = 103;
	//włącz obsługę przerwania U2RX
	IFS1bits.U2RXIF = 0;		//czyść flagę przerwania
	IEC1bits.U2RXIE = 1;		//włącz przerwanie
	//włącz moduł UART2
	U2MODEbits.UARTEN = 1;

	/////////////////////////////////////////////////////
	//nieskończona pętla
	kursor = 0;
	for(;;)						
	{
		//czy nadeszła nowa wiadomość
		if(flaga)
		{
			flaga = 0;					//zerowanie flagi
			if(dane == '$') kursor = 1;	//szukaj początku wiadomości
			if(kursor>120) kursor = 0;	//zabezpiecz tablicę
			if(kursor>0) 
			{
				kursor++;				//inkrementuj kursor
				tablica[kursor] = dane;	//ładuj dane do tablicy


				if(kursor>46) kursor = 0;
				if(tablica[20] == 'A')	//jeśli dane są poprawne
				{
					//wyświetl współrzędne długości
					if((kursor>21)&&(kursor<34))
					{
						UstawKursorLCD(1, kursor-21);
						Wyslij_do_LCD(tablica[kursor]);
					}
					//wyświetl współrzędne szerokości
					if((kursor>33)&&(kursor<47))
					{
						UstawKursorLCD(2, kursor-33);
						Wyslij_do_LCD(tablica[kursor]);
					}
					//wyświetl inf. o danych poprawnych
					{
						UstawKursorLCD(1, 16);
						Wyslij_do_LCD('A');
					}
				}
				else
				//wyświetl inf. o danych niepoprawnych
				{
					UstawKursorLCD(1, 16);
					Wyslij_do_LCD('V');
				}
				//szukamy ramki $GPRMC
				//tablica[2] = $, tablica[3] = G, tablica[4] = P
				//tablica[5] = R, tablica[6] = M, tablica[7] = C
				if((kursor == 5)&&(tablica[5]!='R')) kursor = 0;
				if((kursor == 6)&&(tablica[6]!='M')) kursor = 0;
				if((kursor == 7)&&(tablica[7]!='C')) kursor = 0;
			}
		}
	}
}
