#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>

#define BAUD 4800
#define UBRR_VAL F_CPU/16/BAUD-1

#define DEBUG_MODE

#define BURST_TIME	70
#define READY_TIME	150
#define TIME_OUT	300
#define MAX 		1020
#define MIN 		10


volatile char ready, burst, first;
int timer;


void start_timer(void);
void stop_timer(void);

void init_uart(unsigned int ubrr) {
	/* Set baud rate */
	UBRRH = (unsigned char)(ubrr>>8 ) ;
	UBRRL = (unsigned char)(ubrr);
	/* Enable receiver and transmitter */
	UCSRB |= (1<<RXEN);
	UCSRB |= (1<<TXEN);
	/* Set frame format: 8data, 2stop bit */
	UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void send_char(unsigned char data) {
	/* Wait for empty transmit buffer */
	while (!(UCSRA & (1<<UDRE)));
		/* Put data into buffer, sends the data */
		UDR = data;
}

void send_string(char *data) {
	while (*data) {
		send_char(*data);
		data++;
	}
}

void adc_init()
{
	ADMUX = 0x60; //avcc with external cap, result left adjust
	ADCSRA = 0x85; //enable adc, prescaler div 32 (4MHz / 32 = 125kHz)
}

void timer_init()
{
	TIFR |= (1<<TOV0);		//set interrupt on overflow
	TIMSK |= (1<<TOIE0);
	TCNT0 = 223;
}

ISR (TIMER0_OVF_vect)
{	
	TCNT0 = 223;
	timer++;
	if (timer == BURST_TIME)
		{
			#ifdef DEBUG_MODE
			send_string("Burst\n\r");
			#endif
			burst = 1;
			ready = 0;
		} else
	if (timer == READY_TIME)
		{
			burst = 0;
			ready = 1;
			#ifdef DEBUG_MODE
			send_string("Ready\n\r");
			#endif
		} else
	if (timer == TIME_OUT)
		{
			#ifdef DEBUG_MODE
			send_string("Time out\n\r");
			#endif
			timer = 0;
			burst = 0;
			ready = 0;
			first = 0;
			stop_timer();
		}
}

void start_timer()
{
	TCCR0 |= (1<<CS02);
}

void stop_timer()
{
	TCCR0 &= ~(1<<CS02);
}

int ADC_convert(int channel)
{
	ADMUX |= (0x0F & (channel));
	ADCSRA |= (1<<ADSC);
	return ADCH;
}

int main() 
{
	int value, i, dummy;
	char buffer[1];

	adc_init();
	init_uart(UBRR_VAL);
	timer_init();
	send_string("Clapper V1.2 \n\r");

	i = 100;
	ready = 0;
	burst = 0;
	first = 0;

	DDRB = 0x04;
	PORTB &= ~(1<<PB2);
	PORTB |= (1<<PB0) | (1<<PB1);

	sei();

	while (1) 
	{
		if (bit_is_clear(PINB,PB0))
			{
				_delay_ms(250);
				#ifdef DEBUG_MODE
				send_string("Sensibility up\n\r");
				#endif
				if (i < MAX)
				{
					i +=10;
				} else
					i = MAX;
				#ifdef DEBUG_MODE
				send_string(itoa(i,buffer,10));
				send_string("\n\r");
				#endif
			}
		if (bit_is_clear(PINB,PB1))
			{
				_delay_ms(250);
				#ifdef DEBUG_MODE
				send_string("Sensibility down\n\r");
				#endif
				if (i > MIN)
				{
					i -=10;
				} else
					i = MIN;
				#ifdef DEBUG_MODE
				send_string(itoa(i,buffer,10));
				send_string("\n\r");
				#endif
			}
		
	//	value = (ADCH * 5) / 255; get the voltage on adc0
		value = ADC_convert(0x00);
		if (value >= i)
			{
				#ifdef DEBUG_MODE
				send_string("Beat\n\r");
				#endif

			if (!first)
				{
					start_timer();			
					first = 1;
					
					#ifdef DEBUG_MODE
					send_string("First Pulse\n\r");
					#endif
				} else
			
			if (burst)
				{
					timer = 0;
					first = 0;
					burst = 0;
					stop_timer();

					#ifdef DEBUG_MODE
					send_string("False Pulse\n\r");
					#endif
				} else {

			if (ready)
				{
					stop_timer();
					timer = 0;
					first = 0;
					ready = 0;

					PORTB ^= (1<<PB2);

					#ifdef DEBUG_MODE
					send_string("ON/OFF Lights\n\r");
					#endif

					value = 0;
					ADCH = 0;
					_delay_ms(10);
					value = ADC_convert(0x00);
					_delay_ms(1000);

				}
}
					_delay_ms(40);
				
				
			}
	}
}
