169 lines
4.2 KiB
C
169 lines
4.2 KiB
C
|
|
#include "sys_config.h"
|
||
|
|
#include "typesdef.h"
|
||
|
|
#include "osal/string.h"
|
||
|
|
#include "osal/msgqueue.h"
|
||
|
|
#include "osal/work.h"
|
||
|
|
#include "osal/string.h"
|
||
|
|
#include "keyWork.h"
|
||
|
|
#include "keyScan.h"
|
||
|
|
#include "adkey.h"
|
||
|
|
#include "power_checkkey.h"
|
||
|
|
#include "csi_kernel.h"
|
||
|
|
/*****************************************
|
||
|
|
* 按照不同按键,请注册对应按键进来,参看adkey.c
|
||
|
|
*
|
||
|
|
*
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* adkey或者ioKey或者touchkey
|
||
|
|
* 添加多个的例子
|
||
|
|
* static key_channel_t *button_channels[] = {&adkey_key,&powercheck_key,NULL};
|
||
|
|
*****************************************/
|
||
|
|
|
||
|
|
static key_channel_t *button_channels[] = {&adkey_key,NULL};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//添加其他不同类型的按键头文件
|
||
|
|
static void *g_key_msgq = NULL;
|
||
|
|
static struct list_head wait_register_list;
|
||
|
|
static struct list_head register_list;
|
||
|
|
static uint8_t key_callback_change = 0;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
void *add_keycallback(key_callback callback,void *priv)
|
||
|
|
{
|
||
|
|
struct key_callback_list_s *add_list = os_zalloc(sizeof(struct key_callback_list_s));
|
||
|
|
if(!add_list)
|
||
|
|
{
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
add_list->priv = priv;
|
||
|
|
add_list->callback = callback;
|
||
|
|
add_list->flag = 0;
|
||
|
|
INIT_LIST_HEAD(&add_list->list);
|
||
|
|
|
||
|
|
uint32_t flags;
|
||
|
|
os_printf("add_list:%X\n",add_list);
|
||
|
|
flags = disable_irq();
|
||
|
|
list_add_tail(&add_list->list, &wait_register_list);
|
||
|
|
key_callback_change = 1;
|
||
|
|
enable_irq(flags);
|
||
|
|
return add_list;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
uint8_t remove_keycallback(struct key_callback_list_s *remove_list)
|
||
|
|
{
|
||
|
|
uint32_t flags;
|
||
|
|
flags = disable_irq();
|
||
|
|
remove_list->flag = 1;
|
||
|
|
key_callback_change = 1;
|
||
|
|
enable_irq(flags);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//获取按键的workqueue或者任务
|
||
|
|
static int32 key_read_loop(struct os_work *work)
|
||
|
|
{
|
||
|
|
struct key_msg_s key_msg;
|
||
|
|
struct key_callback_list_s *ptr, *next;
|
||
|
|
void *msg = g_key_msgq;
|
||
|
|
int res;
|
||
|
|
uint32_t val = 0;
|
||
|
|
uint32_t extern_value = 0;
|
||
|
|
//判断一下标志位
|
||
|
|
//可能有链表要移除或者新增加callback
|
||
|
|
if(key_callback_change)
|
||
|
|
{
|
||
|
|
uint32_t flags;
|
||
|
|
|
||
|
|
flags = disable_irq();
|
||
|
|
//先添加,后移除
|
||
|
|
list_for_each_entry_safe(ptr, next, &wait_register_list, list)
|
||
|
|
{
|
||
|
|
list_del(&ptr->list);
|
||
|
|
list_add_tail(&ptr->list, ®ister_list);
|
||
|
|
}
|
||
|
|
|
||
|
|
list_for_each_entry_safe(ptr, next, ®ister_list, list)
|
||
|
|
{
|
||
|
|
// 对每个节点执行操作
|
||
|
|
if(ptr->flag)
|
||
|
|
{
|
||
|
|
os_printf("del key_callback:%X\n",ptr);
|
||
|
|
list_del(&ptr->list); // 从链表中删除节点
|
||
|
|
os_free(ptr); // 释放节点内存
|
||
|
|
}
|
||
|
|
}
|
||
|
|
key_callback_change = 0;
|
||
|
|
enable_irq(flags);
|
||
|
|
}
|
||
|
|
res = csi_kernel_msgq_get(msg,&key_msg,0);
|
||
|
|
if(!res)
|
||
|
|
{
|
||
|
|
val = key_msg.keycode;
|
||
|
|
extern_value = key_msg.extern_value;
|
||
|
|
//os_printf("key:%d\tstatus:%d\textern_value:%d\n",val>>8,val&0xff,extern_value);
|
||
|
|
list_for_each_entry_safe(ptr, next, ®ister_list, list)
|
||
|
|
{
|
||
|
|
//_os_printf("register ptr:%X\n",ptr);
|
||
|
|
if(ptr->callback)
|
||
|
|
{
|
||
|
|
ptr->callback(ptr,val,extern_value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//隔1ms读取一次按键,因为用的是workqueue,不能卡住这个任务,这里的1ms也不是准确的,因为按键,所以可以延时,如果延时太大,要检查
|
||
|
|
//workqueue哪个事件卡住导致的
|
||
|
|
os_run_work_delay(work, 1);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//注册的的消息函数
|
||
|
|
static int32 key_send_msg_func(uint32_t data,uint32_t extern_value)
|
||
|
|
{
|
||
|
|
struct key_msg_s key_msg = {data,extern_value};
|
||
|
|
if(g_key_msgq)
|
||
|
|
{
|
||
|
|
return csi_kernel_msgq_put(g_key_msgq,&key_msg,0,0);;
|
||
|
|
}
|
||
|
|
return RET_ERR;
|
||
|
|
}
|
||
|
|
|
||
|
|
//初始化函数
|
||
|
|
static struct os_work key_wk;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int32 keyWork_init(int listen_max)
|
||
|
|
{
|
||
|
|
//创建key的信号量
|
||
|
|
INIT_LIST_HEAD(&wait_register_list);
|
||
|
|
INIT_LIST_HEAD(®ister_list);
|
||
|
|
void *key_msgq = (void*)csi_kernel_msgq_new(listen_max,sizeof(struct key_msg_s));
|
||
|
|
if(key_msgq)
|
||
|
|
{
|
||
|
|
g_key_msgq = key_msgq;
|
||
|
|
key_button_scan_init(button_channels,key_send_msg_func);
|
||
|
|
//使用workqueue去监听按键?如果没有workqueue就使用创建线程吧
|
||
|
|
OS_WORK_INIT(&key_wk, key_read_loop, 0);
|
||
|
|
os_run_work_delay(&key_wk, 1);
|
||
|
|
return RET_OK;
|
||
|
|
}
|
||
|
|
return RET_ERR;
|
||
|
|
}
|