/*
 * Hlavni jednotka*****
 *
 * Created: 16.4.2012 11:34:53
 *  Author: JAn Kristel
 */ 


 #define AVR_ATmega644PA
 #define F_CPU 20000000UL
 

 
 
#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h> 
#include <util/delay.h>




volatile uint8_t tel_p [13] ; // "operativni"       
volatile uint8_t tel_m [13] ;// telefoni cislo vyctene ze SIM

volatile uint8_t SMS_p [9]; // operativni pamet sms
volatile uint8_t SMS1 [9] = {'R','E','L','E','1',' ','Z','A','P'}; // predefinovane zpravy k porovnani
volatile uint8_t SMS2 [9] = {'R','E','L','E','2',' ','Z','A','P'};
volatile uint8_t SMS3 [9] = {'R','E','L','E','3',' ','Z','A','P'};
		
volatile uint8_t SMS4 [9] = {'R','E','L','E','1',' ','V','Y','P'}; 
volatile uint8_t SMS5 [9] = {'R','E','L','E','2',' ','V','Y','P'};
volatile uint8_t SMS6 [9] = {'R','E','L','E','3',' ','V','Y','P'};	

	
volatile uint8_t SMS7 [9] = {'R','E','L','1',' ','P','U','L','S'}; 
volatile uint8_t SMS8 [9] = {'R','E','L','2',' ','P','U','L','S'};
volatile uint8_t SMS9 [9] = {'R','E','L','3',' ','P','U','L','S'};		
	
volatile uint8_t SMS10 [9] = {'A','L','A','R','M',' ','S','T','P'}; 
volatile uint8_t SMS11 [9] = {'A','L','A','R','M',' ','D','E','A'}; 
volatile uint8_t SMS12 [9] = {'A','L','A','R','M',' ','Z','S','T'}; 
	


char buffer_0[16];

 // data ze seriaku
volatile uint8_t data_0 ;
volatile uint8_t priznak;
volatile uint8_t priznak_pop;//poplachovz priznak

volatile uint8_t set_status; // registr s nastvenim
volatile uint8_t seteep_status;

//*** definice portu***
#define OK1 PINA7 //PORTA
#define OK2 PINA6
#define OK3 PINA5
#define OK4 PINA4
#define OK5 PINA3  // v pravo blize k napajeni

#define LED1 PORTA0  // oranzova
#define LED2 PORTA1 // cervena
#define AD_AKU PINA2
             
#define TL PINB1  // PORTB
#define INIT_AL PINB2

#define REL1 PORTC2  //PORTC blizek napajeni
#define REL2 PORTC3
#define REL3 PORTC4
#define DET_nap PINC5  // VSTUP Indikace sitoveho napajeni
#define ODP_aku PORTC0 // Odpoji AKU. log "0"
#define ENA_nab PORTC1 // povoleni zakazani nabijeni 

#define RS485 PORTD5 // PORT D - Logicka "0" prijem! 
#define ON_GSM PORTD4   // zapne nizkou impedanci  


//********definice priznaku 
#define usart_p     0   //BIT0  priznak od preruseni prijmu dat
#define prozv       1  // krat prozv.
#define poplach     2   //BIT2 poplach prozvani dlouho
#define poplach_kr  3   //BIT3 
#define strez       4   //BIT4 zastrezeno log 0 zastrezeno
#define vypadek_nap 5   //BIT5
#define vzdal_jed   6   //BIT6 ping vzdal jed. 

//******z eeprom****
#define rele_przv     0   //BIT0 Ovladani rele pomoci prozvoneni 
#define sms_e         1  // posilat sms pri naruseni
#define REL3_poplach  2  // Sepnou rele 3 pri polachu
#define REL1_puls     3  // pri odemceni  cvaknout rele 1
#define prozv_ost     4 // prozvanet i na ostatni tel cisla



//****ad prevodnik*****
#define ADC_VREF_TYPE 0x40

//******definuce buferu pro USART
#define BUF_SIZE 150
//type definition of buffer structure
typedef struct{
    //Array of chars
    uint8_t buffer[BUF_SIZE];
    //array element index
    uint8_t index;
}
u8buf;
//declare buffer
u8buf buf;
//initialize buffer
//*****************

void BufferInit(u8buf *buf)
{
    //set index to start of buffer
    buf->index=0;
}

//write to buffer routine
uint8_t BufferWrite(u8buf *buf, uint8_t u8data)
{
    if (buf->index<BUF_SIZE)
    {
        buf->buffer[buf->index] = u8data;
        buf->index++;
        return (0);
    }
        else 
		{
		return (1);	
		}
		
}
uint8_t BufferRead(u8buf *buf, volatile uint8_t *u8data)
{
    if(buf->index<BUF_SIZE)
    {
      
        *u8data=buf->buffer[buf->index];
	    buf->index++;
		return (0);
    }
      else 
	   {
	   return (1);	
		
	   }
}

//*********************ADC*******
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
_delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return (ADCW);
}

//****************USART1 - na Vzdalena jednotka*********
unsigned char USART_receive_1(void){
  	while(1)
	{
	  if(bit_is_set(UCSR1A,RXC1)) //je li RXC plny zkopiruj data do temp   
	    {
	 return(UDR1);
	    }
		return(0);
	}
 }

void USART_send_1( unsigned char data){
	 
 while(!(UCSR1A & (1<<UDRE1)));
	 UDR1 = data;
}

void USART_putstring_1(volatile char* StringPtr){
	 
	 PORTD |= (1<<RS485); // nastavi vysilani na RS485
	 _delay_us(300);
	  
	 while(*StringPtr != 0x00){
	 USART_send_1(*StringPtr);
	 StringPtr++;}
	
	_delay_ms(1000);
	 PORTD &= ~(1<<RS485); 
}
//---------

//*********USART0 - GSM*************
unsigned char USART_receive_0(void){
  	while(1)
	{
	  if(bit_is_set(UCSR0A,RXC0)) //je li RXC plny zkopiruj data do temp   
	    {
	     return(UDR0);
	    }
		return(0);
	}
}

void USART_send_0( unsigned char data){
	 
 while(!(UCSR0A & (1<<UDRE0)));
	 UDR0 = data;
}

void USART_putstring_0(volatile char* StringPtr){
		  
	 while(*StringPtr != 0x00){
	 USART_send_0(*StringPtr);
	 StringPtr++;}
}


void stav_aku ()// meri pomoci AD napeti na zaloznim akumulatoru
{
        volatile unsigned int vysledek;
        volatile float realne;
	    vysledek = read_adc(0b00000100);
        realne = (float) 5.03 / 1023;
        realne = (float) realne * vysledek;
        vysledek = (float) realne * 100;
      
	    if (vysledek <= 438)
	    {
		_delay_ms(10000);
		PORTC &= ~(1<<ODP_aku);  //odpoji AKU
	   }
 } 

void napajeni()
{ 
   if (PINC &(1<< DET_nap)) 
   {
  	 priznak &= ~(1<<vypadek_nap); // napajeni obnoveno
	 PORTA &= ~(1<<LED1); 
   }
	
  if (!(PINC &(1<< DET_nap)))// detekce vypadku napajeni
  {
    if (!(priznak & (1<<vypadek_nap))) 
   {   
	
    for (volatile uint8_t i=0; i<60; i++)
	 {
	 tl_vyp ();   // jestli do 60 sec nedojde k obnove kvalifikuje se jako vypadek napajeni
	_delay_ms( 500 );
	 PORTA |= (1<<LED2);
    _delay_ms( 500 );
	PORTA  &= ~(1<<LED2); 
	   if (PINC &(1<< DET_nap)) // detekce vobnovy napajeni 
      {
	  return(0);
	  }
	 
      }
	
	 if (!(priznak & (1<<strez))) // vykona jen kdyz je zastrezeno
	 {
     sms_nap(); // posle sms j
     }	
     priznak |= (1<<vypadek_nap); // nastavi priznak
	 PORTA |= (1<<LED1); // signalizace aku napajeni
	       
   }   
 stav_aku (); // je li odpojeno napajeni hlidej akumulator 
 }	
}	


void tl_vyp () // vzpinaci fce aby se nemusel mechanickz odpojovat AKU
{
 if (!(PINB & (1<<TL))) // je li tl stisknuto vykonej
  {
   for (volatile uint8_t i = 0; i<12 ;i++)
   {
    if (!(PINB & (1<<TL)))// casuje dokut se drzi tlac
	 {                        
      PORTA  &= ~(1<<LED1);
  	  _delay_ms(200);
      PORTA  |= (1<<LED1);
	  _delay_ms(200);
     }
	 else
	 { i =12;}
  }    
  
   if (!(PINB & (1<<TL))) 
    {
   PORTC &= ~(1<<ODP_aku); //odpoji akumulator
    }  
   
  }    
}

//*****************************FCE na ovladani GSM*********
//----- hovory----
void prozvon_poplach()
{
 if (priznak & (1<<poplach))
	{	 
 	sprintf ( buffer_0 , "ATD>SM7;") ; 
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d); 
   
   _delay_ms(50000); 
   sprintf ( buffer_0 , "ATH") ;
   USART_putstring_0(buffer_0);
   USART_send_0(0x0d);
    _delay_ms(300); 
 
  }	
   
  if (set_status & (1<<prozv_ost)) // podle nastaveni prozvoni o na ostatni cisla
    {
     if (priznak & (1<<poplach))
	 {	 
 	sprintf ( buffer_0 , "ATD>SM8;") ; 
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d); 
   
    _delay_ms(50000); 
    sprintf ( buffer_0 , "ATH") ;
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d);
    _delay_ms(300); 
 
  }	
  
   if (priznak & (1<<poplach))
	{	 
 	sprintf ( buffer_0 , "ATD>SM9;") ; 
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d); 
   
    _delay_ms(50000); 
    sprintf ( buffer_0 , "ATH") ;
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d);
     _delay_ms(300); 
    
   }
  
   if (priznak & (1<<poplach))
	{	 
 	sprintf ( buffer_0 , "ATD>SM10;") ; 
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d); 
   
    _delay_ms(50000); 
    sprintf ( buffer_0 , "ATH") ;
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d);
      _delay_ms(300); 
 
	}		
 } 

priznak &= ~(1<<poplach); // jen 1x poplach !! 	 
    
}

void prozvon_kr() // kratce prozvoni
{
	if (priznak & (1<<prozv))
	{
	sprintf ( buffer_0 , "ATD>SM7;") ; // dat poyici na SIM
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d); // posle enter / potvrdi prikaz
   
   _delay_ms(12000); // tohle staci na velice kratke prozvoneni
   sprintf ( buffer_0 , "ATH") ;
   USART_putstring_0(buffer_0);
   USART_send_0(0x0d);
  priznak &= ~(1<<prozv);  // aby neprozvanel porad dokola
 
  } 	
}

void zaves() // zavesi a shodi prozvaneni
{
  priznak &= ~(1<<prozv); // zhodi priznak prozvaneni
   sprintf ( buffer_0 , "ATH") ;
   USART_putstring_0(buffer_0);
   USART_send_0(0x0d);
}
//-----SMS---
void posli_sms(unsigned char sms_x) // posle sms z pozice x na SIM
{
	sprintf ( buffer_0 , "at+cmss= \%d" , sms_x) ; // dat poyici na SIM
    USART_putstring_0(buffer_0);
	_delay_ms(20);
	
	USART_send_0(',');
	_delay_ms(20);
	for (unsigned char i = 0; i<13; i++) //tel cislo z RAM
	{
	 _delay_ms(20);
	USART_send_0(tel_m[i]);
	
	}
	 // komletni potvrd entrem
	 _delay_ms(100);
    USART_send_0(0x0d);	
} 
void sms_vzd() // posle sms o odpojeni vzdal jedntky
{
  sprintf ( buffer_0 , "AT+CMGS=") ; 
  USART_putstring_0(buffer_0);
  _delay_ms(20);
  for (unsigned char i = 0; i<13; i++) //dosadi tel cislo z RAM
	{
	 _delay_ms(20);
	 USART_send_0(tel_m[i]);
	}
  USART_send_0(0x0d);
  _delay_ms(300);
  sprintf ( buffer_0 , "!! POZOR !! Vzdalena jednotka odpojena !!") ; 
  USART_putstring_0(buffer_0);	
  USART_send_0(0x1a); 
  _delay_ms(300);

}
void sms_nap () // posle sms o vypadku site 
{
  USART_send_0(0x0d); // stornuje predchozi zadavani
  _delay_ms(400);
  sprintf ( buffer_0 , "AT+CMGS=") ; 
  USART_putstring_0(buffer_0);
  _delay_ms(20);
  for (unsigned char i = 0; i<13; i++) //dosadi tel cislo z RAM
	{
	 _delay_ms(20);
	 USART_send_0(tel_m[i]);
	}
  USART_send_0(0x0d);
  _delay_ms(300);
  sprintf ( buffer_0 , "Vypadek napajeni !!") ; 
  USART_putstring_0(buffer_0);	
  USART_send_0(0x1a); 
  _delay_ms(300);
 }
void sms_piner() // posle SMS o spatne zadanem pinu
{
  USART_send_0(0x0d);
  _delay_ms(400);
  sprintf ( buffer_0 , "AT+CMGS=") ; 
  USART_putstring_0(buffer_0);
  _delay_ms(20);
  for (unsigned char i = 0; i<13; i++) //dosadi tel cislo z RAM
	{
	 _delay_ms(20);
	 USART_send_0(tel_m[i]);
	}
  USART_send_0(0x0d);
  _delay_ms(300);
  sprintf ( buffer_0 , "!! POZOR !! 5x po sobe spatne zadany PIN") ; 
  USART_putstring_0(buffer_0);	
  USART_send_0(0x1a); 
  _delay_ms(300);	
	
}	
void sms_vzdal_rst() // SMS o resetu vzdalene jed.
{
 if (!(priznak & (1<<strez))) 
 {
  USART_send_0(0x0d);
  _delay_ms(400);
  sprintf ( buffer_0 , "AT+CMGS=") ; 
  USART_putstring_0(buffer_0);
  _delay_ms(20);
  for (unsigned char i = 0; i<13; i++) //dosadi tel cislo z RAM
	{
	 _delay_ms(20);
	 USART_send_0(tel_m[i]);
	}
  USART_send_0(0x0d);
  _delay_ms(300);
  sprintf ( buffer_0 , "!!POZOR !! Vzdalena  jednotka vyresetovana !!") ; 
  USART_putstring_0(buffer_0);	
  USART_send_0(0x1a); 
  _delay_ms(300);	
  }
}
void del_sms () // smaze SMS 
{
	sprintf ( buffer_0 , "AT+CMGD=7"); // posledni SMS je prichozi
    USART_putstring_0(buffer_0);
	USART_send_0(0x0d);
	_delay_ms(300);  

	sprintf ( buffer_0 , "AT+CMGD=8"); // 
    USART_putstring_0(buffer_0);
	USART_send_0(0x0d);
	_delay_ms(300);  	
}

//---------

void ping_vzdal() // dotazuje se na vzdalenou jed
{
	

  if (!(priznak & (1<<vzdal_jed))) // po odeslani
  {
 	   sprintf ( buffer_0 , "W") ;
       USART_putstring_1(buffer_0);  
       volatile uint8_t data_1 ;	
       data_1 = USART_receive_1(); // prijima data ze USART1
       _delay_ms(550);
       UCSR1B &= ~((1<<RXEN1)|(1<<RXCIE1)); //zpracovava data zakaz preruseni a RX1 
       if (data_1 == 'Q')
        {
         
          UCSR1B |= (1<<RXEN1)|(1<<RXCIE1);	
          return(0);
        }

     UCSR1B |= (1<<RXEN1)|(1<<RXCIE1);	
     
	  for (int i;i<6; i++) // odladovacka**
      {
	  	PORTA |= (1<<LED1); 
		_delay_ms(500);
		PORTA &= ~(1<<LED1); 
        _delay_ms(500);
	  }
	  
	 
	 sms_vzd();
     priznak  |= (1<<vzdal_jed);
}


}	

void init_GSM ()
  {
	 	
	// zapni GSM modul
  DDRD |=  (1<<ON_GSM);  // nastavi jako vystupni
  PORTD &= ~ (1<<ON_GSM); // log "0" zapne
  _delay_ms(200);
  DDRD &= ~ (1<<ON_GSM); // vysoka impedance (jako vstup)
   _delay_ms(2000);	
	
  sprintf ( buffer_0 , "ATE0") ; //vypne opakovani zadanych AT 
  USART_putstring_0(buffer_0);
  USART_send_0(0x0d);
		
   _delay_ms(4000);	
	
//*************vzcteni Master tel cisla a ulozeni do RAM**********	
	 BufferInit(&buf);
     UCSR0B |= (1<<RXEN0)|(1<<RXCIE0); 
     sprintf ( buffer_0 , "at+cpbr=7"); // 7 pozice SIM master cislo
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);


    if (priznak & (1<<usart_p))  // je dokonceno cteni usart
      {
       BufferInit(&buf); // nastavi ukazatel na zacatek
	    BufferRead(&buf, &data_0); 
        BufferRead(&buf, &data_0);
	   BufferRead(&buf, &data_0); // precte prvni platny znak 
	   if(data_0  == 'O') // je-li ERROR napsi na vzdalenou jed chyba karty
	   {
	 		    
    	BufferInit(&buf);
		//enable reception and RC complete interrupt
        UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
	    priznak  &= ~(1<<usart_p); // shodi priznak prijmu   
		return(0);
	   }
	   
	   	if(data_0  == 'E') 
	   {
		BufferInit(&buf);
		//enable reception and RC complete interrupt
        UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
	    priznak  &= ~(1<<usart_p); // shodi priznak prijmu   
	                         //je li chyba SIM informuj 
       sprintf ( buffer_0 , "!") ;
       USART_putstring_1(buffer_0);
		
		return(0);
	   } 
	   
	  for (; (data_0 != '"') && (data_0 != 'O'); BufferRead(&buf, &data_0)) // pojede tak dlouho dokun nenarazi na +
       {
		 
		   
	   }
		 
      for (uint8_t i =0; i<13 ;i++)  // prekopiruje tel cislo do pole pameti
	   {
	    BufferRead(&buf, &data_0);
		tel_m[i] = data_0;   
	   }
     }	 
	 
	 _delay_ms(300);
	 sprintf ( buffer_0 , "AT+CMGF=1"); //sms v text rezimu
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	
	
	
	}
	
void prichozi_hov ()
  {
	  
	 BufferInit(&buf);
	 priznak  &= ~(1<<usart_p); 
     UCSR0B |= (1<<RXEN0)|(1<<RXCIE0); 
     sprintf ( buffer_0 , "AT+CLCC") ;
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(400);


    if (priznak & (1<<usart_p))  // je dokonceno cteni usart
      {
       BufferInit(&buf); // nastavi ukazatel na zacatek
       	BufferRead(&buf, &data_0);
	    BufferRead(&buf, &data_0); 
        BufferRead(&buf, &data_0); // precte 3 znak v poli (prvni platny)
	     
	  
	    if(data_0  == 'O') 
	   {	 		    
	     // nic noveho - neni prichozi hovor 
		BufferInit(&buf);
        UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
	    priznak  &= ~(1<<usart_p); // shodi priznak prijmu   
		return(0);
	   }
	   
	   if(data_0  == 'E')  // detekce error od odpojene SIM
	   {
	    //JE ji Error tak odejdi a napis na vydalenou
		BufferInit(&buf);
        UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
	    priznak  &= ~(1<<usart_p);    
	                               //je li chyba SIM informuj 
       sprintf ( buffer_0 , "!") ;
       USART_putstring_1(buffer_0);
		
		return(0);
	   }   
	
	  for (; (data_0 != '"') && (data_0 != 'O'); BufferRead(&buf, &data_0)) // pojede tak dlouho dokun nenarazi na "
       { }
		 
      for (uint8_t i =0; i<13 ;i++)
	   {
	    BufferRead(&buf, &data_0);
		tel_p[i] = data_0;   
	   }
		
	 for (int i = 0; i < 13; i++) // porovnava dve pole o delce 13
    {
      if (tel_m[i] != tel_p[i])
      {
   	    BufferInit(&buf);
        UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
	    priznak  &= ~(1<<usart_p); // shodi priznak prijmu
	  
	    // cizi TEL Cislo okamzite polozi !! 
       sprintf ( buffer_0 , "ATH") ;
       USART_putstring_0(buffer_0);
       USART_send_0(0x0d);
	   return(0);
	 }
    } 
		
// tel cislo souhlaci - provede tohle		
    _delay_ms(1500);      
	sprintf ( buffer_0 , "n") ;
    USART_putstring_1(buffer_0);
		 
   _delay_ms(1500); 
   
   priznak |= (1<<prozv);  // prozvoni zpet pro overeni funkcnosti

   	sprintf ( buffer_0 , "ATH") ;
    USART_putstring_0(buffer_0);
    USART_send_0(0x0d);
	
	 if (set_status & (1<<rele_przv))
	 {
	 PORTC ^= (1<<REL1); // prepne rele na 3 sec
	_delay_ms(3000);
	 PORTC ^= (1<<REL1);
	 }
     BufferInit(&buf);
    UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
    priznak  &= ~(1<<usart_p); // shodi priznak prijmu
		
     }
 
  }

void prichozi_SMS()  
{
	volatile uint8_t priz_sms = 0;
	
    BufferInit(&buf);
    priznak  &= ~(1<<usart_p); 
    UCSR0B |= (1<<RXEN0)|(1<<RXCIE0); 	
    sprintf ( buffer_0 , "at+cmgl=") ; // prikay zjisti novou SMS 
    USART_putstring_0(buffer_0);
    USART_send_0('"');
    sprintf ( buffer_0 , "rec unread") ; 
    USART_putstring_0(buffer_0);
    USART_send_0('"');
    _delay_ms(300);
    USART_send_0(0x0d);
    _delay_ms(600);
 
    BufferInit(&buf); // nastavi ukazatel na zacatek
	BufferRead(&buf, &data_0);
	BufferRead(&buf, &data_0); 
    BufferRead(&buf, &data_0); // precte 3 znak v bufferu (prvni platny)
	  
	 
	   if(data_0  == 'O') 
	   {
		
      // neni nova sms
		BufferInit(&buf);
		//enable reception and RC complete interrupt
        UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
		return(0);
	   }
	   
	   if(data_0  == 'E')  
	     {
	    //JE ji Error tak odejdi a napis na vzdalenou
		BufferInit(&buf);
        UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
	    priznak  &= ~(1<<usart_p); // shodi priznak prijmu   
	                               //je li chyba SIM informuj 
       sprintf ( buffer_0 , "!") ;
       USART_putstring_1(buffer_0);
		
		return(0);
	   }   
//-- identifikace tel cisla	
	
	  for (; data_0 != '"' ; BufferRead(&buf, &data_0)) // pojede tak dlouho dokun nenarazi na platne (")
       {}
      BufferRead(&buf, &data_0);
	  for (; data_0 != '"' ; BufferRead(&buf, &data_0)) 
	  {}
	  BufferRead(&buf, &data_0);
	  for (; data_0 != '"' ; BufferRead(&buf, &data_0))
	  {}
	 
	  for (uint8_t i =0; i<13 ;i++) // tel cislo do RAM
	   {
	    BufferRead(&buf, &data_0);
		tel_p[i] = data_0;   
	   }
  
	  for (int i = 0; i < 13; i++) // porovnava dve pole o delce 13
       { 
	    if (tel_m[i] != tel_p[i])
         {
         //rozdilne vyskoc
   	     BufferInit(&buf);
         UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
         del_sms();
	     return(0);
	    }
	   }
//---- zpracovani SMS-----------	  
	 for (; data_0 != 0x0A ; BufferRead(&buf, &data_0)) // najede na platne znakz SMS
	  { } 
		  
	 for (uint8_t i =0; i<9 ;i++) // SMS cislo do RAM
	   {
	    BufferRead(&buf, &data_0);
		SMS_p[i] = data_0;   
	   }  
		  
//---sms1----
       for (int i = 0; i<9; i++) // otestuje SMS1
       { 
	    if (SMS1[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) // aby se toto provedlo jen jednou
      {
      PORTC |= (1<<REL1);
	  del_sms();
	  priznak |= (1<<prozv); // prozvoni pro overeni
	  return(0);
	  }
//--- sms2---	 
       for (int i = 0; i<9; i++) 
       { 
	    if (SMS2[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}		
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
      PORTC |= (1<<REL2);
	  del_sms();
	  priznak |= (1<<prozv);
	  return(0);
	  }
	  
	  
//-- sms3---
	 
       for (int i = 0; i<9; i++) 
       { 
	    if (SMS3[i] == SMS_p[i]) { priz_sms = 10; }
		else {i=10; priz_sms=0;}		
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
      PORTC |= (1<<REL3);
	  del_sms();
	  priznak |= (1<<prozv);
	  return(0);
	  }

//---sms4--

       for (int i = 0; i<9; i++) 
       { 
	    if (SMS4[i] == SMS_p[i]) {priz_sms = 10;}
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
      PORTC  &= ~(1<<REL1);
	  del_sms();
	  priznak |= (1<<prozv);
	  return(0);
	  }
	 
	 
//----sms5--

       for (int i = 0; i<9; i++) 
       { 
	    if (SMS5[i] == SMS_p[i]) { priz_sms = 10;}
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
      PORTC  &= ~(1<<REL2);
	  del_sms();
	  priznak |= (1<<prozv);
	  return(0);
	  }
//sms6	 

       for (int i = 0; i<9; i++) 
       { 
	    if (SMS6[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
       PORTC  &= ~(1<<REL3);
       del_sms();
	   priznak |= (1<<prozv);
	   return(0);
	  }



//sms7	--- na 2 sec zmeni stav relatka

       for (int i = 0; i<9; i++) 
       { 
	    if (SMS7[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
       PORTC ^= (1<<REL1); // 
	   _delay_ms(2000);
	   PORTC ^= (1<<REL1);
       del_sms();
	   priznak |= (1<<prozv);
	  return(0);
	  }
	  
//sms8

       for (int i = 0; i<9; i++) 
       { 
	    if (SMS8[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
       PORTC ^= (1<<REL2); // 
	   _delay_ms(2000);
	   PORTC ^= (1<<REL2);
       del_sms();
	   priznak |= (1<<prozv);
	  }
	  
//sms9	 

       for (int i = 0; i<9; i++) 
       { 
	    if (SMS9[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
       PORTC ^= (1<<REL3); // 
	   _delay_ms(2000);
	   PORTC ^= (1<<REL3);
       del_sms();
	   priznak |= (1<<prozv);
	  }	  


//sms10	
       for (int i = 0; i<9; i++) 
       { 
	    if (SMS10[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
	  zaves(); // zavesi a rusi priznak prozvaneni
	  del_sms();
	  priznak |= (1<<prozv);
	  return(0);
	  }
	  
//sms11	 
	   for (int i = 0; i<9; i++) 
       { 
	    if (SMS11[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
	  priznak |= (1<<strez);  // odstrezi alarm
	  sprintf ( buffer_0 , "d") ; // info na vzdalenou jednotku
      USART_putstring_1(buffer_0);
	  del_sms();
	  priznak |= (1<<prozv);
	  PORTC  &= ~(1<<REL3);  // pri odstrezeni vypne rele 3 - vypne sirenu
	  priznak &= ~(1<<poplach); // zastavi prozvaneni
	  return(0);
	  }
	  
//sms12		  
	  
	   for (int i = 0; i<9; i++) 
       { 
	    if (SMS12[i] == SMS_p[i]) {  priz_sms = 10; }
		else {i=10; priz_sms=0;}	
	   }	   	 
	     	   
	  if (priz_sms == 10 ) 
      {
	  priznak &= ~(1<<strez); // zastrezi alarm
	  sprintf ( buffer_0 , "z") ; // info na vzdalenou jednotku
      USART_putstring_1(buffer_0);
	  del_sms();
	  priznak |= (1<<prozv);
	  return(0);
	  }  

	  del_sms();
}


//********************vektory preruseni*************
ISR(USART1_RX_vect)
{
  volatile uint8_t data_1 ;	
 data_1 = USART_receive_1(); // prijima data ze USART1

  UCSR1B &= ~((1<<RXEN1)|(1<<RXCIE1)); //zpracovava data zakaz preruseni a RX1 

 switch (data_1)
 {
    case  '@':     // prijmuty znak ze vzdalene jed. (zstrezeno)
  //  PORTA |= (1<<LED1);
    priznak |= (1<<prozv); // priznak prozvaneni( overeni ze je zastrezeno)
	priznak &= ~(1<<strez); // log 0
    break;


    case  '&':

    PORTC  &= ~(1<<REL3);  // pri odstrezeni vypne rele 3 - vypne sirenu
	priznak &= ~(1<<poplach); // zastavi prozvaneni
	zaves(); // po odstrezeni zastavi eventuelni poplach
	priznak |= (1<<strez); // log 1 - odstrezeno  -  defaul zastrezeno
    break;
	 
	case  '/':
    PORTC &= ~(1<<ODP_aku); // odpoji AKU kdyz bude potreba zresetovat cely system
    break; 
	
	case  '+':
    sms_piner();
    break;
	
//--	
	
	case  'j':
    set_status |= (1<<REL3_poplach);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status); // hned zapise hodnotu do eepromm
	_delay_ms(100);
	break;
	
	case  'v':
    set_status &= ~(1<<REL3_poplach);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status);
		_delay_ms(100);
    break;
//--	

	case  'd': 
    set_status |= (1<<sms_e);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status);
	break;
	case  'x':
    set_status &= ~(1<<sms_e);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status);
   	_delay_ms(100);
    break;
//--

	case  'l': 
    set_status |= (1<<prozv_ost);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status); 
	break;
	case  'b':
    set_status &= ~(1<<prozv_ost);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status);
    break;
//--
   	case  'r': // sepnou rele pri prozvoneni
    set_status |= (1<<rele_przv);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status);
	break;
	case  'm':
    set_status &= ~(1<<rele_przv);
	seteep_status = set_status;
    eeprom_write_byte (0x02,set_status);
    break;
	
	case '#':      // info o resetu
	sms_vzdal_rst();
	break;
	 
 }
  UCSR1B |= (1<<RXEN1)|(1<<RXCIE1);	
	
}

ISR(USART0_RX_vect)
{
	
		
	 uint8_t u8temp;
    
	 if(bit_is_set(UCSR0A,RXC0)) //je li RXC plny zkopiruj data do temp   
	    {
	     u8temp=UDR0;
	    }
		  
   if ((BufferWrite(&buf, u8temp)==1)||(u8temp =='O')) // prijme li velke O konci cteni
    {
        //disable reception and RX Complete interrupt po prijmu zakaze preruseni dokut data nezpracuje
         UCSR0B &= ~((1<<RXEN0)|(1<<RXCIE0)); 
     
	    priznak |= (1<<usart_p);          //nastavi priznak prijmu dat
      //  PORTA ^= (1<<LED1);  a zde log 0     // jen na odladeni indikace kominukace s GSM
	}
 }

ISR(INT2_vect)
{ 

			
 if (!(PINA & (1<<OK1))) 
 {
  if (!(priznak & (1<<strez))) // vykona jen kdyz je zastrezeno
	{
      priznak |= (1<<prozv); // nastavi priznak jen kratce
	  _delay_ms(400);
	}    
 }					 
			

 if (!(PINA & (1<<OK2))) 
 {
 
    if (!(priznak & (1<<strez))) // vykona jen kdyz je zastrezeno
	{
     priznak |= (1<<prozv);  // nastavi priznak jen kratce
     if (set_status & (1<<sms_e))   {posli_sms(2);}// jen kdzy je povoleno
	 _delay_ms(400);
	}   
 }
   
  if (!(PINA & (1<<OK3)))
  {

   if (!(priznak & (1<<strez))) // vykona jen kdyz je zastrezeno log0
	 { 

      if (set_status & (1<<REL3_poplach))   {PORTC |= (1<<REL3);}
      priznak |= (1<<poplach); 
	  if (set_status & (1<<sms_e))	 {posli_sms(3);}
	 _delay_ms(400);
	}    
  }
   
   
  if (!(PINA & (1<<OK4))) 
  {
   if (!(priznak & (1<<strez))) // vykona jen kdyz je zastrezeno
    { 

      if (set_status & (1<<REL3_poplach))   {PORTC |= (1<<REL3);}
      priznak |= (1<<poplach); 
	  if (set_status & (1<<sms_e))	 {posli_sms(4);}
	   _delay_ms(400);
    }    
  }			
				

  if (!(PINA & (1<<OK5))) 
  {
   if (!(priznak & (1<<strez)))
    { 
	
      if (set_status & (1<<REL3_poplach))   {PORTC |= (1<<REL3);}
      priznak |= (1<<poplach); 
	  if (set_status & (1<<sms_e))	 {posli_sms(5);}
	   _delay_ms(400);
	}    
  }			
 }

//---------------------------

void format_sim ()
{
 if (!(PINB & (1<<TL))) // je li tl stisknuto vykonej
  {
   for (volatile uint8_t i = 0; i<8 ;i++)
   {
    if (!(PINB & (1<<TL)))// casuje dokut se drzi tlac
	 {                        
    PORTA  &= ~(1<<LED1);
    PORTA |= (1<<LED2);
	_delay_ms(1000);
    PORTA  &= ~(1<<LED2);
	PORTA |= (1<<LED1);
	_delay_ms(1000);
    }
	else{ i =7;}
   
    }
   // cas dosel overi stale stik tl  a vzkona fci
   if (!(PINB & (1<<TL))) 
   {
	PORTA |= (1<<LED2); 
	PORTA |= (1<<LED1); // kdyz signalizace zacatku formatu
	//********nastavi eeprom***
	eeprom_write_word(0x02,0b00010101); // BIT 1 sms, 2 rele, 4 ost. proy,  0 bit ovladat rele proyv. 
    //*****	
	
  sprintf ( buffer_0 , "at+cpbw=7,+420,,TEL1") ; //Vytvori novy zaznam na SIM pozice 7 - MASTER 
  USART_putstring_0(buffer_0);
  USART_send_0(0x0d);
  _delay_ms(500);	

  sprintf ( buffer_0 , "at+cpbw=8,+420,,TEL2") ; 
  USART_putstring_0(buffer_0);
  USART_send_0(0x0d);
  _delay_ms(500);	
  
  sprintf ( buffer_0 , "at+cpbw=9,+420,,TEL3") ; 
  USART_putstring_0(buffer_0);
  USART_send_0(0x0d);
  _delay_ms(500);
  
  sprintf ( buffer_0 , "at+cpbw=10,+420,,TEL4") ; 
  USART_putstring_0(buffer_0);
  USART_send_0(0x0d);
  _delay_ms(500);	
  
  //******************SMS***********
  //****************************Vytvori(preddefinuje prazdne sms) SMS************

      _delay_ms(10000);
	 sprintf ( buffer_0 , "AT+CMGF=1"); //sms v text rezimu
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	 

     sprintf ( buffer_0 , "AT+CMGD=1"); // smaze SMS (uvolni pozice) 
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(200);

     sprintf ( buffer_0 , "AT+CMGD=2"); 
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	 
     sprintf ( buffer_0 , "AT+CMGD=3"); 
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	 
	 sprintf ( buffer_0 , "AT+CMGD=4"); 
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	 
     sprintf ( buffer_0 , "AT+CMGD=5");  
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	 
     sprintf ( buffer_0 , "AT+CMGD=6"); 
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	 
     sprintf ( buffer_0 , "AT+CMGD=7"); 
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);	 	 	  	 

     sprintf ( buffer_0 , "AT+CMGD=8"); 
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);	
	 
	 sprintf ( buffer_0 , "AT+CMGD=9"); // dalsi prichozi bude na pozici 10 !!
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);	
//------  vytvori prazdne sms
     
     sprintf ( buffer_0 , "AT+CPMS="); 
     USART_putstring_0(buffer_0);
	 _delay_ms(10);
	  USART_send_0('"'); // kvuli uvozovkam
	  USART_send_0('S'); // nastavi pamet SIM
	  USART_send_0('M'); // kvuli uvozovkam
	  USART_send_0('"');
	  USART_send_0(',');
	  USART_send_0('"'); 
	  USART_send_0('S'); 
	  USART_send_0('M');
	  USART_send_0('"');
	  USART_send_0(',');
	  USART_send_0('"'); 
	  USART_send_0('S'); 
	  USART_send_0('M');
	  USART_send_0('"');
	  
	 USART_send_0(0x0d);
	 _delay_ms(900);

  
	//------------zahajeni tvorbu SMS--------- 
	 sprintf ( buffer_0 , "AT+CMGw"); //ukladani na SIM - jen poprve asi
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
	 
	 sprintf ( buffer_0 , "ZONA 1"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0); 
	 USART_send_0(0x1a);
	 _delay_ms(2000);
	 
	 sprintf ( buffer_0 , "AT+CMGw"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
     	 
	 sprintf ( buffer_0 , "ZONA 2"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0); 
	 USART_send_0(0x1a); 
    _delay_ms(2000);
	 
	
	
	 sprintf ( buffer_0 , "AT+CMGw"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	  _delay_ms(300);
     	 
	 sprintf ( buffer_0 , "ZONA 3"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0); 
	 USART_send_0(0x1a); 
	 _delay_ms(2000);


     sprintf ( buffer_0 , "AT+CMGw"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	 _delay_ms(300);
     
	 
	 sprintf ( buffer_0 , "ZONA 4"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0); 
	 USART_send_0(0x1a); 
	_delay_ms(2000);


	 sprintf ( buffer_0 , "AT+CMGw"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	  _delay_ms(300);
     
	 
	 sprintf ( buffer_0 , "ZONA 5"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0); 
	 USART_send_0(0x1a); 
	 _delay_ms(2000);


	 sprintf ( buffer_0 , "AT+CMGw"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0);
	 USART_send_0(0x0d);
	  _delay_ms(300);
	 
	 sprintf ( buffer_0 , "ZONA 6"); //prace s sms v textovem rezimu
     USART_putstring_0(buffer_0); 
	 USART_send_0(0x1a); 
	 _delay_ms(2000);
  	
    }
   }
    PORTA  &= ~(1<<LED2); // po dokonceni zhasne LED
	PORTA  &= ~(1<<LED1); 	
}
 	  	
void init()
{

#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif


PORTA = 0b11111111;
DDRA =  0b00000011; //PA0-2 vystup LED a Ovladani nabijeni - zybtek vstupy OD poplachu + AD aku
PORTA = 0b11111111; // enable pull up

//PORTD = 0x00;
DDRD = 0b00110000; // PD4-5 vystup na zapnuti GSM a Config RS248

PORTB = 0x00;
DDRB = 0b00000000; // PB1 a PB2 vstupy od INIT poplach a vstup Tlac.

PORTC = 0x00;
DDRC = 0b11011111; // PC5 vstup detekce vypadku napajeni jinak ovladaci vystupy
	



// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: On
// INT2 Mode: Any change
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-15: Off
// Interrupt on any change on pins PCINT16-23: Off
// Interrupt on any change on pins PCINT24-31: Off
EICRA=0x10;
EIMSK=0x04;
EIFR=0x04;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;


//*********************************USART na GSM modul*******************
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600 //19200
UCSR0A=0x00;
//UCSR0B=0x18; //puvodni  
UCSR0B=0x00;
UCSR0B |= (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0); //UCSR0B=0x18;  
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x81;  





//****************************USART na vzdalenou jednotku*****************
// USART1 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART1 Receiver: On
// USART1 Transmitter: On
// USART1 Mode: Asynchronous
// USART1 Baud Rate: 9600
UCSR1A=0x00;
//UCSR1B=0x18;
UCSR1B=0x00;
UCSR1B |= (1<<TXEN1)|(1<<RXEN1)|(1<<RXCIE1);
UCSR1C=0x06;
UBRR1H=0x00;
UBRR1L=0x81;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR1=0x00;


// ADC initialization
// ADC Clock frequency: 625,031 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: Free Running
// Digital input buffers on ADC0: Off, ADC1: Off, ADC2: On, ADC3: Off
// ADC4: Off, ADC5: Off, ADC6: Off, ADC7: Off
DIDR0=0xFB;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0xA5;
ADCSRB&=0xF8;


	
	 
 _delay_ms(1500); // overeni vzdalene jed.
 sprintf ( buffer_0 , "a") ;
 USART_putstring_1(buffer_0);

set_status = eeprom_read_byte(0x02); // nacte nastaveni z eeprom

format_sim ();
sei();
BufferInit(&buf);

PORTC |= (1<<ODP_aku);  // pripoji akumulator 



//
_delay_ms(2000);
PORTC &= ~ (1<<ENA_nab); // na test pripoji
_delay_ms(2000);
PORTC |= (1<<ENA_nab); // odpoji nabijeni


}

int main(void)
{
 	
  init();       // zavola inicializaci
  init_GSM ();  //
  
    while(1)
    {
		
	 napajeni();
	 prozvon_poplach();
	 prozvon_kr();
	 ping_vzdal();
	  
    _delay_ms(10000);
	 
      prichozi_hov ();
	 _delay_ms(400);
      prichozi_SMS();
      tl_vyp ();   


	_delay_ms( 2000 );
	 PORTA |= (1<<LED2);
   	_delay_ms( 2000 );
    PORTA  &= ~(1<<LED2);
  
  
   }
return(0);	
}