/*
 * adc.c
 *
 * Created: 25/09/2016 12:52:02
 *  Author: Ledo
 */ 

#include "adc.h"

void adc_init(uint8_t gain)
{
	/* Assign and enable GPIO pins to the ADC function. */
	gpio_enable_module(ADC_GPIO_MAP, sizeof(ADC_GPIO_MAP) /
			sizeof(ADC_GPIO_MAP[0]));

   /* Configure the ADC for the application*/
   adc_config_t.frequency                = 1000000;
   adc_config_t.reference_source         = ADCIFA_ADCREF0;//ADCIFA_REF1V;//ADCIFA_ADCREF;//ADCIFA_ADCREF0;//ADCIFA_REF1V//ADCIFA_REF06VDD
   adc_config_t.sample_and_hold_disable  = false;
   adc_config_t.single_sequencer_mode    = true;
   adc_config_t.free_running_mode_enable = false;
   adc_config_t.sleep_mode_enable        = false;
   adc_config_t.mux_settle_more_time     = false;	
   
   /* Get ADCIFA Factory Configuration */
   adcifa_get_calibration_data(&AVR32_ADCIFA, &adc_config_t);

   /* Calibrate offset first*/
   adcifa_calibrate_offset(&AVR32_ADCIFA, &adc_config_t, sysclk_get_cpu_hz());
   
   //ADCIFA_set_offset_calibration(0);
   
   /* Configure ADCIFA core */
   adcifa_configure(&AVR32_ADCIFA, &adc_config_t, sysclk_get_cpu_hz());
   ADCIFA_disable();
   
 	/* ADCIFA sequencer 0 configuration structure*/
 	adcifa_sequence_opt.convnb              = NUMBER_OF_SEQUENCE;
 	adcifa_sequence_opt.resolution          = ADCIFA_SRES_12B;
 	adcifa_sequence_opt.trigger_selection   = ADCIFA_TRGSEL_SOFT;
 	adcifa_sequence_opt.start_of_conversion = ADCIFA_SOCB_ALLSEQ;
 	adcifa_sequence_opt.sh_mode             = ADCIFA_SH_MODE_OVERSAMP;
 	adcifa_sequence_opt.half_word_adjustment= ADCIFA_HWLA_NOADJ;
 	adcifa_sequence_opt.software_acknowledge= ADCIFA_SA_NO_EOS_SOFTACK;
    //adcifa_sequence_opt.sh_mode = ADCIFA_SH_MODE_STANDARD;
 	/* ADCIFA conversions for sequencer 0*/
 	adcifa_sequence_conversion_opt[0].channel_p = V_INP;
 	adcifa_sequence_conversion_opt[0].channel_n = V_INN;
 	adcifa_sequence_conversion_opt[0].gain      = gain;//ADCIFA_SHG_4;
 	adcifa_sequence_conversion_opt[1].channel_p = I_INP;
 	adcifa_sequence_conversion_opt[1].channel_n = I_INN;
 	adcifa_sequence_conversion_opt[1].gain      = ADCIFA_SHG_2;  
 	adcifa_sequence_conversion_opt[2].channel_p = NTC_INP;
 	adcifa_sequence_conversion_opt[2].channel_n = NTC_INN;
 	adcifa_sequence_conversion_opt[2].gain      = ADCIFA_SHG_1;
	
   
    /* Configure ADCIFA sequencer 0 */
    adcifa_configure_sequencer(&AVR32_ADCIFA, 0, &adcifa_sequence_opt,
    adcifa_sequence_conversion_opt);

    AVR32_ADCIFA.cfg = AVR32_ADCIFA.cfg & 0xFFFFFF7F;
    /* Start ADCIFA sequencer 0 */
	ADCIFA_enable();
    adcifa_start_sequencer(&AVR32_ADCIFA, 0);
   	
}


void Read_adc_values(int16_t * adc_values[])
{
			/* Get Values from sequencer 0 */
	if (adcifa_get_values_from_sequencer(&AVR32_ADCIFA, 0,
			&adcifa_sequence_opt, adc_values) == ADCIFA_STATUS_COMPLETED) 
	{
			/*
			 * Clear end-of-sequence for sequencer 0,
			 * ready for next conversion.
			 */
			ADCIFA_clear_eos_sequencer_0();

			/* Start new ADCIFA sequencer 0 */
			adcifa_start_sequencer(&AVR32_ADCIFA, 0);
	
	}

}

int8_t adc_offset(void)
{
	int8_t offset;
	switch(Params.adc_gain)
	{
		case 0:
		offset = ADC_OFFSET;
		break;
		case 1:
		offset = ADC_OFFSET * 2;
		break;
		case 2:
		offset = ADC_OFFSET * 4;
		break;
		case 3:
		offset = ADC_OFFSET * 8;
		break;
		case 4:
		offset = ADC_OFFSET * 16;
		break;
		case 5:
		offset = ADC_OFFSET * 32;
		break;
		case 6:
		offset = ADC_OFFSET * 64;
		break;
		default:
		break;

	}
	return offset;
	
}


/*
void adc_start(void)
{
	// start conversion
	AVR32_ADCIFA->cr = AVR32_ADCIFA_START_MASK;
}

void adc_enable(volatile avr32_adcifa_t * adc, unsigned short channel)
{

	// enable channel
	AVR32_ADCIFA->cher = (1 << channel);
}
*/