// ******************************************************************
// *                Mecséry István   - 2008                   		*
// ******************************************************************
// *  Program:      GSM telefonos kapcsolo							*
// *  Változat:                                          			*
// *  Dátum:      	2008.12.08.                            			*
// ******************************************************************
// *  Processzor = PIC16F877A     Órajel = 3.6864 MHz          		*
// ******************************************************************
// Telefon jelelnlétét ellenőrzi és az RB0-RB1-en jelzi.
// Hívó számának azonosítása után RB2-RB3 kimenetek állapota 
// ellenkezőre vált. A hívást minden esetben bontja.

#include <16F877A.h>

#FUSES NOWDT                 		//No Watch Dog Timer
#FUSES XT                    		//Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                 		//No Power Up Timer
#FUSES NOPROTECT             		//Code not protected from reading
#FUSES NODEBUG               		//No Debug mode for ICD
#FUSES NOBROWNOUT            		//No brownout reset
#FUSES NOLVP                 		//No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                 		//No EE protection
#FUSES NOWRT                 		//Program memory not write protected

#use delay(clock=3686400)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7,ERRORS)
#use fast_io(B)
#zero_ram

#include <string.h>

#define	Kimenet1	PIN_B2			
#define Kimenet2	PIN_B3			
#define piros_LED	PIN_B0			//Piros LED -> telefon nincs jelen - komm. nem jó
#define zold_LED	PIN_B1			//Zöld LED  -> telefon jelen van - komm. OK

//----------Változók ---------------------------------------------
int1 flag_ok;						//OK - telefon jelen van
int1 flag_ring;						//Bbejövő hívás

int RXmod;
int i; 
int Szamlalo_1;
int Szamlalo_2;						//idő túlfutás számlálója a jelenlét ell-hez
char ertek;
char sajat_telszam[10] = {"000000000"}; //ide kell a telefonszám (9 jegy)
char valasz1[5] = {"CLCC"};
char adat[11];

//----------Megszakítások-----------------------------------------
/* 	Megahtározott időközönként "ATE0" kiküldésével telefon ellenőrzése.
	A telefon "OK"-val válaszol. Igy ellenőrizzük, hogy jelen van-e (ezt csak konstatáljuk). */
#int_TIMER0							
void TIMER0_isr(void) 				
{	
	if (!--Szamlalo_1)
	{								
		printf("ATE0\r");
		Szamlalo_1 = 140;			//Kb. 10 mp-ként küldi az "ATE0"-át. Lehet csak "AT"-t 
	}								//küldeni...
}
//================================================================
/* 	Ha a Szamlalo nullázódik a telefon jelelnlétété jelző led piros lesz.
	A Szamlalo-t az "ATE0"-ra kapott helyes "OK" válasz ellenőrzésekor töltjük fel. */
#int_TIMER1
void TIMER1_isr(void) 
{
	if (!--Szamlalo_2)				//Ha letelt az idő, piros led bekapcs.
	{
		output_low(zold_LED);   	//Zöld led kikapcs.
   		output_high(piros_LED);  	//Piros led bekapcs.
 	}  	
}
//================================================================
/* UART vétel esetén megszakítás. Mindaddig amig van adat a bufferben a megszakítás újra végrehajtódik. */
#int_RDA							
void RDA_isr(void) 
{
	ertek = getc();
	switch (RXmod)
   	{
    	case 0:	
    			switch (ertek)  //Az első vett karaktereket ellenőrizzük.
    			{				//OK-nál és RING-nél csak az első karaktereket ellenőrizzük.
								//További elemzés csak a "+"-szal kezdődő válaszoknál kell.	
	    			case 'O': flag_ok = 1;   break;		//OK válasz
	    			case 'R': flag_ring = 1; break;		//RING -> bejövő hívás
	    			case '+': RXmod = 1;				//Minden más kérdésre adott válasz.
	    		} break;
    	case 1:								//+ után a harmadik bájt.
        case 2:
        case 3:
        case 4:
        		adat[RXmod - 1] = ertek;
				RXmod++;
				if (RXmod == 5)
				{		
					if (!strcmp(valasz1, adat)) //A válaszban "CLCC" karakter sorozat megvan?
					{
						 RXmod = 5;			//Ha igen, elemezzük a választ.
					}
					else 
					{
						RXmod = 0;
					}
				} break;  	
      	case 5: 							//Válasz értékelése. 
      			if (ertek == '0')			//Válasz formátuma : +CLCC:1,1,4,0,0,"+36XXXXXXXXX",145 vagy csak +CLCC: 1,1,4,0,0
      			{							//Megkeressük az első "0"-át.
	      			RXmod = 6;
	      		} break;
		case 6:								//A "0" után letárolunk 3 karaktert -> [,0,] vagy [,0 ]
		case 7:
		case 8:
				adat[RXmod - 6] = ertek;
				RXmod++;
				if (RXmod == 9)
				{
					if (adat[2] == ',')		//Megnézzük a 3. vett karakter ","-e? 
					{
						RXmod = 9;			//Ha igen, akkor telefonszám is van.
					}
					else					//Ha nincs ",", akkor nincs telefonszám, nem is fogunk csinálni semmit.
					{
						RXmod = 0;
					}
				} break;
		case 9:
				if (ertek == '6')			//Telefonszám ellenőrzéséhez megkeressük a +36-ban a 6-ost.
      			{
      				RXmod = 10;				//A 6-os után a telefonszám jön. Lehet gondolkodni, hogyan kezelje, ha
      			} break;					// a telefonszám nem +36-tal kezdődik...pl.: 4 karaktert beolvasni -> ["+36] 
											// és utána ellenőrizni!
       	case 10: 							// Itt a telefonszám jegyeit beolvassuk.
      	case 11:
      	case 12:
      	case 13:
      	case 14:
      	case 15:
      	case 16:
      	case 17:
      	case 18:
      			adat[RXmod - 10] = ertek;
				RXmod++;
				if (RXmod == 19)
				{
					if (!strcmp(sajat_telszam, adat)) 	//Ellenőrizzük a számot.
					{
						output_toggle(Kimenet1);		//Amennyiben a telefonszám azonosítva, 
						output_toggle(Kimenet2);		//a két kimenetet ellenkezőjére váltjuk.
					}
					for (i = 0; i < 11; i++); 			//Tömböt töröljük, 
					{									//hogy a következő vételt ne zavarja.
						adat[i] = 0;
					}
					RXmod = 0;
				} break;
		default: RXmod = 0; 
	}//switch (RXmod)
}//RDA_isr
//================================================================
void main(void)
{
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
	setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);	 
	
	set_tris_b (0b11110000);

	output_low(Kimenet2);						//Kimenet 2 kikapcsolva.
	output_high(Kimenet1);						//Kimenet 1 bekapcsolva.
	
	enable_interrupts(INT_TIMER0);				//Megszakítások engedélyezése.
	enable_interrupts(INT_TIMER1);
	enable_interrupts(INT_RDA); 
   	enable_interrupts(GLOBAL);
	
    while(1)									//Ezután csak folyamatosan ez megy.
    {
		if (flag_ring)							//Csöngetés után lekérdezni milyen szám hívott.
		{
			disable_interrupts(INT_TIMER0);	
			flag_ring = 0;
			printf("AT+CLCC\r");				//Telefonszám lekérése.
			delay_ms(1000);
			printf("ATH\r");					//Hívás megszakítása.
			delay_ms(1000);	
			set_timer0(0);
			enable_interrupts(INT_TIMER0);	
		}
		else if (flag_ok)						//Ha a válasz "O"K, akkor zöld led bekapcsolása.
		{
			flag_ok = 0;
			Szamlalo_2 = 20;
			output_low(piros_LED);   			//Piros led kikapcs.
   			output_high(zold_LED);				//Zöld led bekapcs.
   		}
		delay_ms(500);	
   	}// while(1)
}//main
//================================================================