// kniihovna pro RFM12B moduly
// NUTNO změnit nastavení spi_init(); podle poouitého MCU !!!!!

#include "rfm.h"



//------------------------------------
//spi initialization
//-----------------------------------
void spi_init(void){
	DDR_SPI=0;
	DDR_SPI |= (1<<MOSI)|(1<<SCK)|(1<<SS);
	SPCR |=(1<<SPE)|(1<<MSTR)|(1<<SPR0);
	SPSR=1;
										// Porty, Piny, DDR nastavení pro Master - zřízení č. 1
	DDRA|=(1<<0)|(1<<1)|(1<<2);				// RTC 
	PORTA&=~(_BV(0)|_BV(1)|_BV(2));				// RTC
	DDRD = 0x82;						// tl, piezo, uart
	PORTD = 0xBE;						// talčítka, UART, piezo

	//EEPROM_clear();
	readtime();
	//EEPROM_write(0,27);					//porovnávací úroveň sepnutí rel0
	//EEPROM_write(1,28);					//porovnávací úroveň sepnutí rel1
	//EEPROM_write(2,33);					//porovnávací úroveň varování
}
//------------------------------------
//spi send and receive two bytes simultaneously
//-----------------------------------
  unsigned int rf_writecmd(unsigned int cmd){
	unsigned int receive=0;
	PORT_SPI &= ~(_BV(SS));
	if(ID1[0]==1)
	SPDR=(cmd>>8);
	wait_spi_complete();
	receive=SPDR<<8;
	SPDR=cmd;
	wait_spi_complete();
	receive|=SPDR;
	PORT_SPI |= _BV(SS);
	return receive;
  }
//------------------------------------
//rfm inicializace
//-----------------------------------
  void rf_init(void) {
    rf_writecmd(0x80E7); //EL,EF,868band,12.0pF
    rf_writecmd(0xA640); //frequency select
    rf_writecmd(0xC623); //4.8kbps
    rf_writecmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
    rf_writecmd(0xC2AC); //AL,!ml,DIG,DQD4
    rf_writecmd(0xCA81); //FIFO8,SYNC,!ff,DR
    rf_writecmd(0xCED4); //SYNC=2DD4
    rf_writecmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
    rf_writecmd(0x9850); //!mp,90kHz,MAX OUT
    rf_writecmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDITCBW0
    rf_writecmd(0xE000); //NOT USED
    rf_writecmd(0xC800); //NOT USED
    rf_writecmd(0xC040); //1.66MHz,2.2V
  }
//------------------------------------
//poslat data
//-----------------------------------
void rf_send(unsigned char data){
	  
    WAIT_NIRQ_LOW();
	
    rf_writecmd(0xB800 + data);
  }
//------------------------------------
//sleep (reim idle)
//-----------------------------------
void rf_sleep(void){
  rf_writecmd(0x8201); 
  rf_writecmd(0x0000);
}
//------------------------------------
//Transmitter
//-----------------------------------
void rf_transmitter(void){
  rf_writecmd(0x8239); //er,!ebb,ET,ES,EX,!eb,!ew,DC 
  rf_writecmd(0x0000);
}
//------------------------------------
//Receiver
//-----------------------------------
void rf_receiver(void){
  rf_writecmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC (bug was here)
  rf_writecmd(0x0000);
}
//----------------------------------
//reset bufferu
//----------------------------------
void rf_fifo_reset() {		
  rf_writecmd(0xCA81);
  rf_writecmd(0xCA83);
  }
//----------------------------------
//Hlavička zprávy
//----------------------------------
void rf_head(void) {		
	rf_writecmd(0);
	rf_send(0xAA);
	rf_send(0xAA);
	rf_send(0xAA);
	rf_send(0x2D);
	rf_send(0xD4);
  }
//----------------------------------
//Konec zprávy
//----------------------------------
void rf_end(void) {		
	rf_send(0xAA);
	rf_send(0xAA);
	rf_send(0xAA);
  }

//-------------------------------------
  //funkce pro čtení z bufferu
//-------------------------------------
unsigned char rf_read(void) {
	return (rf_writecmd(0xB000)&0xff);
  }
//-------------------------------------
// Poslání celé zprávy
//-------------------------------------
void zprava(char *znaky){
unsigned char pom3;
	rf_transmitter();

	rf_head();
	while(( pom3 = *znaky++ )){
        rf_send(pom3);
		}
	rf_end();
	rf_receiver();
}
//---------------------------------
// Poslání zprávy o 4 znacích
//-------------------------------------
void zprava4(char *znaky){
char j;
	rf_transmitter();
	
	rf_head();
	for(j=0;j<4;j++){
        rf_send(*znaky++);
		}
	rf_end();
	rf_receiver();
}
//----------------------------------------
// Příjem zprávy o 4 znacích
//----------------------------------------
void precist(char *kam){
	unsigned char jj;
	for(jj=0;jj<4;jj++){
	while(bit_is_clear(PIN_SPI,FFIT))
	continue;
	*kam=rf_read();
	kam++;
	_delay_us(10);
		}
	rf_fifo_reset();
	}
/*-----------------------------------------
 poslání jednoho datového paketu - ID, parametr, data ; 
 vrací hodnotu poslanou ze Slave, jestlie zpráva nepříjde, nebo je
 pokozená, vrací číslo 255

-----------------------------------------*/

unsigned char datapaket( char *ID, char parametr, char data){
 char msg[4],pom[4]={0,0,0,0},q,opak=2;
	msg[0]=*ID++;
	msg[1]=*ID;
	msg[2]=parametr;
	msg[3]=data;
	for(q=0;q<opak;q++){
		 zprava4(msg);
 		 int0=0;
		 while(int0<waitmsg){					//čekání na příchozí zprávu
			if(bit_is_set(PIN_SPI,FFIT)){
				precist(pom);
				q=opak;
				break;
				}		
			  _delay_us(1);
			  }
			}
	q=255;		
	if((pom[0]==msg[0]) & (pom[1]==msg[1])&(pom[2]==msg[2])){	
			q=pom[3];}
				
		return(q);	
			}

/********************************************
 BASE2 - vyslání času,  načtení teploty ze slave2 vrací počet erorů
------------------------------------------*/
unsigned char base(char *ID){
char err=0,tep01,tep02;
	  if(*ID==ID2[0]){
		if((tep01=datapaket(ID2,'t',teplota))>150)			//na teplotu je posílán poadavek 2x
			err++;											//tyto dvě změřené teploty musí být shodné
		else{		
			if((tep02=datapaket(ID2,'t',teplota))>150)
				err++;
			else{
				if(tep01==tep02)
				teplota=tep01;
				 }
			}
	  }
	  if(*ID==ID1[0]){
	  	if((datapaket(ID1,'T',teplota))>150)			//na teplotu je posílán poadavek 2x
			err++;											//tyto dvě změřené teploty musí být shodné
		else{		
			if((datapaket(ID1,'T',teplota))>150)
				err++;
				}
	  }

		if((datapaket(ID,'H',hodiny()))==255)
			err++;
		if((datapaket(ID,'M',minuty()))==255)
			err++;
	return(err);
}
/********************************************
 parameters_out - varování, nastevení
  vrací počet erorů
------------------------------------------*/
unsigned char parameters_out(char *ID){
char err=0;
	
	if((datapaket(ID,'R',rel0))==255)
			err++;;
	if((datapaket(ID,'L',rel1))==255)
			err++;
	if((datapaket(ID,'W',warning))==255)
			err++;
	return(err);
}
/********************************************
 parameters_in - načtení ze slave varování, nastevení
  vrací počet erorů 
------------------------------------------*/
unsigned char parameters_in(char *ID){
unsigned char err=0;

	if((rel0=datapaket(ID,'r',0))==255)
			err++;
	if((rel1=datapaket(ID,'l',0))==255)
			err++;
	if((warning=datapaket(ID,'w',0))==255)
			err++;
	return(err);
			}
/*pp****************************************
zápis do EEPROM na poadovanou adresu
------------------------------------------*/
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEWE));
EEAR = uiAddress;
EEDR = ucData;
/* Write logical one to EEMWE */
EECR |= (1<<EEMWE);
/* Start eeprom write by setting EEWE */
EECR |= (1<<EEWE);
while(EECR & (1<<EEWE));
}
/*pp****************************************
čtení z EEPROM z dané adresy
------------------------------------------*/
unsigned char EEPROM_read(unsigned int uiAddress)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEWE));
EEAR = uiAddress;
/* Start eeprom read by writing EERE */
EECR |= (1<<EERE);
/* Return data from data register */
return EEDR;
}
/*pp****************************************
nový zápis do EEPROM na přítí adresy (počet řádků záznamu je uveden na adrese 1)
	kadý záznam má tři řádky (den, měsíc, událost)
------------------------------------------*/
void EEPROM_write_new(unsigned char data){
unsigned int rows;
unsigned char count,pom01;
	count=EEPROM_read(3);					//počet záznamů je uveden na řádku 3 (maximum je 170)
	if(count>168)
		EEPROM_clear();
	rows=(count*3)+4;
	pom01=dny();
	EEPROM_write(rows,pom01);				
	rows++;
	pom01=mesice();
	EEPROM_write(rows,pom01);
	rows++;
	EEPROM_write(rows,data);
	count++;
	EEPROM_write(3,count);
	par_set=1;									//vynucení přenosu nastavovacích signálů
}
/*****************************************
vymazat EEPROM
------------------------------------------*/
void EEPROM_clear(void){
		EEPROM_write(3,0);
		}
/*****************************************
vyčtení EEPROM a odeslání na UART
------------------------------------------*/
void EEPROM_read_send(void){
unsigned int rows;
unsigned char count;
	count=EEPROM_read(3);					//počet záznamů je uveden na řádku 1 (maximum je 170)
	rows=4;
	while(rows<(count*3+4)){
		while ( bit_is_clear(UCSRA,UDRE));
		UDR=EEPROM_read(rows);
		while (bit_is_clear(UCSRA,TXC));
		UCSRA&=~(_BV(TXC));
		rows++;
		}
	}
/*****************************************
porovnání stavů a provedení výkonů
------------------------------------------*/
void compare(void){
unsigned char tep_mem;
		tep_mem=EEPROM_read(0);					//rozhodovací úroveň pro sepnutí rel0 je na pozici 0
			if((teplota>=tep_mem)&(rel0==0)){
				rel0=1;
				EEPROM_write_new(1);			//zápis do EEPROM = 1 ... zapnutí relé0
				}
			if((teplota<=(tep_mem-2))&(rel0==1)){
				rel0=0;
				EEPROM_write_new(2);			//zápis do EEPROM = 2 ... vypnutí relé0
				}

			if (rel0==4){						//relé 0 vypnuto manuálně
				rel0=2;							// oetřeno tak, aby se zapsalo do EEPROM jen jednou
				EEPROM_write_new(8);
				}
			if (rel0==5){						//relé 0 zapnuto manuálně
				rel0=3;							// oetřeno tak, aby se zapsalo do EEPROM jen jednou
				EEPROM_write_new(9);
				}
			if (rel1==4){						//relé 1 vypnuto manuálně
				rel1=2;							// oetřeno tak, aby se zapsalo do EEPROM jen jednou
				EEPROM_write_new(10);
				}
			if (rel1==5){						//relé 1 zapnuto manuálně
				rel1=3;							// oetřeno tak, aby se zapsalo do EEPROM jen jednou
				EEPROM_write_new(11);
				}

		tep_mem=EEPROM_read(1);					//rozhodovací úroveň pro sepnutí rel1 je na pozici 1
			if((teplota>=tep_mem)&(rel1==0)){
				rel1=1;
				EEPROM_write_new(3);			//zápis do EEPROM = 3 ... zapnutí relé1
				}
			if((teplota<=(tep_mem-2))&(rel1==1)){
				rel1=0;
				EEPROM_write_new(4);			//zápis do EEPROM = 4 ... vypnutí relé1
				}
		tep_mem=EEPROM_read(2);					//rozhodovací úroveň pro sepnutí varování je na pozici 2
			if((teplota>=tep_mem)&(warning==0)){
				warning=1;
				if (rel0!=3)
					rel0=1;
				if (rel1!=3)
					rel1=1;
				EEPROM_write_new(5);			//zápis do EEPROM = 5 
				}
			if((teplota<=(tep_mem-2))&(warning>0)){
				warning=0;
				par_set=1;							//vynucení přenosu nastavovacích signálů
				}
			if(warning==1){
				PIP_ON
				LIGHT_ON
				_delay_ms(50);
				LIGHT_OFF
				PIP_OFF
				}
		}
/*****************************************
zobrazení obrazpvky v pohotovosti
------------------------------------------*/
void disp_view(void){
char text[16],h,m;
		lcd_gotoxy(13,0);
		lcd_puts("   ");
		lcd_gotoxy(0,0);
		m=minuty();
		h=hodiny();
		if((h<10)&(m<10))												//výpis na disp.
				sprintf(text,"%d%cC    0%d:0%d",teplota,178,h,m);
			else if(m<10)
				sprintf(text,"%d%cC    %d:0%d",teplota,178,h,m);
			else if(h<10)
				sprintf(text,"%d%cC    0%d:%d",teplota,178,h,m);
			else
				sprintf(text,"%d%cC    %d:%d",teplota,178,h,m);
		lcd_puts(text);
		lcd_gotoxy(0,1);
		if((rel0==1)|(rel0==3))
				lcd_puts("R0-ZAP  ");
		else		
				lcd_puts("R0-VYP  ");
		
		if((rel1==1)|(rel1==3))
				lcd_puts("  R1-ZAP");
		else		
				lcd_puts("  R1-VYP");
	}
