/************ ADC.c *********/

#include	"ADC.h"

/*******************************************************************/
/*	-SetUpADC ( Port Configurtion, Justification,  Voltage Referenced )
/*		-Port Configurtion
/*		-Justification
/*		-Voltage Referenced
/*		-Clock Conversion
/*		configures the ADC Port.
/*
/*	-SetADCChannel ( ADCChannel )
/*		-ADC Channel
/*		sets the channel to be read.
/*
/*	-ReadADC ( )
/*		-
/*		returns the value stored in ADRESL and ADRESH.
/*
/*	Note: the ADCConfig0 works only for the ANSEL Register, previously
/*	you had to set the TRISx Register(s).
/*	There is no ANSELH for the sAN8:sAN13, you have to do it manualy.
/******************************************************************/

/********* Configures the ADC Register ********************/
void SetUpADC ( unsigned char ADCConfig0, unsigned char ADCConfig1, 
				unsigned char ADCConfig2, unsigned char ADCConfig3 )
{
	unsigned char Temp;
	
	ADCON0 = 0x00;					// Set to POR/BOR values.
#if	defined ( _PIC16F887_H_ ) || defined ( _PIC16F886_H_ ) || defined ( _PIC18F26K80_H_ ) || defined ( _PIC18F45K22_H_ )
	ADCON1 = 0x00;						// Set to POR/BOR values.
	#if	defined ( _PIC18F26K80_H_ ) || defined ( _PIC18F45K22_H_ )
		ADCON2 = 0x00;				// Set to POR/BOR values.
		#if	defined ( _PIC18F26K80_H_ )
			ANCON0 = 0x00;			// Equal to ANSELx.
			ANCON1 = 0x00;
		#elif defined ( _PIC18F45K22_H_ )
			ANSELA = 0x00;				// Equal to ANSELx.
		#endif
	#endif
#endif

#if defined ( _PIC18F26K80_H_ )
	ANCON0 = ( 0x1F & ADCConfig0 );	// Making sure the ANSELx is input
										// only for the first 5 Channels. 
#elif defined ( _PIC18F45K22_H_ )
	ANSELA = ( 0x0F & ADCConfig0 );	// Making sure the ANSELx is input								
										// only for the first 4 Channels. 
#elif defined ( _PIC16F887_H_ ) || defined ( _PIC16F886_H_ ) || defined ( _PIC12F683_H_ )
	ANSEL = ADCConfig0;				// Making sure with the ANSEL is input.
#endif

#if defined ( _PIC18F26K80_H_ ) || defined ( _PIC18F45K22_H_ )
	ADCON2 . ADFM = ADCConfig1;	// Passing justification value.
#elif	defined ( _PIC16F887_H_ ) || defined ( _PIC16F886_H_ )
	ADCON1 . ADFM = ADCConfig1;	// Passing justification value.
#elif defined	( _PIC12F683_H_ )
	ADCON0 . ADFM = ADCConfig1;	// Passing justification value.
#endif
	

#if defined ( _PIC18F26K80_H_ )
	Temp = ADCON1;
	Temp |= ADCConfig2 << 0x03; 		// Passing Vref value.
	ADCON1 = Temp;
#elif defined ( _PIC18F45K22_H_ )
	Temp = ADCON1;
	Temp |= ADCConfig2;				// Passing Vref value.
	ADCON1 = Temp;
#elif defined ( _PIC16F887_H_ ) || defined ( _PIC16F886_H_ )
	Temp = ADCON1;
	Temp |= ADCConfig2 << 0x04;		// Passing Vref value.
	ADCON1 = Temp;
#elif defined	( _PIC12F683_H_ )
	Temp = ADCON0;
	Temp |= ADCConfig2;				// Passing Vref value.
	ADCON0 = Temp;
#endif


#if defined ( _PIC18F26K80_H_ ) || defined ( _PIC18F45K22_H_ )
	Temp = ADCON2;
	Temp |= ADCConfig3;				// Coversion Clock value passed.
	ADCON2 = Temp;
#elif	defined ( _PIC16F887_H_ ) || defined ( _PIC16F886_H_ )
	ADCON0 |= ADCConfig3;				// Coversion Clock value passed.
#elif defined	( _PIC12F683_H_ )
	ANSEL |= ADCConfig3;				// Coversion Clock value passed.
#endif
	
	ADCON0 . ADON = 0x01;			// ADC Enabled.
	}
	
/********* Selects the ADC Channel  to use ********************/
void SetADCChannel ( unsigned char ADCChannel )
{
	unsigned char Temp;

#if	defined ( _PIC18F26K80_H_ ) || defined ( _PIC18F45K22_H_ )
	Temp = ADCON0;
	Temp &= 0b10000011;				// Cleaning up the previous channel.
	ADCON0 = Temp;
#elif	defined ( _PIC16F887_H_ ) || defined ( _PIC16F886_H_ )
	ADCON0 &= 0b11000011;				// Cleaning up the previous channel.
#elif defined	( _PIC12F683_H_ )
	ADCON0 &= 0b11110011;				// Cleaning up the previous channel.
#endif
	Temp = ADCON0;
	Temp |= ADCChannel;				// Setting the AD channel to read
	ADCON0 = Temp;				// without changing the ADCON0 value.
	}		


/********* Read the ADC Channel in use ************************/
int ReadADC ( void )
{
	ADCON0 . GO = 0x01;					// Starts the convertion.				
	while ( ADCON0 . GO );					// Wait until convertion is done.

	return ( ( ( unsigned int ) ADRESH ) << 8 ) | 	// Return the value from two Bytes.
			( ADRESL );
	}