/*********************************************************************
 *                  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
 */


//ADC Function Prototypes
void FC_CAL_Enable_ADC (MX_UINT8 Channel, MX_UINT8 Conv_Speed, MX_UINT8 Vref, MX_UINT8 T_Charge);
MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode);
void FC_CAL_Disable_ADC (void);


//ADC Global Variables
MX_UINT8 old_tris, tris_mask;
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_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x04;									//begin conversion and wait until it has finished
		while (adcon0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x07;
		adcon0 = 0x00;
	}
#endif


// ADC Type 2 Supported Devices ************************************************************
// 16F88
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_2
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x04;									//begin conversion and wait until it has finished
		while (adcon0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ansel = 0x00;
		adcon0 = 0x00;
	}
#endif


// ADC Type 3 Supported Devices ************************************************************
// 16F616, 16F676, 16F677, 16F684, 16F685, 16F687, 16F688, 16F689, 16F690
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_3
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ansel = 0x00;
		adcon0 = 0x00;
		#ifdef ANSELH
			anselh = 0x00;
		#endif
	}
#endif


// ADC Type 4 Supported Devices ************************************************************
// 16F737, 16F747, 16F767, 16F777
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_4
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x04;									//begin conversion and wait until it has finished
		while (adcon0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x07;
		adcon0 = 0x00;
	}
#endif


// ADC Type 5 Supported Devices ************************************************************
// 12F615, 12HV615, 12F675, 12F683
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_5
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ansel = 0x00;
		adcon0 = 0x00;
	}
#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_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x04;									//begin conversion and wait until it has finished
		while (adcon0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (adres << 2);								//10-bit ADC
		}
		else
			iRetVal = adres;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x07;
		adcon0 = 0x00;
	}
#endif



// ADC Type 7 Supported Devices ************************************************************
// 16F883, 16F884, 16F886, 16F887
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_7
	void FC_CAL_Enable_ADC (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 (13):
					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(adcon0, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ansel = 0x00;
		adcon0 = 0x00;
		#ifdef ANSELH
			anselh = 0x00;
		#endif
	}
#endif


// ADC Type 8 Supported Devices ************************************************************
// 16F785
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_8
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ansel0 = 0x00;
		adcon0 = 0x00;
		#ifdef ANSEL1
			ansel1 = 0x00;
		#endif
	}
#endif


// ADC Type 9 Supported Devices ************************************************************
// 16F913, 16F914, 16F916, 16F917, 16F946
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_9
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon0 = 0x00;
		ansel = 0x00;
	}
#endif


// ADC Type 10 Supported Devices ***********************************************************
// 12C671, 12C672, 12CE673, 12CE674
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_10
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adres << 2);								//10-bit ADC
		}
		else
			iRetVal = adres;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x07;
		adcon0 = 0x00;
	}
#endif


// ADC Type 11 Supported Devices ***********************************************************
// 16C717, 16C770, 16C771
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_11
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x04;									//begin conversion and wait until it has finished
		while (adcon0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon0 = 0x00;
		ansel = 0x00;
	}
#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_Enable_ADC (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(adcon0, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x0f;
		adcon0 = 0x00;
	}
#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_Enable_ADC (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);
	//Vref- beállítása, ha nem kell, a következő sort törölni!
			

		delay_us(T_Charge);										//wait the acquisition time
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		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

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x0f;
		adcon0 = 0x00;
	}
#endif


// ADC Type 14 Supported Devices ***********************************************************
// 18F2331, 18F2431, 18F4331, 18F4431
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_14
	void FC_CAL_Enable_ADC (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(adcon0, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon0 = 0x00;
		ansel0 = 0x00;
		#ifdef ANSEL1
			ansel1 = 0x00;
		#endif
	}
#endif


// ADC Type 15 Supported Devices ***********************************************************
// 18F1220, 18F1320
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_15
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x7f;
		adcon0 = 0x00;
	}
#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_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x04;									//begin conversion and wait until it has finished
		while (adcon0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x07;
		adcon0 = 0x00;
	}
#endif


// ADC Type 17 Supported Devices ***********************************************************
// 18F1230, 18F1330
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_17
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x00;
		adcon0 = 0x00;
	}
#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

	MX_UINT8 * ansel_reg;					//ANSEL register pointer

	void FC_CAL_Enable_ADC (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
			st_bit(adcon1, ADREF1);

		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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ansel_reg = 0x00;
		adcon0 = 0x00;
	}
#endif


// ADC Type 19 Supported Devices ***********************************************************
// 18F13K50, 18F14K50, 18LF13K50, 18LF14K50
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_19
	void FC_CAL_Enable_ADC (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
			st_bit(adcon1, PVCFG0);

		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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ansel = 0;
		adcon0 = 0x00;
		#ifdef ANSELH
			anselh = 0;
		#endif
	}
#endif


// ADC Type 20 Supported Devices ***********************************************************
// 18F23K20, 18F24K20, 18F25K20, 18F26K20, 18F43K20, 18F44K20, 18F45K20, 18F16K20
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_20
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ansel = 0;
		adcon0 = 0x00;
		#ifdef ANSELH
			anselh = 0;
		#endif
	}
#endif


// ADC Type 21 Supported Devices ***********************************************************
// 18F2xJ11, 18F4xJ11
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_21
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ancon0 = 0xFF;
		ancon1 = 0x1F;
		adcon0 = 0x00;
	}
#endif


// ADC Type 22 Supported Devices ***********************************************************
// 10F220, 10F222
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_22
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
			iRetVal = (adres << 2);								//10-bit ADC
		else
			iRetVal = adres;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		adcon0 = 0x00;											//Reset ADC Registers
	}
#endif


// ADC Type 23 Supported Devices ***********************************************************
// 16F1826, 16F1827
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_23

	MX_UINT8 * ansel_reg;					//ANSEL register pointer

	void FC_CAL_Enable_ADC (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
			st_bit(adcon1, ADPREF1);

		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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ansel_reg = 0x00;
		adcon0 = 0x00;
	}
#endif


// ADC Type 24 Supported Devices ***********************************************************
// 18F65J50, 18F66J50, 18F66J55, 18F67J50, 18F85J50, 18F86J50, 18F86J55, 18F87J50
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_24
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		ancon0 = 0x00;
		ancon1 = 0x00;
		adcon0 = 0x00;
	}
#endif


// ADC Type 25 Supported Devices ***********************************************************
// 18F66J93, 18F67J93, 18F86J93, 18F87J93, 18F66J90, 18F67J90, 18F86J90, 18F87J90
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_25
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x0f;
		adcon0 = 0x00;
	}
#endif


// ADC Type 26 Supported Devices ***********************************************************
// 16F1822, 16F1823, 16F1824, 16F1825, 16F1828, 16F1829
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_26

	MX_UINT8 * ansel_reg;					//ANSEL register pointer

	void FC_CAL_Enable_ADC (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
		}

		if (Vref != 0)											//assign VREF functionality
			st_bit(adcon1, ADPREF1);

		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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ansel_reg = 0x00;
		adcon0 = 0x00;
	}
#endif


// ADC Type 27 Supported Devices ***********************************************************
// 16F1946, 16F1947
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_27

	MX_UINT8 * ansel_reg;					//ANSEL register pointer

	void FC_CAL_Enable_ADC (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 (11):
					tris_mask = 0x10;
					tris_reg = &trisg;
					ansel_reg = &anselg;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_13
				case (11):
					tris_mask = 0x08;
					tris_reg = &trisg;
					ansel_reg = &anselg;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_14
				case (11):
					tris_mask = 0x04;
					tris_reg = &trisg;
					ansel_reg = &anselg;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_15
				case (11):
					tris_mask = 0x02;
					tris_reg = &trisg;
					ansel_reg = &anselg;
					break;
			#endif
			#ifdef MX_ADC_CHANNEL_16
				case (11):
					tris_mask = 0x01;
					tris_reg = &trisg;
					ansel_reg = &anselg;
					break;
			#endif
		}

		if (Vref != 0)											//assign VREF functionality
			st_bit(adcon1, ADPREF1);

		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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ansel_reg = 0x00;
		adcon0 = 0x00;
	}
#endif


// ADC Type 28 Supported Devices ***********************************************************
// 18F65K22, 18F66K22, 18F67K22, 18F85K22, 18F86K22, 18F87K22,
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_28
	void FC_CAL_Enable_ADC (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
			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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 4);							//12-bit ADC
			iRetVal = iRetVal | (adresl >> 4);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon0 = 0x00;
		ancon0 = 0x00;
		#ifdef ANCON1
			ancon1 = 0x00;
		#endif
		#ifdef ANCON2
			ancon2 = 0x00;
		#endif
	}
#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

	MX_UINT8 * ansel_reg;					//ANSEL register pointer

	void FC_CAL_Enable_ADC (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
			st_bit(adcon1, PVCFG0);

		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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x02;									//begin conversion and wait until it has finished
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		*ansel_reg = 0x00;
		adcon0 = 0x00;
	}
#endif


// ADC Type 30 Supported Devices ************************************************************
// 16F870, 16F871, 16F872, 16F873, 16F874, 16F876, 16F877
// *******************************************************************************************/

#ifdef MX_ADC_TYPE_30
	void FC_CAL_Enable_ADC (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
	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;

		adcon0 = adcon0 | 0x04;									//begin conversion and wait until it has finished
		while (adcon0 & 0x04);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 2);							//10-bit ADC
			iRetVal = iRetVal | (adresl >> 6);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*tris_reg = old_tris;									//restore old tris value, and reset adc registers
		adcon1 = 0x07;
		adcon0 = 0x00;
	}
#endif



// ADC Type 32 Supported Devices ***********************************************************
// 18F2xK80, 18F4xK80, 18F6xK80
// *****************************************************************************************/

#ifdef MX_ADC_TYPE_32
	void FC_CAL_Enable_ADC (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
			st_bit(adcon1, VCFG0);

		delay_us(T_Charge);										//wait the acquisition time

	}

	MX_UINT16 FC_CAL_Sample_ADC (MX_UINT8 Sample_Mode)
	{
		MX_UINT16 iRetVal;
		
		adcon0 = adcon0 | 0x02;
		while (adcon0 & 0x02);
		if (Sample_Mode)
		{
			iRetVal = (adresh << 4);							//12-bit ADC
			iRetVal = iRetVal | (adresl >> 4);
		}
		else
			iRetVal = adresh;									//8-bit ADC

		return (iRetVal);
	}

	void FC_CAL_Disable_ADC ()
	{
		*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
