// f_cpu 128kHz, CLDIV8 kikapcsolva, ATiny45


#include <avr/io.h>         //avr/io.h=m16def.inc-el csak itt automatikusan megy nem kell külön jelezni melyik uC
#include <avr/interrupt.h>  //ez tartalmazza az ISR makrókat (megszakításokat)
#include <util/delay.h>		//időzítés _delay_us(), és _delay_ms() függvényeket tartalmazza
#include <avr/wdt.h>		//Watchdog kikapcsolásához kell    
 
#define WHT()			 PORTB = 0b00001111 //fehér (mind)

#define RED()         	 PORTB = 0b00001001 //csak piros PB0 

#define YLLW()       	 PORTB = 0b00001011 //piros-zöld=sárga 

#define GRN()        	 PORTB = 0b00001010 //csak zöld PB1
	
#define CYAN()       	 PORTB = 0b00001110 //zöld-kék=cián

#define BLUE()			 PORTB = 0b00001100 //csak kék PB2

#define MAG()			 PORTB = 0b00001101 //piros-kék=magnetta

#define LED_OFF()        PORTB = 0b00001000 // semmi

#define SYS_OFF()        PORTB = 0b00000000 // kikacsolás ha a PB3 alacsonyra váltsuk (erre külső alkarészek megszakítják a teljes árramellátást)

// ----- Globális változó -------
volatile unsigned short b; 		// 0 - 65535 

// ------- változók ------
unsigned char a;
//a = 0;
unsigned short adc;

// --- m_delay_10ms definiálása --
void m_delay_10ms(unsigned long val) {
           while(val--) _delay_ms(10);}



// ----- init ------
void init(void)				//külső függvény nincs bemenő se kimenő paraméter, csak szimplán lefut
        {
		wdt_disable();			//watchdog kipakcsolása

		PRR= 0b00001010;		// energiatakarékosság, kikapcsoljuk a Timer1 és USI modult

        DDRB= 0b00001111;		//kimenettek def.

// ---------  ADC -------
		DIDR0 = (1<<ADC1D);		//digitális port lekapcsolása az ad bemenetről
		ADMUX = 0b10000000;     // Belső 1.1v referencia kiválasztása

        ADCSRA =  (1<<ADEN)     // bekapcsoljuk az ADC-t

               |  (0<<ADATE)    // auto trigger endély - tiltva

               |  (0<<ADSC);    // start conv.

// -------- TIMER0 -------
        TCCR0B = 0b00000101;		//előosztást beállítjuk, most 1024, és belső órajelről megy
              
		TIFR = 0b00000010;		// overflow flag - ha ezt nem állítjuk 1-re nem történik megszakítás túlcsorduláskor

        sei();					//engedélyezzük hogy a megszakítás hívást
        } 						//init vége

// --------  adc  --------
unsigned short ADConvert(unsigned char channel) {
		ADMUX &= ~(1<<MUX1|1<<MUX0);

		ADMUX |= channel;

        ADCSRA |= (1<<ADSC);

        while(ADCSRA & (1<<ADSC));

        return ADC;}



// -------- MAIN --------
int main(){

extern volatile unsigned short b;




	init(); // portok beállításai lefuttatása

   	for (;;) {			
	if (a == 0)	{									// bekapcsolás utáni "animáció", csak bekapcsoláskor fut le
								m_delay_10ms(30);	// kezdeti várás
								WHT();				//fehér be
  								m_delay_10ms(10);	// vár
								LED_OFF();			// fehér ki
								m_delay_10ms(30);	// vár
								WHT();				//fehér be
								m_delay_10ms(25);	// vár
								LED_OFF();			// fehér ki
								a++ ;}
	else{
	if (b == 1100){									// ha "b" eléri a kívánt értéket kikapcsolás animációval
								WHT();				//fehér be
								m_delay_10ms(10);	// vár
								LED_OFF();			// fehér ki
								m_delay_10ms(35);	// vár
								WHT();				//fehér be
								m_delay_10ms(10);	// vár
								LED_OFF();			// fehér ki
								m_delay_10ms(35);	// vár
								WHT();				//fehér be
								m_delay_10ms(10);	// vár
								SYS_OFF();			// kikapcsolás
								}
    else{	

      adc = ADConvert(2);    //mérés
//      adc változóra írjuk az aktuális ADC értéket, az érték egy 0-1023 (10bit) közötti szám.
  		if(adc > 1022)			RED(); 		// piros
        else if(adc > 940)		YLLW();		// sárga
		else if(adc > 830)		GRN();		// zöld
		else if(adc > 680)		CYAN();		// cián
		else if(adc > 480)		BLUE();		// kék
		else if(adc > 240)		MAG();		// magnetta			
		else	LED_OFF();	//sötétség, sok if vége
			}
			_delay_ms(20);
		if (adc < 250) TIMSK=(1<<TOIE0); else TIMSK=(0<<TOIE0);	 //engedélyezzük a megszakítást, ha adc kisebb a megadottnál, tehát elndul a kikapcsolási időzítés
		} 
	 } //for vége
	 
} //main vége

// --megszakítás --
ISR(TIMER0_OVF_vect)     //megszakítási vektor TIMER1 értelemszerű, OVF - overflow vagyis akkor fog ide ugrani (megszakadni a program futás) ha túlcsordult
        { extern volatile unsigned short b;
		b++;
		}
		
        
