//nacteni hlavickovych souboru
#include "qs.h"
#include "pit.h"
#include "gpio.h"
#include "occs.h"
#include "sys.h"
#include "adc.h"
#include "cop.h"
#include "cmp.h"
#include "dac.h"
#include "iic.h"
#include "intc.h"
#include "pwm.h"
#include "qtimer.h"
#include "sci.h"
#include "spi.h"
#include "freemaster.h"

//deklarace funkci
void smer1_dvoufaz(void);
void smer2_dvoufaz(void);
void smer1_jednofaz(void);
void smer2_jednofaz(void);
void smer1_pulkrok(void);
void smer2_pulkrok(void);

//definice promennych
UWord16 rezim = 1;				//0 .. jednofazove rizeni
								//1 .. dvoufazove rizeni
								//2 .. pulkrokove rizeni
UWord16 vystup1 = 0b1010;		//pocatecni stav pro rizeni 1
UWord16 vystup2 = 0b1000;		//pocatecni stav pro rizeni 0 a 2
UWord16 prepinac;				//promenna pro ulozeni stavu prepinace
UWord16 perioda = 100;			//promenna pro nastaveni rychlosti otaceni
UWord16	pocitadlo;				//promenna pro citac PIT
UWord16 ad_vstup;				//promenna pro hodnoty z ad prevodniku

//hlavni funkce programu
void main (void) 
{
	ioctl(COP, COP_INIT, NULL);
	ioctl(SYS, SYS_INIT, NULL);
	ioctl(GPIO_A, GPIO_INIT, NULL);	//inicializace GPIO portu A
	ioctl(GPIO_B, GPIO_INIT, NULL);	//inicializace GPIO portu B
	ioctl(GPIO_C, GPIO_INIT, NULL);	//inicializace GPIO portu C
	ioctl(PIT_0, PIT_INIT, NULL);	//inicializace PIT_0 casovace
	ioctl(SCI_0, SCI_INIT, NULL);
	FMSTR_Init();
	ioctl(ADC,	ADC_INIT, NULL);	//inicializace ADC
	ioctl(INTC, INTC_INIT, NULL);	//inicializace Interrupt Controller
	archEnableInt();
	while(1)						//nekonecna smycka
	{
	   	ioctl(COP, COP_CLEAR_COUNTER, NULL);	//nulovani citace COP
    	FMSTR_Poll();
	}
}
//---------------------------------------------------------
//funkce volana pri preruseni od casovace PIT_0
void pit0isr(void)
{
	#pragma interrupt
	perioda = 0xFFFF / (ad_vstup >> 3);	//vypocet periody
	if (perioda < 25)		//horni omezeni rychlosti krokovani
		perioda = 25;
	if (perioda > 10000)	//dolni omezeni rychlosti krokovani
		perioda = 10000;
	prepinac = ioctl( GPIO_C, GPIO_READ_DATA, NULL) & BIT_1 ;	//precteni vstupu
	if	(pocitadlo >= perioda)		//testovani podnimky
	{
		if (rezim == 0)				//testoavni rezimu 0
		{
			if (prepinac)			//je-li prepinac sepnut
			{		
				smer1_jednofaz();	//volani funkce pro prvni smer otaceni	
				ioctl(GPIO_A, GPIO_WRITE_DATA, vystup2); //zapis dat na vystup
				pocitadlo = 0;		//nulovani promenne pocitadlo
			}
			else					//je-li prepinac rozepnut
			{
				smer2_jednofaz();	//volani funkce pro opacny smer otaceni
				ioctl(GPIO_A, GPIO_WRITE_DATA, vystup2); //zapis dat na vystup
				pocitadlo = 0;		//nulovani promenne pocitadlo
			}
		}
		if (rezim == 1)				//testovani rezimu 1
		{
			if (prepinac)
			{		
				smer1_dvoufaz();	
				ioctl(GPIO_A, GPIO_WRITE_DATA, vystup1);
				pocitadlo = 0;
			}
			else
			{
				smer2_dvoufaz();
				ioctl(GPIO_A, GPIO_WRITE_DATA, vystup1);
				pocitadlo = 0;
			}
		}
		if (rezim == 2)				//testovani rezimu 2
		{
			if (prepinac)
			{		
				smer1_pulkrok();	
				ioctl(GPIO_A, GPIO_WRITE_DATA, vystup2);
				pocitadlo = 0;
			}
			else
			{
				smer2_pulkrok();
				ioctl(GPIO_A, GPIO_WRITE_DATA, vystup2);
				pocitadlo = 0;
			}
		}
	}
	pocitadlo++;								//inkrementace promenne pocitadlo
	ioctl(ADC, ADC_START, NULL);				//start prevodu A/D prevodniku
	ioctl(PIT_0, PIT_CLEAR_ROLLOVER_INT, NULL);	//smazani priznaku preruseni pro PIT_0
	FMSTR_Recorder();
}
//----------------------------------------------------------
//funkce volana pri preruseni od ADC
void adc0isr(void)
{
	#pragma interrupt
	ad_vstup = (UWord16)ioctl(ADC, ADC_READ_SAMPLE, 0);	//precteni hodnoty z A/D prevodniku
	ioctl(ADC, ADC_CLEAR_STATUS_EOSI, NULL);			//smazani priznaku preruseni od ADC
}
//----------------------------------------------------------
//funkce volana pri jednofazovem rezimu rizeni
void smer1_jednofaz(void)
{
	switch (vystup2)				//testovani promenne vystup2 
	{
		case 0b1000:				//jestliže vystup2 = 0b1000
			vystup2 = 0b0010;		//priradi promenne vystup2 hodnotu 0b0010
			break;
		case 0b0010:				//dale analogicky
			vystup2 = 0b0100;
			break;
		case 0b0100:
			vystup2 = 0b0001;
			break;
		case 0b0001:
			vystup2 = 0b1000;
			break;
		default: break;	
	}
}
//funkce volana pri jednofazovem rezimu rizeni - reverzni smer
void smer2_jednofaz(void)
{
	switch (vystup2)
	{
		case 0b1000:
			vystup2 = 0b0001;
			break;
		case 0b0001:
			vystup2 = 0b0100;
			break;
		case 0b0100:
			vystup2 = 0b0010;
			break;
		case 0b0010:
			vystup2 = 0b1000;
			break;
		default: break;	
	}
}
//------------------------------------------------------------
////funkce volana pri dvoufazovem rezimu rizeni
void smer1_dvoufaz(void)
{
	switch (vystup1)
	{
		case 0b1010:
			vystup1 = 0b0110;
			break;
		case 0b0110:
			vystup1 = 0b0101;
			break;
		case 0b0101:
			vystup1 = 0b1001;
			break;
		case 0b1001:
			vystup1 = 0b1010;
			break;
		default: break;	
	}
}

//funkce volana pri dvoufazovem rezimu rizeni - reverzni smer
void smer2_dvoufaz(void)
{
	switch (vystup1)
	{
		case 0b1010:
			vystup1 = 0b1001;
			break;
		case 0b1001:
			vystup1 = 0b0101;
			break;
		case 0b0101:
			vystup1 = 0b0110;
			break;
		case 0b0110:
			vystup1 = 0b1010;
			break;
		default: break;	
	}
}
//------------------------------------------------------------
//funkce volana pri pulkrokovem rezimu rizeni
void smer1_pulkrok(void)
{
	switch (vystup2)
	{
		case 0b1000:
			vystup2 = 0b1010;
			break;
		case 0b1010:
			vystup2 = 0b0010;
			break;
		case 0b0010:
			vystup2 = 0b0110;
			break;
		case 0b0110:
			vystup2 = 0b0100;
			break;
		case 0b0100:
			vystup2 = 0b0101;
			break;
		case 0b0101:
			vystup2 = 0b0001;
			break;
		case 0b0001:
			vystup2 = 0b1001;
			break;
		case 0b1001:
			vystup2 = 0b1000;
			break;
		default: break;	
	}
}

//funkce volana pri pulkrokovem rezimu rizeni - reverzni smer
void smer2_pulkrok(void)
{
		switch (vystup2)
	{
		case 0b1000:
			vystup2 = 0b1001;
			break;
		case 0b1001:
			vystup2 = 0b0001;
			break;
		case 0b0001:
			vystup2 = 0b0101;
			break;
		case 0b0101:
			vystup2 = 0b0100;
			break;
		case 0b0100:
			vystup2 = 0b0110;
			break;
		case 0b0110:
			vystup2 = 0b0010;
			break;
		case 0b0010:
			vystup2 = 0b1010;
			break;
		case 0b1010:
			vystup2 = 0b1000;
			break;
		default: break;	
	}
}