
#define F_CPU 16000000					// frekvence krystalu
#include <math.h>
#include <avr/io.h>						// I/O vstupy ATmega16
#include <util/delay.h>					// knihovna easu
#include <avr/interrupt.h>
#define LCD
#include "mojelib1.h"					// knihovna pro LCD
#include "twi_lib.h"					// knihovna i2c/twi
//#include "twi_lib.c"

/*--------------------------------------------------------*/
//otestujeme jestli jsou koeficienty opravdu jako v datasheetu.
#define READ_EEPROM 0xA1 	// adresa pro čtení (0xA0+1)
#define WRITE_EEPROM 0xA0
#define READ_AD 0xEE


void vypis(void);
void icoef(void);
void khz(void);
unsigned int teplota(void);
unsigned int tlak(void);
void teplota_a_tlak(void);
long int Get2_x(unsigned char i);
void Pocitej(void);
void reset_high(void);
void reset_low(void);


unsigned int C1;
unsigned int C2;
unsigned int C3;
unsigned int C4;
unsigned int C5;
unsigned int C6;
unsigned int C7;
unsigned char A;
unsigned char B;
unsigned char C;
unsigned char D;


unsigned int D1;
unsigned int D2;

float DUT;
float OFF;
float SENS;
float X;
float Press;
float Temperatur;
//long Altitude;

char buffer1[16];
char buffer2[16];


int main (void)
{
		sei();


		khz();	//spusti 32 khz

		_delay_ms(100);

		i2c_init();
		icoef(); // vyčte koeficienty C1 az D z eeprom

	while (1)
	{
		DDRB=0xff;
		PORTB = 0x00;
		teplota_a_tlak();	//zmeri teplotu a tlak
		Pocitej(); //spocita teplotu a tlak
		TWCR =0x00;//vypne i2c

		dtostrf(Temperatur, 2, 2, buffer1);
		//itoa(D1,buffer1,10);
   		dtostrf(Press, 5, 2, buffer2);


	DDRC = 0xff;//c je vystup
	PORTC = 0b11000010; //povoleni lcd


	init_lcd();			//inicializace LCD
	_delay_ms(5);

	cls();				// smazání LCD displeje
	_delay_ms(5);


	line_1();
	lcd_text("Tep:");
	gotoxy(1,6);
	lcd_puts(buffer1);
	gotoxy(1,16);
	lcd_text("C");

	line_2();
	lcd_text("Tlk:");
	gotoxy(2,6);
	lcd_puts(buffer2);
	gotoxy(2,14);
	lcd_text("hpa");
	_delay_ms(500);
	}
	return 1;
}




//-------------------funkce---------------//
void icoef(void)
{
	unsigned char ucValue;

	i2c_start_wait(WRITE_EEPROM);
	i2c_write(16); //zaciname na 16. registru
	//i2c_stop();

	i2c_rep_start(READ_EEPROM);

	ucValue=i2c_readAck();
	C1=ucValue;
	ucValue = i2c_readAck();
	C1 <<= 8;
	C1 |= ucValue;

	ucValue=i2c_readAck();
	C2=ucValue;
	ucValue = i2c_readAck();
	C2 <<= 8;
	C2 |= ucValue;

	ucValue=i2c_readAck();
	C3=ucValue;
	ucValue = i2c_readAck();
	C3 <<= 8;
	C3 |= ucValue;

	ucValue=i2c_readAck();
	C4=ucValue;
	ucValue = i2c_readAck();
	C4 <<= 8;
	C4 |= ucValue;

	ucValue=i2c_readAck();
	C5=ucValue;
	ucValue = i2c_readAck();
	C5 <<= 8;
	C5 |= ucValue;

	ucValue=i2c_readAck();
	C6=ucValue;
	ucValue = i2c_readAck();
	C6 <<= 8;
	C6 |= ucValue;

	ucValue=i2c_readAck();
	C7=ucValue;
	ucValue = i2c_readAck();
	C7 <<= 8;
	C7 |= ucValue;

	ucValue=i2c_readAck();
	A=ucValue;

	ucValue=i2c_readAck();
	B=ucValue;

	ucValue=i2c_readAck();
	C=ucValue;

	ucValue=i2c_readNak();
	D=ucValue;
	i2c_stop();


}

unsigned int teplota(void)
{
	unsigned char ucData;
	unsigned int wADT;

	i2c_start_wait(READ_AD);
	i2c_write(0xff);
	i2c_write(0xE8);
	i2c_stop();

	_delay_ms(40);

	i2c_rep_start(READ_AD);
	i2c_write(0xFD);
	i2c_rep_start(0xEF);

	ucData = i2c_readAck();
	wADT = ucData;
	wADT <<= 8;
	ucData = i2c_readNak();
	i2c_stop();
	wADT |= ucData;

	return wADT;
}

unsigned int tlak(void)
{
	unsigned char ucData;
	unsigned int wADp;

	i2c_start_wait(READ_AD);
	i2c_write(0xff);
	i2c_write(0xF0);
	i2c_stop();

	_delay_ms(45);

	i2c_rep_start(READ_AD);
	i2c_write(0xFD);
	i2c_rep_start(0xEF);

	ucData = i2c_readAck();
	wADp = ucData;
	wADp <<= 8;
	ucData = i2c_readNak();
	i2c_stop();
	wADp |= ucData;

	return wADp;

}


void teplota_a_tlak(void)
{
	long uiSumADValue;
	uiSumADValue = 0;
	reset_high();
	_delay_ms(2);

	D1 = tlak();
	uiSumADValue += D1;
	D1= tlak();
	uiSumADValue += D1;
	D1= tlak();
	uiSumADValue += D1;
	D1= tlak();
	uiSumADValue += D1;
	D1=uiSumADValue >> 2;

	D2=teplota();

	reset_low();
	//mozna pridat i twir=0x00; a mozna vypnout i clock
}

long int Get2_x(unsigned char i) //vypocte dva na ntou
{
	long int uiData;
	uiData=2;
	i=i-1;
 while(i)
 	{
		uiData <<= 1;
		i--;
	 }
 return uiData;
}

void Pocitej(void)
{
	float middle1;
	float middle2;
	float middle3;
	float middle4;

	//vypocitat DUT
	if(D2<C5)
   	 {
		middle1 = (float)D2-(float)C5;
		middle2 = (middle1*middle1)/16384;
		middle3 = middle2*B;
		middle4 = Get2_x(C);
		middle4 = middle3/middle4;
		DUT = middle1 - middle4;
	 }
	else
	 {
		middle1 = (float)D2-(float)C5;
		middle2 = middle1*middle1/16384;
		middle3 = middle2*A;
		middle4 = Get2_x(C);
		middle4 = middle3/middle4;
		DUT = middle1 - middle4;
	 }

	//vypocitat OFF
	middle1=(float)C4-1024;
	middle2=16384;//Get2_x(14);
	middle3=DUT*middle1;
	middle4=middle3/middle2;
	middle4=(float)C2+middle4;
	OFF = middle4*4;

	//vypocet SENS
	middle1=(float)C3*DUT;
	middle2 = 1024;//Get2_x(10);
	middle3 = middle1/middle2;
	SENS = C1+middle3;

	//vypocti X
	middle1=16384;//Get2_x(14);
	middle2=(float)D1-7168;
	middle3=middle2*SENS;
	middle4=middle3/middle1;
	X=middle4-OFF;

	//vypocet tlaku na 2 decimal
	middle1=X*100;
	middle2=32;//Get2_x(5);
	middle3=middle1/middle2;
	middle4=C7*10;
	Press = middle3+middle4;
	Press = Press/100;//jen proto, aby to sedelo s predpovedi

	//vypocet teploty
	/*middle1=DUT*C6;
	middle1=middle1/65536;//Get2_x(16);
	middle2=DUT/Get2_x(D);
	middle3=250+middle1-middle2;
	Temp=middle3;*/
	Temperatur = 250+((DUT*C6)/65536)-(DUT/Get2_x(D));
	Temperatur = (Temperatur/10)-10;
}

void reset_high(void)
{
	DDRB=0b00000001;
  	PORTB=0b00000001;
}

void reset_low(void)
{
	DDRB=0b00000001;
  	PORTB=0b00000000;
}


void vypis(void)
{
		DDRC = 0xff;
		PORTC = 0b11000010;
		cls(); // smaže displej
		_delay_ms(2);

		gotoxy(1,1);
		lcd_text("koef1:");
		gotoxy(1,9);
		lcd_byt(A);
		_delay_ms(10);

		gotoxy(2,1);
		lcd_text("koef2:");
		gotoxy(2,9);
		lcd_byt(B);
		_delay_ms(1000);
		//_delay_ms(1000);

}

void khz(void)//generuje 32 khz z oc2
{
	DDRD=0b10000000;

		TCCR2|=(1<<WGM21)|(0<<WGM20)|(1<<COM20)|(1<<CS21);
		OCR2=30; //generuje khz  f= f(proc)/(2*preddelicka*(1+OCR2))
}
