/*********************************************************************
 *                  Flowcode CAL ADC File
 *
 * File: PIC_CAL_ADC.c
 *
 * (c) 2011 Matrix Multimedia Ltd.
 * http://www.matrixmultimedia.com
 *
 * Software License Agreement
 *
 * The software supplied herewith by Matrix Multimedia Ltd (the
 * “Company”) for its Flowcode graphical programming language is
 * intended and supplied to you, the Company’s customer, for use
 * solely and exclusively on the Company's products. The software
 * is owned by the Company, and is protected under applicable
 * copyright laws. All rights are reserved. Any use in violation
 * of the foregoing restrictions may subject the user to criminal
 * sanctions under applicable laws, as well as to civil liability
 * for the breach of the terms and conditions of this licence.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 * Changelog:
 *
 *  date  | by | description
 * -------+----+-----------------------------------------------------
 * 060911 | BR | Created
 * 200911 | BR | Updated to include all ADC type files
 * 110512 | BR | Fixed a bug with ADC type 13 and Vref+
 * 161012 | BR | Fixed a bug with ADC type 32 and 10 bit instead of 12 bit
 * 171212 | BR | Moved the code to begin the sample to allow for more optimised ADC readings
 * 020713 | LM | Standard API calls
 * 240414 | LM | Additions to support Touch via ADC
 * 040215 | LM | 16F726 fix modified so as to work with 16F1937
 * 070716 | LM | Updates to touch re XC8 compiler
 */


//ADC Function Prototypes
void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge);
MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode);
void FC_CAL_ADC_Disable (void);
#ifdef MX_ADC_TOUCH
	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel);
#endif

//ADC Global Variables
MX_UINT8 old_tris, tris_mask;
volatile MX_UINT8 * tris_reg;					//TRIS register pointer


// ADC Type 1 Supported Devices ************************************************************
// 16F818, 16F819, 16F873A, 16F874A, 16F876A, 16F877A,
// *******************************************************************************************/

#ifdef MX_ADC_TYPE_1
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x0E;
					else
						ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x04;
					else
						ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x02;
					else
						ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x02;
					else
						ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					if (Vref == 0)
						ADCON1 = 0x09;
					else
						ADCON1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					if (Vref == 0)
						ADCON1 = 0x00;
					else
						ADCON1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					if (Vref == 0)
						ADCON1 = 0x00;
					else
						ADCON1 = 0x01;
					break;
			#endif
		}

		if (Conv_Speed > 3)										//assign conversion speed
			st_bit(ADCON1, ADCS2);

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 3);	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x04;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x04;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x07;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#define MX_ADC_TOUCH_CASE(ADC, PT, BIT)		\
			case (ADC):							\
			TRIS##PT &= ~(1<<BIT);				\
			PORT##PT |= (1<<BIT);				\
			ADCON0 = (ADC << 3) | 0xC1;			\
			ADCON0 &= ~(1<<0);					\
			PORT##PT &= ~(1<<BIT);				\
			TRIS##PT |= (1<<BIT);				\
			ADCON1 = 0x80;						\
			ADCON0 |= (1<<0);					\
			ADCON0 |= (1<<2);					\
			while (ADCON0 & (1<<2));			\
			result = (ADRESH << 8) | ADRESL;	\
			break;

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		MX_UINT16 result = 0;
		MX_UINT8  temp = ADCON1;
		ADCON1 = 0x87;				// all ports digital

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
					MX_ADC_TOUCH_CASE(0, A, 0);
			#endif
			#ifdef MX_ADC_CHANNEL_1
					MX_ADC_TOUCH_CASE(1, A, 1);
			#endif
			#ifdef MX_ADC_CHANNEL_2
					MX_ADC_TOUCH_CASE(2, A, 2);
			#endif
			#ifdef MX_ADC_CHANNEL_3
					MX_ADC_TOUCH_CASE(3, A, 3);
			#endif
			#ifdef MX_ADC_CHANNEL_4
					MX_ADC_TOUCH_CASE(4, A, 5);
			#endif
			#ifdef MX_ADC_CHANNEL_5
					MX_ADC_TOUCH_CASE(5, E, 0);
			#endif
			#ifdef MX_ADC_CHANNEL_6
					MX_ADC_TOUCH_CASE(6, E, 1);
			#endif
			#ifdef MX_ADC_CHANNEL_7
					MX_ADC_TOUCH_CASE(7, E, 2);
			#endif
		}
		ADCON1 = temp;
		return result;
	}
	#endif // MX_ADC_TOUCH

#endif


// ADC Type 2 Supported Devices ************************************************************
// 16F88
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_2
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		if (Vref == 1)											//assign VREF functionality
			st_bit(ADCON1, VCFG1);

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSEL = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSEL = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x40;
					tris_reg = &TRISB;
					ANSEL = 0x40;
					break;
			#endif
		}

		if (Conv_Speed > 3)										//assign conversion speed
			st_bit(ADCON1, ADCS2);

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 3);	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x04;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x04;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSEL = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH

#endif


// ADC Type 3 Supported Devices ************************************************************
// 16F616, 16F676, 16F677, 16F684, 16F685, 16F687, 16F688, 16F689, 16F690
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_3
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = ((Conv_Speed & 0x07) << 4);				//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSEL = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x01;
					tris_reg = &TRISC;
					ANSEL = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x02;
					tris_reg = &TRISC;
					ANSEL = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ANSEL = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ANSEL = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ANSELH = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ANSELH = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSELH = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSELH = 0x08;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref == 1)											//assign VREF functionality
			st_bit(ADCON0, VCFG);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSEL = 0x00;
		ADCON0 = 0x00;
		#ifdef _ANSELH_ANS8_POSN
			ANSELH = 0x00;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 4 Supported Devices ************************************************************
// 16F737, 16F747, 16F767, 16F777
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_4
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = 0x00;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADCON1 = 0x0E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADCON1 = 0x0D;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADCON1 = 0x0C;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON1 = 0x0B;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ADCON1 = 0x0A;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ADCON1 = 0x09;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ADCON1 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ADCON1 = 0x07;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ADCON1 = 0x06;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ADCON1 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ADCON1 = 0x01;
					break;
			#endif
		}

		if (Vref == 1)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);

		if (Conv_Speed > 3)										//assign conversion speed
			st_bit(ADCON1, ADCS2);

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6));					//turn ADC on
		ADCON0 = ADCON0 | ((Channel & 0x07) << 3);
		ADCON0 = ADCON0 | ((Channel & 0x08) >> 2);
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x04;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x04;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x07;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 5 Supported Devices ************************************************************
// 12F615, 12HV615, 12F675, 12F683
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_5
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		tris_reg = &TRISIO;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x10;
					ANSEL = 0x08;
					break;
			#endif
		}

		ANSEL = ANSEL | ((Conv_Speed & 0x07) << 4);				//assign conversion speed

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref == 1)											//assign VREF functionality
			st_bit(ADCON0, VCFG);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSEL = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 6 Supported Devices ************************************************************
// 16C72, 16C72A, 16CR72, 16F72, 16C73, 16C73A, 16C73B, 16F73, 16C74, 16C74A, 16C74B, 16F74,
// 16C76, 16F76, 16C77, 16F77, 16C716, 16F716
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_6
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADCON1 = 0x00;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ADCON1 = 0x00;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ADCON1 = 0x00;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ADCON1 = 0x00;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ADCON1 = 0x00;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 + 1;

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 3);	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x04;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (ADRES << 2);								//10-bit ADC
		}
		else
			iRetVal = ADRES;									//8-bit ADC

		ADCON0 = ADCON0 | 0x04;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x07;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif



// ADC Type 7 Supported Devices ************************************************************
// 16F883, 16F884, 16F886, 16F887
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_7
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = 0x00;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANSEL = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANSEL = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANSEL = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ANSEL = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ANSELH = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ANSELH = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANSELH = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSELH = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANSELH = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSELH = 0x20;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 2);	//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSEL = 0x00;
		ADCON0 = 0x00;
		#ifdef _ANSELH_ANS8_POSN
			ANSELH = 0x00;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 8 Supported Devices ************************************************************
// 16F785
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_8
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL0 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL0 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL0 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSEL0 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x01;
					tris_reg = &TRISC;
					ANSEL0 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x02;
					tris_reg = &TRISC;
					ANSEL0 = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ANSEL0 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ANSEL0 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ANSEL1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ANSEL1 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSEL1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSEL1 = 0x08;
					break;
			#endif
		}

		ADCON1 = ((Conv_Speed & 0x07) << 4);					//assign conversion rate

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON0, VCFG);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSEL0 = 0x00;
		ADCON0 = 0x00;
		#ifdef _ANSEL1_ANS8_POSN
			ANSEL1 = 0x00;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 9 Supported Devices ************************************************************
// 16F913, 16F914, 16F916, 16F917, 16F946
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_9
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANSEL = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANSEL = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANSEL = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ANSEL = 0x80;
					break;
			#endif
		}

		ADCON1 = ((Conv_Speed & 0x07) << 4);					//assign conversion rate

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON0, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON0 = 0x00;
		ANSEL = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 10 Supported Devices ***********************************************************
// 12C671, 12C672, 12CE673, 12CE674
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_10
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		tris_reg = &TRISIO;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					if (Vref == 0)
						ADCON1 = 0x06;
					else
						ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					if (Vref == 0)
						ADCON1 = 0x02;
					else
						ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					if (Vref == 0)
						ADCON1 = 0x00;
					else
						ADCON1 = 0x01;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 3);	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRES << 2);								//10-bit ADC
		}
		else
			iRetVal = ADRES;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x07;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 11 Supported Devices ***********************************************************
// 16C717, 16C770, 16C771
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_11
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = 0x00;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANSEL = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANSEL = 0x20;
					break;
			#endif
		}

		if (Conv_Speed > 3)										//assign conversion speed
			st_bit(ADCON1, ADFM);

		if (Vref != 0)											//assign VREF functionality
		{
			st_bit(ADCON1, VCFG0);
			st_bit(ADCON1, VCFG1);
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 3);	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x04;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x04;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON0 = 0x00;
		ANSEL = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 12 Supported Devices ***********************************************************
// 18F6310, 18F6390, 18F6410, 18F6490, 18F6520, 18F6527, 18F6585, 18F66J60, 18F66J65,
// 18F6620, 18F6622, 18F6627, 18F6680, 18F67J60, 18F6720, 18F6722, 18F8310, 18F8390,
// 18F8410, 18F8490, 18F8520, 18F8527, 18F8585, 18F86J60, 18F86J65, 18F8620, 18F8622,
// 18F8627, 18F8680, 18F87J60, 18F8720, 18F8722, 18F96J60, 18F96J65, 18F97J60
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_12
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = Conv_Speed & 0x07;								//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADCON1 = 0x0E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADCON1 = 0x0D;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADCON1 = 0x0C;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON1 = 0x0B;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ADCON1 = 0x0A;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISF;
					ADCON1 = 0x09;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISF;
					ADCON1 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISF;
					ADCON1 = 0x07;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x08;
					tris_reg = &TRISF;
					ADCON1 = 0x06;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x10;
					tris_reg = &TRISF;
					ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x20;
					tris_reg = &TRISF;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x40;
					tris_reg = &TRISF;
					ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x10;
					tris_reg = &TRISH;
					ADCON1 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISH;
					ADCON1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (14):
					tris_mask = 0x40;
					tris_reg = &TRISH;
					ADCON1 = 0x00;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (15):
					tris_mask = 0x80;
					tris_reg = &TRISH;
					ADCON1 = 0x00;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x0f;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 13 Supported Devices ***********************************************************
// 18F2220, 18F2221, 18F2320, 18F2321, 18F24J10, 18F2410, 18F2420, 18F2423, 18F2450,
// 18F2455, 18F2480, 18F25J10, 18F2510, 18F2515, 18F2520, 18F2523, 18F2525, 18F2550,
// 18F2580, 18F2585, 18F2610, 18F2620, 18F2680, 18F4220, 18F4221, 18F4320, 18F4321,
// 18F44J10, 18F4410, 18F4420, 18F4423, 18F4450, 18F4455, 18F4480, 18F45J10, 18F4510,
// 18F4515, 18F4520, 18F4523, 18F4525, 18F4550, 18F4580, 18F4585, 18F4610, 18F4620,
// 18F4680, 18F4682, 18F4685
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_13
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = Conv_Speed & 0x07;								//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADCON1 = 0x0E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADCON1 = 0x0D;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADCON1 = 0x0C;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON1 = 0x0B;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ADCON1 = 0x0A;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ADCON1 = 0x09;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ADCON1 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ADCON1 = 0x07;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ADCON1 = 0x06;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ADCON1 = 0x02;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);								//BR changed from ADCON0 05/12

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
		  #ifdef MX_ADC_BITS_12
			iRetVal = (ADRESH << 4);							//12-bit ADC
			iRetVal = iRetVal | (ADRESL >> 4);
		  #else
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		  #endif
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x0f;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 14 Supported Devices ***********************************************************
// 18F2331, 18F2431, 18F4331, 18F4431
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_14
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = 0x00;											//set up ADC conversion
		ADCON2 = Conv_Speed & 0x07;
		ADCON3 = 0x00;
		ADCHS = 0x00;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADCON0 = 0x00;
					ANSEL0 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADCON0 = 0x04;
					ANSEL0 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADCON0 = 0x08;
					ANSEL0 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON0 = 0x0C;
					ANSEL0 = 0x08;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ADCON0 = 0x00;
					ADCHS = 0x01;
					ANSEL0 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ADCON0 = 0x04;
					ADCHS = 0x10;
					ANSEL0 = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ADCON0 = 0x08;
					ADCHS = 0x04;
					ANSEL0 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ADCON0 = 0x0C;
					ADCHS = 0x40;
					ANSEL0 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ADCON0 = 0x00;
					ADCHS = 0x02;
					ANSEL1 = 0x01;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = ADCON0 | 0x01;									//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON0 = 0x00;
		ANSEL0 = 0x00;
		#ifdef ANSEL1_ANS8_POSN
			ANSEL1 = 0x00;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 15 Supported Devices ***********************************************************
// 18F1220, 18F1320
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_15
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = Conv_Speed & 0x07;								//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADCON1 = 0x7E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADCON1 = 0x7D;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADCON1 = 0x7B;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON1 = 0x77;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ADCON1 = 0x6F;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ADCON1 = 0x5F;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ADCON1 = 0x3F;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON0, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x7f;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 16 Supported Devices ***********************************************************
// 18F242, 18F2439, 18F248, 18F252, 18F2539, 18F258, 18F442, 18F4439, 18F448, 18F452,
// 18F4539, 18F458
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_16
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					if (Vref != 0)
						ADCON1 = 0x05;
					else
						ADCON1 = 0x0E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					if (Vref != 0)
						ADCON1 = 0x05;
					else
						ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					if (Vref != 0)
						ADCON1 = 0x03;
					else
						ADCON1 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON1 = 0x04;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					if (Vref != 0)
						ADCON1 = 0x03;
					else
						ADCON1 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					if (Vref != 0)
						ADCON1 = 0x0A;
					else
						ADCON1 = 0x09;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					if (Vref != 0)
						ADCON1 = 0x01;
					else
						ADCON1 = 0x00;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					if (Vref != 0)
						ADCON1 = 0x01;
					else
						ADCON1 = 0x00;
					break;
			#endif
		}

		if (Conv_Speed > 3)										//assign conversion speed
			st_bit(ADCON1, ADCS2);

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 3);	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x04;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x04;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x07;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 17 Supported Devices ***********************************************************
// 18F1230, 18F1330
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_17
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = Conv_Speed & 0x07;
		ADCON1 = 0x00 | (0x01 << Channel);

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x40;
					tris_reg = &TRISA;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 18 Supported Devices ***********************************************************
// 16F722, 16F723, 16F724, 16F726, 16F727, 16F1933, 16F1934, 16F1936, 16F1937, 16F1939
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_18

	#ifndef ADREF1
		#define ADREF1 ADPREF1
	#endif

	volatile MX_UINT8 * ANSEL_reg;					//ANSEL register pointer

	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = (Conv_Speed & 0x07) << 4;						//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANSEL_reg = &ANSELE;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANSEL_reg = &ANSELE;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ANSEL_reg = &ANSELE;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 | (Vref & 0x03);					//Mod to allow FVR as VREF

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		*ANSEL_reg = *ANSEL_reg | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			#ifdef _ADRESH_ADRESH_POSN
				iRetVal = (ADRESH << 2);						//10-bit ADC
				iRetVal = iRetVal | (ADRESL >> 6);
			#else
				iRetVal = (ADRES << 2);							//10-bit ADC
			#endif
		}
		else
			#ifdef _ADRESH_ADRESH_POSN
				iRetVal = ADRESH;								//8-bit ADC
            #else
				iRetVal = ADRES;
		    #endif

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		//*ANSEL_reg = 0x00;
		//ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH


	#ifdef _ADRESH_ADRESH_POSN
	  #define MX_ADC_TOUCH_CASE(ADC, PORT, BIT)	\
			case (ADC):							\
			FCP_TRIS_##PORT &= ~(1<<BIT);		\
			FCP_LAT_##PORT |= (1<<BIT);			\
			ANSEL##PORT |= (1<<BIT);			\
			ADCON0 = (ADC << 2) | 1;			\
			ADCON0 &= (1<<0);					\
			FCP_LAT_##PORT &= ~(1<<BIT);		\
			FCP_TRIS_##PORT |= (1<<BIT);		\
			ADCON0 = (ADC << 2) | 1;			\
			ADCON0 = (ADC << 2) | 3;			\
			while (ADCON0 & (1<<1));			\
			ANSEL##PORT &= ~(1<<BIT);			\
			return (ADRESH << 8) | ADRESL;
	#else
	  #define MX_ADC_TOUCH_CASE(ADC, PORT, BIT)	\
			case (ADC):							\
			FCP_TRIS_##PORT &= ~(1<<BIT);		\
			FCP_LAT_##PORT |= (1<<BIT);			\
			ANSEL##PORT |= (1<<BIT);			\
			ADCON0 = (ADC << 2) | 1;			\
			ADCON0 &= (1<<0);					\
			FCP_LAT_##PORT &= ~(1<<BIT);		\
			FCP_TRIS_##PORT |= (1<<BIT);		\
			ADCON0 = (ADC << 2) | 1;			\
			ADCON0 = (ADC << 2) | 3;			\
			while (ADCON0 & (1<<1));			\
			ANSEL##PORT &= ~(1<<BIT);			\
			return (ADRES << 2);
	#endif


	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		ADCON1 = 0xf0;						// Right justified result and set FRC clock mode

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
					MX_ADC_TOUCH_CASE(0, A, 0);
			#endif
			#ifdef MX_ADC_CHANNEL_1
					MX_ADC_TOUCH_CASE(1, A, 1);
			#endif
			#ifdef MX_ADC_CHANNEL_2
					MX_ADC_TOUCH_CASE(2, A, 2);
			#endif
			#ifdef MX_ADC_CHANNEL_3
					MX_ADC_TOUCH_CASE(3, A, 3);
			#endif
			#ifdef MX_ADC_CHANNEL_4
					MX_ADC_TOUCH_CASE(4, A, 5);
			#endif
			#ifdef MX_ADC_CHANNEL_5
					MX_ADC_TOUCH_CASE(5, A, 0);
			#endif
			#ifdef MX_ADC_CHANNEL_6
					MX_ADC_TOUCH_CASE(6, E, 1);
			#endif
			#ifdef MX_ADC_CHANNEL_7
					MX_ADC_TOUCH_CASE(7, E, 2);
			#endif
			#ifdef MX_ADC_CHANNEL_8
					MX_ADC_TOUCH_CASE(8, B, 2);
			#endif
			#ifdef MX_ADC_CHANNEL_9
					MX_ADC_TOUCH_CASE(9, B, 3);
			#endif
			#ifdef MX_ADC_CHANNEL_10
					MX_ADC_TOUCH_CASE(10, B, 1);
			#endif
			#ifdef MX_ADC_CHANNEL_11
					MX_ADC_TOUCH_CASE(11, B, 4);
			#endif
			#ifdef MX_ADC_CHANNEL_12
					MX_ADC_TOUCH_CASE(12, B, 0);
			#endif
			#ifdef MX_ADC_CHANNEL_13
					MX_ADC_TOUCH_CASE(13, B, 5);
			#endif
		}
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 19 Supported Devices ***********************************************************
// 18F13K50, 18F14K50, 18LF13K50, 18LF14K50
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_19
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = 0;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSEL = 0x08;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x01;
					tris_reg = &TRISC;
					ANSEL = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x02;
					tris_reg = &TRISC;
					ANSEL = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ANSEL = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ADCON1 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ANSELH = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ANSELH = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSELH = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSELH = 0x08;
					break;
			#endif
		}

		ADCON2 = Conv_Speed & 0x07;								//assign conversion rate

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 | ((Vref & 0x03) << 2);				//Mod to allow FVR as VREF

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSEL = 0;
		ADCON0 = 0x00;
		#ifdef _ANSELH_ANS8_POSN
			ANSELH = 0;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 20 Supported Devices ***********************************************************
// 18F23K20, 18F24K20, 18F25K20, 18F26K20, 18F43K20, 18F44K20, 18F45K20, 18F16K20
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_20
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = 0;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL = 0x08;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANSEL = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANSEL = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANSEL = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ADCON1 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ANSELH = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ANSELH = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANSELH = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSELH = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANSELH = 0x10;
					break;
			#endif
		}

		ADCON2 = Conv_Speed & 0x07;								//assign conversion rate

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSEL = 0;
		ADCON0 = 0x00;
		#ifdef _ANSELH_ANS8_POSN
			ANSELH = 0;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 21 Supported Devices ***********************************************************
// 18F2xJ11, 18F4xJ11
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_21
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = 0;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANCON0 = 0xFE;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANCON0 = 0xFD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANCON0 = 0xFB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANCON0 = 0xF7;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANCON0 = 0xEF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANCON0 = 0xDF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANCON0 = 0xBF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ANCON0 = 0x7F;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ANCON1 = 0x1E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ANCON1 = 0x1D;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANCON1 = 0x1B;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANCON1 = 0x17;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANCON1 = 0x0F;
					break;
			#endif
		}

		ADCON1 = Conv_Speed & 0x07;								//assign conversion rate

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON0, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANCON0 = 0xFF;
		ANCON1 = 0x1F;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 22 Supported Devices ***********************************************************
// 10F220, 10F222
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_22
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON0 = 0x00;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					asm("movf 1,w");
					asm("tris 6");
					ADCON0 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					asm("movf 2,w");
					asm("tris 6");
					ADCON0 = 0x84;
					break;
			#endif
		}

		ADCON0 = ADCON0 | 0x01;									//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;


		while (ADCON0 & 0x02);
		if (Sample_Mode)
			iRetVal = (ADRES << 2);								//10-bit ADC
		else
			iRetVal = ADRES;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		ADCON0 = 0x00;											//Reset ADC Registers
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 23 Supported Devices ***********************************************************
// 16F1826, 16F1827
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_23

	MX_UINT8 * ANSEL_reg;					//ANSEL register pointer

	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = (Conv_Speed & 0x07) << 4;						//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x40;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x80;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 | (Vref & 0x03);					//Mod to allow FVR as VREF

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		*ANSEL_reg = *ANSEL_reg | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
// Fix for 16F707
#ifdef _ADRESH_ADRESH_POSN
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC
#else
			iRetVal = ADRES;									//8-bit ADC
#endif
		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ANSEL_reg = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 24 Supported Devices ***********************************************************
// 18F65J50, 18F66J50, 18F66J55, 18F67J50, 18F85J50, 18F86J50, 18F86J55, 18F87J50
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_24
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = (Conv_Speed & 0x07);

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANCON0 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANCON0 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANCON0 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANCON0 = 0x08;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANCON0 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISF;
					ANCON0 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x20;
					tris_reg = &TRISF;
					ANCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x40;
					tris_reg = &TRISF;
					ANCON1 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x10;
					tris_reg = &TRISH;
					ANCON1 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISH;
					ANCON1 = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (14):
					tris_mask = 0x40;
					tris_reg = &TRISH;
					ANCON1 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (15):
					tris_mask = 0x80;
					tris_reg = &TRISH;
					ANCON1 = 0x80;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON0, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANCON0 = 0x00;
		ANCON1 = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 25 Supported Devices ***********************************************************
// 18F66J93, 18F67J93, 18F86J93, 18F87J93, 18F66J90, 18F67J90, 18F86J90, 18F87J90
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_25
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = Conv_Speed & 0x07;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADCON1 = 0x0E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADCON1 = 0x0D;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADCON1 = 0x0C;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADCON1 = 0x0B;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ADCON1 = 0x0A;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x80;
					tris_reg = &TRISF;
					ADCON1 = 0x09;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISF;
					ADCON1 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISF;
					ADCON1 = 0x07;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x08;
					tris_reg = &TRISF;
					ADCON1 = 0x06;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x10;
					tris_reg = &TRISF;
					ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x20;
					tris_reg = &TRISF;
					ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x40;
					tris_reg = &TRISF;
					ADCON1 = 0x03;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			st_bit(ADCON1, VCFG0);

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x0f;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 26 Supported Devices ***********************************************************
// 12F1822, 16F1823, 16F1824, 16F1825, 16F1828, 16F1829
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_26

	MX_UINT8 * ANSEL_reg;					//ANSEL register pointer

	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = (Conv_Speed & 0x07) << 4;						//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x01;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x02;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
		}

		switch (Vref)
		{
			case 1:		// Vref selected
				ADCON1 |= 2;
				break;
			case 2:		// FVR selected
				ADCON1 |= 3;
				FVRCON |= 0x81;		// ADC FVR output is enabled, 1x (1.024V)
				break;
			default:	// VDD selected
				break;
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		*ANSEL_reg = *ANSEL_reg | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ANSEL_reg = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 27 Supported Devices ***********************************************************
// 16F1946, 16F1947
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_27

	MX_UINT8 * ANSEL_reg;					//ANSEL register pointer

	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = (Conv_Speed & 0x07) << 4;						//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x80;
					tris_reg = &TRISF;
					ANSEL_reg = &ANSELF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISF;
					ANSEL_reg = &ANSELF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISF;
					ANSEL_reg = &ANSELF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x08;
					tris_reg = &TRISF;
					ANSEL_reg = &ANSELF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x10;
					tris_reg = &TRISF;
					ANSEL_reg = &ANSELF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x20;
					tris_reg = &TRISF;
					ANSEL_reg = &ANSELF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x40;
					tris_reg = &TRISF;
					ANSEL_reg = &ANSELF;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x10;
					tris_reg = &TRISG;
					ANSEL_reg = &ANSELG;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x08;
					tris_reg = &TRISG;
					ANSEL_reg = &ANSELG;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (14):
					tris_mask = 0x04;
					tris_reg = &TRISG;
					ANSEL_reg = &ANSELG;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (15):
					tris_mask = 0x02;
					tris_reg = &TRISG;
					ANSEL_reg = &ANSELG;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_16
				case (16):
					tris_mask = 0x01;
					tris_reg = &TRISG;
					ANSEL_reg = &ANSELG;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 | (Vref & 0x03);					//Mod to allow FVR as VREF

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		*ANSEL_reg = *ANSEL_reg | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ANSEL_reg = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 28 Supported Devices ***********************************************************
// 18F65K22, 18F66K22, 18F67K22, 18F85K22, 18F86K22, 18F87K22,
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_28
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = Conv_Speed & 0x07;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANCON0 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANCON0 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANCON0 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANCON0 = 0x08;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANCON0 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x80;
					tris_reg = &TRISF;
					ANCON0 = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISF;
					ANCON0 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISF;
					ANCON0 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x08;
					tris_reg = &TRISF;
					ANCON1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x10;
					tris_reg = &TRISF;
					ANCON1 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x20;
					tris_reg = &TRISF;
					ANCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x40;
					tris_reg = &TRISF;
					ANCON1 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x10;
					tris_reg = &TRISH;
					ANCON1 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISH;
					ANCON1 = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (14):
					tris_mask = 0x40;
					tris_reg = &TRISH;
					ANCON1 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (15):
					tris_mask = 0x80;
					tris_reg = &TRISH;
					ANCON1 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_16
				case (16):
					tris_mask = 0x10;
					tris_reg = &TRISG;
					ANCON2 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_17
				case (17):
					tris_mask = 0x08;
					tris_reg = &TRISG;
					ANCON2 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_18
				case (18):
					tris_mask = 0x04;
					tris_reg = &TRISG;
					ANCON2 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_19
				case (19):
					tris_mask = 0x02;
					tris_reg = &TRISG;
					ANCON2 = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_20
				case (20):
					tris_mask = 0x08;
					tris_reg = &TRISH;
					ANCON2 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_21
				case (21):
					tris_mask = 0x04;
					tris_reg = &TRISH;
					ANCON2 = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_22
				case (22):
					tris_mask = 0x02;
					tris_reg = &TRISH;
					ANCON2 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_23
				case (23):
					tris_mask = 0x01;
					tris_reg = &TRISH;
					ANCON2 = 0x80;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 | ((Vref & 0x03) << 4);				//Mod to allow FVR as VREF

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 4);							//12-bit ADC
			iRetVal = iRetVal | (ADRESL >> 4);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON0 = 0x00;
		ANCON0 = 0x00;
		#ifdef _ANCON1_ANSEL8_POSN
			ANCON1 = 0x00;
		#endif
		#ifdef _ANCON2_ANSEL16_POSN
			ANCON2 = 0x00;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 29 Supported Devices ***********************************************************
// 18F23K22, 18F24K22, 18F25K22, 18F26K22, 18F43K22, 18F44K22, 18F45K22, 18F46K22,
// 18LF23K22, 18LF24K22, 18LF25K22, 18LF26K22, 18LF43K22, 18LF44K22, 18LF45K22, 18LF46K22,
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_29

	volatile MX_UINT8 * ANSEL_reg;					//ANSEL register pointer

	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON2 = Conv_Speed & 0x07;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANSEL_reg = &ANSELA;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANSEL_reg = &ANSELE;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANSEL_reg = &ANSELE;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ANSEL_reg = &ANSELE;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSEL_reg = &ANSELB;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (14):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (15):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_16
				case (16):
					tris_mask = 0x10;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_17
				case (17):
					tris_mask = 0x20;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_18
				case (18):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_19
				case (19):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ANSEL_reg = &ANSELC;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_20
				case (20):
					tris_mask = 0x01;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_21
				case (21):
					tris_mask = 0x02;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_22
				case (22):
					tris_mask = 0x04;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_23
				case (23):
					tris_mask = 0x08;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_24
				case (24):
					tris_mask = 0x10;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_25
				case (25):
					tris_mask = 0x20;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_26
				case (26):
					tris_mask = 0x40;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_27
				case (27):
					tris_mask = 0x80;
					tris_reg = &TRISD;
					ANSEL_reg = &ANSELD;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 | ((Vref & 0x03) << 2);				//Mod to allow FVR as VREF

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		*ANSEL_reg = *ANSEL_reg | tris_mask;

		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ANSEL_reg = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 30 Supported Devices ************************************************************
// 16F870, 16F871, 16F872, 16F873, 16F874, 16F876, 16F877
// *******************************************************************************************/

#ifdef MX_ADC_TYPE_30
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x0E;
					else
						ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x04;
					else
						ADCON1 = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x02;
					else
						ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					if (Vref == 0)
						ADCON1 = 0x02;
					else
						ADCON1 = 0x03;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					if (Vref == 0)
						ADCON1 = 0x09;
					else
						ADCON1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					if (Vref == 0)
						ADCON1 = 0x00;
					else
						ADCON1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					if (Vref == 0)
						ADCON1 = 0x00;
					else
						ADCON1 = 0x01;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Conv_Speed << 6)) | (Channel << 3);	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x04;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x04;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ADCON1 = 0x07;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 31 Supported Devices ************************************************************
// 12F510, 16F506
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_31
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON0 = (0xC1 | (Conv_Speed << 4) | (Channel << 2));	//turn ADC on
		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);

		iRetVal = ADRES;										//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 32 Supported Devices ***********************************************************
// 18F2xK80, 18F4xK80, 18F6xK80
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_32
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = 0;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANCON0 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANCON0 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANCON0 = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANCON0 = 0x08;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANCON0 = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANCON0 = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANCON0 = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ANCON0 = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANCON1 = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANCON1 = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANCON1 = 0x04;
					break;
			#endif
		}

		ADCON2 = Conv_Speed & 0x07;								//assign conversion rate

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref != 0)											//assign VREF functionality
			ADCON1 = ADCON1 | ((Vref & 0x03) << 4);				//Mod to allow FVR as VREF

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 4);							//12-bit ADC
			iRetVal = iRetVal | (ADRESL >> 4);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANCON0 = 0x00;
		ANCON1 = 0x00;
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 33 Supported Devices ***********************************************************
// 16F183xx
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_33
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON0 = 0x01 | (Channel << 2);
		ADCON1 = (Conv_Speed << 4) | (Vref);

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);

		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 34 Supported Devices ***********************************************************
// 16F188xx
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_34
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		// set the ADCC to the options selected in the User Interface
	    // ADDSEN disabled; ADGPOL digital_low; ADIPEN disabled; ADPPOL VSS;
	    //ADCON1 = 0x00;
	    // ADCRS 0; ADMD Basic_mode; ADACLR disabled; ADPSIS ADFLTR;
	    //ADCON2 = 0x00;
	    // ADCALC First derivative of Single measurement; ADTMD disabled; ADSOI ADGO not cleared;
	    //ADCON3 = 0x00;
	    // ADACT disabled;
	    //ADSTAT = 0x00;
	    // Conversion Speed;
	    //ADCLK = 0x00;
	    // ADNREF VSS; ADPREF VDD;
	    ADREF = 0x00;

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ADPCH = 0x00;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ADPCH = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ADPCH = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ADPCH = 0x03;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ADPCH = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ADPCH = 0x05;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x40;
					tris_reg = &TRISA;
					ADPCH = 0x06;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x80;
					tris_reg = &TRISA;
					ADPCH = 0x07;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ADPCH = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ADPCH = 0x09;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ADPCH = 0x0A;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ADPCH = 0x0B;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ADPCH = 0x0C;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ADPCH = 0x0D;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (14):
					tris_mask = 0x40;
					tris_reg = &TRISB;
					ADPCH = 0x0E;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (15):
					tris_mask = 0x80;
					tris_reg = &TRISB;
					ADPCH = 0x0F;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_16
				case (16):
					tris_mask = 0x01;
					tris_reg = &TRISC;
					ADPCH = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_17
				case (17):
					tris_mask = 0x02;
					tris_reg = &TRISC;
					ADPCH = 0x11;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_18
				case (18):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ADPCH = 0x12;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_19
				case (19):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ADPCH = 0x13;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_20
				case (20):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ADPCH = 0x14;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_21
				case (21):
					tris_mask = 0x10;
					tris_reg = &TRISC;
					ADPCH = 0x15;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_22
				case (22):
					tris_mask = 0x20;
					tris_reg = &TRISC;
					ADPCH = 0x16;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_23
				case (23):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ADPCH = 0x17;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_24
				case (24):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ADPCH = 0x18;
					break;
			#endif
		}

	    ADCON0 = 0x80;							// ADGO stop; ADFM left; ADON enabled; ADCONT disabled; ADCS FRC;

		ADCLK = Conv_Speed & 0x3F;				//assign conversion rate

		old_tris = *tris_reg;					//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;

		if (Vref != 0)							//assign VREF functionality
			ADREF = ADREF | Vref;				//Mod to allow FVR as VREF

		delay_us(T_Charge);						//wait the acquisition time

		// Start the conversion
        ADCON0bits.ADGO = 1;

	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0bits.ADGO);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		//ADCON0 = 0x00;
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


// ADC Type 35 Supported Devices ************************************************************
// PIC16F1764
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_35
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		ADCON1 = ((Conv_Speed & 0x07) << 4);				//assign conversion rate

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSELA = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSELA = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSELA = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSELA = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x01;
					tris_reg = &TRISC;
					ANSELC = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x02;
					tris_reg = &TRISC;
					ANSELC = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ANSELC = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ANSELC = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ANSELC = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ANSELC = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSELB = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSELB = 0x20;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 = (0x01 | (Channel << 2));						//turn ADC on

		if (Vref == 1)											//assign VREF functionality
			ADCON1 |= 2;

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 = ADCON0 | 0x02;									//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x02;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSELA = 0x00;
		ANSELC = 0x00;
		ADCON0 = 0x00;
		#ifdef _ANSELB_ANSB4_POSN
			ANSELB = 0x00;
		#endif
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif



// ADC Type 36 Supported Devices ************************************************************
// PIC18F24K40
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_36
	void FC_CAL_ADC_Enable (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge)
	{
		if (Conv_Speed & 0x40)
		{
			ADCON0 = 0x10;							//FRC Clock Source
		}
		else
		{
			ADCON0 = 0x00;							//OSC Based Clock Source
			ADCLK = Conv_Speed & 0x3F;				//assign conversion rate
		}

		switch (Channel)
		{
			#ifdef MX_ADC_CHANNEL_0
				case (0):
					tris_mask = 0x01;
					tris_reg = &TRISA;
					ANSELA = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_1
				case (1):
					tris_mask = 0x02;
					tris_reg = &TRISA;
					ANSELA = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_2
				case (2):
					tris_mask = 0x04;
					tris_reg = &TRISA;
					ANSELA = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_3
				case (3):
					tris_mask = 0x08;
					tris_reg = &TRISA;
					ANSELA = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_4
				case (4):
					tris_mask = 0x10;
					tris_reg = &TRISA;
					ANSELA = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_5
				case (5):
					tris_mask = 0x20;
					tris_reg = &TRISA;
					ANSELA = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_6
				case (6):
					tris_mask = 0x40;
					tris_reg = &TRISA;
					ANSELA = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_7
				case (7):
					tris_mask = 0x80;
					tris_reg = &TRISA;
					ANSELA = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_8
				case (8):
					tris_mask = 0x01;
					tris_reg = &TRISB;
					ANSELB = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_9
				case (9):
					tris_mask = 0x02;
					tris_reg = &TRISB;
					ANSELB = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_10
				case (10):
					tris_mask = 0x04;
					tris_reg = &TRISB;
					ANSELB = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_11
				case (11):
					tris_mask = 0x08;
					tris_reg = &TRISB;
					ANSELB = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_12
				case (12):
					tris_mask = 0x10;
					tris_reg = &TRISB;
					ANSELB = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (13):
					tris_mask = 0x20;
					tris_reg = &TRISB;
					ANSELB = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (14):
					tris_mask = 0x40;
					tris_reg = &TRISB;
					ANSELB = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (15):
					tris_mask = 0x80;
					tris_reg = &TRISB;
					ANSELB = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_16
				case (16):
					tris_mask = 0x01;
					tris_reg = &TRISC;
					ANSELC = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_17
				case (17):
					tris_mask = 0x02;
					tris_reg = &TRISC;
					ANSELC = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_18
				case (18):
					tris_mask = 0x04;
					tris_reg = &TRISC;
					ANSELC = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_19
				case (19):
					tris_mask = 0x08;
					tris_reg = &TRISC;
					ANSELC = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_20
				case (20):
					tris_mask = 0x10;
					tris_reg = &TRISC;
					ANSELC = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_21
				case (21):
					tris_mask = 0x20;
					tris_reg = &TRISC;
					ANSELC = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_22
				case (22):
					tris_mask = 0x40;
					tris_reg = &TRISC;
					ANSELC = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_23
				case (23):
					tris_mask = 0x80;
					tris_reg = &TRISC;
					ANSELC = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_24
				case (24):
					tris_mask = 0x01;
					tris_reg = &TRISD;
					ANSELD = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_25
				case (25):
					tris_mask = 0x02;
					tris_reg = &TRISD;
					ANSELD = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_26
				case (26):
					tris_mask = 0x04;
					tris_reg = &TRISD;
					ANSELD = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_27
				case (27):
					tris_mask = 0x08;
					tris_reg = &TRISD;
					ANSELD = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_28
				case (28):
					tris_mask = 0x10;
					tris_reg = &TRISD;
					ANSELD = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_29
				case (29):
					tris_mask = 0x20;
					tris_reg = &TRISD;
					ANSELD = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_30
				case (30):
					tris_mask = 0x40;
					tris_reg = &TRISD;
					ANSELD = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_31
				case (31):
					tris_mask = 0x80;
					tris_reg = &TRISD;
					ANSELD = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_32
				case (32):
					tris_mask = 0x01;
					tris_reg = &TRISE;
					ANSELE = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_33
				case (33):
					tris_mask = 0x02;
					tris_reg = &TRISE;
					ANSELE = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_34
				case (34):
					tris_mask = 0x04;
					tris_reg = &TRISE;
					ANSELE = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_35
				case (35):
					tris_mask = 0x08;
					tris_reg = &TRISE;
					ANSELE = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_36
				case (36):
					tris_mask = 0x10;
					tris_reg = &TRISE;
					ANSELE = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_37
				case (37):
					tris_mask = 0x20;
					tris_reg = &TRISE;
					ANSELE = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_38
				case (38):
					tris_mask = 0x40;
					tris_reg = &TRISE;
					ANSELE = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_39
				case (39):
					tris_mask = 0x80;
					tris_reg = &TRISE;
					ANSELE = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_40
				case (40):
					tris_mask = 0x01;
					tris_reg = &TRISF;
					ANSELF = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_41
				case (41):
					tris_mask = 0x02;
					tris_reg = &TRISF;
					ANSELF = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_42
				case (42):
					tris_mask = 0x04;
					tris_reg = &TRISF;
					ANSELF = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_43
				case (43):
					tris_mask = 0x08;
					tris_reg = &TRISF;
					ANSELF = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_44
				case (44):
					tris_mask = 0x10;
					tris_reg = &TRISF;
					ANSELF = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_45
				case (45):
					tris_mask = 0x20;
					tris_reg = &TRISF;
					ANSELF = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_46
				case (46):
					tris_mask = 0x40;
					tris_reg = &TRISF;
					ANSELF = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_47
				case (47):
					tris_mask = 0x80;
					tris_reg = &TRISF;
					ANSELF = 0x80;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_48
				case (48):
					tris_mask = 0x01;
					tris_reg = &TRISG;
					ANSELG = 0x01;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_49
				case (49):
					tris_mask = 0x02;
					tris_reg = &TRISG;
					ANSELG = 0x02;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_50
				case (50):
					tris_mask = 0x04;
					tris_reg = &TRISG;
					ANSELG = 0x04;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_51
				case (51):
					tris_mask = 0x08;
					tris_reg = &TRISG;
					ANSELG = 0x08;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_52
				case (52):
					tris_mask = 0x10;
					tris_reg = &TRISG;
					ANSELG = 0x10;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_53
				case (53):
					tris_mask = 0x20;
					tris_reg = &TRISG;
					ANSELG = 0x20;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_54
				case (54):
					tris_mask = 0x40;
					tris_reg = &TRISG;
					ANSELG = 0x40;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_55
				case (55):
					tris_mask = 0x80;
					tris_reg = &TRISG;
					ANSELG = 0x80;
					break;
			#endif
		}

		old_tris = *tris_reg;									//store old tris value, and set the i/o pin as an input
		*tris_reg = old_tris | tris_mask;
		ADCON0 |= 0x80;											//turn ADC on

		ADREF = Vref;											//assign VREF functionality

		delay_us(T_Charge);										//wait the acquisition time

		ADCON0 |= 0x01;											//begin next conversion
	}

	MX_UINT16 FC_CAL_ADC_Sample (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		while (ADCON0 & 0x01);
		if (Sample_Mode)
		{
			iRetVal = (ADRESH << 2);							//10-bit ADC
			iRetVal = iRetVal | (ADRESL >> 6);
		}
		else
			iRetVal = ADRESH;									//8-bit ADC

		ADCON0 = ADCON0 | 0x01;									//begin next conversion

		return (iRetVal);
	}

	void FC_CAL_ADC_Disable ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ANSELA = 0x00;
		ANSELB = 0x00;
		ANSELC = 0x00;

		#ifdef _ANSELD_ANSD0_POSN
			ANSELD = 0x00;
		#endif
		#ifdef _ANSELE_ANSE0_POSN
			ANSELE = 0x00;
		#endif
		#ifdef _ANSELF_ANSF0_POSN
			ANSELF = 0x00;
		#endif
		#ifdef _ANSELG_ANSG0_POSN
			ANSELG = 0x00;
		#endif

		ADCON0 = 0x00;
	}

	#ifdef MX_ADC_TOUCH

	#warning "ADC Touch not yet supported on this device"

	MX_UINT16 FC_CAL_ADC_Touch (MX_UINT8 Channel)
	{
		return 0;
	}
	#endif // MX_ADC_TOUCH
#endif


