#include <system.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#pragma DATA _CONFIG1H, _OSC_HS_1H 
#pragma DATA _CONFIG2H, _WDT_OFF_2H 
#pragma DATA _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
#pragma DATA _CONFIG3H, _MCLRE_ON_3H
#pragma CLOCK_FREQ 20000000

#include "button_lib.h"
#include "LCD_lib.h"
#include "A2DConv.h"
#include "generator_commands.h"
#include "GPS_parse_lib.h"

//Global Interrupt Bits//
volatile bit peie@INTCON.6;
volatile bit gie@INTCON.7;
volatile bit ipen@RCON.7;
//Timer 0 Interrupt Signals//
volatile bit tmr0if@INTCON.2;
volatile bit tmr0ie@INTCON.5;
//Button Interrupt Signals//
volatile bit int2ie@INTCON3.4;  //B2
volatile bit int2if@INTCON3.1;
volatile bit intedg2@INTCON2.4;
//A2D Conversion Interrupt Signal//
volatile bit adif@PIR1.6;
volatile bit adie@PIE1.6;
//A2D Convert Variables//
unsigned char ultracap_voltage;
unsigned char gen_output;
int monitorucs;
unsigned char dispucvoltage;
//GPS Receive Interrupt Signals//
volatile bit rcif@PIR1.5;
volatile bit rcie@PIE1.5;
volatile bit rcip@IPR1.5;
//GPS Send/Receive Signals
volatile bit txen@TXSTA.5;
volatile bit trmt@TXSTA.1;
volatile bit cren@RCSTA.4;
//Generator Control Signals//
volatile bit starte@LATB.3;
volatile bit fuelvalv@LATB.4;
volatile bit glowp@LATE.0;
unsigned char monitor_ultracaps;
//Initialization Variables;
bool go;
bool ready;
int tmr0counter;
char interruptson;

void initialize(void)
{
	//Enable Global Interrupts//
	peie = 1;
	gie = 1;
	//ipen = 1;
	//Set LED's For Output//
	trisd = 0;
	latd = 0;
	//Call Initialization Functions//
	button2_init();
	A2D_init();
	gen_commands_init();
	GPS_init();
	LCD_init();
	//Initalize Variables//
	go = 0;
	ready = 0;
	tmr0counter = 0;
	monitorucs = 0;
}

void interrupt(void)
{
	if (go == 0)
	{
		if (tmr2if)
		{
			go = debounce3();
			tmr2if = 0;
			button_init();
		}
	}
	if (tmr0if)
	{	
		tmr0counter++;
		if (ready ==1)
		{
			display();		
		}
		if (ready==0)
		{
			LCD_clear();
			LCD_printf("Please Wait,");
			LCD_cursor(0x40);
			if (tmr0counter%2==0)
				LCD_printf("Acquiring Satellites");
			if (tmr0counter%2==1)
				LCD_printf("Engine Warming......");
			if (tmr0counter>9)
			{
				LCD_clear();
				LCD_printf("You may now begin");
				LCD_curosr(0x40);
				LCD_printf("your hybrid driving");
				LCD_cursor(0x14);
				LCD_printf("sequence".);
				ready = 1;
				tmr0counter=1;
				button_init();
			}
		}
		tmr0if=0;
	}
	if (rcif)
	{
		redGPS(1);
		rcif = 0;
	}
	return;
}

void main()
{
	initialize();											//Initialize all libraries
						LCD_printf("Welcome to the New");	//Display Message to user
	LCD_cursor(0x40);	LCD_printf("Hybrid Electric");		//Second line of cursor is at 0x40, so need to account for this
	LCD_cursor(0x14);	LCD_printf("Vehicle Experience");
	delay_s(2);
						LCD_printf("Please Press 'Begin'");
	LCD_cursor(0x40);	LCD_printf("Button to Start Your");
	LCD_cursor(0x40);	LCD_printf("Driving Sequence");

	while (!go);
	glowplug = 1;	//Warm up the engine
	cren = 1;		//Accept receptions from the GPS 
	//Bits for Timer 0 Control Reg for interrupt every 1.677 seconds
	//Bit7 = 1 : Timer0 Enable
	//Bit6 = 0 : Timer0 16-bit Counter
	//Bit5 = 0 : Timer 0 clock source select CLKO
	//Bit4 = 1 : Edge Select (high-to-low)
	//Bit3 = 0 : Prescalar Bit is assigned
	//Bit2:0 = 110 : Prescale at 1:128 
	t0con = 10010110b;
	tmr0ie = 1;	
	while(!ready);	//Wait for engine to warm and satellites to acquire
	rcie = 1;		//Turn on the EUSART interrupt flag bit
	while(1)
	{
		//Check Voltage on Ultracaps and Charge if Necessary//
		delay_ms(100);
		ultracap_voltage = ultracap_voltage3();
		delay_ms(10);
		checkbuttons();
		if (ultracap_voltage < 159)
		{
			start_charge();				//Turn on fuelvalve and starter signals
			check_starter();			//Turns off starter once generator is on; Will not continue until starter signal goes off
			monitor_ultracaps(1);		//Monitor ultracap stack value and turn off generator at full charge
		}//end if(uc<130)
	}	
	return;
}
