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

#define max(a,b) ((a)>(b) ? (a) : (b))
#define min(a,b) ((a)<(b) ? (a) : (b))

#define N 50

int main(void)
{
	uint32_t accu=0;
	int i=0;

	// set OC0A (PB0) and OC0B (PB1) as output
	DDRB |= (1<<PB0) | (1<<PB1);

	// init PWM
	TCCR0A |= (1<<COM0A1)   // enable compare output A
	          | (1<<COM0B1) // enable compare output B
	          | (1<<WGM00); // phase-correct pwm mode
	TCCR0B |= (1<<CS00);

	// enable pull-up on ADC2 (PB4)
	PORTB |= (1<<PB4);

	// init ADC
	ADMUX |= (1<<MUX1);     // select ADC2 as analog input
	DIDR0 |= (1<<ADC2D);    // disable ADC2 digital input
	ADCSRA |= (1<<ADPS2)    // prescaler: 16
	          | (1<<ADEN)   // enable
	          | (1<<ADSC)   // start
	          | (1<<ADATE); // auto-trigger (free-running)

	// set PWM level
	OCR0A = 0;
	OCR0B = 0;

	while(1) {
		uint16_t input;

		// read analog input
		input = ADCL;
		input |= ADCH << 8;

		accu += input;
		i++;

		if(i==N) {
			int32_t mean = accu / N;
			OCR0B = max(0,mean-512) >> 1;
			accu = 0;
			i = 0;
		}

		OCR0A++;
		_delay_ms(1);
	}

	return 0;
}
