
#define	_IN_TRIGGER_C
#include "trigger.h"
#include "iwdog.h"

//-------------------------------------------------------

//-------------------------------------------------------

//-------------------------------------------------------


#define	TRIGGER_TIME		10		// 10  毫秒 触发

#define	MS_SYS_TICK			(SYSCLK/1000)

#define	US100_SYS_TICK		(SYSCLK/10000)

#define	US_SYS_TICK			(SYSCLK/1000000)

#define	NS100_SYS_TICK		(SYSCLK/10000000)

//-------------------------------------------------------

//#define	SYS_TICK_NUM	MS_SYS_TICK

int volatile g_mstimer = 0;		// 1ms++

//-------------------------------------------------------

int g_triggerListNum = 0;
TriggerCtrl g_triggerCtrlList[MAX_TRIGGER_TASK];

u32 volatile g_triggerTimer = 0;		// 每10ms++
int g_triggerTask = 0;
int g_triggerInited = 0;

//-------------------------------------------------------

void InitTrigger(void)
{
	if (g_triggerInited == 0)
	{
		SysTick_Config(MS_SYS_TICK);		// 系统时钟产生1ms中断
		NVIC_SetPriority(SysTick_IRQn, 0);

		g_mstimer = 0;

		// 变量
		g_triggerListNum = 0;
		memset(&g_triggerCtrlList, 0, sizeof(TriggerCtrl)*MAX_TRIGGER_TASK);

		g_triggerTimer = 0;
		g_triggerTask = 0;
		g_triggerInited = 1;

		InitIWDog(1000);	// 1秒复位看门狗
	}
}

int AddTriggerToList(int gapms, TriggerFunc exf, TriggerFunc tskf)
{
	int rslt;

	if (gapms <= 0)
	{
		gapms = 1;
	}

	// 向上取整
//	gapms = (gapms + (TRIGGER_TIME-1)) / TRIGGER_TIME;
//	gapms *= TRIGGER_TIME;

	if (g_triggerInited != 0 && g_triggerListNum < MAX_TRIGGER_TASK && gapms != 0)
	{
		g_triggerCtrlList[g_triggerListNum].triggerTimer = gapms;
		g_triggerCtrlList[g_triggerListNum].triggerExFunc = exf;
		g_triggerCtrlList[g_triggerListNum].triggerTaskFunc = tskf;
		rslt = g_triggerListNum;
		g_triggerListNum++;
	}
	else
	{
		printf("AddTriggerToList failed, g_triggerInited=%d, g_triggerListNum = %d, gap=%d\r\n", g_triggerInited, g_triggerListNum, gapms);
		rslt = -1;
	}

	return rslt;
}

void TriggerExTask(void)
{
	int i;
	if (g_triggerInited != 0)
	{
		for (i = 0; i < g_triggerListNum; i++)
		{
			if ((g_mstimer % g_triggerCtrlList[i].triggerTimer) == 0)
			{
				if (g_triggerCtrlList[i].triggerExFunc != NULL)
				{
					g_triggerCtrlList[i].triggerExFunc();
				}
				if (g_triggerCtrlList[i].triggerTaskFunc != NULL)
				{
					g_triggerCtrlList[i].triggerTask = 1;
					g_triggerTask = 1;
				}
			}
		}
	}
}

#if (TRIGGER_MAXTIM > 0)
// 定时触发任务
void TriggerTask(void)
{
	static int index = 0;
	int i = 0;
	if (g_triggerInited != 0 && g_triggerTask != 0)
	{
		u32 timer = GetUsSoftTimer();
		for (i = index; i < g_triggerListNum; i++)
		{
			if (g_triggerCtrlList[i].triggerTask != 0)
			{
				g_triggerCtrlList[i].triggerTask = 0;
				g_triggerCtrlList[i].triggerTaskFunc();
			}
			if (GetUsSoftTimer() - timer > TRIGGER_MAXTIM)
			{
				//printf("TriggerTask use > 1ms, break\r\n");
				i++;
				break;
			}
		}
		if (i >= g_triggerListNum)
		{
			i = 0;
		}
		index = i;
	}
}
#else
// 定时触发任务
void TriggerTask(void)
{
	int i;
	if (g_triggerInited != 0 && g_triggerTask != 0)
	{
		for (i = 0; i < g_triggerListNum; i++)
		{
			if (g_triggerCtrlList[i].triggerTask != 0)
			{
				g_triggerCtrlList[i].triggerTask = 0;
				g_triggerCtrlList[i].triggerTaskFunc();
			}
		}
	}
}
#endif

// 1ms 中断
void TriggerIntProc(void)
{
	g_mstimer++;
	TriggerExTask();
	if ((g_mstimer%TRIGGER_TIME) == 0)		// 每10ms执行一次
	{
		g_triggerTimer++;
		FeedIWDog();		// 喂看门狗
	}
}

u32 GetTickTimer(void)
{
	return SysTick->VAL;
}

// 得到时间计数, 单位100ns
u32 Get100NsSoftTimer(void)
{
	u32 val, stim, stim2;
	stim = g_mstimer;		// 读取
	val = SysTick->VAL;
	stim2 = g_mstimer;		// 再次读取
	if (stim != stim2)		// 如果不同, 说明中间产生了中断
	{
		val = SysTick->VAL;	// 重新读取
		stim = stim2;
	}

	return (stim + 1) * 10000 - ((val+1) / NS100_SYS_TICK);
}

// 得到时间计数, 单位1us
u32 GetUsSoftTimer(void)
{
	u32 volatile val, stim, stim2;
	stim = g_mstimer;		// 读取
	val = SysTick->VAL;
	stim2 = g_mstimer;		// 再次读取
	if (stim != stim2)		// 如果不同, 说明中间产生了中断
	{
		val = SysTick->VAL;	// 重新读取
		stim = stim2;
	}

	return (stim + 1) * 1000 - ((val+1) / US_SYS_TICK);
}

// 得到时间计数, 单位0.1ms
u32 Get100UsSoftTimer(void)
{
	u32 volatile val, stim, stim2;
	stim = g_mstimer;		// 读取
	val = SysTick->VAL;
	stim2 = g_mstimer;		// 再次读取
	if (stim != stim2)		// 如果不同, 说明中间产生了中断
	{
		val = SysTick->VAL;	// 重新读取
		stim = stim2;
	}
	return (stim + 1)* 10  - ((val+1) / US100_SYS_TICK);
}

// 得到时间计数, 单位1ms
u32 GetMsSoftTimer(void)
{
	return g_mstimer;
}

// 得到时间计数, 单位:1ms 精度:10ms
u32 GetMsSoftTimer10(void)
{
	return g_mstimer;
//	return g_triggerTimer*TRIGGER_TIME;
}
