
// ****************************************************************************
//
//                           Page TG - Time Gate
//
// ****************************************************************************

#include "../include.h"

volatile u32 TGCounterH;	// counter HIGH, counts 10us, max. 11 hours and 55 minutes
volatile u32 TGCounterL;	// counter LOW, counts 10us, max. 11 hours and 55 minutes
Bool TGPause = False;		// pause update

/*
// TG Timer 1 interrupt handler (at 100kHz) ... handler located at page_asm.S
//HANDLER void TIM1_UP_IRQHandler()
HANDLER void TG_Handler()
{
	// clear interrupt flag
	TIM1_UpIntClr();

	// get input pin state
	if (GPIO_In(IN_GPIO) != 0)
	{
		// increment counter HIGH
		TGCounterH++;
	}
	else
	{
		// increment counter LOW
		TGCounterL++;
	}
}
*/

// TG initialize
void TG_Init()
{
	// setup input pin to floating input with pull-up
	GPIO_Mode(IN_GPIO, GPIO_MODE_IN_PU);

	// Enable timer clock source
	TIM1_ClkEnable();

	// Reset timer to default setup
	TIM1_Reset();

	// select input from internal clock CK_INT
	TIM1_InMode(TIM_INMODE_INT);

	// set prescaler to 48 MHz
	TIM1_Presc(1-1);

	// set load period to get 10 us overload; 48MHz/480 = 100 kHz
	TIM1_Load(480-1);

	// reload immediately
	TIM1_Update();

	// set CNT Timer 1 interrupt handler
	SetHandler(IRQ_TIM1_UP, TG_Handler);

	// enable update interrupt
	TIM1_UpIntEnable();
	NVIC_IRQEnable(IRQ_TIM1_UP);
	TIM1_UpIntClr();

	// reset counters
	TGCounterH = 0;
	TGCounterL = 0;

	// enable timer
	TIM1_Enable();
}

// TG terminate
void TG_Term()
{
	// interrupt disable
	NVIC_IRQDisable(IRQ_TIM1_UP);
	TIM1_UpIntDisable();
	TIM1_UpIntClr();
	NVIC_IRQClear(IRQ_TIM1_UP);

	// reset input pin
	GPIO_PinReset(IN_GPIO);

	// reset Timer 1
	TIM1_Reset();

	// Timer 1 clock disable
	RCC_TIM1ClkDisable();
}

// draw one value (count in 10us, 100 kHz)
//  max. 11:55:49.67295
void TG_DispVal(u32 val, int y)
{
	int i, j, h, min, sec, us;
	u8* s;

	// separate values
	sec = val/100000;
	us = val - sec*100000;	// = count of 10 us
	min = sec/60;
	sec -= min*60;
	h = min/60;
	min -= h*60;

	// hours
	s = DecNumBuf;
	i = h/10;
	*s++ = i + '0';
	j = h - i*10;
	*s++ = j + '0';
	*s++ = ':';

	// minutes
	i = min/10;
	*s++ = i + '0';
	j = min - i*10;
	*s++ = j + '0';
	*s++ = ':';

	// seconds
	i = sec/10;
	*s++ = i + '0';
	j = sec - i*10;
	*s++ = j + '0';
	*s++ = '.';

	// 10-microseconds (5 digits)
	i = us/10000;
	*s++ = i + '0';
	j = us - i*10000;
	i = j/1000;
	*s++ = i + '0';
	j = j - i*1000;
	i = j/100;
	*s++ = i + '0';
	j = j - i*100;
	i = j/10;
	*s++ = i + '0';
	j = j - i*10;
	*s++ = j + '0';
	*s = 0;

	// clear row
	DrawRectClrFast(0, y, WIDTH, FONTH2);

	// 00:00:59.99999
	if ((h == 0) && (min == 0))
	{
		DrawText2(DecNumBuf + 6, (WIDTH-8*16)/2, y);
	}
	else
	{
		DrawText(DecNumBuf, (WIDTH-14*8)/2, y+6);
	}
}

// display current counter value
void TG_Disp()
{
	// repaint page header
	PageHead();

	// select font 8x12
	SelFont12();

	// pause
	if (TGPause)
	{
		DrawRectClr(PageX, ROW0_Y, WIDTH-1-PageX, FONTH);
		DrawText("HOLD", (WIDTH-1-PageX-4*8)/2+PageX, ROW0_Y);
	}
	else
	{
		// display values
		TG_DispVal(TGCounterH, ROW1_Y);
		TG_DispVal(TGCounterL, ROW3_Y);
	}

	// display update
	DispUpdate();
}

// Page TG (returns key PREV/NEXT)
u8 PageTG()
{
	u8 key;

	// TG initialize
	TG_Init();

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

		// display current counter value
		TG_Disp();

		// keyboard input
		key = KeyGet();
		switch (key)
		{
		// Prev
		case KEY_PREV:
		// Next
		case KEY_NEXT:
			// TG terminate
			TG_Term();
			return key;

		// Hold - hold
		case KEY_HOLD:
			TGPause = !TGPause;
			break;

		// Slow - reset
		case KEY_SLOW:
			di();
			TGCounterH = 0;
			TGCounterL = 0;
			ei();
			TGPause = False;
			break;
		}
	}
}
