#include "system.h"

#define BAT_PRESENT 30 //1e-2V
#define CHARGE_GOOD 90 // %
#define CHARGE_BAD 75 // %
const float inscale[3] = {0.1661779, 0.332355816, 0.9775171065};
const uint16_t full_charge[2][3] = {{170, 310, 1000}, //1e-2V
								    {130, 280, 600}}; //1e-2V

uint16_t values[3];

void readValues();
int8_t selectValue();
uint8_t computeChargeLeft(uint8_t selected);

int main(void)
{
	int8_t selected = 0;
	uint8_t charge = 0;
	
	system_setup();
	
	splashscreen();
	_delay_ms(1000);
	dots = 0b0100;

	while (1) 
    {
		readValues();
		selected = selectValue();
		
		if(selected != -1)
		{
			charge = computeChargeLeft(selected);
			
			_SET_OK(charge > CHARGE_GOOD);
			_SET_NOK(charge < CHARGE_BAD);
			
			value = values[selected];
			convert();
			fillBuffer();
		}
		else
		{
			clearBuffer();
			_SET_OK(0);
			_SET_NOK(0);
		}
    }
}


// Read and scale all three analog channels
void readValues(){
	uint8_t i;
	
	for(i=0; i<3; i++){
		float val = (float) adc_read(i);
		values[i] = (int) (val * inscale[i]);
		values[i] = _MIN(_MAX(0, values[i]), 9999);
		_delay_us(200);
	}
}

// Return the first reading above the threshold
int8_t selectValue(){
	uint8_t i;
	
	for(i=0; i<3; i++){
		if(values[i] > BAT_PRESENT)
			return i;
	}
	
	return -1;
}

// Simple linearized charge curve
uint8_t computeChargeLeft(uint8_t selected){
	float charge = (float) values[selected] / (float) full_charge[_MODE()][selected];
	charge *= 100;
	charge = _MIN(_MAX(charge, 0), 100);
	
	return (uint8_t) charge;
}


