LL01/code_app_out/Source/module/keyboard/key_digital_driver.c
2025-04-26 16:03:23 +08:00

698 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*****************************************************************************
** Filename : keyboard_drive.c
** Project :
** Module :
** Processor : Freescale S12Z
** Date/Time : 2019-09-04, 9:00
** Abstract :
** Contents :
** Author : mingyea
** http :
** mail :
** --------------------------------------------------------------------------
**
** --------------------------------------------------------------------------
******************************************************************************/
#include "common_types.h"
#include "common_memory.h"
#include "key_digital_driver.h"
/*****************************************************************************
* Include Files
*****************************************************************************/
/*****************************************************************************
* Defines
*****************************************************************************/
/*****************************************************************************
* Macros
*****************************************************************************/
/*****************************************************************************
* Type Defines
*****************************************************************************/
/*****************************************************************************
*Static Variable
*****************************************************************************/
/*****************************************************************************
*Global Variable
*****************************************************************************/
/*****************************************************************************
*Constant
*****************************************************************************/
/*****************************************************************************
*Function Prototype
*****************************************************************************/
static key_digital_driver_s g_key_digital_driver;
static void key_digital_driver_alone_checkio(u8 id);
static void key_digital_driver_alone_up_task(u8 id);
static void key_digital_driver_alone_task(u8 id);
static void key_digital_driver_alone_shortdown_task(u8 id);
static void key_digital_driver_alone_longdown_task(u8 id);
static void key_digital_driver_alone_stick_task(u8 id);
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None
|Output parameters : None
|Return value : None
|Description :
*****************************************************************************/
void key_digital_driver_init(void)
{
u8 i;
key_digital_driver_cfg_init();
common_memory_clear((u8*)&g_key_digital_driver,sizeof(g_key_digital_driver));
for(i = 0; i < KEY_DIGITAL_DRIVER_KEY_TOTAL; i++)
{
g_key_digital_driver.digital_key[i].event = KEY_DIGITAL_EVENT_NULL;
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 越界保護由key_digital_driver_alone_task來保證
*****************************************************************************/
static void key_digital_driver_alone_checkio(u8 id)
{
u8 l_ret;
const key_digital_driver_cfg_tab_s *p_key_table;
p_key_table = (const key_digital_driver_cfg_tab_s*)&g_key_digital_driver_cfg_tab[id];
#ifdef KEY_DIGITAL_DRIVER_DEBUG
l_ret = key_digital_driver_cfg_debug_read_pin(id);
#else
l_ret = gpio_read_pin_input(p_key_table->gpio_base,p_key_table->pin_id);
#endif
g_key_digital_driver.digital_key[id].phy_cur_level = l_ret;
if(l_ret == (u8)(p_key_table->valid_level))
{
g_key_digital_driver.digital_key[id].logic_cur_level = 1u;
}
else
{
g_key_digital_driver.digital_key[id].logic_cur_level = 0u;
}
//變化時,計時清零
if(g_key_digital_driver.digital_key[id].phy_cur_level != g_key_digital_driver.digital_key[id].phy_pre_level)
{
g_key_digital_driver.digital_key[id].timecount = 0u;
}
g_key_digital_driver.digital_key[id].timecount++;
g_key_digital_driver.digital_key[id].phy_pre_level = g_key_digital_driver.digital_key[id].phy_cur_level;
g_key_digital_driver.digital_key[id].logic_pre_level = g_key_digital_driver.digital_key[id].logic_cur_level;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 越界保護由key_digital_driver_alone_task來保證
*****************************************************************************/
static void key_digital_driver_alone_up_task(u8 id)
{
//key_digital_driver_cfg_tab_s *p_key_table;
//p_key_table = (key_digital_driver_cfg_tab_s*)&g_key_digital_driver_cfg_tab[id];
#ifdef KEY_DIGITAL_INIT_INVALID
if(KEY_DIGITAL_DRIVER_SUBSTATE_UP == g_key_digital_driver.digital_key[id].sub_state)
#else
if(1)
#endif
{
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].debounce_time)//g_key_cfg_times[KEY_DIGITAL_DITHERING_TIME_ID]) //p_key_table->debounce_time
{
//g_key_digital_driver.digital_key[id].timecount=0u;
if(g_key_digital_driver.digital_key[id].logic_cur_level!=0u) //邏輯有效
{
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_INIT;
g_key_digital_driver.digital_key[id].state = KEY_DIGITAL_DRIVER_STATE_SHORT_DOWN;
g_key_digital_driver.digital_key[id].event |= KEY_DIGITAL_EVENT_PRESSED;
}
else
{
//g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_UP;
}
}
}
else
{
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].debounce_time)//g_key_cfg_times[KEY_DIGITAL_DITHERING_TIME_ID]) /*PRQA S 2880*/ /*KEY_DIGITAL_INIT_INVALID关闭了*/
{
g_key_digital_driver.digital_key[id].timecount=0u;
if(g_key_digital_driver.digital_key[id].logic_cur_level!=0u) //邏輯有效
{
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_ERROR;
}
else
{
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_UP;
}
}
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 越界保護由key_digital_driver_alone_task來保證
*****************************************************************************/
static void key_digital_driver_alone_shortdown_task(u8 id)
{
//key_digital_driver_cfg_tab_s *p_key_table;
//p_key_table = (key_digital_driver_cfg_tab_s*)&g_key_digital_driver_cfg_tab[id];
if(g_key_digital_driver.digital_key[id].logic_cur_level!=0u) //邏輯有效
{
//長按有效
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].long_down_time)//g_key_cfg_times[KEY_DIGITAL_LONGDOWN_TIMEOUT_ID])
{
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_INIT;
g_key_digital_driver.digital_key[id].state = KEY_DIGITAL_DRIVER_STATE_LONG_DOWN;
g_key_digital_driver.digital_key[id].event |= KEY_DIGITAL_EVENT_LONG_DOWN;
}
}
else
{
//彈起
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].debounce_time)//g_key_cfg_times[KEY_DIGITAL_DITHERING_TIME_ID])
{
g_key_digital_driver.digital_key[id].timecount=0u;
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_UP;
g_key_digital_driver.digital_key[id].state = KEY_DIGITAL_DRIVER_STATE_UP;
g_key_digital_driver.digital_key[id].event = KEY_DIGITAL_EVENT_RELEASE;
g_key_digital_driver.digital_key[id].event |= KEY_DIGITAL_EVENT_SHORT_DOWN_RELEASE;
}
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 越界保護由key_digital_driver_alone_task來保證
*****************************************************************************/
static void key_digital_driver_alone_longdown_task(u8 id)
{
//key_digital_driver_cfg_tab_s *p_key_table;
//p_key_table = (key_digital_driver_cfg_tab_s*)&g_key_digital_driver_cfg_tab[id];
if(g_key_digital_driver.digital_key[id].logic_cur_level!=0u) //邏輯有效
{
//卡住有效
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].stick_time)//g_key_cfg_times[KEY_DIGITAL_STUCK_TIMEOUT_ID])
{
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_INIT;
g_key_digital_driver.digital_key[id].state = KEY_DIGITAL_DRIVER_STATE_STICK;
}
}
else
{
//彈起
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].debounce_time)//g_key_cfg_times[KEY_DIGITAL_DITHERING_TIME_ID])
{
g_key_digital_driver.digital_key[id].timecount=0u;
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_UP;
g_key_digital_driver.digital_key[id].state = KEY_DIGITAL_DRIVER_STATE_UP;
g_key_digital_driver.digital_key[id].event = KEY_DIGITAL_EVENT_RELEASE;
}
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 越界保護由key_digital_driver_alone_task來保證
*****************************************************************************/
static void key_digital_driver_alone_stick_task(u8 id)
{
//key_digital_driver_cfg_tab_s *p_key_table;
//p_key_table = (key_digital_driver_cfg_tab_s*)&g_key_digital_driver_cfg_tab[id];
if(g_key_digital_driver.digital_key[id].logic_cur_level!=0u) //邏輯有效
{
//卡住有效
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].stick_time)//g_key_cfg_times[KEY_DIGITAL_STUCK_TIMEOUT_ID])
{
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_INIT;
g_key_digital_driver.digital_key[id].state = KEY_DIGITAL_DRIVER_STATE_STICK;
}
}
else
{
//彈起
if(g_key_digital_driver.digital_key[id].timecount>=g_key_digital_driver_cfg_tab[id].debounce_time)//g_key_cfg_times[KEY_DIGITAL_DITHERING_TIME_ID])
{
g_key_digital_driver.digital_key[id].timecount=0u;
g_key_digital_driver.digital_key[id].sub_state=KEY_DIGITAL_DRIVER_SUBSTATE_UP;
g_key_digital_driver.digital_key[id].state = KEY_DIGITAL_DRIVER_STATE_UP;
}
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description :
*****************************************************************************/
static void key_digital_driver_alone_task(u8 id)
{
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
key_digital_driver_alone_checkio(id);
switch(g_key_digital_driver.digital_key[id].state)
{
case KEY_DIGITAL_DRIVER_STATE_UP:
key_digital_driver_alone_up_task(id);
break;
case KEY_DIGITAL_DRIVER_STATE_SHORT_DOWN:
key_digital_driver_alone_shortdown_task(id);
break;
case KEY_DIGITAL_DRIVER_STATE_LONG_DOWN:
key_digital_driver_alone_longdown_task(id);
break;
case KEY_DIGITAL_DRIVER_STATE_STICK:
key_digital_driver_alone_stick_task(id);
break;
default:
break;
}
//消抖後的按鍵狀態變化;
if(g_key_digital_driver.digital_key[id].pre_state != g_key_digital_driver.digital_key[id].state)
{
g_key_digital_driver.digital_key[id].state_change=1u;
if( (g_key_digital_driver.digital_key[id].state ==KEY_DIGITAL_DRIVER_STATE_SHORT_DOWN)
|| (g_key_digital_driver.digital_key[id].state ==KEY_DIGITAL_DRIVER_STATE_UP) )
{
g_key_digital_driver.digital_key[id].change =1u;
}
}
else
{
g_key_digital_driver.digital_key[id].state_change=0u;
g_key_digital_driver.digital_key[id].change =0u;
}
g_key_digital_driver.digital_key[id].pre_state = g_key_digital_driver.digital_key[id].state;
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None
|Output parameters : None
|Return value : None
|Description :
*****************************************************************************/
void key_digital_driver_normal_task(void)
{
u8 i;
for(i = 0u; i < KEY_DIGITAL_DRIVER_KEY_TOTAL; i ++)
{
key_digital_driver_alone_task(i);
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的狀態
*****************************************************************************/
key_digital_driver_state_e key_digital_driver_get_state(u8 id)
{
key_digital_driver_state_e l_state;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_state = g_key_digital_driver.digital_key[id].state;
}
else
{
l_state= KEY_DIGITAL_DRIVER_STATE_UP; //越界就是,無效
}
return l_state;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的狀態
*****************************************************************************/
key_digital_driver_state_e key_digital_driver_get_event(u8 id)
{
key_digital_driver_state_e l_state;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_state = g_key_digital_driver.digital_key[id].event;
}
else
{
l_state= KEY_DIGITAL_EVENT_NULL; //越界就是,無效
}
g_key_digital_driver.digital_key[id].event = KEY_DIGITAL_EVENT_NULL;
return l_state;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的物理電平
*****************************************************************************/
u8 key_digital_driver_get_phy_level(u8 id)
{
u8 l_level;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_level = g_key_digital_driver.digital_key[id].phy_cur_level;
}
else
{
l_level= (u8)GPIO_LEVEL_LOW;
}
return l_level;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的物理電平
*****************************************************************************/
u8 key_digital_driver_get_logic_level(u8 id)
{
u8 l_level;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_level = g_key_digital_driver.digital_key[id].logic_cur_level;
}
else
{
l_level =0u;
}
return l_level;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的變化,注意,要馬上處理,下一周期就無變化了, 一般用于按键从无效到有效。或者从有效到无效,且消抖后。
*****************************************************************************/
u8 key_digital_driver_get_change(u8 id)
{
u8 l_change;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_change = g_key_digital_driver.digital_key[id].change;
}
else
{
l_change = 0u;
}
return l_change;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的變化,注意,要馬上處理,下一周期就無變化了, 一般用于按键从无效到有效。或者从有效到无效,且消抖后。
*****************************************************************************/
u8 key_digital_driver_get_state_change(u8 id)
{
u8 l_change;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_change = g_key_digital_driver.digital_key[id].state_change;
}
else
{
l_change = 0u;
}
return l_change;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的計時一般配合state一起使用
*****************************************************************************/
key_digital_key_tim_t key_digital_driver_get_timecount(u8 id)
{
key_digital_key_tim_t l_timecount;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_timecount = g_key_digital_driver.digital_key[id].timecount;
}
else
{
l_timecount= KEY_DIGITAL_DRIVER_DEBOUNCE_INIT;
}
return l_timecount;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 进入sleep前要做的事情;---把数据
*****************************************************************************/
void key_digital_driver_goto_sleep(void)
{
u8 i;
//再次记录 上次值和当前值,保持一致
for(i=0u;i<KEY_DIGITAL_DRIVER_KEY_TOTAL;i++)
{
g_key_digital_driver.digital_key[i].phy_pre_level = g_key_digital_driver.digital_key[i].phy_cur_level;
g_key_digital_driver.digital_key[i].logic_pre_level = g_key_digital_driver.digital_key[i].logic_cur_level;
g_key_digital_driver.digital_key[i].state = KEY_DIGITAL_DRIVER_STATE_UP;
g_key_digital_driver.digital_key[i].pre_state = g_key_digital_driver.digital_key[i].state;
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 进入sleep前要做的事情;---把数据
*****************************************************************************/
void key_digital_driver_goto_wakeup(void)
{
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的物理電平,上次的。 为了减少执行时间,不判断越界
*****************************************************************************/
u8 key_digital_driver_get_phy_pre_quick(u8 id)
{
return g_key_digital_driver.digital_key[id].phy_pre_level;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 轻量级扫描,只在进入休眠后;
*****************************************************************************/
void key_digital_driver_quick_scan(void)
{
u8 l_ret;
u8 i;
const key_digital_driver_cfg_tab_s *p_key_table;
for(i=0u;i<KEY_DIGITAL_DRIVER_KEY_TOTAL;i++)
{
p_key_table = (const key_digital_driver_cfg_tab_s*)&g_key_digital_driver_cfg_tab[i];
#ifdef KEY_DIGITAL_DRIVER_DEBUG
l_ret = key_digital_driver_cfg_debug_read_pin(i);
#else
l_ret = gpio_read_pin_input(p_key_table->gpio_base,p_key_table->pin_id);
#endif
g_key_digital_driver.digital_key[i].phy_cur_level = l_ret;
#if 1
if(l_ret == (u8)(p_key_table->valid_level))
{
g_key_digital_driver.digital_key[i].logic_cur_level = (u8)KEY_DIGITAL_DRIVER_LOGIC_VALID;
}
else
{
g_key_digital_driver.digital_key[i].logic_cur_level = (u8)KEY_DIGITAL_DRIVER_LOGIC_INIT;
}
#endif
}
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 轻量级判斷,是否按鍵有變化; 0表示沒有變化1表示有變化
*****************************************************************************/
key_digital_driver_diff_e key_digital_driver_judge_diff_wakeup(void)
{
u8 i;
key_digital_driver_diff_e l_result =KEY_DIGITAL_DRIVER_DIFF_NULL;
for(i=0u;i<KEY_DIGITAL_DRIVER_KEY_TOTAL;i++)
{
if(g_key_digital_driver.digital_key[i].phy_cur_level != g_key_digital_driver.digital_key[i].phy_pre_level)
{
l_result=KEY_DIGITAL_DRIVER_DIFF_SURE;
break;
}
}
return l_result;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 判斷,是否按鍵有真正的,有效按下
*****************************************************************************/
key_digital_driver_diff_e key_digital_driver_judge_state_wakeup(void)
{
u8 i;
key_digital_driver_diff_e l_result =KEY_DIGITAL_DRIVER_DIFF_NULL;
for(i=0u;i<KEY_DIGITAL_DRIVER_KEY_TOTAL;i++)
{
//if(g_key_digital_driver.digital_key[i].state != KEY_DIGITAL_DRIVER_STATE_UP)
if(g_key_digital_driver.digital_key[i].logic_cur_level == 1u)
{
l_result=KEY_DIGITAL_DRIVER_DIFF_SURE;
break;
}
}
return l_result;
}
/*****************************************************************************
|Prototype :
|Called by :
|Preconditions : -
|Input parameters : None id 是邏輯id
|Output parameters : None
|Return value : None
|Description : 回讀按鍵的物理電平;休眠之前的,用于于唤醒时,比较,是否有变化
*****************************************************************************/
u8 key_digital_driver_get_phy_pre_level(u8 id)
{
u8 l_level;
if(id<KEY_DIGITAL_DRIVER_KEY_TOTAL)
{
l_level = g_key_digital_driver.digital_key[id].phy_pre_level;
}
else
{
#if 0
if(g_key_digital_driver_cfg_tab[id].valid_level==GPIO_LEVEL_LOW)
{
l_level= (u8)GPIO_LEVEL_HIGH; //越界就是,配置的無效電平
}
else
{
l_level= (u8)GPIO_LEVEL_LOW;
}
#else
l_level= (u8)GPIO_LEVEL_LOW;
#endif
}
return l_level;
}