#pragma once

#include <zephyr/zephyr.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/adc.h>


#define ADC_NODE_BAT DT_NODELABEL(adc)

static const struct device *adc_dev_bat = DEVICE_DT_GET(ADC_NODE_BAT);

#define ADC_RESOLUTION_BAT		12
#define ADC_CHANNEL_BAT			0
#define ADC_PORT_BAT			SAADC_CH_PSELP_PSELP_AnalogInput7	//AIN2 P0.31
#define ADC_REFERENCE_BAT		ADC_REF_INTERNAL					//0.6V
#define ADC_GAIN_BAT			ADC_GAIN_1_5						//ADC_REFERENCE*5

struct adc_channel_cfg channel_cfg_bat = {
	.gain = ADC_GAIN_BAT,
	.reference = ADC_REFERENCE_BAT,
	.acquisition_time = ADC_ACQ_TIME_DEFAULT,
	.channel_id = ADC_CHANNEL_BAT,
#ifdef CONFIG_ADC_NRFX_SAADC
	.input_positive = ADC_PORT_BAT
#endif
};


int16_t sample_buffer_bat[1];
struct adc_sequence sequence_bat = {
	/* individual channels will be added below */
	.channels = BIT(ADC_CHANNEL_BAT),
	.buffer = sample_buffer_bat,
	/* buffer size in bytes, not number of samples */
	.buffer_size = sizeof(sample_buffer_bat),
	.resolution = ADC_RESOLUTION_BAT
};


void bat_monitor_init(void){
    int ret;

	if (!device_is_ready(adc_dev_bat)) {
		return;
	}

	ret = adc_channel_setup(adc_dev_bat, &channel_cfg_bat);
	if (ret != 0) {
		printk("ADC bat_monitor adc_channel_setup failed with error %d \n", ret);
		return;
	}
}

double measure_battery(void){
    int ret;

	// MEASURE SAMPLE
	ret = adc_read(adc_dev_bat, &sequence_bat);
	if (ret != 0) {
		printk("ADC reading failed with error %d \n", ret);
		return;
	}

	// CALCULATE VALUE
	int32_t mv_value = sample_buffer_bat[0];
	//printk("ADC: %d ... ", mv_value);
	int32_t adc_vref = adc_ref_internal(adc_dev_bat);
	adc_raw_to_millivolts(adc_vref, ADC_GAIN_BAT, ADC_RESOLUTION_BAT, &mv_value);
	//printk("U0: %d mV ... ", mv_value);
	double mv_val_real = mv_value > 0 ? (double)mv_value/0.714285 : 0;
	printk("Ucc: %.2f mV \n", mv_val_real);


    return mv_val_real;
}
