#include "header.h"

// 24.2 : The ADC generates a 10-bit result which is presented in the ADC Data Registers, ADCH and ADCL

void adc_init(uint8_t prescaler_value) {
    ADMUX = (1 << REFS0);											// Table 24-3 : set voltage reference, AVCC with external capacitor at AREF pin
    ADCSRA = (1 << ADEN); 											// 24.9.2 : enable ADC
	ADCSRA |= (1 << ADATE); 										// 24.9.2 : enable Auto Trigger -> it will start a conversion on the selected channel in ADMUX when the selected source (in ADCSRB) is triggered
	ADCSRA |= (1 << ADIE);									 		// 24.9.2 : enable ADC Interrupt
    ADCSRA |= ADC_PRESCALE_SET(prescaler_value);					// Table 24-5 : prescaler ADC

	ADCSRB = ADC_TRIGGER_TIMER_1_COMPARE_B;							// Table 24-6 : ADC Auto Trigger Source
	ADMUX = (ADMUX & 0b11110000) | (adc_channel & 0b00001111);		// Table 24-4 : Select ADC channel 0
}

uint16_t calibrate_temperature(uint16_t value, uint8_t speed) {		// 24.8 : Temperature Measurement
	// calibration random
	uint16_t offset = (540 - (25*speed));
	value = (value - offset) / speed;
	return value;
}

void adc_print_dec(uint16_t value) {
	// if (adc_channel == ADC_THERMISTOR) {
	// 	value = calibrate_temperature(value, 5);
	// }
	char buffer[17] = {0};
	uint16_to_string(value, buffer);
	uart_printstr(buffer);
}

ISR(ADC_vect) {														// Table 12-6 : interrupt vector for ADC Conversion Complete
	uint16_t value = ADC;											// 24.9.3.2 : read ADC 16 bits precision
	adc_print_dec(value);
	adc_channel = (adc_channel + 1) % 3;							// loop through channels
	ADMUX = (ADMUX & 0b11110000) | (adc_channel & 0b1111);			// Table 24-4 : Select ADC channel
	if (adc_channel != 0) {
		uart_printstr(", ");
		ADCSRA |= (1 << ADSC);										// 24.9.2 : start next conversion
	} else {
		uart_printstr("\r\n");
	}
}
