[转]ZLG7290键盘驱动开发心得

来源:互联网 发布:淘宝客服怎么说话技巧 编辑:程序博客网 时间:2024/05/16 08:57

ZLG7290键盘驱动开发心得
Wikee 20070714

1、了解键盘驱动结构,清楚准备要修改的地方和目的
Wince50的键盘驱动主要分几个层,

  键盘驱动分层结构


其中GWES和layout manager一般不用修改,但是可以看看里面的源码帮助理解驱动的接口,主要看初始化PDD的函数KeybdDriverInitializeEx()和回调函数KeybdEventCallback()就可以了。
Input language一般是0409,美国101键盘输入即可,不用修改。
PS/2和Matrix都是PDD,一般PS/2是默认的,如果没有PS/2键盘的话可以使用PS2_NOP_Entry即可。主要修改工作就是Matrix的driver和layout。

2、修改驱动、虚拟键值对照表和中断
我原来BSP中就已经具有KEYBD的源码,修改工作就在这个基础上的。目录在PLATFORM/SMDK2410/DRIVERS/KEYBD/。查看kbds3c2410us项目下的SOURCES文件如下:

================================================
SYNCHRONIZE_DRAIN=1

RELEASETYPE=PLATFORM

TARGETNAME=KbdS3C2410Us  (生成的DLL的名称,会在bib文件中调用该文件,同时改名为kbdmouse.dll来加载)
DEFFILE=KbdUS.def
TARGETTYPE=DYNLINK
DLLENTRY=DllMain
TARGETLIBS= /
    $(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/ceddk.lib

(这些是用到的库文件,TARGETPLATROOT目录下的几个就是我们要修改的,COMMONOAKROOT下的是标准的库文件一般不去修改。S3C2410KBD.lib对应KBDCOMMON目录,S3C2410_Layout.lib对应MATRIX_0409目录,PddList.lib对应PDDLIST目录,只需修改这三个目录。其中PDDLIST我没有修改,因为里面只是声明了两个PDD结构,正是我所需要的,如果不是则需要修改)
SOURCELIBS=/
    $(_TARGETPLATROOT)/lib/$(_CPUINDPATH)/S3C2410KBD.lib /
    $(_TARGETPLATROOT)/lib/$(_CPUINDPATH)/S3C2410_Layout.lib /
    $(_TARGETPLATROOT)/lib/$(_CPUINDPATH)/PddList.lib /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/Nop_KbdCommon.lib /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/PS2_AT_00000409.lib /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/LayoutManager.lib    /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/KeybdIst.lib    /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/NumPadRmp.lib /
    $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/InputLang_0409.lib /

WINCETARGETFILE=dummy

SOURCES=

==============================================

下面是platform.bib中有关键盘的内容:其中一大堆IF是根据你的OS的选择来COPY不同的键盘驱动DLL文件,只要保证OS中选择了S32410 Matrix Keyboard/Mouse English特性即可。
; @CESYSGEN IF CE_MODULES_KEYBD || CE_MODULES_POINTER
#if ! (defined BSP_NOKEYBD && defined BSP_NOMOUSE)
IF LOCALE=0411 !
IF LOCALE=0412 !
IF BSP_KEYBD_NOP
; @CESYSGEN IF CE_MODULES_NOPKEYBOARD
    kbdmouse.dll        $(_FLATRELEASEDIR)/KbdNopUs.dll            NK  SH
; @CESYSGEN ENDIF CE_MODULES_NOPKEYBOARD
ENDIF    ; BSP_KEYBD_NOP
IF BSP_KEYBD_NOP !
(起效的是这句把KbdS3C2410Us.dll装进NK中,这样修改的驱动才会被使用到。)
    kbdmouse.dll        $(_FLATRELEASEDIR)/KbdS3C2410Us.dll        NK  SH
ENDIF    ; BSP_KEYBD_NOP
(后面省略)。。。。
; @CESYSGEN ENDIF CE_MODULES_KEYBD || CE_MODULES_POINTER
==================================================

注册表一般不用修改,我只是增加了IIC的基地址进去,替换原来的SPI基地址。
[HKEY_LOCAL_MACHINE/HARDWARE/DEVICEMAP/KEYBD]
    "DriverName"="kbdmouse.dll"
    "SysIntr"=dword:10    ; SYSINTR_FIRMWARE + 0
    "IOBase"=dword:B1600000
;    "SSPBase"=dword:B1900000
    "IICBase"=dword:B1400000

===============================================

经过上面的分析,已经清楚需要修改的地方了
KBDCOMMON下的:kbd.cpp和s3c2410kbd.cpp
MATRIX_0409下的:s3c2410.cpp

我在KBDCOMMON文件夹下添加了从网上下载的iic.h和zlg7290.h,主要是定义的一些宏。s3c2410kbd.cpp中去掉原来PS/2的获取键值的子函数,增加ZLG7290的获取键值的子函数,还有根据硬件修改POWERON函数等。7290的子函数,周工网站有下,网上还有针对2410的IIC程序也找一个来自己分析后添加。KBD.CPP一般也不改,我在Matrix_Entry()函数中加上串口调试输出,来确定这个PDD被加载了。

关键在函数KeybdPdd_GetEventEx2(),这个函数在每次中断被键盘IST调用,可以看成是对中断的一个响应即可。IST我们使用默认的,可以在PUBLIC/COMMON/OAK/DRIVERS/KEYBD/下找到,这里同时还有layout maneger的代码。在这个函数中加上获取ZLG7290 IIC端口内容的函数ZLG7290_GetKey(key);其中key是一个4字节的数组,存放ZLG7290的前4个字节内容,第一个字节的第0位表示是否有键按下,第二字节是键值,没有键按下则为0,第3个为repeat count,第4个为功能键。具体看ZLG7290datasheet。

MATRIX_0409中的s3c2410.cpp就是修改ScanCodeToVKeyTable。Layout manager是根据偏移量来查找虚拟键值的。也就是以scancode为下标,对应的vkey为内容的一维数组而已。如果不支持的键,则填0即可,但是数组长度不要变,最好把原来的注释掉,复制后修改。
UINT8 ScanCodeToVKeyTable[] =
{
    0,  // Scan Code 0x0
    VK_F1, // Scan Code 0x1
    VK_F2, // Scan Code 0x2
    VK_F3, // Scan Code 0x3
    VK_F4, // Scan Code 0x4
    0, // Scan Code 0x5
    0, // Scan Code 0x6
    0, // Scan Code 0x7
    0, // Scan Code 0x8
    VK_ESCAPE, // Scan Code 0x9,esc
    VK_RETURN, // Scan Code 0xA,enter
    VK_UP, // Scan Code 0xB
    VK_RIGHT, // Scan Code 0xC
    0, // Scan Code 0xD
    0, // Scan Code 0xE
    0, // Scan Code 0xF
    0, // Scan Code 0x10
    VK_LEFT, // Scan Code 0x11
    VK_DOWN, // Scan Code 0x12
    'B', // Scan Code 0x13,back light
……
}

至此驱动修改完成,但是却不能正确运行。因为中断等没有修改正确,不能保证拿来的BSP就可以使中断正确了。如果使用与原来BSP同样的开发板就不需要修改。
中断的修改一般涉及到中断处理的几个函数,在KENEL/HAL/下的cfw.c和子目录下的armint.c。把对应的中断处理case分支,返回SYSINTR_KEYBOARD,或者处理SYSINTR_KEYBOARD对应case分支内容。

3、修改驱动注意的地方
    修改工作主要是对键盘驱动的结构流程的熟悉过程。我从键盘驱动不懂到修改成功经过了两周多,主要的修改代码工作才用了两天多一点。原因主要是对PB的不熟练和结构流程不熟悉造成的,多操作,多看书和help,多问人,多查看相关代码才是最快的方法。
    首先,确保你的硬件没有问题,是正常的。我之前使用ADS调试已经确认硬件正常,这个很重要,否则在软件上瞎搞,你也不会看到正确的结果出现的。
    第二,掌握一种调试手段。我的开发板没有网卡,不能使用PB进行代码调试,非常的痛苦,只能使用串口调试。我的BSP DEBUG下不能编译通过,现在在查问题,只能使用RELASE版。这样只能使用RETAILMSG宏来调试,但是注意不能选SHIP_BUILD一项。
  第三,灵活地调试。驱动的流程都是一层一层的,层之间使用接口函数,这样就提供了分层测试的方法。我在测试layout maneger时不使用获取的键值,而是定义一个键值当是硬件返回的扫描码来测试,结果成功,能在wince上看到该键值的效果了,表示上层从layout maneger和GWES都没问题了。当时我只是模拟了一下向下键,看到开始栏上光标不断移动,心里别提多开心了。这时候ZLG7290还没有做通呢。
之后是调试中断,因为我使用的不是原来的中断号了,我使用EINT10,但是有一段时间不能响应,后来才查到原因。因为EINT10的引脚GPG2其他驱动使用到了,这些后来才加载的驱动把端口修改了!我在PB中查找GPGCON的所有内容,把相关的驱动修改后,中断才正常。同样IIC的两个端口引脚也是一样。现在我明白了WINCE的所有驱动、OAL都是一个相关的整体,一发动全身。
最后调试7290要注意IIC的通讯频率,7290最高25K不能过高,在ADS中可以的程序放到WINCE下不一定可以,因为两者频率不一定相同。IIC的超时也要注意,改到WINCE下不能太短,否则根本没有IIC波形生成。因为太快了,上一个数据都没有移出去,下一个数据就把移位寄存器中的数据冲掉了,是得不到正确数据回应的。需要有一定硬件知识。
Layout maneger具有auto-repaet功能,还需要分keyup和keydown,7290没有这个标志,我采取双边沿中断的方式,按一次键产生两次中断,第一次是keydow你,第二次是keyup,使用7290的第一个字节的0位来判断。
第四,就是多看多查PB的help,当中什么都有了。
These all!