yangtch的个人空间 https://blog.eetop.cn/562 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

硬件工程师眼中的WINCE 键盘驱动的自定义修改(2)

已有 3656 次阅读| 2010-8-17 00:24 |个人分类:WINCE

在回答完第一个问题之后,让我们在考虑第二个问题,读取键盘扫描码的问题,第一个是时间,无疑是在键盘按下,触发中断时候进行键盘扫描;第二个小问题,在那个函数中,添加我们的扫描代码?

KEYBD_IST keybdIst;

       keybdIst.hevInterrupt = m_hevInterrupt;

       keybdIst.dwSysIntr_Keybd = g_dwSysIntr_Keybd;

       keybdIst.uiPddId = v_uiPddId;

       keybdIst.pfnGetKeybdEvent = KeybdPdd_GetEventEx2;

       keybdIst.pfnKeybdEvent = v_pfnKeybdEvent;

             

KeybdIstLoop(&keybdIst);

 

这个代码很有特色,进行了一些初始化,就调用KeybdIstLoop()函数,只能寄希望与KeybdIstLoop()是否又什么玄机,keybdIst对象首先挂接了hevInterrupt事件,挂接了系统中断g_dwSysIntr_Keybd,又看到一个很有意思的成员变量 keybdIst.pfnGetKeybdEvent = KeybdPdd_GetEventEx2,由字面意思可以看出keybdIst.pfnGetKeybdEvent.pfn是个函数指针,搜索一下KeybdPdd_GetEventEx2,终于得到了问题2的答案,我们的键盘扫描码程序放在这里就可以了。

令人鄙视的复制 粘贴

static UINT KeybdPdd_GetEventEx2(UINT uiPddId, UINT32 rguiScanCode[16], BOOL rgfKeyUp[16])

{

    SETFNAME(_T("KeybdPdd_GetEventEx2"));

 

    UINT32   scInProgress = 0;

    static UINT32   scPrevious;

 

    BOOL            fKeyUp;

    UINT8           ui8ScanCode;

    UINT            cEvents = 0;

 

    DEBUGCHK(rguiScanCode != NULL);

    DEBUGCHK(rgfKeyUp != NULL);

 

       getsFromKBCTL(&ui8ScanCode, 1);

 

    DEBUGMSG(ZONE_SCANCODES,

        (_T("%s: scan code 0x%08x, code in progress 0x%08x, previous 0x%08x\r\n"),

        pszFname, ui8ScanCode, scInProgress, scPrevious));

 

    scInProgress = ui8ScanCode;

    if (scInProgress == scPrevious) {

        //     mdd handles auto-repeat so ignore auto-repeats from keybd

    } else {

        // Not a repeated key.  This is the real thing.

        scPrevious = scInProgress;

       

        if (ui8ScanCode & scKeyUpMask) {

            fKeyUp = TRUE;

            scInProgress &= ~scKeyUpMask;

        } else {

            fKeyUp = FALSE;

        }

       

        rguiScanCode[cEvents] = scInProgress;

              rgfKeyUp[cEvents] = fKeyUp;

        ++cEvents;

    }

 

    return cEvents;

}

 

不仔细分析了,大体说一下吧。硬件结构上,SMDK2440开发板采用UR5HCSPI芯片实现键盘阵列接口,getsFromKBCTL(&ui8ScanCode, 1);读取UR5HCSPI芯片的一个扫描码,将按键的扫描码保存在rguiScanCode[]数组中,rgfKeyUp表示按键状态。FALSE表示按键按下,TRUE表示按键已经弹起。这样就将按键值和按键状态传递给操作系统。

这段代码运行恰恰是在中断触发后立即执行的一段代码,时间上符合;执行键盘扫描程序,并把按键状态传递给WINCE,功能符合;终于找到点了。下面就需要我们在正确的时间,正确的代码段 运行正确的代码。

修改代码,删除KeybdPdd_GetEventEx2()函数中的所有代码,并添加子定义功能代码:

static UINT KeybdPdd_GetEventEx2(UINT uiPddId, UINT32 rguiScanCode[16], BOOL rgfKeyUp[16])

{

       scInProgress  = KeyBoard_Scan(); //按键扫描程序

rguiScanCode[cEvents] = scInProgress;

rgfKeyUp[cEvents] = FALSE; //必须为FALSE,否则表示按键没按下就弹起,逻辑上不通

    ++cEvents;

rguiScanCode[cEvents] = scInProgress;

rgfKeyUp[cEvents] =TRUE;

    ++cEvents;

       return cEvents;

}

KeyBoard_Scan();函数中要完成 自定义 按键键值读取,抖动处理等,并返回按键值。

 

rguiScanCode[cEvents] = scInProgress;

rgfKeyUp[cEvents] = FALSE;

rguiScanCode[cEvents] = scInProgress;

rgfKeyUp[cEvents] =TRUE;

    ++cEvents;

       return cEvents;

因为是测试代码,代码写得很烂,逻辑上并没有判断按键弹起的时刻。改进方法:键盘按下,下降沿触发中断,读取键值,并rguiScanCode[cEvents] = scInProgress; rgfKeyUp[cEvents] = FALSE;传递给操作系统,修改中断触发方式,改为上升沿触发,当按键弹起时,会再次调用KeybdPdd_GetEventEx2(),将rguiScanCode[cEvents] = scInProgress;

rgfKeyUp[cEvents] =TRUE;传递给操作系统,修改中断方式为下降沿触发。

 

问题3键盘扫描码该如何与操作系统的码字对应起来?求助网络吧,” WinCE的标准键盘驱动框架定义了两张映射表:即Scan codevirtual key的映射表(Device layout),和virtual keyunicode的映射表(input language)。通过修改这两张映射表的定义,我们就可以控制键盘上的每一个按键或者按键组合的输出。第一张表,就在C:\WINCE500\PLATFORM\SMDK2440A\Src\Drivers\Keybd\Matrix_0409\s3c2440.cpp中,UINT8 ScanCodeToVKeyTable[]。那么我们怎么修改这张表为自己所用?

例如我们有10个键盘,第1个键的扫描码为0X1(即当scInProgress  = KeyBoard_Scan();的输出为0X1),并对应于WINCE的‘1’就可以这样写,以此类推,这样ScanCodeToVKeyTable[]=

{

0,  // Scan Code 0x0

       1, // Scan Code 0x1

       2, // Scan Code 0x2

       3, // Scan Code 0x3

       4, // Scan Code 0x4

       5, // Scan Code 0x5

       6, // Scan Code 0x6

       7, // Scan Code 0x7

       8, // Scan Code 0x8

       9, // Scan Code 0x9

}

如果换一种定义,例如 a b c d……,可以写成

ScanCodeToVKeyTable[]=

{

a,  // Scan Code 0x0

       b, // Scan Code 0x1

       c, // Scan Code 0x2

       d, // Scan Code 0x3

       e, // Scan Code 0x4

       f, // Scan Code 0x5

       g, // Scan Code 0x6

       h, // Scan Code 0x7

       i, // Scan Code 0x8

       j, // Scan Code 0x9

}

剩下一个问题,virtual keyunicode的映射表(input language),因为目前并不需要这个还没研究过,算是一点小遗憾吧。先留在这里,慢慢补充。

 

最后总结一下,

1 BOOL Ps2Keybd::IsrThreadProc()实现了硬件中断与WINCE之间的挂接;

2 KeybdPdd_GetEventEx2()函数完成自定义的键盘扫描程序,并把键盘信息传递给操作系统;

3 ScanCodeToVKeyTable完成了键盘扫描键值到WINCE虚拟键值的映射;

上面三点即为自定义键盘驱动所要修改之处。

 

                                                                                    yang_tch@163.com

点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 9

    评论
  • 363

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-4 20:10 , Processed in 0.016211 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部