⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv_keypad.c

📁 sparc硬件平台上的键盘驱动
💻 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 + -