/****************************************************************************
 *
 * Projekt			:	Magnetfeldmessgeraet
 * Dateiname		:	drvAdc.c
 * Autor			:	Eros Schatzmayer
 * Erstellungsdatum	:	17.04.2019
 * Beschreibung		:	"Treiber fuer Zugriffe auf den internen ADC"
 *
 *
 * Versionsgeschichte
 * 	Revision 1.0	28.05.2020 SCE
 *
 ****************************************************************************/

/****************************************************************************/
/* COMPILER Direktiven */

/****************************************************************************/
/* INCLUDE Dateien */
#include "DrvAdc.h"
#include "SPI.h"

/****************************************************************************/
/* KONSTANTEN */

/****************************************************************************/
/* Globale Variablen */

/****************************************************************************/
/* Funktionen */
//ADC-Kanal setzen
void DrvAdc_Select(uint8_t u8_type)
{
	switch (u8_type)
	{
		case ADC_U_HALL:
		{
			ADCSRA = (1<<ADEN) | (0<< ADSC) | (0<< ADATE) |  	//ADC enable
			(1<< ADIF) | (0<< ADIE) | 							//Interrupt disabled
			//					 	(0<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK / 4 = 5MHz      @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 10uS bis Messwertuebernahme
			//					 	(0<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK / 8 = 2.5MHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 16.8uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (0<< ADPS0);		//CLK /16 = 1.25MHz   @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 31uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (1<< ADPS0);		//CLK /32 = 625kHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 62uS bis Messwertuebernahme
			(1<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK /64 = 312.5kHz  @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 112uS bis Messwertuebernahme
			// 					 	(1<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK/128 = 156.25kHz @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 216uS bis Messwertuebernahme
			ADMUX = ADC_REF_AVCC | ADC_U_HALL;	// Kanal auswählen
			break;
		}
		case ADC_U_CALIB:
		{
			ADCSRA = (1<<ADEN) | (0<< ADSC) | (0<< ADATE) |  	//ADC enable
			(1<< ADIF) | (0<< ADIE) | 							//Interrupt disabled
			//					 	(0<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK / 4 = 5MHz      @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 10uS bis Messwertuebernahme
			//					 	(0<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK / 8 = 2.5MHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 16.8uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (0<< ADPS0);		//CLK /16 = 1.25MHz   @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 31uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (1<< ADPS0);		//CLK /32 = 625kHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 62uS bis Messwertuebernahme
			(1<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK /64 = 312.5kHz  @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 112uS bis Messwertuebernahme
			// 					 	(1<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK/128 = 156.25kHz @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 216uS bis Messwertuebernahme
			ADMUX = ADC_REF_AVCC | ADC_U_CALIB;	// Kanal auswählen
			break;
		}
		case ADC_U_OFFSET:
		{
			ADCSRA = (1<<ADEN) | (0<< ADSC) | (0<< ADATE) |  	//ADC enable
			(1<< ADIF) | (0<< ADIE) | 							//Interrupt disabled
			//					 	(0<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK / 4 = 5MHz      @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 10uS bis Messwertuebernahme
			//					 	(0<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK / 8 = 2.5MHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 16.8uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (0<< ADPS0);		//CLK /16 = 1.25MHz   @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 31uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (1<< ADPS0);		//CLK /32 = 625kHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 62uS bis Messwertuebernahme
			(1<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK /64 = 312.5kHz  @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 112uS bis Messwertuebernahme
			// 					 	(1<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK/128 = 156.25kHz @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 216uS bis Messwertuebernahme
			ADMUX = ADC_REF_AVCC | ADC_U_HALL; // Kanal auswählen
			break;
		}
		case ADC_U_RS232:
		{
			ADCSRA = (1<<ADEN) | (0<< ADSC) | (0<< ADATE) |  	//ADC enable
			(1<< ADIF) | (0<< ADIE) | 							//Interrupt disabled
			//					 	(0<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK / 4 = 5MHz      @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 10uS bis Messwertuebernahme
			//					 	(0<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK / 8 = 2.5MHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 16.8uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (0<< ADPS0);		//CLK /16 = 1.25MHz   @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 31uS bis Messwertuebernahme
			//					 	(1<< ADPS2) | (0<< ADPS1) | (1<< ADPS0);		//CLK /32 = 625kHz    @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 62uS bis Messwertuebernahme
			(1<< ADPS2) | (1<< ADPS1) | (0<< ADPS0);		//CLK /64 = 312.5kHz  @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 112uS bis Messwertuebernahme
			// 					 	(1<< ADPS2) | (1<< ADPS1) | (1<< ADPS0);		//CLK/128 = 156.25kHz @ 20MHz (50..200kHz for max resolution, 1.5 ADC cycles ) => 216uS bis Messwertuebernahme
			ADMUX = ADC_REF_AVCC | ADC_U_RS232;	// Kanal auswählen
			break;
		}
	}

	ADCSRA |= (1<<ADSC);              	//ignore first conversion
	while (ADCSRA & (1<<ADSC));
}

//ADC abschalten
void DrvAdc_Stop()
{
  ADCSRA &= ~(1<<ADEN);             	//deactivate adc
}

//Messung starten und Wert zurueckgeben
uint16_t DrvAdc_Read()
{
	ADCSRA |= (1<<ADSC);              	//conversion
 	while (ADCSRA & (1<<ADSC));

	return ADCW;
}
/****************************************************************************
 *
 * Projekt			:	Magnetfeldmessgeraet
 * Dateiname		:	drvAdc.c
 * Autor			:	Eros Schatzmayer
 * Erstellungsdatum	:	17.04.2019
 * Beschreibung		:	"Treiber fuer Zugriffe auf den externen ADC"
 ****************************************************************************/
void AdcExt_Init(void)
{	
	// SPI enable
	SPIInit(ENABLE_SPI);
	
	// CS auf Low ziehen um ADC zu enablen
	DEF_EADC_SEL;
	CLR_EADC_SEL;
	_delay_ms(1000);
	_delay_us(3);
	
	// Die zwei Bytes für das Konfigurationsregister des ADCs schicken.
	SPITransmit(CONFIG_MSB);
	SPITransmit(CONFIG_LSB);
	
	// SPI Interface resetten
	SET_EADC_SEL;
	
	// SPI disable
	SPIInit(DISABLE_SPI);
}
uint16_t AdcExt_Read(void)
{
	uint16_t u16_measVal;
	uint8_t u8_adcDataRegMSB, u8_adcDataRegLSB, u8_adcConfigRegMSB, u8_adcConfigRegLSB;
	
	// SPI enable
	SPIInit(ENABLE_SPI);
	
	// CS auf Low ziehen um ADC zu enablen
	DEF_EADC_SEL;
	CLR_EADC_SEL;
	_delay_us(3);

	
	u8_adcDataRegMSB = SPIReceive(CONFIG_MSB);
	u8_adcDataRegLSB = SPIReceive(CONFIG_LSB);

	
	// SPI Interface resetten
	SET_EADC_SEL;
	
	// SPI disable
	SPIInit(DISABLE_SPI);
	
	// 16-Bit Wert aus zwei 8-Bit Werten zusammenstellen
	u16_measVal = ((uint16_t)u8_adcDataRegMSB << 8) | u8_adcDataRegLSB;
	
	return u16_measVal;
}
	
