// clock is 600khz (4.8Mhz / 8)
//#define F_CPU 0600000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

FUSES = 
{
    (FUSE_CKDIV8 & FUSE_CKSEL0), // .low
    HFUSE_DEFAULT // .high
};

/*
PB0 - red. active high
PB1 - green. active high
*/

#define RED_BIT		PORTB0
#define GREEN_BIT	PORTB1


// when going from up to down or vice versa, wait this long (ms)
#define CHANGE_DELAY	100

// how many ms to wait before changing the brightness up/down
#define TIME_BEFORE_CHANGE		10


#define MAX_RED_VALUE	205
#define MIN_RED_VALUE	0

#define MAX_GREEN_VALUE	255
#define MIN_GREEN_VALUE	50

enum { UP, DOWN };

void simple_movement();
void fade_movement();

int main()
{
	// Set LED pins as outputs
	DDRB |= _BV(DDB0);
	DDRB |= _BV(DDB1);

	PORTB = 0x00; // all off

	//simple_movement();

	fade_movement();
	
	return 1;
}

void simple_movement()
{
	// Set all Port B pins as low
	PORTB = 0x00;

	// red on 
	PORTB |= (1 << RED_BIT);

	while( 1 )
	{
		// sleep
		_delay_ms(500);

		if( PORTB & (1 << RED_BIT) )
		{
			PORTB = (0 << RED_BIT) | (1 << GREEN_BIT);
		}
		else
		{
			PORTB = (1 << RED_BIT) | (0 << GREEN_BIT);
		}
	}
}

void fade_movement()
{
	// Initialize the PWM to a duty-cycle of 0 (or off)
	OCR0A = MAX_RED_VALUE; // red
	OCR0B = MIN_GREEN_VALUE; // green

	uint8_t red_direction = UP;
	uint8_t green_direction = DOWN;

	// Configure Timer/Counter
	// Set output pin to 1 when the counter matches the value in OC0A/OC0B.
	// Set output pin to 0 when the counter overflows.
	TCCR0A |= _BV(COM0A1); 
	TCCR0A |= _BV(COM0B1); 

	// Select Fast PWM Mode
	TCCR0A |= _BV(WGM01) | _BV(WGM00); 

	// Use the internal clock for the counter with no prescaling.
	TCCR0B = _BV(CS00);

	for (;;)
	{
		_delay_ms(TIME_BEFORE_CHANGE);
	
		if( red_direction == UP )
		{
			OCR0A++;
		}
		else
		{
			OCR0A--;
		}

		if( green_direction == UP )
		{
			OCR0B++;
		}
		else
		{
			OCR0B--;
		}

		if( OCR0A == MAX_RED_VALUE )
		{
			red_direction = DOWN;
		}
	
		if( OCR0A == MIN_RED_VALUE )
		{
			red_direction = UP;
		}

		if( OCR0B == MAX_GREEN_VALUE )
		{
			green_direction = DOWN;
		}
	
		if( OCR0B == MIN_GREEN_VALUE )
		{
			green_direction = UP;
		}

	/*	if( OCR0A == MAX_RED_VALUE || OCR0A == MIN_RED_VALUE || 
			OCR0B == MAX_GREEN_VALUE || OCR0B == MIN_GREEN_VALUE )
		{
			_delay_ms(CHANGE_DELAY);
		}
	*/
	}
}


