
#include "Key.h"

/*------------------------------------------------------------------------------------------*/

/*---------------------------------------------------------------------*/

/*-----按键服务函数调用周期。单位ms--------*/
#define KEY_CALL_CYCLE 10U

/*-----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------*/
typedef struct
{
	uint16_t u16KeyShortPressTime;	   /*¶Ì°´¼ì²âÊ±¼ä*/
	uint16_t u16KeyLongPressTime;	   /*³¤°´¼ì²âÊ±¼ä*/
	uint16_t u16KeySuperLongPressTime; /*³¬³¤°´¼ì²âÊ±¼ä*/
	uint16_t u16KeyLoosenTime;		   /*ËÉ¿ª¼ì²âÊ±¼ä*/
	uint16_t u16KeyValidOFFTime;	   /*ÓÐÐ§OFF¼ì²âÊ±¼ä*/
	uint16_t u16KeyValidONTime;		   /*ÓÐÐ§ON¼ì²âÊ±¼ä*/

} Key_Parameter_st_t;

typedef struct
{
	Key_Real_Status_en_t enKeyTypeLast;
	uint16_t u16KeyInvalidTimeCount;
	uint16_t u16KeyValidTimeCount;
	uint16_t u16KeyFirstIGNTimeRecord;
	Key_IGN_en_t enKeyIGNFirstStatus;
	Key_IGN_en_t enKeyIGNStatusLast;
	uint8_t u8KeyIGNChangeFlag;
	uint16_t u16KeyIGNTimeCount;

} Key_Ctr_st_t;
/*------------------------------------------------------------------------------------------*/

#pragma ghs section bss = ".myNonInitArea"
static Key_Parameter_st_t stKeyParameter;
#pragma ghs section bss = default

static Key_Ctr_st_t stKeyCtrVariate[KEY_NUM_MAX];
//static Key_IGN_en_t enKeyIGNFirstStatus = KEY_IG_INVALID;
//static Key_IGN_en_t enKeyIGNStatusLast = KEY_IG_INVALID;
//static uint8_t u8KeyIGNChangeFlag = 0U;
//static uint16_t u16KeyIGNTimeCount;

/*-----------------------------------------------------------------------------------------*/
static void Key_Process(Key_Num_en_t enKeyIndex);
void Key_Service(void);
void Key_Init(void);
Key_Set_en_t Key_Parameter_Set_Short_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_Long_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_Super_Long_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_OFF_Press_Time(uint16_t u16Time);
Key_Set_en_t Key_Parameter_Set_ON_Press_Time(uint16_t u16Time);

/*-----------------------------------------------------*/
static void Key_Process(Key_Num_en_t enKeyIndex)
{
	if (enKeyIndex < KEY_NUM_MAX)
	{
		/*Key_Real_Status_en_t enKeyRealType = (*stKeyAttribute[enKeyIndex].penKeyRealStatus);*/
		Key_Real_Status_en_t enKeyRealType = KEY_CAN_NONE;
		Key_IGN_en_t enKeyIGNRealStatus = Key_Get_IGN_Status();

		if (stKeyAttribute[enKeyIndex].pfnKeyReadStatusCallBack != 0U)
		{
			enKeyRealType = stKeyAttribute[enKeyIndex].pfnKeyReadStatusCallBack();
		}
		/*CAN°´¼ü*/
		if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NO_DEBOUNCE_RISE)
		{
			if (enKeyRealType <= KEY_CAN_LONG_PRESS_NOT_RELEASE)
			{
				if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
				{
					if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) &&
						(enKeyRealType == KEY_CAN_SHORT_PRESS))
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS);
					}
					else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) &&
							 (enKeyRealType == KEY_CAN_LONG_PRESS))
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
					}
					else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_NONE) &&
							 (enKeyRealType == KEY_CAN_LONG_PRESS_NOT_RELEASE))
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS);
					}
					else
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_NONE);
					}
				}

				stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType;
			}
			else
			{
				stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_CAN_NONE;
			}
		}
		else if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NO_DEBOUNCE_FALL)
		{
			if (enKeyRealType <= KEY_CAN_LONG_PRESS_NOT_RELEASE)
			{
				if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
				{
					if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_SHORT_PRESS) &&
						(enKeyRealType == KEY_CAN_NONE))
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS);
					}
					else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_LONG_PRESS) &&
							 (enKeyRealType == KEY_CAN_NONE))
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
					}
					else if ((stKeyCtrVariate[enKeyIndex].enKeyTypeLast == KEY_CAN_LONG_PRESS_NOT_RELEASE) &&
							 (enKeyRealType == KEY_CAN_NONE))
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS);
					}
					else
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_NONE);
					}
				}

				stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType;
			}
			else
			{
				stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_CAN_NONE;
			}
		}
		/*Ó²Ïß°´¼ü*/
		else if (stKeyAttribute[enKeyIndex].enKeyType == KEY_NEED_DEBOUNCE_NORMAL)
		{
			if (enKeyRealType == KEY_LINE_LOOSEN) /*空闲*/
			{
				if (stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount <= stKeyParameter.u16KeyLoosenTime)
				{
					stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount += KEY_CALL_CYCLE;
				}
				else
				{
					stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
					stKeyCtrVariate[enKeyIndex].enKeyTypeLast = KEY_LINE_LOOSEN;
					stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
					stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus = KEY_IG_INVALID;
					stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = KEY_IG_INVALID;
					stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag = 0U;
					stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U;
				}
				if ((stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount >= stKeyParameter.u16KeyLoosenTime) &&
					(stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime) &&
					(stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount < stKeyParameter.u16KeyLongPressTime))
				{
					stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
					/* call back */
					if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
					{
						stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SHORT_PRESS);
					}
				}
			}
			else if (enKeyRealType == KEY_LINE_PRESS) /*按键按下*/
			{
				if (stKeyCtrVariate[enKeyIndex].enKeyTypeLast != enKeyRealType)
				{
					stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
					stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
					stKeyCtrVariate[enKeyIndex].enKeyTypeLast = enKeyRealType;
					stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U;

					stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus = enKeyIGNRealStatus;

					stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = enKeyIGNRealStatus;
				}
				else
				{
					if (stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast != enKeyIGNRealStatus)
					{
						stKeyCtrVariate[enKeyIndex].enKeyIGNStatusLast = enKeyIGNRealStatus;
						if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus != enKeyIGNRealStatus)
						{
							stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount;
						}

						stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount = 0U;
					}
					else
					{
						if (stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount < 0xFFF0U)
						{
							stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount += KEY_CALL_CYCLE;
						}
					}

					if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount < 0xFFF0U)
					{
						stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount += KEY_CALL_CYCLE;
					}
					if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus != enKeyIGNRealStatus)
					{
						stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag = 1U;
					}

					if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyShortPressTime)
					{
						stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U;
					}
					if (stKeyCtrVariate[enKeyIndex].u8KeyIGNChangeFlag == 0U)
					{
						if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeySuperLongPressTime)
						{
							if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
							{
								stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_SUPER_LONG_PRESS);
							}
						}
						else if (stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount >= stKeyParameter.u16KeyLongPressTime)
						{
							if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
							{
								stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_LONG_PRESS);
							}
						}
					}
					else
					{
						if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus == KEY_IG_OFF)
						{
							if (enKeyIGNRealStatus == KEY_IG_ON)
							{
								if ((stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord >= stKeyParameter.u16KeyValidOFFTime) &&
									(stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount >= stKeyParameter.u16KeyValidONTime))
								{
									if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
									{
										stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_OFF_TO_ON);
									}
									stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
								}
							}
						}
						else if (stKeyCtrVariate[enKeyIndex].enKeyIGNFirstStatus == KEY_IG_ON)
						{
							if (enKeyIGNRealStatus == KEY_IG_OFF)
							{
								if ((stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord >= stKeyParameter.u16KeyValidONTime) &&
									(stKeyCtrVariate[enKeyIndex].u16KeyIGNTimeCount >= stKeyParameter.u16KeyValidOFFTime))
								{
									if (stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack != 0U)
									{
										stKeyAttribute[enKeyIndex].pfnKeyOperationCallBack(KEY_EVENT_ON_TO_OFF);
									}
									stKeyCtrVariate[enKeyIndex].u16KeyFirstIGNTimeRecord = 0U;
								}
							}
						}
					}
				}
			}
			else
			{
				/*ERROR*/
				stKeyCtrVariate[enKeyIndex].u16KeyInvalidTimeCount = 0U;
				stKeyCtrVariate[enKeyIndex].u16KeyValidTimeCount = 0U;
				stKeyCtrVariate[enKeyIndex].enKeyTypeLast = (Key_Real_Status_en_t)0U;
			}
		}
		else
		{
		}
	}
}
/*10ms调用一次*/
void Key_Service(void)
{
	uint8_t i = 0U;
	for (i = 0U; i < KEY_NUM_MAX; i++)
	{
		Key_Process((Key_Num_en_t)i); /*Key_Num_en_t*/
	}
}
/*首次上电时调用一次即可*/
void Key_Init(void)
{
	uint8_t i = 0U;
	for (i = 0U; i < KEY_NUM_MAX; i++)
	{
		stKeyCtrVariate[i].enKeyTypeLast = KEY_CAN_NONE;
		stKeyCtrVariate[i].u16KeyInvalidTimeCount = 0U;
		stKeyCtrVariate[i].u16KeyValidTimeCount = 0U;
		stKeyCtrVariate[i].u16KeyFirstIGNTimeRecord = 0U;
		stKeyCtrVariate[i].enKeyIGNFirstStatus = KEY_IG_INVALID;
		stKeyCtrVariate[i].enKeyIGNStatusLast = KEY_IG_INVALID;
		stKeyCtrVariate[i].u8KeyIGNChangeFlag = 0U;
		stKeyCtrVariate[i].u16KeyIGNTimeCount = 0U;
	}
	stKeyParameter.u16KeyLoosenTime = 50U;
	stKeyParameter.u16KeyShortPressTime = 40U;
	stKeyParameter.u16KeyLongPressTime = 2000U;
	stKeyParameter.u16KeySuperLongPressTime = 30000U;
	stKeyParameter.u16KeyValidOFFTime = 200U;/*按键动作时间*/
	stKeyParameter.u16KeyValidONTime = 1000U;
}
/*对于硬线按键而言，判断短按的时间参数*/
Key_Set_en_t Key_Parameter_Set_Short_Press_Time(uint16_t u16Time)
{
	Key_Set_en_t enKeySetResult = KEY_SET_OK;
	if (u16Time < stKeyParameter.u16KeyLoosenTime)
	{
		enKeySetResult = KEY_SET_ERROR;
	}
	else if (u16Time > stKeyParameter.u16KeyLongPressTime)
	{
		enKeySetResult = KEY_SET_ERROR;
	}
	else
	{
		stKeyParameter.u16KeyShortPressTime = u16Time;
	}

	return enKeySetResult;
}
/*对于硬线按键而言，判断长按的时间参数*/
Key_Set_en_t Key_Parameter_Set_Long_Press_Time(uint16_t u16Time)
{
	Key_Set_en_t enKeySetResult = KEY_SET_OK;
	if (u16Time < stKeyParameter.u16KeyShortPressTime)
	{
		enKeySetResult = KEY_SET_ERROR;
	}
	else if (u16Time > stKeyParameter.u16KeySuperLongPressTime)
	{
		enKeySetResult = KEY_SET_ERROR;
	}
	else
	{
		stKeyParameter.u16KeyLongPressTime = u16Time;
	}
	return enKeySetResult;
}
/*对于硬线按键而言，判断超长按的时间参数*/
Key_Set_en_t Key_Parameter_Set_Super_Long_Press_Time(uint16_t u16Time)
{
	Key_Set_en_t enKeySetResult = KEY_SET_OK;
	if (u16Time < stKeyParameter.u16KeyLongPressTime)
	{
		enKeySetResult = KEY_SET_ERROR;
	}
	else
	{
		stKeyParameter.u16KeySuperLongPressTime = u16Time;
	}
	return enKeySetResult;
}
