
// ****************************************************************************
//
//                         Page CH - charge meter
//
// ****************************************************************************

#include "../include.h"

double CHEnergy = 0;	// Ch charge in mAh
u32 CHLast = 0;		// time of last measure
Bool CHLastValid = False; // time of last measure is valid

// CH update (takes 500ms)
void CH_Update()
{
	// I update
	I_Update();

	// get current
	s32 val = IState;
	if (val < 0) val = 0;

	// add current
	u32 t = Time();
	if (CHLastValid)
	{
		u32 dt = t - CHLast;
		double dval = (double)val * dt / ((double)3600*1000000*HCLK_PER_US);
		CHEnergy += dval;
	}
	CHLast = t;
	CHLastValid = True;
}

// CH initialize (initializes BAT measure, too)
void CH_Init()
{
	// I initialize
	I_Init();

	// set 'Hold' key to long mode
	KeyHoldLong();
}

// CH terminate (terminates BAT measure, too)
void CH_Term()
{
	// set 'Hold' key to default short mode
	KeyHoldShort();

	// I terminate
	I_Term();
}

// CH display
void CH_Disp()
{
	// clear area
	DrawRectClrFast(0, TITLE_H, WIDTH, HEIGHT-TITLE_H);

	// select font 8x12
	SelFont12();

	// display current ("1.234mA")
	DispVal((WIDTH-6*8-4)/2, ROW1_Y, IState, 4, -3, 'A', True, True);

	// CH energy
	double val = CHEnergy;
	if (val < 0) val = 0;
	int ex = -3;
	while ((val > 0) && (val < 10000) && (ex > -12))
	{
		val *= 10;
		ex--;
	}

	while ((val > 100000) && (ex < 9))
	{
		val /= 10;
		ex++;
	}

	// display energy
	u32 p = (u32)val;
	int x = DispUVal(8, ROW2_Y, p, 4, ex, 'A', False, False);
	DrawChar2('h', x, ROW2_Y);

	// display tare correction
	I_DispTare();

	// display update
	DispUpdate();
}

// Page CH (returns key PREV/NEXT)
u8 PageCH()
{
	int i;
	u8 key;

	// Ch initialize (initializes BAT measure, too)
	CH_Init();

	// Ch display
	CH_Disp();

	while (True)
	{
		// reload watchdog counter
		IWDG_Reload();

		// update battery supply voltage (takes 100ms)
		BAT_Update();

		// Ch update (takes 500ms)
		CH_Update();

		// Ch display
		CH_Disp();

		// keyboard input
		key = KeyGet();
		switch (key)
		{
		// change page
		case KEY_PREV:
		case KEY_NEXT:
			// Ch terminate (terminates BAT measure, too)
			CH_Term();
			return key;

		// Hold - reset
		case KEY_HOLD:
			CHEnergy = 0;	// CH energy in mAh
			CHLastValid = False; // time of last measure is not valid
			CH_Disp();
			break;

		// Hold long - reset
		case KEY_HOLD_LONG:
			// I tare
			I_Tare();
			break;
		}
	}
}
