// Executable name : main
// Version         : 2018
// Created date    : 30. 3. 2018
// Last update     : 14. 5. 2018
// Author          : Martin Matoušek


#define XTAL 		1000000
#define F_CPU 		1000000

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>		
#include <stdint.h>

unsigned long frequency=28000000;
int i;
unsigned long controlRegister; 
unsigned long freqLSB; 
unsigned long freqMSB; 
unsigned long freqLSB1; 
unsigned long phaseLSB; 
unsigned long phaseMSB; 
unsigned long freqMSB1; 

volatile int direction;
volatile int analog_value;
volatile int analog_value_new;
volatile int kapacita;
volatile int indukcnost;


//////////////////////////////////////////////////////////////////////////////////


void dds_send_bit(unsigned long data)
{
	PORTC &= ~(1 << PC0);
	_delay_us(5);
	PORTC |= (1<<PC0);		
	_delay_us(10);
	
	PORTC &= ~(1<<PC2);		
		
	for(i = 0; i < 16; i++)
	{
		if(data&0x8000)
			PORTC |= (1 << PC1);			
		else 
			PORTC &= ~(1 << PC1);
			
		_delay_us(3);		
		PORTC &= ~(1 << PC0);
		_delay_us(3);					
		PORTC |= (1 << PC0);			
		data=data<<1;
		_delay_us(1);
	}
	
	PORTC |= (1 << PC2);				 
	PORTC |= (1 << PC0);
	_delay_us(10);
	
}
/////////////////////////////////////////////////////////////////////////

 ISR(INT0_vect)						// Vektor přerušení pro INT0
{
	GICR &= 0b10111111;				// Nastavení zakázání přerušení pro INT0

	if (direction == 1)				
		{
			direction = 0;			
		}
	else							
		{
			direction = 1;			
		}
}
/////////////////////////////////////////////////////////////////////////
	ISR(ADC_vect)					// přerušení po ukončení A/D převodu
	{
		analog_value = ADCH;
	}
	
	ISR(TIMER0_COMP_vect)			// přerušení po shodě registru TCNT0 a OCR0
	{
		
	}
	
	ISR(TIMER0_OVF_vect)			// přerušení po přetečení TCNT0
	{
		
	}
/////////////////////////////////////////////////////////////////////////

void EEPROM_write(unsigned int Addresa, unsigned char Data)
{								
																
		while(EECR & (1<<EEWE));			//čekání na požadavek	
													
		EEAR = Addresa;						//nastavení adresy	
		EEDR = Data;						
													
		EECR |= (1<<EEMWE);					// zápis registru EEMWE
		EECR |= (1<<EEWE);					//zápis do eeprom
}
/////////////////////////////////////////////////////////////////////////

int main(void)
{
	
	MCUCSR = (1<<JTD);
	MCUCSR = (1<<JTD);
	
	GICR |= 0b01000000;		// Nastavení povolení přerušení pro INT0
	MCUCR |= 0b00000010;	// Nastavení reakce na sestupnou hranu pro INT0
	
	TCCR0 = 0b01101100;		// rychlý PWM režim,neinvertující režim, předdělička 256
	TIMSK = 0b00000011;		// povolení přerušení pří shodě i při přetečení

	DDRC = 0xFF;			
	PORTC = 0xFF;
	
	DDRD = 0xF0;		
	PORTD = 0xFF;		
	
	DDRB = 0xFF;			
	PORTB = 0b00001000;
	
	DDRA = 0x00;			
	PORTA = 0x00;
	_delay_us(10);
	
	
	PORTC &= ~(1<<PC3);			//reset
	PORTC |= (1 << PC2);		//nastavení FSYNC 
	PORTC |= (1 << PC0);

	OCR0 = 0x00;
	
	sei();


	/////////////////////////////////////////////////////////////////

	controlRegister = 0b0010000000000000;
	dds_send_bit(controlRegister);
		
	phaseLSB = 0b110000000000000;
	phaseMSB = 0b111000000000000;
	
	frequency=28000000;
	frequency=frequency*3.615;				//Vynasobeno 2^28/fclk
	frequency=frequency<<2;					//Zarovnani MSB poloviny doprava
	freqLSB=frequency;
	freqMSB=frequency>>16;
	freqLSB=freqLSB>>2;						//Zpetne zarovnani LSB poloviny
	freqLSB=(freqLSB&0x7FFF)|0x4000;		//Volba FREQ0
	freqMSB=(freqMSB&0x7FFF)|0x4000;

	frequency=19000000;
	frequency=frequency*3.615;				//Vynasobeno 2^28/fclk
	frequency=frequency<<2;					//Zarovnani MSB poloviny doprava
	freqLSB=frequency;
	freqMSB=frequency>>16;
	freqLSB=freqLSB>>2;						//Zpetne zarovnani LSB poloviny
	freqLSB1=(freqLSB&0x7FFF)|0x4000;		//Volba FREQ0
	freqMSB1=(freqMSB&0x7FFF)|0x4000;

	dds_send_bit(phaseMSB);
	dds_send_bit(phaseLSB);		
	dds_send_bit(freqLSB);
	dds_send_bit(freqMSB);
	
	
	while(1){
		
		if (direction == 1)				// Pokud je směr 1, provede se přizpůsobení
		{
			//dds_send_bit(freqLSB);
			//dds_send_bit(freqMSB);
			
			for(i = 0; i < 255; i++)
			{
				OCR0 = i;
				PORTD &= ~(1<<PC6);			
				PORTD |= (1 << PC7);
				_delay_ms(1);
				
				ADCSRA |= 0b01000000;		// spuštění A/D převodu
				_delay_ms(800);				

				if (analog_value_new < analog_value)
				{
					kapacita = i;
					indukcnost = 0;
					analog_value_new = analog_value;
				}
				
				PORTD &= ~(1<<PC7);			
				PORTD |= (1 << PC6);
				_delay_ms(1);
				
				ADCSRA |= 0b01000000;		// spuštění A/D převodu
				_delay_ms(800);				

				if (analog_value_new < analog_value)
				{
					kapacita = i;
					indukcnost = 1;
					analog_value_new = analog_value;
				}
			}
			
			
		}
		else
		{
			//dds_send_bit(freqLSB1);
			//dds_send_bit(freqMSB1);
			
		}
		
		EEPROM_write(0,kapacita);
		EEPROM_write(1,indukcnost);
		
		OCR0 = kapacita;
		if (indukcnost == 1)				
		{
			PORTD &= ~(1<<PC7);
			PORTD |= (1 << PC6);
		}
		else
		{
			PORTD &= ~(1<<PC6);
			PORTD |= (1 << PC7);
		}
		
		///////////////////////////////////////////////////////////////////////////
		_delay_ms(1);
		GIFR |= 0b01000000;		// Vymazání požadavku na přerušení
		GICR |= 0b01000000;		// Nastavení povolení přerušení pro INT0
	}
	
	return 0;
}
