Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
216
sdk/lib/key/keyScan.c
Normal file
216
sdk/lib/key/keyScan.c
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "keyScan.h"
|
||||
|
||||
/*************************************************************************************
|
||||
* 按键扫描判断的timer事件
|
||||
* 最终调用key_scan_init来注册事件
|
||||
*
|
||||
*
|
||||
**************************************************************************************/
|
||||
static void g_key_scan(key_channel_t *ch)
|
||||
{
|
||||
const keys_t *arg = ch->key_arg;
|
||||
uint8 key = ch->scan(ch);
|
||||
uint8 key_code = KEY_EVENT_MAX;
|
||||
uint8 key_event = KEY_EVENT_MAX;
|
||||
|
||||
//分析按键情况
|
||||
//按键可能被释放或者说原本就是没有被按下
|
||||
if(key == 0)
|
||||
{
|
||||
//按键没有被按下,无需去管理
|
||||
if(ch->last_key == 0)
|
||||
{
|
||||
goto g_key_scan_end;
|
||||
}
|
||||
|
||||
//按键从被按下到释放,反馈事件,有两种可能:短按释放,长按释放,异常情况则是(消抖没有完成就被释放)
|
||||
else
|
||||
{
|
||||
|
||||
//异常事件,正常不可能存在,检查程序,可能存在按键抖动情况,不作任何判断
|
||||
if(ch->last_event == KEY_EVENT_MAX)
|
||||
{
|
||||
//printf("%s:%d err,last key:%d,now key:%d\tlast_event:%d\n",__FUNCTION__,__LINE__,ch->last_key,key,ch->last_event );
|
||||
//printf("last time:%d\tnow time:%d\n",ch->last_time,os_jiffies());
|
||||
}
|
||||
else if(ch->last_event == KEY_EVENT_LDOWN || ch->last_event == KEY_EVENT_REPEAT)
|
||||
{
|
||||
ch->last_event = KEY_EVENT_MAX;
|
||||
key_event = KEY_EVENT_LUP;
|
||||
key_code = ch->last_key;
|
||||
}
|
||||
else if(ch->last_event == KEY_EVENT_DOWN)
|
||||
{
|
||||
ch->last_event = KEY_EVENT_MAX;
|
||||
key_event = KEY_EVENT_SUP;
|
||||
key_code = ch->last_key;
|
||||
}
|
||||
ch->last_key = key;
|
||||
}
|
||||
}
|
||||
|
||||
//有多种情况,key与last key不一样,分两种情况,按键抖动(相隔的时间太短),则以后面的key为准,并且时间清0,另一种则是按键检测的时候,错过了up的事件(因为用软定时,有可能错过,这个时候应该发出一个up事件,但也有可能按键接触不良,可以先发出up事件,key当作没有,等待下次的key再去判断)
|
||||
else
|
||||
{
|
||||
|
||||
//同样按键,判断时间超出按键抖动范围,如果是,则发出被按下事件
|
||||
if(key == ch->last_key)
|
||||
{
|
||||
//上一次没有事件,则是消抖时间完成,发出按键按下事件
|
||||
if(ch->last_event == KEY_EVENT_MAX)
|
||||
{
|
||||
if(os_jiffies() - ch->last_time > arg->period_dither)
|
||||
{
|
||||
ch->last_event = KEY_EVENT_DOWN;
|
||||
key_event = KEY_EVENT_DOWN;
|
||||
key_code = ch->last_key;
|
||||
//无需更新时间,下一次则进入去判断是否长按
|
||||
ch->last_time = os_jiffies();
|
||||
|
||||
}
|
||||
//消抖时间没有完成
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
//上一次已经有down的事件,则需要继续判断后续的事件(是否为长按或者重复按键)
|
||||
else
|
||||
{
|
||||
|
||||
//短按,超过长按的时间,发出长按被按下的事件
|
||||
if(ch->last_event == KEY_EVENT_DOWN )
|
||||
{
|
||||
if(os_jiffies() - ch->last_time > arg->period_long)
|
||||
{
|
||||
//长按事件被按下
|
||||
ch->last_event = KEY_EVENT_LDOWN;
|
||||
key_event = KEY_EVENT_LDOWN;
|
||||
key_code = ch->last_key;
|
||||
//用于判断是否是重复按键
|
||||
ch->last_time = os_jiffies();
|
||||
}
|
||||
//不是长按,还在等待时间
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ch->last_event == KEY_EVENT_LDOWN || ch->last_event == KEY_EVENT_REPEAT)
|
||||
{
|
||||
if(os_jiffies() - ch->last_time > arg->period_repeat)
|
||||
{
|
||||
ch->last_event = KEY_EVENT_REPEAT;
|
||||
key_event = KEY_EVENT_REPEAT;
|
||||
key_code = ch->last_key;
|
||||
//用于判断下一次判断
|
||||
ch->last_time = os_jiffies();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os_printf("%s:%d err,last key:%d,now key:%d\tlast_event:%d\n",__FUNCTION__,__LINE__,ch->last_key,key,ch->last_event );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//刚被按下,则记录时间,等待抖动结束
|
||||
if(!ch->last_key)
|
||||
{
|
||||
ch->last_time = os_jiffies();
|
||||
ch->last_key = key;
|
||||
}
|
||||
|
||||
//两次按键不一致,那么就要去识别事件,如果last_event没有事件,代表消抖没有完成,则重新计算时间,如果消抖完成,则需要发出up事件,last_key = 0
|
||||
else if(ch->last_key != key)
|
||||
{
|
||||
//消抖没有完成,更新按键的值
|
||||
if(ch->last_event == KEY_EVENT_MAX)
|
||||
{
|
||||
ch->last_time = os_jiffies();
|
||||
ch->last_key = key;
|
||||
}
|
||||
//消抖完成,发出up事件,然后last_key设置为0,等待下次按键判断
|
||||
else
|
||||
{
|
||||
if(ch->last_event == KEY_EVENT_LDOWN || ch->last_event == KEY_EVENT_REPEAT)
|
||||
{
|
||||
ch->last_event = KEY_EVENT_MAX;
|
||||
key_event = KEY_EVENT_LUP;
|
||||
key_code = ch->last_key;
|
||||
}
|
||||
else if(ch->last_event == KEY_EVENT_DOWN)
|
||||
{
|
||||
ch->last_event = KEY_EVENT_MAX;
|
||||
key_event = KEY_EVENT_SUP;
|
||||
key_code = ch->last_key;
|
||||
ch->last_time = os_jiffies();
|
||||
}
|
||||
ch->last_key = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_key_scan_end:
|
||||
if(key_event != KEY_EVENT_MAX)
|
||||
{
|
||||
// key_map_t *map = ch->key_table_map;
|
||||
//uint32 map_msg = map[key_code][key_event];
|
||||
uint32 map_msg = (key_code<<8 | key_event);
|
||||
if(map_msg && ch->key_send)
|
||||
{
|
||||
ch->key_send(map_msg,ch->extern_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//timer事件
|
||||
static void key_auto_timer_cb(void *arg)
|
||||
{
|
||||
key_channel_t **channel = (key_channel_t **)arg;
|
||||
key_channel_t **ch;
|
||||
for (ch = &channel[0]; *ch; ++ch)
|
||||
{
|
||||
if(!(*ch)->enable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if((*ch)->prepare)
|
||||
{
|
||||
(*ch)->prepare(*ch);
|
||||
}
|
||||
if((*ch)->scan)
|
||||
{
|
||||
g_key_scan(*ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static os_timer_t key_timer;
|
||||
//先初始化,然后注册timer,注册按键的映射表,最后启动timer
|
||||
void key_button_scan_init(key_channel_t **channel,key_send_msg send)
|
||||
{
|
||||
key_channel_t **ch = channel;
|
||||
for (; *ch; ++ch)
|
||||
{
|
||||
(*ch)->last_event = KEY_EVENT_MAX;
|
||||
(*ch)->last_key = KEY_EVENT_MAX;
|
||||
(*ch)->last_time = os_jiffies();
|
||||
(*ch)->key_send = send;
|
||||
if((*ch)->init)
|
||||
{
|
||||
(*ch)->init(*ch);
|
||||
}
|
||||
}
|
||||
os_timer_init(&key_timer, key_auto_timer_cb, OS_TIMER_MODE_PERIODIC, (void*)channel);
|
||||
os_timer_start(&key_timer, 5);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user