/****************************************************************** Includes */
#include <stdio.h>          // Standard Input/Output
#include <avr/io.h>         // AVR device-specific IO definitions
#include <compat/deprecated.h>  // Use sbi(), cbi() function
#include <avr/interrupt.h>	// Interrupt Service routine

#define F_CPU 16000000UL     // CPU clock frequency (in Hertz)    
#include <util/delay.h>     // util_delay

#define RX_BUFSIZE 80       // Buffer RX

/******************************************************* Prototype functions */
static int uart_putchar(char c, FILE *stream);
static int uart_getchar(FILE *stream);
static FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
void Init_Serial(unsigned int baudrate);

void W1(void);
void W2(void);
unsigned int ADCx[8];
/************************************************************* USART putchar */
static int uart_putchar(char c, FILE *stream)
{   
    loop_until_bit_is_set(UCSRA, UDRE);
    UDR = c;

    return 0;
}

/************************************************************* USART getchar */
static int uart_getchar(FILE *stream) {
  
    uint8_t c;
	        
        loop_until_bit_is_set(UCSRA, RXC);
	        
        if (UCSRA & _BV(FE))    return _FDEV_EOF;
//        if (UCSRA & _BV(DOR))   return _FDEV_ERR;

        c = UDR;



    return c;
}

/*********************************************************** Initialize UART */
static void USART_Init(unsigned int baud)
{
	// Set baud rate
	UBRRH = (unsigned char) (baud>>8);
	UBRRL = (unsigned char) baud;
    
	UCSRA = (1<<U2X);
	// Enable receiver and tramsmitter
	UCSRB = (1<<RXEN) | (1<<TXEN);

	// Set frame format: 8data, NoneParity, 1stop bit
	UCSRC = (1<<URSEL)|(3<<UCSZ0);

    // Set address uart_str to stdout/stdin
    stdout = stdin = &uart_str;
}

/************************************************************ Main Functions */
/***************************************************************** delay_ms */

void delay_ms(uint16_t i)
{
    for (;i > 0; i--)
        _delay_ms(1);
}

/************************************************************* USART PWM */
void init_PWM1(void)
{
	// PORT PA0,PA1 PA2 Output
    DDRC = (1<<DDC5)|(1<<DDC4)|(1<<DDC3); 
	// PORT PD5(OC1A),PD4(OC1B) Output PWM
    DDRB = (1<<DDB1)|(1<<DDB2);             

	// Clear up-counting Set downcounting
    TCCR1A = (1<<COM1A1)|(0<<COM1A0);   
	TCCR1A |= (1<<COM1B1)|(0<<COM1B0);

	// Mode 8: PWM,Phase and Frequency Corect (TOP = ICR1A)
    TCCR1B  = (1<<WGM13)|(0<<WGM12);    
    TCCR1A |= (0<<WGM11)|(0<<WGM10);  
	
	// clk_IO/1 (From prescaler)	    
    TCCR1B |= (0<<CS12)|(1<<CS11)|(0<<CS10); 

	ICR1 = 20000;		// Freq = 1000 Hz(TOP = ICR1) //1000=100%
    
    // Duty Cycle 50%
    OCR1A = 1500;      	// Output Compare Register 1 A //500 = 50%
    OCR1B = 1500;       	// Output Compare Register 1 B //500 = 50%

    TCNT1 = 0;          	// Clear Timer
  
  	// T/C1 Output Compare A/B Match and Timer Overflow interrupt Enable
 //   TIMSK = (1<<OCIE1A)|(1<<OCIE1B)|(1<<TOIE1);    

 //   sei();                  // Set I-bit global interrupt enable
	
}

int ADC_init(void)
{
	DDRC = 0x00;

	// AVCC with external capacitor at AREF pin
	ADMUX = (0<<REFS1)|(1<<REFS0);

	// ADC Enable & Auto Trigger Disable
	ADCSRA = (1<<ADEN);
	ADCSRA |= (1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0);	// XTAL/8

	ADCSRA |= (1<<ADSC);				// ADC Start Conversion
	while (!(ADCSRA &(1<<ADIF)));    // Wait Coversion completes

	return ADCW;
}

void ADC_read(void)
{

		ADMUX = (0<<REFS1)|(1<<REFS0)|0x00;
		ADCSRA |= (1<<ADSC);				// ADC Start Conversion
		while (!(ADCSRA &(1<<ADIF)))    // Wait Coversion completes
         			 ;
		ADCx[0] = ADCW;                     // Read ADC

		ADMUX = (0<<REFS1)|(1<<REFS0)|0x01;
		ADCSRA |= (1<<ADSC);				// ADC Start Conversion
		while (!(ADCSRA &(1<<ADIF)))    // Wait Coversion completes
         			 ;
		ADCx[1] = ADCW;                     // Read ADC

		ADMUX = (0<<REFS1)|(1<<REFS0)|0x02;
		ADCSRA |= (1<<ADSC);				// ADC Start Conversion
		while (!(ADCSRA &(1<<ADIF)))    // Wait Coversion completes
         			 ;
		ADCx[2] = ADCW;                     // Read ADC

		ADMUX = (0<<REFS1)|(1<<REFS0)|0x03;
		ADCSRA |= (1<<ADSC);				// ADC Start Conversion
		while (!(ADCSRA &(1<<ADIF)))    // Wait Coversion completes
         			 ;
		ADCx[3] = ADCW;                     // Read ADC

		ADMUX = (0<<REFS1)|(1<<REFS0)|0x04;
		ADCSRA |= (1<<ADSC);				// ADC Start Conversion
		while (!(ADCSRA &(1<<ADIF)))    // Wait Coversion completes
         			 ;
		ADCx[4] = ADCW;                     // Read ADC

		ADMUX = (0<<REFS1)|(1<<REFS0)|0x05;
		ADCSRA |= (1<<ADSC);				// ADC Start Conversion
		while (!(ADCSRA &(1<<ADIF)))    // Wait Coversion completes
         			 ;
		ADCx[5] = ADCW;                     // Read ADC
}

int test_return(char x)
{
	if(x >=54) return 1;

	return 0;
}

int main(void)
{   
	char c;
	int i;
    USART_Init(16);     // baudrate to 115,200 bps using a 16MHz crystal

	init_PWM1();

	//port PD6,PD7 Input
	DDRD |= (0<<DDD6)|(0<<DDD7);

	ADC_init();         

    printf("\fHello KID!!! \r\n");

	while (1) {
/*
		ADC_read();

		for(i=0;i<6;i++){
			printf("%4d = %4d",i,ADCx[i]);
		}
		printf("\r\n");
		delay_ms(10);
 */
 	i = getchar();
 	c = test_return(i);

	printf("%d \r\n",c);

    }

}



/*********************************************** External Interrupt Request 0 */

void W1(void)
{
	OCR1A = 1300;      	// Output Compare Register 1 A //500 = 50%
    OCR1B = 1700;       	// Output Compare Register 1 B //500 = 50%
	delay_ms(1000);

	OCR1A = 1700;      	// Output Compare Register 1 A //500 = 50%
    OCR1B = 1300;       	// Output Compare Register 1 B //500 = 50%
	delay_ms(1000);
}

void W2(void)
{
	OCR1A = 1400;      	// Output Compare Register 1 A //500 = 50%
    OCR1B = 1600;      	// Output Compare Register 1 B //500 = 50%
	delay_ms(300);

	OCR1A = 1600;      	// Output Compare Register 1 A //500 = 50%
    OCR1B = 1400;       	// Output Compare Register 1 B //500 = 50%
	delay_ms(300);
}

