// für die Doku,
// 	-anfänglich hatte ich das SEI vergessen
//	-das volatile bei IrSend ist dringend notwendig
#include <inttypes.h>

#include <stdlib.h>
//#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//#define F_CPU 3686411UL
#define F_CPU 8000000UL
#include <avr/delay.h>

// constants
// globals
#define ARRAYLEN 50
#define INTERRUPTS_PER_SECOND   152000
#define INTERRUPTS_PER_MILLISECOND (INTERRUPTS_PER_SECOND / 1000)

volatile unsigned int IrCounter = 0;
#if 0
//Nur für den test
unsigned int IrArray[ARRAYLEN] = {
100,
10,
200,
10,
400,   
0
};
#else
unsigned int IrArray[ARRAYLEN] = {
2,
278,   
134,   
18,  
14,  
19,  
13,  
19,  
48,  
20,  
13,  
18,  
49,  
18,  
14,  
19,  
13,  
20,  
13,  
18,  
134,   
19,  
14,  
19,  
48,  
18,  
14,  
19,  
13,  
19,  
14,  
18,  
48,  
19,  
14,  
18,  
14,  
19,
0,
0,
0
};
#endif
//volatile unsigned int *IrPtr;
volatile unsigned char IrIndex = 0;
volatile unsigned char IrSend = 0; //volatile notwendig
volatile unsigned char IrPulsing = 0; // sind wir im Puls, oder zählen wir gerade eine Pause
volatile unsigned char IrPP = 3; // rise und fall, die 38kHz Schwingungen Pulspauseverhältnis 1:3


// functions
void init_timer1()
{
    TCCR1A = 0;
    TCCR1B = _BV (WGM12) | _BV (CS10);

	// set PoutputCompare to get desired Timer1 frequency
	OCR1A = (unsigned short) ((uint32_t) F_CPU / INTERRUPTS_PER_SECOND -1);
	TCNT1 = 0;

   // output compare interrupt for timer 1
   //timer_enable_int (_BV (OCIE1A));
   TIMSK1 = 1<<OCIE1A;
}

//************************************************************
//
//    LED Functions
//
//************************************************************

void on (void)
{
	PORTD = 0x01; 
}

#define ON PORTD = 0x01 

void off (void)
{
	PORTD = 0x00;
}

#define OFF PORTD = 0x00

//************************************************************
//
//    Interrupt Functions
//
//************************************************************

SIGNAL (SIG_OUTPUT_COMPARE1A)
{
	//diese Routine soll jetzt 152000mal / Sekunde aufgerufen werden
	if (IrSend != 0)
	{
		IrPP--;
		if (IrPP == 0) 
		{
			IrPP = 4; // Puls-Pause-Verhältnis 1:3
			if (IrPulsing)
				ON;			
			else
				OFF;
			IrCounter--;
			if (IrCounter == 0)
			{
				IrPulsing = !IrPulsing;			
				//IrPtr++;
				IrIndex++;
				//IrCounter = *IrPtr;
				IrCounter = IrArray[IrIndex];
				if (IrCounter == 0) // Sequenz zuende
				{
					OFF;
					IrSend = 0;
				}
			}
		}
		else
		{
			OFF;
		}
	}
}

//************************************************************
//
//    User Functions
//
//************************************************************

void ioinit (void)
{
	DDRD = 0x01;
	PORTD = 0x00; //off
	init_timer1();
}

void IrInit(void)
{
	IrArray[0] = 278;
	IrArray[1] = 127;   
	IrArray[2] = 18,   
	IrArray[3] = 12;  
	IrArray[4] = 19;  
	IrArray[5] = 12;  
	IrArray[6] = 18;  
	IrArray[7] = 45;
  	IrArray[8] = 18;  
	IrArray[9] = 13;  
	IrArray[10] = 18;  
	IrArray[11] = 45;  
	IrArray[12] = 18;  
	IrArray[13] = 13;  
	IrArray[14] = 18;  
	IrArray[15] = 12; 
	IrArray[16] = 19;  
	IrArray[17] = 12;  
	IrArray[18] = 18;  
	IrArray[19] = 127;  
	IrArray[20] = 18;  
	IrArray[21] = 45;  
	IrArray[22] = 18;  
	IrArray[23] = 12;  
	IrArray[24] = 19;   
	IrArray[25] = 44;   
	IrArray[26] = 18;   
	IrArray[27] = 13;
	IrArray[28] = 18;
	IrArray[29] = 45;
	IrArray[30] = 18;
	IrArray[31] = 13;
	IrArray[32] = 18;
	IrArray[33] = 13;
	IrArray[34] = 18;
	IrArray[35] = 13;
	IrArray[36] = 17;
	IrArray[37] = 788;
	IrArray[38] = 0;
}

int main (void)
{
	IrInit();
    ioinit ();
	off();
	sei();
	while (1)
	{
		if ((PIND & 0x02) && (IrSend == 0))
		{
			IrCounter = IrArray[0];
			//IrPtr = &IrArray[1];
			IrIndex = 0;
			IrPulsing = 1; //?
			IrSend = 1;
		}
	}	
	off();
    return (0);
}
