/**************************************************************
   Schemat podłączeń programowanego układu

                 +----v----+
           MCLR [| 1     40|] 
                [| 2     39|] 
                [| 3     38|] RB5 -> DB4_LCD
                [| 4     37|] RB4 -> DB5_LCD
                [| 5     36|] RB3 -> DB6_LCD
                [| 6     35|] RB2 -> DB7_LCD
   serwo <- RA5 [| 7     34|] RB1 -> RS_LCD
                [| 8     33|] RB0 -> EN_LCD
                [| 9     32|] VDD
                [|10     31|] VSS
            VDD [|11     30|] 
            VSS [|12     29|] 
(20 MHz) / OSC1 [|13     28|]
         \ OSC2 [|14     27|]
      W1 -> RC0 [|15     26|] RC7 -> K4
      W2 -> RC1 [|16     25|] RC6 -> K3
      W3 -> RC2 [|17     24|] RC5 -> K2
      W4 -> RC3 [|18     23|] RC4 -> K1
                [|19     22|] 
                [|20     21|] 
                 +---------+
                 PIC16F877A

***************************************************************/

//definiujemy szybkość oscylatora dla funkcji __delay_
#define _XTAL_FREQ 20000000
#include <htc.h>
//////////////////////////////////////
#define TRIS_RS_LCD   TRISBbits.TRISB1
#define TRIS_EN_LCD   TRISBbits.TRISB0
#define TRIS_DB4_LCD  TRISBbits.TRISB5
#define TRIS_DB5_LCD  TRISBbits.TRISB4
#define TRIS_DB6_LCD  TRISBbits.TRISB3
#define TRIS_DB7_LCD  TRISBbits.TRISB2

#define RS_LCD   PORTBbits.RB1
#define EN_LCD   PORTBbits.RB0
#define DB4_LCD  PORTBbits.RB5
#define DB5_LCD  PORTBbits.RB4
#define DB6_LCD  PORTBbits.RB3
#define DB7_LCD  PORTBbits.RB2

#include "lcd.h"
//////////////////////////////////////
#define TRIS_W1  TRISCbits.TRISC0
#define TRIS_W2  TRISCbits.TRISC1
#define TRIS_W3  TRISCbits.TRISC2
#define TRIS_W4  TRISCbits.TRISC3
#define TRIS_K1  TRISCbits.TRISC4
#define TRIS_K2  TRISCbits.TRISC5
#define TRIS_K3  TRISCbits.TRISC6
#define TRIS_K4  TRISCbits.TRISC7

#define PORT_W1  PORTCbits.RC0
#define PORT_W2  PORTCbits.RC1
#define PORT_W3  PORTCbits.RC2
#define PORT_W4  PORTCbits.RC3
#define PORT_K1  PORTCbits.RC4
#define PORT_K2  PORTCbits.RC5
#define PORT_K3  PORTCbits.RC6
#define PORT_K4  PORTCbits.RC7

#include "klawiatura.h"
//////////////////////////////////////
//oscylator 20 MHz (FOSC_HS)
//watchdog wyłączony (WDTE_OFF)
//wyłączone LVP (Low-Voltage ICSP Programming) (LVP_OFF)
__CONFIG(FOSC_HS & WDTE_OFF & LVP_OFF);

char napis0[] = "Podaj kod:";		//10 znaków
char napis1[] = "Kod bledny!";		//11 znaków
char napis2[] = "Kod poprawny";		//12 znaków
char napis3[1];

char kod_pobrany[4];				//tablica odebranego kodu
char kod[4] = {6, 8, 7, 6};			//tablica kodu wzorcowego

//uśmiech
const char nowy_znak1[8] = {0b00000, 0b01010, 0b00000, 0b00100,
                            0b00100, 0b10001, 0b01110, 0b00000};
//ę
const char nowy_znak2[8] = {0b00000, 0b00000, 0b01110, 0b10001,
                            0b11111, 0b10000, 0b01110, 0b00011};
//ł
const char nowy_znak3[8] = {0b01100, 0b00100, 0b00110, 0b00100,
                            0b01100, 0b00100, 0b01110, 0b00000};

void KodPrawidlowy()
{
	char i;
	//wyświetl informację o poprawnie podanym kodzie
	UstawKursorLCD(2, 3);	//wiersz 2 kolumna 3
	WyswietlLCD(napis2, 12);//wyświetl napis
	//serwomechanizm otwiera zamek (ruch w prawo) - 5s
	for(i=0; i<250; i++)
	{
		PORTAbits.RA5 = 1;
		__delay_us(2300);
		PORTAbits.RA5 = 0;
		__delay_us(17700);
	}
	//serwomechanizm zwalnia zatrzask (ruch w lewo) - 2 s
	for(i=0; i<111; i++)
	{
		PORTAbits.RA5 = 1;
		__delay_us(700);
		PORTAbits.RA5 = 0;
		__delay_us(17300);
	}
}

void KodBledny()
{
	//wyświetl informację błędnie podanym kodzie
	UstawKursorLCD(2, 4);	//wiersz 2 kolumna 4
	WyswietlLCD(napis1, 11);//wyświetl napis
	//czekaj 5 s
	__delay_ms(5000);
}

void main()
{
	ADCON1 = 0x06;				//wyłączenie linii analogowych 
                    			//(wszystkie linie cyfrowe)
	TRISAbits.TRISA5 = 0;		//linia z serwomechanizmem wyjściowa

	WlaczLCD();							//inicjalizacja wyświetlacza LCD
	Zapisz_nowy_znakLCD(nowy_znak1, 0);	//koduj nowy znak (uśmiech)
	Zapisz_nowy_znakLCD(nowy_znak2, 1);	//koduj nowy znak (ę)
	Zapisz_nowy_znakLCD(nowy_znak3, 2);	//koduj nowy znak (ł)
	napis1[5] = 2;						//przypisanie kodu nowego znaku
	napis1[6] = 1;						//przypisanie kodu nowego znaku
	Wlacz_klawiature();					//inicjalizacja portów klawiatury
	
	napis3[0] = 0;				//załaduj numer nowego znaku

	for(;;)						//pętla nieskończona
	{	
		CzyscLCD();				//reset wyświetlacza
		UstawKursorLCD(1, 4);	//wiersz 1 kolumna 4
		WyswietlLCD(napis0, 10);//wyświetl napis "Podaj kod:"

		//pobierz kod
		kod_pobrany[0] =
			Czekaj_na_klawisz();//czekaj na klawisz :)
		UstawKursorLCD(2, 7);	//wiersz 2. kolumna 7.
		WyswietlLCD(napis3, 1);	//wyświetl znak "uśmiech"
		__delay_ms(250);		//zaczekaj na stabilizację impulsu

		kod_pobrany[1] =
			Czekaj_na_klawisz();//czekaj na klawisz :)
		UstawKursorLCD(2,8);	//wiersz 2. kolumna 8.
		WyswietlLCD(napis3, 1);	//wyświetl znak "uśmiech"
		__delay_ms(250);		//zaczekaj na stabilizację impulsu

		kod_pobrany[2] =
			Czekaj_na_klawisz();//czekaj na klawisz :)
		UstawKursorLCD(2, 9);	//wiersz 2. kolumna 9.
		WyswietlLCD(napis3, 1);	//wyświetl znak "uśmiech"
		__delay_ms(250);		//zaczekaj na stabilizację impulsu

		kod_pobrany[3] =
			Czekaj_na_klawisz();//czekaj na klawisz :)
		UstawKursorLCD(2, 10);	//wiersz 2. kolumna 10.
		WyswietlLCD(napis3, 1);	//wyświetl znak "uśmiech"

		//porównaj pobrany kod z wzorcowym
		if((kod_pobrany[0] == kod[0])&&
		   (kod_pobrany[1] == kod[1])&&
		   (kod_pobrany[2] == kod[2])&&
		   (kod_pobrany[3] == kod[3]))
		KodPrawidlowy();
			else
		KodBledny();
	}
}
