sunignol
驱动牛犊
驱动牛犊
  • 注册日期2007-06-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
阅读:1814回复:9

新发一帖问2410在WINCE中的键盘驱动修改

楼主#
更多 发布于:2007-06-25 17:08
之前发了一帖求助,地址为http://bbs.driverdevelop.com/htm_data/48/0706/102704.html,谢谢各位高手的帮助
现在汇报下修改的情况,请大家继续指导(编译能通过了,但功能还没实现):

1.目的:在2410芯片系统上外接编码器,例如,理论上用8-3编码器可以将最多8个按键优先编码成3位的一个数据,用EINT方式通知2410读取。硬件RC电路防抖,加软件延时防抖。我需要29个按键,则理论上要级联出一个32-5编码器

2.测试:针对开发板提供的具体资源,测试驱动修改目的如下:EINT0作为通知中断;EINT11(GPG3)和EINT19(GPG11)作为2位编码输入

3.文件修改:

(1)C:\WINCE420\PLATFORM\SMDK2410\KERNEL\HAL\power.c
不知道这个文件是不是初始化所有端口的,对GPG控制:
//*** PORT G GROUP
    //Ports  : GPG15 GPG14 GPG13 GPG12 GPG11  GPG10    GPG9     GPG8     GPG7      GPG6    
    //Signal : nYPON YMON  nXPON XMON  EINT19 DMAMODE1 DMAMODE0 DMASTART KBDSPICLK KBDSPIMOSI
    //Setting: OUT   OUT   OUT   OUT   IN     OUT      OUT      OUT      OUT       OUT
    //Binary : 01    01,   01    01,   00     01,      01       01,      01        01
    //PU_OFF :  1     1     1     1,    1-ext  1        1        1,       1         1
    //---------------------------------------------------------------------------------------
    //Ports  : GPG5       GPG4      GPG3   GPG2    GPG1    GPG0    
    //Signal : KBDSPIMISO LCD_PWREN EINT11 nSS_SPI IRQ_LAN IRQ_PCMCIA
    //Setting: IN         IN        IN     IN      IN      IN
    //Binary : 00         00,       00     00,     00      00
    //PU_OFF :  0-ext      0,        1-EXT  0       0       0
    s2410IOP->rGPGDAT = 0x0 |(1<<11)|(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<9)|(1<<8)|(1<<7)|(1<<6) ;
    s2410IOP->rGPGCON = 0x55155000;   //GPG11=OUT  //for debug
    s2410IOP->rGPGUP  = 0xfbc8;


(2)C:\WINCE420\PLATFORM\SMDK2410\INC下的S2410.H和oalintr.h未修改

(3)C:\WINCE420\PLATFORM\SMDK2410\KERNEL\HAL下CFW.C
修改了电源中断(原占用了EINT0和2)和键盘中断(原为EINT1)的EINT分配
case SYSINTR_POWER:
        //s2410INT->rSRCPND  = BIT_EINT0;
        // S3C2410X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
        //if (s2410INT->rINTPND & BIT_EINT0) s2410INT->rINTPND = BIT_EINT0;
        //s2410INT->rINTMSK &= ~BIT_EINT0;
        s2410INT->rSRCPND  = BIT_EINT2;
        // S3C2410X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
    if (s2410INT->rINTPND & BIT_EINT2) s2410INT->rINTPND = BIT_EINT2;
    s2410INT->rINTMSK &= ~BIT_EINT2;
    break;

——————————————————————————————
    case SYSINTR_POWER:
        //s2410INT->rINTMSK |= BIT_EINT0;
        s2410INT->rINTMSK |= BIT_EINT2;
        break;
——————————————————————————————
    case SYSINTR_KEYBOARD:    // Keyboard on EINT1.

        s2410INT->rSRCPND  = BIT_EINT0;
        // S3C2410X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
        if (s2410INT->rINTPND & BIT_EINT0) s2410INT->rINTPND = BIT_EINT0;

        s2410INT->rINTMSK &= ~BIT_EINT0;
        break;
——————————————————————————————
    case SYSINTR_KEYBOARD:
        s2410INT->rINTMSK |= BIT_EINT0;
        break;
——————————————————————————————
    case SYSINTR_KEYBOARD:
        s2410INT->rINTMSK &= ~BIT_EINT0;
        break;

总之是见SYSINTR_KEYBOARD就全改成EINT0,见SYSINTR_POWER就全去掉EINT0
sunignol
驱动牛犊
驱动牛犊
  • 注册日期2007-06-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-06-25 17:12
(4)C:\WINCE420\PLATFORM\SMDK2410\KERNEL\HAL\ARM\armint.c
修改对中断的分配:
else if (IntPendVal == INTSRC_EINT2)    // EINT2
    { 
        s2410INT->rINTMSK |= BIT_EINT2;
        s2410INT->rSRCPND  = BIT_EINT2;    /* Interrupt Clear                */
        if (s2410INT->rINTPND & BIT_EINT2) s2410INT->rINTPND  = BIT_EINT2;
//        RETAILMSG(1, (TEXT(">>> CPUPowerReset \r\n")));
        RETAILMSG(1,(TEXT(">>> >>> Reset Button Pressed <<< <<< \r\n")));
        CPUPowerReset();

        return(SYSINTR_POWER);
————————————————————————————————————
    else if (IntPendVal == INTSRC_EINT0)    // Keyboard interrupt is connected to EINT1.
    { 
        s2410INT->rINTMSK |= BIT_EINT0;
        s2410INT->rSRCPND  = BIT_EINT0;
        if (s2410INT->rINTPND & BIT_EINT0) s2410INT->rINTPND  = BIT_EINT0;

        return(SYSINTR_KEYBOARD);
——————————————————————————————
    //else if (IntPendVal == INTSRC_EINT0)  { // POWER BUTTON
        //s2410INT->rINTMSK |= BIT_EINT0;
        //s2410INT->rSRCPND  = BIT_EINT0;    /* Interrupt Clear                */
        //if (s2410INT->rINTPND & BIT_EINT0) s2410INT->rINTPND  = BIT_EINT0;

        //return(SYSINTR_POWER);    
    //}              //这段SYSINTR_POWER占用EINT0的直接不用
sunignol
驱动牛犊
驱动牛犊
  • 注册日期2007-06-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-06-25 17:17
(5) C:\WINCE420\PLATFORM\SMDK2410\DRIVERS\KEYBD\KBDCOMMON\s3c2410kbd.cpp
修改getsFromKBCTL实现从GPG对应2位去数,改变后面的m的值
void getsFromKBCTL(UINT8 *m) {
    int    j;
    volatile tmp = 1;

    //m = ((v_pIOPregs->rGPGDAT >> 3)|(v_pIOPregs->rGPGDAT >> 10))&(0x3<<0);
    m = 0;
    if (v_pIOPregs->rGPGDAT&0x8) *m|=0x1;
        if (v_pIOPregs->rGPGDAT&(0x1<<11)) *m|=0x2;
    for(j = 0; j < 3; j++)
        tmp += tmp;
    for(j = 0; j < 250 * 30; j++)
        tmp += tmp;

 //if (m != ((v_pIOPregs->rGPGDAT >> 3)|(v_pIOPregs->rGPGDAT >> 10))&(0x3<<0)) m=0xFF;
 
//        for(j = 0; j < 400; j++)
//            tmp+= tmp;
    }


修改KeybdPdd_GetEventEx2,直接调用getsFromKBCTL
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);

    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;
}


修改Ps2Keybd::KeybdPowerOn,就是一段初始化EINT0和GPG口,代码就不贴了
sunignol
驱动牛犊
驱动牛犊
  • 注册日期2007-06-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-06-25 17:20
最后,由于BSP自带的POWERBOTTON驱动调用了EINT0作为电源软开关,我直接把这个从定好的PLATFORM里删了
然后编译,C:\WINCE420\PLATFORM\SMDK2410\DRIVERS\KEYBD\KBDCOMMON\s3c2410kbd.cpp里对getsFromKBCTL函数的描述非常影响成功率
编译成功的代码是
if (v_pIOPregs->rGPGDAT&0x8) m+=1;
        if (v_pIOPregs->rGPGDAT&(0x1<<11)) m+=2;
sunignol
驱动牛犊
驱动牛犊
  • 注册日期2007-06-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-06-25 17:23
最后编译通过
但是一按EINT0,WINCE就死翘翘了……
是不是还有需要改动的文件啊?
sunignol
驱动牛犊
驱动牛犊
  • 注册日期2007-06-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-06-25 17:32
哪位高人心生怜悯的
加我QQ指导下……88989799
学硬件的写C简直是种折磨
zhengshijie
驱动小牛
驱动小牛
  • 注册日期2003-07-11
  • 最后登录2009-03-18
  • 粉丝1
  • 关注0
  • 积分8分
  • 威望217点
  • 贡献值0点
  • 好评度199点
  • 原创分3分
  • 专家分0分
6楼#
发布于:2007-06-26 01:32
因为m是指针,所以getsFromKBCTL(UINT8 *m)
m=0;应修改成*m=0;另外你编译成功的代码也不能用,你是要操作指针指向的内容,而不是指针自己,所以一律都对*m操作,如果编译不过,把编译错误贴上来,加个强制类型转换应该就没问题了。
sunignol
驱动牛犊
驱动牛犊
  • 注册日期2007-06-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分290分
  • 威望30点
  • 贡献值0点
  • 好评度29点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-06-26 10:38
编译通过了……
但是
使用按键没有任何反应
不过WINCE没有死
wikee
驱动小牛
驱动小牛
  • 注册日期2003-02-25
  • 最后登录2009-02-21
  • 粉丝0
  • 关注0
  • 积分355分
  • 威望108点
  • 贡献值0点
  • 好评度104点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-06-27 16:52
我也需要改WINCE的键盘驱动,我的平台使用IIC接口的ZLG7290芯片扩展的键盘。
查了一下网络上的资料,我认为有两者实现方法:
1、改动原KEYBOARD的代码中有关SCAN_CODE的部分和中断部分。就像楼主正在做的。
2、写一个流驱动接到键盘中断,在IST中处理SCAN_CODE和虚键值的转换。资料如下:

WINCE的键盘驱动程序开发的注意事项 -
转自:http://winceblog.blogspot.com/2007/02/wince.html
 
WINCE中标准的键盘驱动程序接口可以参考PS2键盘的驱动程序,但那个接口比较复杂,对于了解流接口的人来说,实现一个流接口的驱动程序应该是一个更好的选择.我们只需要实现一个流接口驱动程序,发生中断以后读到键盘的扫描码,将其用MapVirtualKey转化成虚键,再调用keybd_event函数将些虚键发送出去即可。只是我们需要注意记录CTRL,ALT等特殊键的状态。
注意:
1,某些键的扫描码有两个值,以0XE0或0XE1开始,注意正确处理。
2,一个PS2键盘不需要初始化就可以工作,但我们可以发送RESET命令再读其返回值来判断键盘是否已经连接。
3,必须加上kbdmous.dll,这个模块,我们的键盘驱动才能正常工作,通常只需要加上NOP Keyboard/Mouse English,再加上相应的注册表设置就行。
4,系统中只能有一个标准接口的键盘驱动,即kbdmouse.dll,所以如果我们有更多的键盘硬件需要驱动,就需要把其它的做成流接口的,最多将一个写成标准的键盘驱动,当然也可以把所有的都写成流接口驱动,再加上NOP Keyboard/Mouse English

我想第一种方法,应该是最好的方法,但是就是复杂了一点。第二种方法有点旁门左道的意思,但是应该也是可行的。

目前,我还在看资料,碰到的第一个问题就是:我的OS中已经有了一种键盘驱动了,叫做S32410 Matrix Keyboard/Mouse English,查了一下没有源码,或者不知道在哪个文件夹下。我又添加了S32410 Matrix Keyboard/Mouse Common,这个是有源码的,可以修改。两个特性一起是否有冲突呢?
诚心请教达人。
microsun
论坛版主
论坛版主
  • 注册日期2002-11-11
  • 最后登录2014-07-18
  • 粉丝0
  • 关注0
  • 积分1052分
  • 威望1159点
  • 贡献值0点
  • 好评度848点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-07-04 08:12
我想第一种方法,应该是最好的方法,但是就是复杂了一点。第二种方法有点旁门左道的意思,但是应该也是可行的。


这个也不全是,第一种驱动系统中应该是只能有一个,而流接口的可以有多个,
学海无涯
游客

返回顶部