#include "adc.h"

#define ADC_CONVERSION_TIMEOUT 1000U

// The ADC needs a 50-200 kHz clock. At F_CPU = 8 MHz that is a /64 prescaler
// (125 kHz); the old /2 ran it at 4 MHz, far out of spec.
#define ADC_PRESCALER_64 ((1 << ADPS2) | (1 << ADPS1))

// The 1.1 V bandgap reference needs time to settle after the mux is switched.
#define ADC_SETTLE_US 200

int8_t adc_Initialize(void)
{
    //REFS VAL_0x01; ADLAR disabled; MUX adc0; 
    ADMUX = 0x40;

    //ACME disabled; ADTS VAL_0x00; 
    ADCSRB = 0x00;

    ADCSRA = (1 << ADEN) | ADC_PRESCALER_64;

    return 0;
}

void adc_Disable(void)
{
	ADCSRA &= ~(1 << ADEN);
}

void adc_Enable(void)
{
	ADCSRA |= (1 << ADEN);
}


void adc_StartConversion(uint8_t channel)
{
    if (channel == 0)
    {
     
        ADMUX=0b01000000;
    }
    else if (channel == 14)
    {
//        ADMUX=0b01001110;
        ADMUX=(0x01 << REFS0) | (0<<ADLAR) | (0x0e << MUX0);
    }
    else
    {
	ADMUX &= ~0x0f;
	ADMUX |= channel;
    }
	_delay_us(ADC_SETTLE_US);
	ADCSRA |= (1 << ADSC);
}

bool adc_IsConversionDone(void)
{
	return ((ADCSRA & (1 << ADIF)));
}

uint16_t adc_GetConversionResult(void)
{
	// ADC reads ADCL then ADCH in the right order. Reading the two volatile
	// registers in one expression leaves the order unspecified, and taking ADCH
	// first breaks the data-register lock and corrupts the result.
	return ADC;
}

uint16_t adc_GetConversion(uint8_t channel)
{
	adc_StartConversion(channel);

	// A conversion is 13 ADC clocks (~104 us at 125 kHz); bail out rather than
	// hang if the ADC is disabled or its clock is gated off.
	uint16_t attempts = 0;
	while (!adc_IsConversionDone()) {
		if (++attempts > ADC_CONVERSION_TIMEOUT) {
			return 0;
		}
		_delay_us(10);
	}

	uint16_t res = adc_GetConversionResult();
	ADCSRA |= (1 << ADIF);
	return res;
}
