#include <avr/io.h>
#include <avr/signal.h>
#include "sio.c"

#define CLK_ms 10 // set the updates for every 10ms
unsigned int CNT_timer1; // the delay time
volatile unsigned int CLK_ticks = 0; // the current number of ms
volatile unsigned int CLK_seconds = 0; // the current number of seconds
int count = 0; // a count value to be output on port B

void PWM_setup()
{
	//using OCR2
	DDRD = 0xFF; //set as output
	TCCR2 = _BV(WGM21)|_BV(WGM20)|_BV(COM21)|_BV(CS20); //fast PWM
	OCR2 = 0xFF; //100% duty cycle
}

void PWM_write(int val)
{
	OCR2 = val; // duty cycle
}
void AD_setup()
{
	ADMUX = 0xC0; // set the input to channel 0
	ADCSRA = 0xE0;// turn on ADC and set to free running
}

int AD_read ()
{
	return ADCW;
}

void IO_setup()
{
	DDRB = 0xFF; // all of port B is outputs
}

void IO_update()
{
	// This routine will run once per interrupt for updates
	// Update the PWM wave every second
	PORTB = count;
	OCR2 = count;
	
	
}




SIGNAL(SIG_OVERFLOW1)
{ 
	// The interrupt calls this function
	CLK_ticks += CLK_ms;
	if(CLK_ticks >= 1000)
	{ 
		// The number of interrupts between output changes
		CLK_ticks = CLK_ticks - 1000;
		CLK_seconds++;
		IO_update();
	}
	TCNT1 = CNT_timer1;
}


void CLK_setup()
{ 
	// Start the interrupt service routine
	TCCR1A = (0<<COM1A1) | (0<<COM1A0)| (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10) | (0<<FOC1A) | (0<<FOC1B);
	// disable PWM and Compare Output Modes
	TCCR1B = (0<<WGM12) | (0<<WGM13) | (0<<ICNC1) | (0<<ICES1) | (1<<CS12) | (0<<CS11) | (1<<CS10); 
	// set to clk/1024
	CNT_timer1 = 0xFFFF - CLK_ms * 16; // 16 = 1ms, 160 = 10ms
	TCNT1 = CNT_timer1; // start at the right point
	
	//SFIOR &= PSR10; // reset the scaling bit
	// use CLK/1024 prescale value
	TIFR&=~(1<<TOV1); // set to use overflow interrupts
	TIMSK = (1<< TOIE1 );// enable TCNT1 overflow
	sei(); // enable interrupts flag
}




int main ()	
{	
	int c;
	sio_init();
	AD_setup();
	PWM_setup();
	IO_setup();
	CLK_setup();
	DDRA = (unsigned char)0;
	
	
	for(;;){
		while((c = input()) == -1){} // wait for a keypress

		if(c == '+')
		{ 
			// increment the output on port B
			if(++count > 255) count = 255;
			outln("counter incremented");
		} 
		else if(c == '-')
		{
			if(--count < 0) count = 0;
			outln("counter decremented");
		} 
		else if(c == 'p')
		{
			outint(count);
		} 
		else if(c == 'h')
		{
			outln("HELP: +, -, p, q");
		} 
		else if(c == 'q')
		{
			break;
		}
	}

	while (1)
	{
		PWM_write(AD_read() >> 2);
	}
	
	sio_cleanup();
	return 1;
}


