阅读:1814回复:9
新发一帖问2410在WINCE中的键盘驱动修改
之前发了一帖求助,地址为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 |
|
沙发#
发布于: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的直接不用 |
|
板凳#
发布于: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口,代码就不贴了 |
|
地板#
发布于: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; |
|
地下室#
发布于:2007-06-25 17:23
最后编译通过
但是一按EINT0,WINCE就死翘翘了…… 是不是还有需要改动的文件啊? |
|
5楼#
发布于:2007-06-25 17:32
哪位高人心生怜悯的
加我QQ指导下……88989799 学硬件的写C简直是种折磨 |
|
6楼#
发布于:2007-06-26 01:32
因为m是指针,所以getsFromKBCTL(UINT8 *m)
m=0;应修改成*m=0;另外你编译成功的代码也不能用,你是要操作指针指向的内容,而不是指针自己,所以一律都对*m操作,如果编译不过,把编译错误贴上来,加个强制类型转换应该就没问题了。 |
|
7楼#
发布于:2007-06-26 10:38
编译通过了……
但是 使用按键没有任何反应 不过WINCE没有死 |
|
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,这个是有源码的,可以修改。两个特性一起是否有冲突呢? 诚心请教达人。 |
|
9楼#
发布于:2007-07-04 08:12
我想第一种方法,应该是最好的方法,但是就是复杂了一点。第二种方法有点旁门左道的意思,但是应该也是可行的。
这个也不全是,第一种驱动系统中应该是只能有一个,而流接口的可以有多个, |
|
|