#include <htc.h>
#include <stdio.h>
#include "sonarcontrol.h"
#include "main.h"

#define RD 1 // PORTB reading (low)
#define WR 2 // PORTB writing (low)
#define RXF 4 // PORTB recieving permited (low)
#define TXE 2 // PORTE writing permited (low)

#define LED 0 // PORTE

#define COM_TIMEOUT 5000 // communication time out
#define LED_BLINK_TIME_FAST 4 // led blink period
#define LED_BLINK_TIME_SLOW 16 // led blink period

unsigned char LedBlinkCounter = 0;
unsigned char GoalLedBlinkCounter = LED_BLINK_TIME_SLOW;
unsigned char Measuring; // start measure

void SendHeader(void)
{
	SendByte('Z');
	SendByte('Z');
	SendByte('S');
	SendByte('S');
}

void SendByte(unsigned char d)
{
	unsigned int counter = 0;

	while((PORTE&(0x01 << TXE)) != 0)
	{
		if(++counter == COM_TIMEOUT) return;
	}
	 // until TXE != 0 (can transmit)
	
	PORTD = d;	
	PORTB |= (0x01 << WR); // WR = 1
	PORTB &= ~(0x01 << WR); // WR = 0
}

void SendString(unsigned char str[], unsigned char length)
{
	unsigned char i;
	for(i = 0; i < length; i++)
	{
		SendByte(str[i]);
	}
}

unsigned char RecieveByte(void)
{
	unsigned char result;
	TRISD = 0xff;
	while((PORTB&(0x01 << RXF)) != 0); // until RXF != 0 (can recieve)
	PORTB &= ~(0x01 << RD); // RD = 0	
	result = PORTD;
	PORTB |= (0x01 << RD); // RD = 1
	TRISD = 0x00;
	return result;
}	


void main(void)
{
	unsigned char stemp[5];

	Measuring = 0;
	#ifdef OSCON
	Measuring = 1;
	#endif

	ADCON1 = 0x06; // all pins as digital
	TRISA = 0x00;
	TRISD = 0x00; // PORTD output - communication with FTDI
	TRISE = 0x00 | (0x01 << TXE); // RXE input
	TRISB = 0x00 | (0x01 << RXF); // RXF input

	TRISC = 0x00 | (0x01 << CCP1) | (0x01 << CCP2) ;  // CCP input pin 	

	PORTB = 0x00;
	PORTB |= (0x01 << RD); //RD = 1
	PORTE = 0x00;
	PORTC = 0x00;

	T2CON = 0xff; // max. preddelicka, postdelicka, tmr on
	CCP1CON = 0x04; // CCP1 capture mode - falling edge
	CCP2CON = 0x04; // CCP2 capture mode - falling edge
	T1CON = 0x00; // 1:1 pre, internal,off	

	CCP1IE = 0;
	CCP2IE = 0;
	TMR2IE = 1;
	PEIE = 1; // all peripheral interrupts are enabled

	ei(); // enable all interrupts

	while(1)
	{ 
	#ifdef COMM
	if(Measuring != 0)
	{
		for(unsigned char i = 0; i < 12; i++)
		{
			#ifdef COMTEST
			if(i == 0)
			{
				Time[i][0]++;
				//Time[i][0] = 128;
				if(Time[i][0] == 0)
				{
					Time[i][1]++;
				}
				__delay_ms(300);
				continue;
			}
			
			#endif

			Time[i][0] = 0xff;
			Time[i][1] = 0xff;
		}
	}
	#endif
	#ifndef OSCON
	#ifndef MEAS13
	#ifndef COMTEST
	if(Measuring != 0)
	{	
		for(CurrentMode = 0; CurrentMode < 4; CurrentMode++)
		{
			Measure(CurrentMode,0);
		}
	}
	#endif
	#else
	//MEAS13
	CurrentMode = 3;
	Measure(CurrentMode,1);
	#endif
	#else
	//OSCON
	CurrentMode = 3;
	Measure(CurrentMode,1);
	#endif


	#ifdef COMM
	if(Measuring != 0)
	{
	unsigned char chsum = 0;
	SendHeader();
	SendByte('_');
	for(unsigned char i = 0; i < 12; i++)
		{
			unsigned char Hb = Time[i][1];
			unsigned char Lb = Time[i][0];
			sprintf(stemp,"%1x%02x%02x",i,Hb,Lb);
			SendString(stemp,5);
			unsigned char ci;
			for(ci = 0; ci < 5; ci++)
			{
				chsum += stemp[ci];
			}
		}
	unsigned char sch[2];
	sprintf(sch,"%02x",chsum);
	SendString(sch,2);
	SendByte('_');
	SendHeader();
	}

	if((PORTB&(0x01 << RXF)) == 0)
		{
			unsigned char d = RecieveByte();
			if(d == 'r') 
			{	
				Measuring = ~Measuring;
				LedBlinkCounter = 0;
				if(Measuring == 0x00)
					GoalLedBlinkCounter = LED_BLINK_TIME_SLOW;
				else
					GoalLedBlinkCounter = LED_BLINK_TIME_FAST;
			}
			if(d == 'h')
			{
				Measuring = 0;
				GoalLedBlinkCounter = LED_BLINK_TIME_SLOW;
				LedBlinkCounter = 0;
				SendByte('H');
				SendByte('e');
				SendByte('l');
				SendByte('l');
				SendByte('o');
			}
		}

	#endif

	}	  
}

void interrupt global_int(void)
{
	if ((CCP1IF)&&(CCP1IE))
	{
		CCP1IF = 0;
		//falling edge
		if(CCP1M0 == 0)
		{
			FallingEdge(0);
		}
	}

	if ((CCP2IF)&&(CCP2IE))
	{
		CCP2IF = 0;
		//falling edge
		if(CCP2M0 == 0)
		{
			FallingEdge(1);
		}
	}


	if ((TMR2IF)&&(TMR2IE)) 
	{
		unsigned char temp;	
		TMR2IF=0;
		if(++LedBlinkCounter == GoalLedBlinkCounter)
		{
			LedBlinkCounter = 0;

			// negace led
			temp = PORTE & (0x01 << LED);
			if(temp)
				PORTE &= ~(0x01 << LED);
			else
				PORTE |= (0x01 << LED);
		}
	}

	if ((TMR1IF)&&(TMR1IE)) 
	{
		TMR1IF = 0;
		#ifdef COMM
		SendHeader();
		SendByte('_');
		SendByte('E');
		SendByte('_');		
		SendHeader();
		#endif
	}
	return;
}
