#ifndef KEY_H__
#define KEY_H__
//#define KEY_PLATFORM_16BIT
#ifdef KEY_PLATFORM_16BIT
typedef unsigned char Key_uint8_t;
typedef unsigned int Key_uint16_t;
typedef unsigned long Key_uint32_t;
#else
typedef unsigned char Key_uint8_t;
typedef unsigned short Key_uint16_t;
typedef unsigned int Key_uint32_t;
typedef unsigned long long Key_uint64_t;
#endif
/*所有按键枚举*/
/*默认所有按键在任意电源状态下均可被触发*/
typedef enum
{
    KEY_UP   = 0U,
    KEY_DOWN,
    KEY_ENTER,
    KEY_RETURN,
    KEY_MENU,
    KEY_ODOTRIP,
	KEY_NUM_MAX,
} Key_Num_en_t;
/*--------------------------Do not modify the following--------------------------------*/
/*--------------------------Do not modify the following--------------------------------*/
/*--------------------------Do not modify the following--------------------------------*/
#define KEY_RAM_DATA_LEN (KEY_NUM_MAX * 16U + 24U)
typedef enum
{
	/*按键检测方式选择*/
	/*按键不需要消抖，并且在无效状态切换到有效状态的上升沿触发按键动作。
	一般用于CAN发送按键处理后状态时*/
	KEY_NO_DEBOUNCE_RISE = 0U,
	/*按键不需要消抖，并且在有效状态切换到无效状态的下降沿触发按键动作。
	一般用于CAN发送按键处理后状态时*/
	KEY_NO_DEBOUNCE_FALL,
	/*按键需要消抖，短按松手触发，长按按住即可触发。
	一般用于硬线按键，AD按键，CAN发送按键实时状态时*/
	KEY_NEED_DEBOUNCE_NORMAL,
	KEY_TYPE_MAX,
} Key_Type_en_t;
/*按键相关设置返回状态*/
typedef enum
{
	KEY_SET_OK = 0U,
	KEY_SET_ERROR,
	KEY_SET_MAX,
} Key_Set_en_t;
/*-----传入的按键状态--------*/
typedef enum
{
	/*当按键检测方式选择需要消抖时使用*/
	KEY_REALTIME_LOOSEN = 0U, /*按键松开*/
	KEY_REALTIME_PRESS,		  /*按键按下*/
	/*当按键检测方式选择不需要消抖时使用*/
	KEY_STATUS_IDLE,
	KEY_STATUS_SHORT_PRESS_1,
	KEY_STATUS_SHORT_PRESS_2,
	KEY_STATUS_LONG_PRESS_1,
	KEY_STATUS_LONG_PRESS_2,
	KEY_STATUS_LONG_PRESS_3,
	KEY_STATUS_LONG_PRESS_4,
	KEY_STATUS_MAX,
} Key_Status_en_t;
/*按键支持的具体动作*/
typedef enum
{
	KEY_EVENT_NONE = 0U, /***超时动作可在这个按键动作下自行计时触发**/
	/*以下按键动作都是单次触发，只有松手后才能再次触发*/
	KEY_EVENT_SHORT_PRESS_1,
	KEY_EVENT_SHORT_PRESS_2,
	KEY_EVENT_LONG_PRESS_1,
	KEY_EVENT_LONG_PRESS_2,
	KEY_EVENT_LONG_PRESS_3,
	KEY_EVENT_LONG_PRESS_4,
	/*OFF时才首先按下按键，然后不松手，之后切换到ON并持续一定时间后触发动作。*/
	KEY_EVENT_OFF_TO_ON,
	KEY_EVENT_ON_TO_OFF,
	KEY_EVENT_MAX,
} Key_Event_en_t;
/*按键IG状态*/
typedef enum
{
	KEY_IG_INVALID = 0U,/***无效的电源状态**/
	KEY_IG_OFF,
	KEY_IG_ON,
} Key_IGN_en_t;
typedef Key_Status_en_t (*Key_Status_Read)(void);
typedef void (*Key_Operation)(Key_Event_en_t enKeyEvent);
/*每个按键的属性*/
typedef struct
{
	/*按键检测方式选择*/
	Key_Type_en_t enKeyType;
	/*获取按键传入状态的回调函数*/
	Key_Status_Read pfnKeyReadStatusCallBack;
	/*按键触发动作的回调函数*/
	Key_Operation pfnKeyOperationCallBack;
} Key_Attribute_st_t;
typedef struct
{
	/*当前IG状态*/
	Key_IGN_en_t enKeyIGNRealStatus;
	/*按键数量，也就是KEY_NUM_MAX*/
	Key_uint8_t u8KeyNum;
} Key_Init_st_t;
/*--------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------*/
/*10ms调用一次*/
extern void Key_Service(void);
/*首次上电时调用.
默认短按1时间100ms~~1000ms，
默认短按2时间1100ms~~2000ms，
长按1时间2000ms，
长按2时间10000ms，
长按3时间30000ms，
长按4时间60000ms，
OFF下时间500ms，ON下时间500ms*/
extern void Key_KL30_Init(Key_uint8_t *pu8KyeRamData, const Key_Attribute_st_t *pstKeyAttribute, Key_Init_st_t *pstKeyInit);
/***确保传入的内存指针在休眠唤醒后不会丢失，那么可正常使用唤醒初始化函数。否是使用上述KL30初始化**/
extern void Key_Wakeup_Init(Key_uint8_t *pu8KyeRamData, const Key_Attribute_st_t *pstKeyAttribute, Key_Init_st_t *pstKeyInit);
/*对于消抖按键而言，判断短按的时间参数。
u16TimeMin :最小识别的时间   u16TimeMax：最大识别的时间 （不可大于短按2的最小识别时间）*/
extern Key_Set_en_t Key_Parameter_Set_Short_Press_1_Time(Key_uint16_t u16TimeMin, Key_uint16_t u16TimeMax);
/*对于消抖按键而言，判断短按2的时间参数。
u16TimeMin :最小识别的时间(不可小于短按1的最大识别时间)   u16TimeMax：最大识别的时间*/
extern Key_Set_en_t Key_Parameter_Set_Short_Press_2_Time(Key_uint16_t u16TimeMin, Key_uint16_t u16TimeMax);
/*对于消抖按键而言，判断长按1的时间参数。不可大于长按2的时间*/
extern Key_Set_en_t Key_Parameter_Set_Long_Press_1_Time(Key_uint16_t u16Time);
/*对于消抖按键而言，判断长按2的时间参数。不可小于长按1的时间，不可大于长按3的时间*/
extern Key_Set_en_t Key_Parameter_Set_Long_Press_2_Time(Key_uint16_t u16Time);
/*对于消抖按键而言，判断长按3的时间参数。不可小于长按2的时间，不可大于长按4的时间*/
extern Key_Set_en_t Key_Parameter_Set_Long_Press_3_Time(Key_uint16_t u16Time);
/*对于消抖按键而言，判断长按4的时间参数。不可小于长按3的时间*/
extern Key_Set_en_t Key_Parameter_Set_Long_Press_4_Time(Key_uint16_t u16Time);
/*设置电源状态给按键，单次调用或者多次调用均可*/
extern void Key_Set_IG_Status(Key_IGN_en_t enIGStatus);
#endif