📄 drv_keypad.c
字号:
/************************************************************
Copyright (C), 2007,DTK Computer.
FileName: kern_irq.c
Author: ljs Version : 1.0.0 Date:2007.08.14
Description: 键盘驱动。给应用层发送事件D_EVENT_KEY,D_EVENT_KEYDOWN,
D_EVENT_KEYUP。
Version: DTK-EMMI-1.0.0
Function List:
History:
<author> <time> <version > <desc>
ljs 2007/08/14 1.0.0 build this moudle
***********************************************************/
#include <malloc.h>
#include <string.h>
#include "../../frame/frm_hd_device.h"
#include "../../public/pub_event.h"
#include "../../frame/frm_event_queue.h"
#include "../../public/pub_event_type.h"
#include "../../service/comm_protocol/srv_gsm_attable.h"
#include "drv_keypad.h"
#define KYEYPAD_IRQ 2
#define BASE_ADDR 0x80000100
extern void frm_printf(D_UINT8 *);
extern d_event_queue win_event_queue;
extern D_UINT8 frm_event_enqueue(d_event_queue* queue, d_event* e);
static D_UINT16 key_buff[KEYPAD_BUFF_LEN];
static D_INT8 key_num=0;
static D_UINT8 key_value[KEYPAD_VALUE_LEN+1];
static D_INT8 key_value_num=0;
static d_event* key_event_key_new(void)
{
d_event* event=NULL;
event = calloc(1,sizeof(d_event));
if( event == NULL )
return NULL;
event->param = malloc(4);
if( event->param == NULL )
{
free(event);
return NULL;
}
event->param_len = 4;
return event;
}
static D_INT32 keypad_irq_handler(D_INT32 irq, void *dev_id, struct leonbare_pt_regs *regs)
{
D_UINT32 keycode=0;
D_UINT32 tmp_keycode=0;
d_event* event=NULL;
D_UINT32 *pbase = (D_UINT32 *)BASE_ADDR;
D_INT16 i,j;
if( key_num == KEYPAD_BUFF_LEN )/*如果键盘缓冲已经满*/
return 0;
kern_disable_irq(KYEYPAD_IRQ);
if( (*(pbase+1) & 0x00000001) )/*有效的按键*/
{
if( !(event=key_event_key_new()) )
goto handler_out;
keycode = (*(pbase+2)) & 0x0000FFFF;
tmp_keycode = keycode & 0x0000003F;
memcpy(event->param, &tmp_keycode, 4);
if( keycode & 0x00000080 ) /*长按键*/
{
event->event_id = D_EVENT_KEYLONG;
frm_event_enqueue(&win_event_queue,event);
goto handler_out;
}
else /*短按键*/
{
if( keycode & 0x00000040 ) /*按下键*/
{
event->event_id = D_EVENT_KEYDOWN;
frm_event_enqueue(&win_event_queue,event);
if( key_num && (key_buff[key_num-1] & 0x00000040) \
&& ((key_buff[key_num-1] & 0x003F) == keycode & 0x0000003F ) )/*重复按键*/
{
;
}
else
{
key_buff[key_num] = keycode & 0x0000FFFF;
key_num++;
}
goto handler_out;
}
else/*释放键*/
{
/*******发送释放键事件*********/
event->event_id = D_EVENT_KEYUP;
frm_event_enqueue(&win_event_queue,event);
/****************************/
if( key_num && (key_buff[key_num-1] & 0x00000040) \
&& ((key_buff[key_num-1] & 0x003F) == keycode & 0x0000003F ) )/*前一按键是本键的按下键*/
{
key_value[key_value_num] = tmp_keycode;
if( key_value_num == KEYPAD_VALUE_LEN )
{
for(i=0; i<key_value_num; i++)
key_value[i] = key_value[i+1];
}
else
key_value_num++;
key_num--;
if( !(event=key_event_key_new()) )
goto handler_out;
memcpy(event->param, &tmp_keycode, 4);
event->event_id = D_EVENT_KEY;
frm_event_enqueue(&win_event_queue,event);
goto handler_out;
}
for(i=0; i<key_num-1; i++)
{
if( (key_buff[i] & 0x00000040) \
&& ((key_buff[i] & 0x003F) == keycode & 0x0000003F ) ) /*该键是否被按下*/
{
for(j=i; j<key_num-1; j++)
key_buff[j] = key_buff[j+1];
key_num--;
break;
}
}
}/*释放键*/
}/*短按键*/
}/*有效的按键*/
handler_out:
kern_enable_irq(KYEYPAD_IRQ);
return 0;
}
D_BOOL drv_keypad_exit(void)
{
return TRUE;
}
D_BOOL drv_keypad_init(d_device *dev)
{
D_INT32 *pbase_addr=NULL;
if( !dev )
return FALSE;
pbase_addr = (D_INT32 *)BASE_ADDR;
kern_disable_irq(KYEYPAD_IRQ);
if( kern_request_irq(KYEYPAD_IRQ, keypad_irq_handler,NULL,1) )
frm_printf("keypad : fail");
else
frm_printf("keypad : OK");
kern_enable_irq(KYEYPAD_IRQ);
return TRUE;
}
/**
读取一个字符
**/
D_INT32 drv_keypad_read(D_INT8* buff, D_UINT32 psize)
{
D_INT16 i;
if( key_value_num == 0 )
return 0;
buff[0] = key_value[0];
key_value_num--;
for(i=0; i<key_value_num; i++)
key_value[i] = key_value[i+1];
return 1;
}
/**
**/
D_BOOL drv_keypad_write(D_UINT32 size, D_INT8* buff)
{
return TRUE;
}
/**
ioctl 操作
request: 0--读控制状态信息
1--设置控制信息
2--刷新读数据缓冲
返回值: 0--成功
1--失败
**/
D_UINT8 drv_keypad_ioctl(D_UINT8 request, void *param)
{
d_keypad_ctl *pctl=NULL;
D_UINT32 tmp_value=0;
D_UINT32 reg_value=0;
D_UINT32 *pbase = (D_UINT32 *)BASE_ADDR;
if( !param )
return 1;
pctl = (d_keypad_ctl *)param;
if( request == 0 )
{
if( *(pbase) & 0x80000000 )
pctl->key_slp = 1;
else
pctl->key_slp = 0;
if( *(pbase) & 0x00010000 )
pctl->key_re_en = 1;
else
pctl->key_re_en = 0;
tmp_value = *pbase & 0x0000F000;
pctl->key_re_tm = tmp_value;
tmp_value = *pbase & 0x00000F00;
pctl->key_pre_tm = tmp_value;
pctl->key_value[0] = key_num;
memcpy(pctl->key_value+1, key_buff, key_num*sizeof(D_UINT16));
}
if( request == 1 )
{
if( pctl->key_slp )
reg_value |= 0x80000000;
if( pctl->key_re_en )
reg_value |= 0x00010000;
tmp_value = pctl->key_re_tm & 0x0F;
tmp_value = tmp_value<2?2:tmp_value;
tmp_value <<= 12;
reg_value |= tmp_value;
tmp_value = pctl->key_pre_tm & 0x0F;
tmp_value = tmp_value<2?2:tmp_value;
tmp_value <<= 8;
reg_value |= tmp_value;
*pbase = reg_value;
}
if( request == 2 )
{
key_value_num = 0;
}
return 0;
}
D_INT8 drv_keypad_open()
{
return 0;
}
D_INT8 drv_keypad_close()
{
return 0;
}
d_device device_keypad = {0x01,0x0C,drv_keypad_init,drv_keypad_exit,\
drv_keypad_read,drv_keypad_write,drv_keypad_ioctl,drv_keypad_open,drv_keypad_close,0};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -