/*
 * p_adc.c
 *
 * Created: 8/19/2020 5:31:04 PM
 *  Author: Penguin
 */ 
#include "p_adc.h"

#define P_ADC_SAMPLE_AMT		128
static uint16_t p_adc_result_buffer[P_ADC_SAMPLE_AMT];
static float p_adc_get_voltage(void);
static uint16_t p_adc_get_raw(void);

static volatile bool b_adc_read_finished = false;
static void p_adc_cb(struct adc_module* const module)
{
	b_adc_read_finished = true;
}

void p_adc_init(void)
{
	// configure adc
	struct adc_config adc_conf;
	adc_get_config_defaults(&adc_conf);
	adc_conf.gain_factor = P_ADC_GAIN_FACTOR;
	adc_conf.clock_prescaler = P_ADC_CLOCK_PRESCALER;
	adc_conf.positive_input = P_FORWARD_POT_POSITIVE_INPUT_PIN;
	adc_conf.negative_input = P_ADC_NEGATIVE_INPUT_PIN;
	adc_conf.resolution = P_ADC_RESOLUTION;
	adc_conf.reference = P_ADC_REFERENCE;
	adc_init(&p_adc_inst, ADC, &adc_conf);
	adc_enable(&p_adc_inst);
	adc_register_callback(&p_adc_inst, p_adc_cb, ADC_CALLBACK_READ_BUFFER);
	adc_enable_callback(&p_adc_inst, ADC_CALLBACK_READ_BUFFER);
}

float p_get_forward_pot_voltage(void)
{
	adc_set_positive_input(&p_adc_inst, P_FORWARD_POT_POSITIVE_INPUT_PIN);
	return p_adc_get_voltage();
	
}

float p_get_reverse_pot_voltage(void)
{
	adc_set_positive_input(&p_adc_inst, P_REVERSE_POT_POSITIVE_INPUT_PIN);
	return p_adc_get_voltage();
}

float p_adc_get_voltage(void)
{
	uint16_t raw = p_adc_get_raw();
	// raw reading / 2^n * Vref
	// n = bit resolution
	// vref = 1/1.48 * Vcc
	// Vcc is supposed to be 3.3, which would give a Vref of 2.2297
	// My vcc is dipping a bit low at 3.26-3.28 so my vref is slightly lower.
	return (float)((float)raw / 4096.0f * P_ADC_VREF_VAL);
}
uint16_t p_adc_get_raw(void)
{
	b_adc_read_finished = false;
	adc_read_buffer_job(&p_adc_inst, p_adc_result_buffer, P_ADC_SAMPLE_AMT);
	while(b_adc_read_finished == false){};
	uint32_t sum = 0;
	for(int ind = 0; ind < P_ADC_SAMPLE_AMT; ind++)
	{
		sum += (uint32_t)p_adc_result_buffer[ind];
	}
	sum /= P_ADC_SAMPLE_AMT;
	return (uint16_t)sum;
}