#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include <stdlib.h>
#include <util/delay.h>


#define NOP() asm volatile ("nop" ::)
#define setbit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clearbit(ADDRESS,BIT) (ADDRESS &=~ (1<<BIT))

#define lesen 1
#define schreiben 2
#define nichts 0

#define t_nichts 		0b00000000
#define t_gedruckt 		0b00000001
#define t_gehalten 		0b00000010
#define t_losgelassen 	0b00000100

void comp1a_stop(void);
void comp1a_start(void);
void comp0a_stop(void);
void comp0a_start(void);
void int0_ein();
void int0_aus();


//********************************************************
//  VARIABLEN
//  *****************************************************

volatile uint8_t zeit_abgelaufen, pegel_gewechselt,byteaktion;
volatile uint8_t t_index,b_index,schreibzyclus,bit; 
volatile uint8_t telegramm[8] ,test,i,aufnahme;
volatile uint8_t pstatus,telegramm_zuende,synchron;
volatile uint8_t t_status,t_pufferneu,t_pufferalt,t_eingelesen,t_counter,t_taste;


uint8_t ee[100] EEMEM; 
// *******************************************************************
//    INTERUPTRUTINEN
// **********************************************************

	
ISR(PCINT1_vect) {
	TCNT1=0;
	pegel_gewechselt=1;
	synchron=0;
}

ISR(TIM0_COMPA_vect) {
	if (b_index){
		if (byteaktion==schreiben){
			test=!test;

			if (telegramm[t_index]&b_index) {
				NOP();
				setbit(PORTB,PB2);
			}
			else {
				clearbit(PORTB,PB2);
			}
		}
		else if (byteaktion==lesen) {
			bit=0;

		//	setbit(PORTB,PB1);

			if (PINB&(1<<PB2)) bit++;
			if (PINB&(1<<PB2)) bit++;
			if (PINB&(1<<PB2)) bit++;
			if (PINB&(1<<PB2)) bit++;
			if (PINB&(1<<PB2)) bit++;
			if( bit>2) telegramm[t_index]|=b_index;
		//	clearbit(PORTB,PB1);
		}
		b_index=b_index<<1;
	}
	else { 
		comp0a_stop();
		NOP();NOP();NOP();NOP();NOP();
		NOP();NOP();NOP();NOP();NOP();
		NOP();
		clearbit(DDRB,PB2);
		clearbit(PORTB,PB2);
		int0_ein();
		t_index++;
		if (t_index>7){
			t_index=0;
			//test=1;
			telegramm_zuende=1;
			if(!t_eingelesen) {
				t_eingelesen=1;
				t_pufferneu=PINA;
				//test=1;
			}
			if (schreibzyclus) schreibzyclus--;
			setbit(GIMSK,PCIE1);
			comp1a_start();
		}
	}
}

ISR(INT0_vect) {
	//test=1;
	int0_aus();	//int0 ausschalte
	byteaktion=nichts;
	b_index=0b00000001;
	if (schreibzyclus&&((t_index==0)||(t_index==1))){
		//Port setzen???
		//test=!test;
		setbit(DDRB,PB2);
		byteaktion=schreiben;
		TCNT0=12;
		NOP();NOP();NOP();NOP();NOP();
	}
	else if (t_index==4) {
		//test=1;
		telegramm[t_index]=0;
		byteaktion=lesen;
		TCNT0=216;
	}
	comp0a_start();
}	


ISR(TIM1_COMPA_vect) {
//GIMSK( INT0 PCIE1 PCIE0    )
	comp1a_stop();
	clearbit(GIMSK,PCIE1);
	synchron=1;
	int0_ein();
}


// *******************************************************************
//    INITIALISIERUNGEN
// **********************************************************

 void comp0a_init(void){ //9000 takte
	setbit(GTCCR,TSM);	  	//Vorteiler Anhalten
	// TCCR0A=COM0A1 COM0A0 COM0B1 COM0B0   WGM01 WGM00 ;
	TCCR0A=	0b00000010; //Fόr CTC-Modus =WGM02..WGM00= 010
	//TCCR0B=FOC0A FOC0B   WGM02 CS02 CS01 CS00
	TCCR0B=	0b00000000; // Vorteiler 1=001 256=100/64=011/1024=101/1=001/8=010
	//TIMSK0=      OCIE0B OCIE0A TOIE0
    TIMSK0= 0b00000010;   // Interrupt freischalten
	// TIFR0=      OCF0B OCF0A TOV0
	setbit(TIFR0,OCF0A);	//Flag lφschen
	TCNT0=0;
	OCR0A=103;
	clearbit(GTCCR,TSM);	
}

inline void comp0a_stop(void) {
	TCCR0B=	0b00000000; // Vorteiler 1=001 256=100/64=011/1024=101/1=001
	TCNT0=0;
	setbit(TIFR0,OCF0A);	//Flag lφschen
}

inline void comp0a_start(void) {
	//TCCR0B=FOC0A FOC0B   WGM02 CS02 CS01 CS00
	TCCR0B=	0b00001010; // Vorteiler 1=001 256=100/64=011/1024=101/1=001
}


 void comp1a_init(void){ //61440 takte = 7,68us
	setbit(GTCCR,TSM);	  	//Vorteiler Anhalten
	// TCCR1A=COM1A 1COM1A0 COM1B1 COM1B0   WGM11 WGM10 ;
	TCCR1A=	0b00000000; //Fόr CTC-Modus =WGM13..WGM10= 0100
	//TCCR1B=ICNC1I CES1  WGM13 WGM12 CS12 CS11 CS10 
	TCCR1B=	0b00001000; // Vorteiler 1=001 256=100/64=011/1024=101/1=001
	//TCCR1C=FOC1A FOC1B       
	TCCR1C=	0b00000000;
	//TIMSK1=   ICIE1   OCIE1B OCIE1A TOIE1 
    TIMSK1= 0b00000010;   // Interrupt freischalten
	// TIFR1=   ICF1   OCF1B OCF1A TOV1
	setbit(TIFR1,OCF1A);	//Flag lφschen
	TCNT1=0;
	OCR1A=60;
	clearbit(GTCCR,TSM);	
}

inline void comp1a_start(void){
	setbit(GTCCR,PSR10);	//vorteiler resetten
	//TCCR1B=ICNC1I CES1  WGM13 WGM12 CS12 CS11 CS10 
	TCCR1B=	0b00001101; // Vorteiler 1=001 256=100/64=011/1024=101/1=001
}

inline void comp1a_stop(void) {
	//TCCR1B=ICNC1I CES1  WGM13 WGM12 CS12 CS11 CS10 
	TCCR1B=	0b00001000; // Vorteiler 1=001 256=100/64=011/1024=101/1=001
}
	

inline void int0_init(void){
//MCUCR (BODS PUD SE SM1 SM0 BODSE ISC01 ISC00) MCUCR
	MCUCR|=	0b00000010;
//GIMSK( INT0 PCIE1 PCIE0    )
//	GIMSK =	0b01000000;
}

inline void int0_ein(){
//  INTF0 PCIF1 PCIF0     = GIFR
	setbit(GIFR,INTF0);
	setbit(GIMSK,INT0);
}

inline void int0_aus(void) {
	clearbit(GIMSK,INT0);
}

inline void pcie1_init(void){
//     PCINT11 PCINT10 PCINT9 PCINT8 =PCMSK1
	PCMSK1=	0b00000100;	//... fόr den Pin an dem Lanc hδngt
}	

void main_init(void){
	DDRB=	0b00000001;
	PORTB=	0b00000000;
	DDRA = 0b00000000;
	PORTA= 0b11000000;
	comp1a_init();
	pcie1_init();
	int0_init();
	comp0a_init();
	sei();
}

void synchronisieren(void){
//GIMSK( INT0 PCIE1 PCIE0    )
	setbit(GIMSK,PCIE1);	//PinChangeInterupt freischalten PB2
	comp1a_start();
}


	
// ******************************************************************
// 				Hauptprogramm
// **************************************************


int main(void){
	main_init();
	synchronisieren();
	_delay_ms(100);
	telegramm_zuende=0;
	while(!telegramm_zuende)
	test=telegramm[4];

	while(1) {
		if(telegramm_zuende) {
			telegramm_zuende=0;
			if(telegramm[4]==0xEB) aufnahme=0;
			if(telegramm[4]==0xFB) aufnahme=1;
/*
			if(telegramm[4]!=test) {
				aufnahme=!aufnahme;
				test=telegramm[4];
   				 eeprom_write_byte(&ee[i], test);
				 i++;
			}*/

		}
		if(aufnahme) setbit(PORTB,PB0); else clearbit(PORTB,PB0);
		if (t_eingelesen) {
			t_pufferneu=~t_pufferneu;
			t_pufferneu&=0b11000000;	
			if(t_pufferneu==t_pufferalt) t_counter++;
			else {t_pufferalt=t_pufferneu; t_counter=0;}
			if (t_counter==5) {
				if(!t_pufferneu){
					t_status|=t_losgelassen;
				}
				else {
					//test=!test;
					t_status|=t_gedruckt;
					t_taste=t_pufferneu;
				}
			}
			if (t_counter>150) {
				if(!t_pufferneu) {
					t_status=t_nichts;
				}
				else {
					t_status|=t_gehalten;
					t_status|=t_gedruckt;
				}
				t_counter=125;
			}
			t_eingelesen=0;
		}
		if(t_status) {
			if (t_status&t_gedruckt) {
				t_status&=~t_gedruckt;
				switch (t_taste) {
					case 0b10000000 : {
						if(!schreibzyclus) {
							//test=!test;
							telegramm[0]= ~0b00011000;
							telegramm[1]= ~0x27;
							schreibzyclus=5;
						}
					}
					case 0b01000000 :{
						if(!schreibzyclus) {
							telegramm[0]= ~0b00011000;
							telegramm[1]= ~0x29;
							i++;
							schreibzyclus=5;
						}
					}
				}
			}
		t_status=t_nichts;
		}

					
}
}

