#include<avr\io.h>
#include<stdio.h>
#include<avr\interrupt.h>
#include<util\delay.h>
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define FE 4
#define UPE 2
#define OVR 3
#define ADC_VREF_TYPE 0x40

unsigned char eeprom_data;
unsigned int eeprom_address;
double adc_data;


void putchar0(unsigned char c)
{
	while((UCSR0A&(1<<UDRE0))==0);
	UDR0=c;	
}

unsigned char getchar0(void) 
{
	unsigned char c;
	
	loop_until_bit_is_set(UCSR0A,RXC0);
	c=UDR0;
	return c;
}

void putchar1(unsigned char c)
{
	while((UCSR1A&(1<<UDRE1))==0);
	UDR1=c;	
}

void puts0(unsigned char *data)
{
	while(*data!='\0')
	{
		putchar0(*data);
		data++;	
	}	
}

void puts1(unsigned char *data)
{
	while(*data!='\0')
	{
		putchar1(*data);
		data++;	
	}	
}

ISR(ADC_vect)
{
	adc_data=ADCW*0.00488;
	printf("\r""%.3f",adc_data);
}

ISR(TIMER1_OVF_vect)
{
	static unsigned char i;

	TCNT1H=0xB7;
	TCNT1L=0x1B;
	i++;
	PORTC=i;
	if(i>255)
	{
		i=0;
	}

}

ISR(USART0_RX_vect)
{
	unsigned char status,data;
	
	status=UCSR0A;
	data=UDR0;
	if((status&(FRAMING_ERROR|PARITY_ERROR|DATA_OVERRUN))==0)
   	{
		putchar0(data);
   	}
}

ISR(USART1_RX_vect)
{
	unsigned char status,data;
	
	status=UCSR1A;
	data=UDR1;
	if((status&(FRAMING_ERROR|PARITY_ERROR|DATA_OVERRUN))==0)
   	{
		putchar1(data);
   	}
}

void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
	cli();
	/* Wait for completion of previous write */
	while(EECR&(1<<EEWE));
	/* Set up address and data registers */
	EEAR=uiAddress;
	EEDR=ucData;
	/* Write logical one to EEMWE */
	EECR|=(1<<EEMWE);
	/* Start eeprom write by setting EEWE */
	EECR|=(1<<EEWE);
	sei();
}

unsigned char EEPROM_read(unsigned int uiAddress)
{
	cli();
	/* Wait for completion of previous write */
	while(EECR&(1<<EEWE));
	/* Set up address register */
	EEAR=uiAddress;
	/* Start eeprom read by writing EERE */
	EECR|=(1<<EERE);
	sei();
	/* Return data from data register */
	return EEDR;
}

int main(void)
{
	unsigned char i;
	// Timer/Counter 0 initialization
	// Clock source: System Clock
	// Clock value: 46,875 kHz
	// Mode: Fast PWM top=FFh
	// OC0 output: Non-Inverted PWM
	ASSR=0x00;
	TCCR0=0x6E;
	TCNT0=0x00;
	OCR0=0x00;

	// Timer/Counter 1 initialization
	// Clock source: System Clock
	// Clock value: 46,875 kHz
	// Mode: Normal top=FFFFh
	// OC1A output: Discon.
	// OC1B output: Discon.
	// OC1C output: Discon.
	// Noise Canceler: Off
	// Input Capture on Falling Edge
	// Timer 1 Overflow Interrupt: On
	// Input Capture Interrupt: Off
	// Compare A Match Interrupt: Off
	// Compare B Match Interrupt: Off
	// Compare C Match Interrupt: Off
	TCCR1A=0x00;
	TCCR1B=0x04;
	TCNT1H=0xB7;
	TCNT1L=0x1B;
	ICR1H=0x00;
	ICR1L=0x00;
	OCR1AH=0x00;
	OCR1AL=0x00;
	OCR1BH=0x00;
	OCR1BL=0x00;
	OCR1CH=0x00;
	OCR1CL=0x00;

	// USART0 initialization
	// Communication Parameters: 8 Data, 1 Stop, No Parity
	// USART0 Receiver: On
	// USART0 Transmitter: On
	// USART0 Mode: Asynchronous
	// USART0 Baud Rate: 9600
	UCSR0A=0x00;
	UCSR0B=0x98;
	UCSR0C=0x06;
	UBRR0H=0x00;
	UBRR0L=0x4D;

	// USART1 initialization
	// Communication Parameters: 8 Data, 1 Stop, No Parity
	// USART1 Receiver: On
	// USART1 Transmitter: On
	// USART1 Mode: Asynchronous
	// USART1 Baud Rate: 9600
	UCSR1A=0x00;
	UCSR1B=0x98;
	UCSR1C=0x06;
	UBRR1H=0x00;
	UBRR1L=0x4D;

	// ADC initialization
	// ADC Clock frequency: 750,000 kHz
	// ADC Voltage Reference: AVCC pin
	ADMUX=0x40;
	ADCSRA=0x8C;

	// Timer(s)/Counter(s) Interrupt(s) initialization
	TIMSK=0x04;
	ETIMSK=0x00;
	DDRC=0xFF;
	DDRB=0x10;
	sei();
	fdevopen(putchar0,getchar0);
	//Test EEPROM
	for(i=0;i<255;i++)
	{
		EEPROM_write(i+256,i);
	}
	for(i=0;i<255;i++)
	{
		putchar(EEPROM_read(i+256));	
	}
	printf("\r\n");
	//Start ADC
	ADCSRA=0xCC;
	while(1)
	//TEST PWM
	{
		for(i=0;i<255;i++)
        {
                OCR0=i;
                _delay_ms(5);
        }
        for(i=255;i>0;i--)
        {
                OCR0=i;
                _delay_ms(5);
        }
		ADCSRA=0xCC;
	}
}
