//pripojenie potrebnych kniznic
#include <avr/io.h>
#include <stdio.h>
#include "lcd.h"
#include "serial.h"
#include <string.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "LCDlibrary.h"


//Pomocne funkcie na spustenie a zastavenie casovaca

#define TIMER_STOP() bits_clear(TCCR0B,(bit(CS02)|bit(CS01)|bit(CS00)));TCNT0=0
#define TIMER_START() TCNT0+=5;bits_set(TCCR0B,(bit(CS01)|bit(CS00)))




//Makra na pracu s bitmi
#define bit(m)		((1<<m))
#define bit_set(p,m) ((p) |= bit(m))
#define bits_set(p,m)	((p) |= (m))
#define bits_clear(p,m) ((p) &= ~(m))




FILE mystdout=FDEV_SETUP_STREAM(sendchar,NULL,_FDEV_SETUP_WRITE); 



//zadefinovanie premennych
int stara=0;
char zobraz[8]={0};
int aktual=0;
int meranie=0;
volatile uint32_t milisekunda;

// A/D converter initialization
void adc_init(void)                                    
{
  ADMUX = 0b01000100;                                  // Ref: external, Channel 4 (ADC4) - NTC
  ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // =0b10000111, A/D ON, prescaler = 128 
}




int main(void) {
	   
	inituart();				// inicializacia seriovej linky
	lcdInit4();                             // inicializacia v 4-bitovom rezime
	adc_init();				// inicializacia AD prevodnika
    lcdControlWrite(LCD_CLR);               	// vymazanie displeja
	stdout = &mystdout;			// odteraz funguje printf();
	
	lcd_puts_addr(0x01,"Ready");
	
	bit_set(TIMSK0,TOIE0);			//Povolenie prerusenia Casovaca 0	
	sei();	


	while(1)
	{
		//nacitanie referencnych hodnot z ADC
		stara= aktual;					// Do premennej stara ulozime predchadzajuci vypocet AD prevodnika
		ADCSRA |= (1<<ADSC);                            // Start A/D conversion
   		while ( !(ADCSRA & (1<<ADIF)));                 // Wait until AD not finished
    	aktual=ADC;						// Aktualna hodnota vypocitana ADC
	
		if (milisekunda>0)
		{
		sprintf(zobraz,"%d ms",milisekunda);		// ulozenie casu v milisekundach do smernika zobraz
		lcd_puts_addr(0x40,zobraz);
		}		

		//spustenie casovaca pri prechode pod senzorom
		if ((meranie == 0)&&(aktual<(stara-100))) //&& (meranie==0))
		{
			
			lcd_puts_addr(0x00,"Counting");
			
   			TIMER_START();
					
			meranie =1;				// zmena premennej, vdaka ktorej mozeme zastavit casovac
			
		}
		
		
		//Zastavenie casovaca po dalsom prechode objektu pred snimacom
		else if  ((meranie==1)&&(aktual < (stara-100))) //&& (meranie == 1) )
		{
			
			lcd_puts_addr(0x00,"Stopped ");
			
			TIMER_STOP();			

			meranie=0;			
			
		}
		
		

		// Pouzitie tlacidiel
		if (ReadButtons() == 1 && meranie==0)		// Prve tlacidlo zastavi casovanie a vymaze display
		{						// ked je pocitanie stopnute
			milisekunda=0;
			lcd_clrscr();
			lcd_puts_addr(0x00," Ready");


		}

		else if (ReadButtons() == 2 && meranie==1)	// Pri pocitani intervalu vymaze hodnotu a
		{						// pokracuje v pocitani od nuly
			milisekunda=0;							
			lcd_clrscr();
			lcd_puts_addr(0x00,"Counting");			
			TIMER_START();
		}

		
		//Program pripraveny pre ostatne dve tlacidla podla potreby uzivatela

		/*else if (ReadButtons() == 4)
		{
			
		}
		else if (ReadButtons() == 8)
		{
			
		}*/
		
		
	
	}
	return 0;
}


//Obsluha prerusenia pre casovac 0
ISR(TIMER0_OVF_vect)
{
	TCNT0+=5;							//Pre presnejsiu hodnotu (1ms) je potrebne inkrementovat register casovaca
	milisekunda++;							//premenna obsahujuca pocet milisekund (32bit hodnota)
}
