#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>


#define RED OCR2
#define GREEN OCR1B
#define BLUE OCR1A



uint16_t pwmtable_8C[45] PROGMEM = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
		  13, 15, 16, 17, 19, 21, 23, 25, 27, 29,
		   32, 35, 38, 41, 45, 49,  54, 58, 64, 70,
		  76, 83, 90, 98, 107, 117, 127, 139, 152, 165,
		  180, 196, 214, 234, 255};


void farbe(volatile uint16_t *farbe,uint8_t  wert, uint8_t  delay)
{
	if(wert == 44)
	{
		for(uint8_t ist = 0;ist<=wert;ist++)
		{
			*farbe = pgm_read_word(pwmtable_8C+ist);
			_delay_ms(delay);
		}
	}
	else
	{
		for(uint8_t ist = 44;ist>=wert;ist--)
		{
			*farbe = pgm_read_word(pwmtable_8C+ist);
			_delay_ms(delay);
		}
	}
}

void init_pwm(void)
{
	//Set registers for PWM of Timer 1
    TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM10);
    TCCR1B = (1<<WGM12) | (1<<CS10); // Fast PWM 8-bit inverted


	//Set registers for PWM of Timer 2
	TCCR2 = (1<<WGM21) | (1<<WGM20) | (1<<COM21) | (1<<CS20); // 8 bit fast PWM inverted
}

void wait(uint8_t waittime)
{
	for(uint8_t i=0;i<waittime*5;i++)
	{
		_delay_ms(200);
	}
}


int main (void) {
	//Set port register as output for Pb3 to Pb1
	DDRB = 0x0E;
	//Initialise pwm
	init_pwm();
	uint8_t delay = 60;

	while(1)
	{
		farbe((uint16_t*)&RED, 	44, delay);
		wait(3);
		farbe(&GREEN, 			44, delay);
		wait(3);
		farbe((uint16_t*)&RED, 	0,	delay);
		wait(3);
		farbe(&BLUE, 			44, delay);
		wait(3);
		farbe(&GREEN, 			0, 	delay);
		wait(3);

		farbe((uint16_t*)&RED, 	44, delay);
		farbe(&GREEN, 			44, delay);
		wait(5);

		for(int ist = 44;ist>=0;ist--)
		{
			RED = pgm_read_word(pwmtable_8C+ist);
			GREEN = pgm_read_word(pwmtable_8C+ist);
			BLUE = pgm_read_word(pwmtable_8C+ist);
			_delay_ms(delay);
		}
	}

   return 0;
}


