//************************************************************************************
//**  
//**  File name:     E:\LIT\Gryphon_Robot\Flowcode\PID_1824_simplified1.c
//**  Generated by:  Flowcode v4.3.7.63
//**  Date:          Saturday, April 16, 2011 12:05:44
//**  Licence:       Professional
//**  Registered to: LIT
//**  
//**  
//**  http://www.matrixmultimedia.com
//************************************************************************************


#define MX_PIC

//Defines for microcontroller
#define MX_EE_SIZE 256
#define MX_SPI
#define MX_SPI_C
#define MX_SPI_SDI 1
#define MX_SPI_SDO 2
#define MX_SPI_SCK 0
#define MX_UART
#define MX_UART_C
#define MX_UART_TX 4
#define MX_UART_RX 5
#define MX_I2C
#define MX_MI2C
#define MX_I2C_C
#define MX_I2C_SDA 1
#define MX_I2C_SCL 0
#define MX_PWM
#define MX_PWM_CNT 2
#define MX_PWM_TRIS1 trisc
#define MX_PWM_1 5
#define MX_PWM_TRIS2 trisc
#define MX_PWM_2 3
#define MX_PWM_TRIS2a trisa
#define MX_PWM_2a 5

//Functions
#define MX_CLK_SPEED 19660800
#ifdef _BOOSTC
#include <system.h>
#endif
#ifdef HI_TECH_C
#include <pic.h>
#endif

//Configuration data
#ifdef _BOOSTC
#pragma DATA 0x8007, 0x9a4
#endif
#ifdef HI_TECH_C
__CONFIG(0x9a4);
#endif
#ifdef _BOOSTC
#pragma DATA 0x8008, 0x1713
#endif
#ifdef HI_TECH_C
__CONFIG(0x1713);
#endif

//Internal functions
#include "C:\Program Files (x86)\Matrix Multimedia\Flowcode V4\FCD\internals.h"

//Macro function declarations
void FCM_PID1();


//Variable declarations
short FCV_PID_D1;
char FCV_AWAY1;
short FCV_GAIN_SCALING;
char FCV_MODE;
char FCV_ENABLE;
char FCV_I_GAIN;
char FCV_HOME_SETPOINT1;
short FCV_PID_P1;
char FCV_SETPOINT1;
char FCV_D_GAIN;
char FCV_AWAY;
short FCV_PID_I1;
char FCV_FEEDBACK1;
char FCV_AWAY_SETPOINT1;
short FCV_PID_PX1;
short FCV_PID_Y1;
char FCV_P_GAIN;
char FCV_HOME;


//Defines:

/**** Macro Substitutions ****
255 = Timer 2 Rollover Value
0x04 = Timer 2 Prescaler Value
%c = Unused
0 = Alternate Pin FCD_PWM0_Enable
******************************/




//PWM(0): //Macro function declarations

void FCD_PWM0_Enable(char nIdx);
void FCD_PWM0_Disable(char nIdx);
void FCD_PWM0_SetDutyCycle(char nIdx, char nDuty);
void FCD_PWM0_ChangePeriod(char nPeriodVal, char nPrescalerVal);
void FCD_PWM0_SetDutyCycle10bit(char nIdx, short nDuty);
//Defines:

/**** Macro Substitutions ****
2 = Which ADC Channel
40 = Acquisition time
3 = Conversion Speed
0 = VRef+ Option
500 = VRef Voltage x 0.01V
******************************/




//ADC(2): //Macro function declarations

void FCD_ADC2_SampleADC();
char FCD_ADC2_ReadAsByte();
short FCD_ADC2_ReadAsInt();
float FCD_ADC2_ReadAsVoltage();
void FCD_ADC2_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE);
//Defines:

/**** Macro Substitutions ****
4 = Which ADC Channel
40 = Acquisition time
3 = Conversion Speed
0 = VRef+ Option
500 = VRef Voltage x 0.01V
******************************/




//ADC(3): //Macro function declarations

void FCD_ADC3_SampleADC();
char FCD_ADC3_ReadAsByte();
short FCD_ADC3_ReadAsInt();
float FCD_ADC3_ReadAsVoltage();
void FCD_ADC3_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE);

//Supplementary defines
#define option_reg OPTION_REG



//PWM(0): //Macro implementations


void FCD_PWM0_Enable(char nIdx)
{
	
	  //error checking
	  #ifndef MX_PWM
	  		#ifdef _BOOSTC
	  			#pragma error "This chip does not have PWM capability"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error This chip does not have PWM capability
			#endif
	  #else
	    #ifndef MX_PWM_CNT
	  		#ifdef _BOOSTC
	  			#pragma error "FCD file error (no MX_PWM_CNT)"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error FCD file error (no MX_PWM_CNT)
			#endif
	    #endif
	    #if (MX_PWM_CNT < 1)
	  		#ifdef _BOOSTC
	  			#pragma error "FCD file error (MX_PWM_CNT < 1)"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error FCD file error (MX_PWM_CNT < 1)
			#endif
	    #endif
	    #if (MX_PWM_CNT > 2)
	  		#ifdef _BOOSTC
	  			#pragma error "FCD file error (MX_PWM_CNT > 2)"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error FCD file error (MX_PWM_CNT > 2)
			#endif
	    #endif
	    #ifndef MX_PWM_TRIS1
	  		#ifdef _BOOSTC
	  			#pragma error "FCD file error (no MX_PWM_TRIS1)"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error FCD file error (no MX_PWM_TRIS1)
			#endif
	    #endif
	    #ifndef MX_PWM_1
	  		#ifdef _BOOSTC
	  			#pragma error "FCD file error (no MX_PWM_1)"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error FCD file error (no MX_PWM_1)
			#endif
	    #endif
	    #if (MX_PWM_CNT == 2)
	      #ifndef MX_PWM_TRIS2
	  		#ifdef _BOOSTC
	  			#pragma error "FCD file error (no MX_PWM_TRIS2)"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error FCD file error (no MX_PWM_TRIS2)
			#endif
	      #endif
	      #ifndef MX_PWM_2
	  		#ifdef _BOOSTC
	  			#pragma error "FCD file error (no MX_PWM_2)"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error FCD file error (no MX_PWM_2)
			#endif
	      #endif
	    #endif
	    #if (0 == 1)
	      #ifndef MX_PWM_TRIS1a
				#ifdef _BOOSTC
					#pragma error "PWM component error (using alternative, but no MX_PWM_TRIS1a)"
				#endif
				#ifdef HI_TECH_C
					#error PWM component error (using alternative, but no MX_PWM_TRIS1a)
				#endif
	        #define MX_PWM_ALT_ERROR
	      #endif
	      #ifndef MX_PWM_1a
				#ifdef _BOOSTC
					#pragma error "PWM component error (using alternative, but no MX_PWM_1a)"
				#endif
				#ifdef HI_TECH_C
					#error PWM component error (using alternative, but no MX_PWM_1a)
				#endif
	        #define MX_PWM_ALT_ERROR
	      #endif
	    #endif
	    #if (0 == 2)
	      #ifndef MX_PWM_TRIS2a
				#ifdef _BOOSTC
					#pragma error "PWM component error (using alternative, but no MX_PWM_TRIS2a)"
				#endif
				#ifdef HI_TECH_C
					#error PWM component error (using alternative, but no MX_PWM_TRIS2a)
				#endif
	        #define MX_PWM_ALT_ERROR
	      #endif
	      #ifndef MX_PWM_2a
				#ifdef _BOOSTC
					#pragma error "PWM component error (using alternative, but no MX_PWM_2a)"
				#endif
				#ifdef HI_TECH_C
					#error PWM component error (using alternative, but no MX_PWM_2a)
				#endif
	        #define MX_PWM_ALT_ERROR
	      #endif
	    #endif
	  #endif

	 #ifdef MX_PWM
	    pr2 = 255;
	    t2con = 0x04;

	  #if (MX_PWM_CNT >= 1)
	    if (nIdx == 1)
	    {
	        ccp1con = 0x0C;

	      #if (0 == 1)
	       #ifndef MX_PWM_ALT_ERROR
	        clear_bit(MX_PWM_TRIS1a, MX_PWM_1a);
	       #endif
	      #else
	        clear_bit(MX_PWM_TRIS1, MX_PWM_1);
	      #endif
		}
	  #endif

	  #if (MX_PWM_CNT >= 2)
	    if (nIdx == 2)
	    {
	        ccp2con = 0x0C;
	      #if (0 == 2)
	       #ifndef MX_PWM_ALT_ERROR
	        clear_bit(MX_PWM_TRIS2a, MX_PWM_2a);
	       #endif
	      #else
	        clear_bit(MX_PWM_TRIS2, MX_PWM_2);
	      #endif
	   }
	  #endif
	 #endif

	 #ifdef MX_PWM_ALT_ERROR
	   #undef MX_PWM_ALT_ERROR
	 #endif

}

void FCD_PWM0_Disable(char nIdx)
{
	
	  //error checking
	  #ifndef MX_PWM
	  		#ifdef _BOOSTC
	  			#pragma error "This chip does not have PWM capability"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error This chip does not have PWM capability
			#endif
	  #endif

	 #ifdef MX_PWM
	  #if (MX_PWM_CNT >= 1)
	    if (nIdx == 1)
	    {
	        ccp1con = 0x00;
	    }
	  #endif

	  #if (MX_PWM_CNT >= 2)
	    if (nIdx == 2)
	    {
	        ccp2con = 0x00;
	    }
	  #endif
	 #endif

}

void FCD_PWM0_SetDutyCycle(char nIdx, char nDuty)
{
	
	  //error checking
	  #ifndef MX_PWM
	  		#ifdef _BOOSTC
	  			#pragma error "This chip does not have PWM capability"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error This chip does not have PWM capability
			#endif
	  #endif

	 #ifdef MX_PWM
	  #if (MX_PWM_CNT >= 1)
	    if (nIdx == 1)
	    {
	        ccpr1l = nDuty;
	    }
	  #endif

	  #if (MX_PWM_CNT >= 2)
	    if (nIdx == 2)
	    {
	        ccpr2l = nDuty;
	    }
	  #endif
	 #endif

}

void FCD_PWM0_ChangePeriod(char nPeriodVal, char nPrescalerVal)
{
	
	  //error checking
	  #ifndef MX_PWM
	  		#ifdef _BOOSTC
	  			#pragma error "This chip does not have PWM capability"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error This chip does not have PWM capability
			#endif
	  #endif

	  #ifdef MX_PWM
	    pr2 = nPeriodVal;

	    switch (nPrescalerVal)
	    {
	        case 1:
	            t2con = 0x04;
	            break;

	        case 4:
	            t2con = 0x05;
	            break;

	        case 16:
	            t2con = 0x06;
	            break;
	    }
	  #endif

}

void FCD_PWM0_SetDutyCycle10bit(char nIdx, short nDuty)
{
	
		char nCCPxCONtemp;

	  //error checking
	  #ifndef MX_PWM
	  		#ifdef _BOOSTC
	  			#pragma error "This chip does not have PWM capability"
	  		#endif
	  		#ifdef HI_TECH_C
	  			#error This chip does not have PWM capability
			#endif
	  #endif

	 #ifdef MX_PWM
	  #if (MX_PWM_CNT >= 1)
	    if (nIdx == 1)
	    {
	        ccpr1l = (nDuty & 0x3FC) >> 2;

	    	nDuty = (nDuty & 0x03) << 4;
	    	nCCPxCONtemp = (ccp1con & 0xCF) | nDuty;
	    	ccp1con = nCCPxCONtemp;
	    }

	  #endif

	  #if (MX_PWM_CNT >= 2)
	    if (nIdx == 2)
	    {
	        ccpr2l = (nDuty & 0x3FC) >> 2;

	    	nDuty = (nDuty & 0x03) << 4;
	    	nCCPxCONtemp = (ccp2con & 0xCF) | nDuty;
	    	ccp2con = nCCPxCONtemp;
	    }

	  #endif
	 #endif

}



//ADC(2): //Macro implementations


void FCD_ADC2_SampleADC()
{
	
	/*******Supported Devices******************************************************************
	// 16F1826, 16F1827
	******************************************************************************************/

		#define MX_ADC_CHANNEL		2
		#define MX_ADC_SAMP_TIME 	40
		#define MX_ADC_CONV_SP		3
		#define MX_ADC_VREF_OPT		0

		//set up ADC conversion
		char old_tris, cnt;
		adcon1 = (MX_ADC_CONV_SP & 0x07) << 4;

		//find appropriate bit
		#if (MX_ADC_CHANNEL == 0)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x01
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 1)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x02
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 2)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x04
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 3)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x08
			#define MX_ADC_ANSEL_REG ansela
			#if (MX_ADC_VREF_OPT != 0)
				#ifdef _BOOSTC
					#pragma error "Target device is currently using AN3 for VREF+"
				#endif
				#ifdef HI_TECH_C
					#error Target device is currently using AN3 for VREF+
				#endif
			#endif
		#endif
		#if (MX_ADC_CHANNEL == 4)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x10
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 5)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x40
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 6)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x80
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 7)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x20
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 8)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x10
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 9)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x08
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 10)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x04
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 11)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x02
			#define MX_ADC_ANSEL_REG anselb
		#endif

		//sanity check
		#ifndef MX_ADC_TRIS_REG
			#ifdef _BOOSTC
				#pragma error "ADC Type 23 conversion code error - please contact technical support"
			#endif
			#ifdef HI_TECH_C
				#error ADC Type 23 conversion code error - please contact technical support
			#endif
		#endif

		//assign VREF functionality
		#if (MX_ADC_VREF_OPT != 0)
			st_bit(adcon1, ADPREF1);
		#endif

		//store old tris value, and set the i/o pin as an analogue input
		old_tris = MX_ADC_TRIS_REG;
		MX_ADC_TRIS_REG = MX_ADC_TRIS_REG | MX_ADC_TRIS_MSK;
		MX_ADC_ANSEL_REG = MX_ADC_ANSEL_REG | MX_ADC_TRIS_MSK;

		//turn ADC on
		adcon0 = 0x01 | (MX_ADC_CHANNEL << 2);

		//wait the acquisition time
		cnt = 0;
		while (cnt < MX_ADC_SAMP_TIME) cnt++;

		//begin conversion and wait until it has finished
		adcon0 = adcon0 | 0x02;
		while (adcon0 & 0x02);

		//restore old tris value, and reset adc registers
		MX_ADC_TRIS_REG = old_tris;
		MX_ADC_ANSEL_REG = 0x00;
		adcon0 = 0x00;

		#undef MX_ADC_TRIS_REG
		#undef MX_ADC_TRIS_MSK
		#undef MX_ADC_ANSEL_REG
		#undef MX_ADC_SAMP_TIME
		#undef MX_ADC_CHANNEL
		#undef MX_ADC_CONV_SP
		#undef MX_ADC_VREF_OPT

}

char FCD_ADC2_ReadAsByte()
{
	
		FCD_ADC2_SampleADC();

		#ifdef _BOOSTC
			#ifdef ADRES
				return ADRES;
			#else
				return ADRESH;
			#endif
		#endif

		#ifdef HI_TECH_C
			#ifdef adres
				return adres;
			#else
				return adresh;
			#endif
		#endif

}

short FCD_ADC2_ReadAsInt()
{
	
		short iRetVal;

		FCD_ADC2_SampleADC();

		#ifdef adres
			iRetVal = (adres << 2);
		#else
			iRetVal = (adresh << 2);
			iRetVal = iRetVal | (adresl >> 6);
		#endif

		return (iRetVal);

}

float FCD_ADC2_ReadAsVoltage()
{
	

		int iSample;
		float fSample, fVoltage, fVperDiv;

		#define MX_ADC_VREF_V		500

		iSample = FCD_ADC2_ReadAsInt();											//Read as 10-bit Integer

		#ifdef _BOOSTC
			fVoltage = float32_from_int32(MX_ADC_VREF_V);					//Convert reference voltage count to floating point (0 - 500 x 10mV)
			fVoltage = float32_mul(fVoltage, 0.01);							//Convert reference voltage count to actual voltage (0 - 5)
			fVperDiv = float32_mul(fVoltage, 0.000976);						//Convert actual voltage to voltage per division (VRef / 1024)
			fSample = float32_from_int32(iSample);							//Convert to floating point variable
			fVoltage = float32_mul(fSample, fVperDiv);						//Calculate floating point voltage
		#endif

		#ifdef HI_TECH_C
			fVoltage = MX_ADC_VREF_V;										//Convert reference voltage count to floating point (0 - 500 x 10mV)
			fVoltage = fVoltage * 0.01;										//Convert reference voltage count to actual voltage (0 - 5)
			fVperDiv = fVoltage * 0.000976;									//Convert actual voltage to voltage per division (VRef / 1024)
			fSample = iSample;												//Convert to floating point variable
			fVoltage = fSample * fVperDiv;									//Calculate floating point voltage
		#endif

		#undef MX_ADC_VREF_V
		return (fVoltage);

}

void FCD_ADC2_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE)
{
	
		float fVoltage;

		fVoltage = FCD_ADC2_ReadAsVoltage();
		FCI_FLOAT_TO_STRING(fVoltage, 2, FCR_RETVAL, FCR_RETVAL_SIZE);	//Convert to String

}



//ADC(3): //Macro implementations


void FCD_ADC3_SampleADC()
{
	
	/*******Supported Devices******************************************************************
	// 16F1826, 16F1827
	******************************************************************************************/

		#define MX_ADC_CHANNEL		4
		#define MX_ADC_SAMP_TIME 	40
		#define MX_ADC_CONV_SP		3
		#define MX_ADC_VREF_OPT		0

		//set up ADC conversion
		char old_tris, cnt;
		adcon1 = (MX_ADC_CONV_SP & 0x07) << 4;

		//find appropriate bit
		#if (MX_ADC_CHANNEL == 0)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x01
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 1)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x02
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 2)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x04
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 3)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x08
			#define MX_ADC_ANSEL_REG ansela
			#if (MX_ADC_VREF_OPT != 0)
				#ifdef _BOOSTC
					#pragma error "Target device is currently using AN3 for VREF+"
				#endif
				#ifdef HI_TECH_C
					#error Target device is currently using AN3 for VREF+
				#endif
			#endif
		#endif
		#if (MX_ADC_CHANNEL == 4)
			#define MX_ADC_TRIS_REG  trisa
			#define MX_ADC_TRIS_MSK  0x10
			#define MX_ADC_ANSEL_REG ansela
		#endif
		#if (MX_ADC_CHANNEL == 5)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x40
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 6)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x80
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 7)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x20
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 8)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x10
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 9)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x08
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 10)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x04
			#define MX_ADC_ANSEL_REG anselb
		#endif
		#if (MX_ADC_CHANNEL == 11)
			#define MX_ADC_TRIS_REG  trisb
			#define MX_ADC_TRIS_MSK  0x02
			#define MX_ADC_ANSEL_REG anselb
		#endif

		//sanity check
		#ifndef MX_ADC_TRIS_REG
			#ifdef _BOOSTC
				#pragma error "ADC Type 23 conversion code error - please contact technical support"
			#endif
			#ifdef HI_TECH_C
				#error ADC Type 23 conversion code error - please contact technical support
			#endif
		#endif

		//assign VREF functionality
		#if (MX_ADC_VREF_OPT != 0)
			st_bit(adcon1, ADPREF1);
		#endif

		//store old tris value, and set the i/o pin as an analogue input
		old_tris = MX_ADC_TRIS_REG;
		MX_ADC_TRIS_REG = MX_ADC_TRIS_REG | MX_ADC_TRIS_MSK;
		MX_ADC_ANSEL_REG = MX_ADC_ANSEL_REG | MX_ADC_TRIS_MSK;

		//turn ADC on
		adcon0 = 0x01 | (MX_ADC_CHANNEL << 2);

		//wait the acquisition time
		cnt = 0;
		while (cnt < MX_ADC_SAMP_TIME) cnt++;

		//begin conversion and wait until it has finished
		adcon0 = adcon0 | 0x02;
		while (adcon0 & 0x02);

		//restore old tris value, and reset adc registers
		MX_ADC_TRIS_REG = old_tris;
		MX_ADC_ANSEL_REG = 0x00;
		adcon0 = 0x00;

		#undef MX_ADC_TRIS_REG
		#undef MX_ADC_TRIS_MSK
		#undef MX_ADC_ANSEL_REG
		#undef MX_ADC_SAMP_TIME
		#undef MX_ADC_CHANNEL
		#undef MX_ADC_CONV_SP
		#undef MX_ADC_VREF_OPT

}

char FCD_ADC3_ReadAsByte()
{
	
		FCD_ADC3_SampleADC();

		#ifdef _BOOSTC
			#ifdef ADRES
				return ADRES;
			#else
				return ADRESH;
			#endif
		#endif

		#ifdef HI_TECH_C
			#ifdef adres
				return adres;
			#else
				return adresh;
			#endif
		#endif

}

short FCD_ADC3_ReadAsInt()
{
	
		short iRetVal;

		FCD_ADC3_SampleADC();

		#ifdef adres
			iRetVal = (adres << 2);
		#else
			iRetVal = (adresh << 2);
			iRetVal = iRetVal | (adresl >> 6);
		#endif

		return (iRetVal);

}

float FCD_ADC3_ReadAsVoltage()
{
	

		int iSample;
		float fSample, fVoltage, fVperDiv;

		#define MX_ADC_VREF_V		500

		iSample = FCD_ADC3_ReadAsInt();											//Read as 10-bit Integer

		#ifdef _BOOSTC
			fVoltage = float32_from_int32(MX_ADC_VREF_V);					//Convert reference voltage count to floating point (0 - 500 x 10mV)
			fVoltage = float32_mul(fVoltage, 0.01);							//Convert reference voltage count to actual voltage (0 - 5)
			fVperDiv = float32_mul(fVoltage, 0.000976);						//Convert actual voltage to voltage per division (VRef / 1024)
			fSample = float32_from_int32(iSample);							//Convert to floating point variable
			fVoltage = float32_mul(fSample, fVperDiv);						//Calculate floating point voltage
		#endif

		#ifdef HI_TECH_C
			fVoltage = MX_ADC_VREF_V;										//Convert reference voltage count to floating point (0 - 500 x 10mV)
			fVoltage = fVoltage * 0.01;										//Convert reference voltage count to actual voltage (0 - 5)
			fVperDiv = fVoltage * 0.000976;									//Convert actual voltage to voltage per division (VRef / 1024)
			fSample = iSample;												//Convert to floating point variable
			fVoltage = fSample * fVperDiv;									//Calculate floating point voltage
		#endif

		#undef MX_ADC_VREF_V
		return (fVoltage);

}

void FCD_ADC3_ReadAsString(char* FCR_RETVAL, char FCR_RETVAL_SIZE)
{
	
		float fVoltage;

		fVoltage = FCD_ADC3_ReadAsVoltage();
		FCI_FLOAT_TO_STRING(fVoltage, 2, FCR_RETVAL, FCR_RETVAL_SIZE);	//Convert to String

}

//Macro implementations

void FCM_PID1()
{
	
	//Read the 8-bit feedback
	//Call Component Macro: Feedback1=ADC(2)::ReadAsByte
	FCV_FEEDBACK1 = FCD_ADC2_ReadAsByte();


	//Calculate P and D values
	//Calculation:
	//  PID_p1 = Setpoint1 - Feedback1
	//  PID_d1 = PID_p1 - PID_px1
	//  PID_px1 = PID_p1
	FCV_PID_P1 = FCV_SETPOINT1 - FCV_FEEDBACK1;
	FCV_PID_D1 = FCV_PID_P1 - FCV_PID_PX1;
	FCV_PID_PX1 = FCV_PID_P1;
	

	//Scale and add the PID terms
	//Calculation:
	//  PID_y1 = ( PID_p1 * P_gain )
	//  PID_y1 = PID_y1 + ( PID_i1 * I_gain )
	//  PID_y1 = PID_y1 + ( PID_d1 * D_gain )
	//  PID_y1 = PID_y1 / Gain_scaling
	FCV_PID_Y1 = ( FCV_PID_P1 * FCV_P_GAIN );
	FCV_PID_Y1 = FCV_PID_Y1 + ( FCV_PID_I1 * FCV_I_GAIN );
	FCV_PID_Y1 = FCV_PID_Y1 + ( FCV_PID_D1 * FCV_D_GAIN );
	FCV_PID_Y1 = FCV_PID_Y1 / FCV_GAIN_SCALING;
	

	//Decision
	//Decision: PID_y1 > 255?
	if (FCV_PID_Y1 > 255)
	{
		//Positive saturation
		//Calculation:
		//  PID_y1 = 255
		FCV_PID_Y1 = 255;
		

	} else {
		//Decision
		//Decision: PID_y1 < 0?
		if (FCV_PID_Y1 < 0)
		{
			//Negative saturation
			//Calculation:
			//  PID_y1 = 0
			FCV_PID_Y1 = 0;
			

		} else {
			//Update I if not saturated
			//Calculation:
			//  PID_i1 = PID_i1 + PID_p1
			FCV_PID_I1 = FCV_PID_I1 + FCV_PID_P1;
			

		}


	}


}

//Supplementary implementations


void main()
{
	
	//Initialisation
	ansela = 0x00;
anselc = 0x00;


	//Interrupt initialisation code
	option_reg = 0xC0;


	//C Code
	//C Code:
	/*Enter C code below these comments
	Alternatively, to enter assembly code,
	use the asm operator in front of each instruction, e.g.
	asm movlw 5
	or enclose several statements within an asm block:
	asm
	{
		movlw 8
		movlw4
	}
	*/

	osccon = 0x7A;



	//Gain settings
	//Calculation:
	//  P_gain = 20
	//  I_gain = 0
	//  D_gain = 0
	//  Gain_scaling = 1
	FCV_P_GAIN = 20;
	FCV_I_GAIN = 0;
	FCV_D_GAIN = 0;
	FCV_GAIN_SCALING = 1;
	

	//PWM output enable
	//Call Component Macro: PWM(0)::Enable(2)
	FCD_PWM0_Enable(2);


	//Term initialisation
	//Calculation:
	//  PID_i1 = 0
	//  PID_p1 = 0
	//  PID_d1 = 0
	//  PID_px1 = 0
	//  Setpoint1 = 127
	FCV_PID_I1 = 0;
	FCV_PID_P1 = 0;
	FCV_PID_D1 = 0;
	FCV_PID_PX1 = 0;
	FCV_SETPOINT1 = 127;
	

	//Loop
	//Loop: While 1
	while (1)
	{
		//Input
		//Input: A5 -> Enable
		trisa = trisa | 0x20;
		FCV_ENABLE = ((porta & 0x20) == 0x20);


		//Input
		//Input: A4 -> Mode
		trisa = trisa | 0x10;
		FCV_MODE = ((porta & 0x10) == 0x10);


		//Input
		//Input: A3 -> Home
		trisa = trisa | 0x08;
		FCV_HOME = ((porta & 0x08) == 0x08);


		//Input
		//Input: C4 -> Away
		trisc = trisc | 0x10;
		FCV_AWAY = ((portc & 0x10) == 0x10);


		//Comment:
		//If Mode is high ==> Automatic Mode
		//If Mode is low ==> Manual Mode


		//Decision
		//Decision: Mode==0?
		if (FCV_MODE==0)
		{
			//Comment:
			//Read setpoint from 
			//external potentiometer


			//Call Component Macro
			//Call Component Macro: Setpoint1=ADC(3)::ReadAsByte
			FCV_SETPOINT1 = FCD_ADC3_ReadAsByte();


			//Decision
			//Decision: Home == 0?
			if (FCV_HOME == 0)
			{
			} else {
				//Comment:
				//Store Home Setpoint if in 
				//Manual Mode and Home = 1.


				//Calculation
				//Calculation:
				//  Home_setpoint1 = Setpoint1
				FCV_HOME_SETPOINT1 = FCV_SETPOINT1;
				

			}


			//Decision
			//Decision: Away == 0?
			if (FCV_AWAY == 0)
			{
			} else {
				//Comment:
				//Store Away Setpoint if in 
				//Automatic Mode and Away = 1.


				//Calculation
				//Calculation:
				//  Away_setpoint1 = Setpoint1
				FCV_AWAY_SETPOINT1 = FCV_SETPOINT1;
				

			}


		} else {
			//Decision
			//Decision: Home==0?
			if (FCV_HOME==0)
			{
			} else {
				//Comment:
				//Use stored home setpoint when 
				//in Automatic Mode and Home = 1.


				//Calculation
				//Calculation:
				//  Setpoint1 = Home_setpoint1
				FCV_SETPOINT1 = FCV_HOME_SETPOINT1;
				

			}


			//Decision
			//Decision: Away==0?
			if (FCV_AWAY==0)
			{
			} else {
				//Comment:
				//Use stored Away setpoint when 
				//in Automatic Mode and Away = 1.


				//Calculation
				//Calculation:
				//  Setpoint1 = Away_setpoint1
				FCV_SETPOINT1 = FCV_AWAY_SETPOINT1;
				

			}


			//Decision
			//Decision: (Home==0) && (Away==0)?
			if ((FCV_HOME==0) && (FCV_AWAY==0))
			{
				//Comment:
				//Use last setpoint if both
				//Home && Away are low.


				//Calculation
				//Calculation:
				//  Setpoint1 = Setpoint1
				FCV_SETPOINT1 = FCV_SETPOINT1;
				

			}


		}


		//Call Macro
		//Call Macro: PID1
		FCM_PID1();


		//Decision
		//Decision: Enable==1?
		if (FCV_ENABLE==1)
		{
			//Update PWM output
			//Call Component Macro: PWM(0)::SetDutyCycle(2, PID_y1)
			FCD_PWM0_SetDutyCycle(2, FCV_PID_Y1);


		} else {
			//Update PWM output
			//Call Component Macro: PWM(0)::SetDutyCycle(2, 127)
			FCD_PWM0_SetDutyCycle(2, 127);


		}


		//Delay
		//Delay: 1 ms
		delay_ms(1);


		//Comment:
		//If Mode is low 
		//(i.e. Manual Mode)


	}


	mainendloop: goto mainendloop;
}

void MX_INTERRUPT_MACRO(void)
{
}



