请教ZLG7290双边沿触发的奇怪问题

gooogleman 2009-03-12 02:13:39
加精
平台2440 5.0 BSP
我使用ZLG7290这个键盘驱动芯片,如果有键按下就会在它的INT引脚发出一个低电平,如果没有按键按下就是高电平。
现在我采用双边沿触发中断,但是出现只要按下一个键,这个键的功能就会不段重复执行,看打印信息中断线程却执行了一次而已。
后来在老帖看到,这个是由于没有处理按键弹起就会这样。可是我明明配置了双边沿触发,并且我用应用程序读出相应的寄存器,和
数据手册吻合。
后来我把键盘的IST部分移植到BSP下加入了打印信息。
BOOL
KeybdIstLoop(
PKEYBD_IST pKeybdIst
)
{
SETFNAME(_T("KeybdIstLoop"));

UINT32 rguiScanCode[16];
BOOL rgfKeyUp[16];
UINT cEvents;
// add by wogo at 2009-03-12
RETAILMSG(1, (TEXT("In KeybdIstLoop Funtion:\r\n")));
DEBUGCHK(pKeybdIst->hevInterrupt != NULL);
DEBUGCHK(pKeybdIst->pfnGetKeybdEvent != NULL);
DEBUGCHK(pKeybdIst->pfnKeybdEvent != NULL);

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

wait_for_keybd_interrupt:
if (WaitForSingleObject(pKeybdIst->hevInterrupt, INFINITE) == WAIT_OBJECT_0)
{
// add by wogo at 2009-03-12
RETAILMSG(1, (TEXT("Deal with hevInterrupt@@@!!! :\r\n")));
cEvents = (*pKeybdIst->pfnGetKeybdEvent)
(pKeybdIst->uiPddId, rguiScanCode, rgfKeyUp);

for (UINT iEvent = 0; iEvent < cEvents; ++iEvent) {
(*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId,
rguiScanCode[iEvent], rgfKeyUp[iEvent]);
}
// cEvents could be 0 if this was a partial scan code, like 0xE0

InterruptDone(pKeybdIst->dwSysIntr_Keybd);
// add by wogo at 2009-03-12
RETAILMSG(1, (TEXT("InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :\r\n")));
}

goto wait_for_keybd_interrupt;

ERRORMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating.\r\n")));
RETAILMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating!!! :\r\n")));
return TRUE;
}



果然按下一次按键只打印了如下信息

Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
按照常理,使用双边触发,按一次应该打印如下。

Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :

现在难搞了,使用应用程序去读中断寄存器的设置,读出是0x22226242,这个和要求完全吻合,怎么就不产生双边沿触发呢?难道是干扰?我的天啊,真是越来越神奇了。
后来,我又单独把EINT11配置成上升沿触发,结果也打印了
Deal with hevInterrupt@@@!!! :
InterruptDone(pKeybdIst->dwSysIntr_Keybd)@@@!!! :
这说明这时候才响应了键盘弹起中断。但是不知道为什么配置成双边触发的时候,响应了键按下之后,键弹起中断就不响应了。

shuiyan牛人,你经验丰富,救救小弟吧。谢谢。


...全文
783 66 打赏 收藏 转发到动态 举报
写回复
用AI写文章
66 条回复
切换为时间正序
请发表友善的回复…
发表回复
tangbin1982 2009-11-05
  • 打赏
  • 举报
回复
uping 学习
frolicdog 2009-09-10
  • 打赏
  • 举报
回复
好久以前的帖子了 今天看了 有一个疑问,为什么按一下 会有无数次触发呢
zhj8727 2009-06-26
  • 打赏
  • 举报
回复
uping
gooogleman 2009-03-19
  • 打赏
  • 举报
回复
这CSDN是不是 被攻击了,明明已经结贴,却还打个问号,还有回复数也不正常。
xqhrs232 2009-03-19
  • 打赏
  • 举报
回复
是不是触发中断线有干扰,还是触发方式没设置对??
gooogleman 2009-03-15
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 jgj58 的回复:]
问题怎么搞得那么复杂!!
VC好多书籍里的高级编程部分都有介绍键盘的部分!我以前做过,不过好久了,没这么复杂啊,可能你的概念还没搞清。
贴那没多代码,把人都搞晕了!
[/Quote]

我的是驱动,不是应用程序。
中断都响应不了,这个是问题所在。
jgj58 2009-03-15
  • 打赏
  • 举报
回复
问题怎么搞得那么复杂!!
VC好多书籍里的高级编程部分都有介绍键盘的部分!我以前做过,不过好久了,没这么复杂啊,可能你的概念还没搞清。
贴那没多代码,把人都搞晕了!
linhezhi 2009-03-15
  • 打赏
  • 举报
回复
顶一下!
ponyroi 2009-03-14
  • 打赏
  • 举报
回复
路过,顶一下
gooogleman 2009-03-14
  • 打赏
  • 举报
回复
[Quote=引用 55 楼 wanyeye 的回复:]
7290 的 速度不要到40K

以前我做的时候,发现老是不行
别看吹的 400K ,每用的的

我当时是 产生中断才去 读键值的
[/Quote]

他那里说7290是低于100K的
我们大于50K就不行了。很慢的。

我现在也是产生中断才去读键值的。总之这个东西有点奇怪,4.2BSP下却行
色郎中 2009-03-14
  • 打赏
  • 举报
回复
7290 的 速度不要到40K

以前我做的时候,发现老是不行
别看吹的 400K ,每用的的

我当时是 产生中断才去 读键值的
singlerace 2009-03-14
  • 打赏
  • 举报
回复
响应时间你用示波器量就好了。从中断开始到IIC上有数据,到数据传输结束,都可以量出来。其它点也可以量,你可以找个闲置的GPIO,或者DEBUG LED,在你想看的地方改变他的状态,然后用示波器抓。
gooogleman 2009-03-14
  • 打赏
  • 举报
回复
是的2440/2410 IIC默认总线频率为100K,但是ZLG7290的IIC总线频率低于100K,所以这个芯片本身决定了不能太高,。

还是理想情况,所以设置成25K到50K之间是比较合理的。
shuiyan 2009-03-14
  • 打赏
  • 举报
回复
IIC一般100KHz,也可以400KHz,除非估计降的极低速,否则2440不会被这个拖垮的。除非在那个读寄存器的函数里做了太多事。

在函数前后读时间,算时间差,这是最简单的。如果要在系统中测perfomance,就需要额外的软件工具了。
gooogleman 2009-03-14
  • 打赏
  • 举报
回复
不好意思,想问一下singlerace 前辈,

如何才能测出一个函数/线程的运行时间呢?这样可以了解效率。
gooogleman 2009-03-14
  • 打赏
  • 举报
回复
IIC时钟、速度相关
#define IICCON_ACKEN (1<<7) //IIC-bus acknowledge enable bit.
#define IICCON_CLK512 (1<<6) // 1 = IICCLK = fPCLK /512
#define IICCON_INTR (1<<5) // IIC-Bus Tx/Rx interrupt enable/disable bit.

#define FInsrt(Value, Field) \
(UData (Value) << FShft (Field))
#define IICCON_CLKPRE(x) FInsrt((x), Fld(4, 0))

//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/4
// If PCLK 50.7MHz, IICCLK = 99KHz, Tx Clock = 25KHz
v_pIICregs->rIICCON = IICCON_ACKEN |IICCON_CLK512 | IICCON_INTR | IICCON_CLKPRE(0x6);


这个速度也不算慢啊。并且这个程序在4.2跑是运行正常的。我提速一半试试。
gooogleman 2009-03-13
  • 打赏
  • 举报
回复
回shuiyan前辈,这个上面的代码不是我写的啊,是微软自带的键盘IST,我只是移植到BSP下编译,这样可以增加打印信息。

这样写没有问题吧。


(*pKeybdIst->pfnKeybdEvent)是BSP下的代码转换过来的。
这里有

KEYBD_IST keybdIst;
keybdIst.hevInterrupt = m_hevInterrupt;
keybdIst.dwSysIntr_Keybd = dwSysIntr_Keybd;
keybdIst.uiPddId = v_uiPddId;
keybdIst.pfnGetKeybdEvent = KeybdPdd_GetEventEx2;
keybdIst.pfnKeybdEvent = v_pfnKeybdEvent;

KeybdIstLoop(&keybdIst);

KeybdPdd_GetEventEx2是扫面键盘的函数,里面调用了7290驱动,我也纳闷啊,代码没有改,在4.2BSP行,在5.0就不行了。

//主要的扫描码处理函数
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=0;
UINT cEvents = 0;
// int i;

unsigned char key[4];

//DEBUGCHK(rguiScanCode != NULL);
//DEBUGCHK(rgfKeyUp != NULL);

//for(i=0;i<4;i++)
// key[i] = 0;
//getsFromKBCTL(&ui8ScanCode, 1);
ZLG7290_GetKey(key);

// RETAILMSG(1, (_T("zlg7290 get keys: %x %x %x %x \r\n"),key[0],key[1],key[2],key[3]));
// OEMWriteDebugString((TEXT("zlg7290 get keys!!!!\r\n")));

// RETAILMSG(1, (_T("v_pIICregs->rIICCON : %x\r\n"),v_pIICregs->rIICCON));
// RETAILMSG(1, (_T("v_pIOPregs->rGPECON : %x\r\n"),v_pIOPregs->rGPECON));

if(key[0]&0x01) //key down
{
fKeyUp = FALSE;
// enable rising int trigger
//v_pIOPregs->rEXTINT1 &= ~(0x7 << 12); // Clear EINT11
//v_pIOPregs->rEXTINT1 |= (0x2 << 8); // fallig edge triggered for EINT11
//v_pIOPregs->rEXTINT1 |= (0x6 << 12); // both edge
//v_pIOPregs->rEXTINT1 |= (0x1 << 14); // enable rising int trigger
}
else//key up
{
fKeyUp = TRUE;
// enable falling int trigger
//v_pIOPregs->rEXTINT1 &= ~(0x7 << 12); // Low level triggered
//v_pIOPregs->rEXTINT1 |= (0x2 << 8); // fallig edge triggered for EINT11
//v_pIOPregs->rEXTINT1 |= (0x6 << 12); // both edge
//v_pIOPregs->rEXTINT1 |= (0x1 << 13); // enable falling int trigger
}

/* if( (key[3] & 0x01) == 0)//F1
{
ui8ScanCode = 0x01;
}
else if( (key[3] & 0x02) == 0)//F2
{
ui8ScanCode = 0x02;
}
else if( (key[3] & 0x04) == 0)//F3
{
ui8ScanCode = 0x03;
}
else if( (key[3] & 0x08) == 0)//F4
{
ui8ScanCode = 0x04;
}
else */
if(key[1] != 0x0)//other KEYS
{
ui8ScanCode = key[1];
}
else
{
ui8ScanCode = 0;
}
//sent bl key press event to backlight driver
/*if(ui8ScanCode == 19) //bl key scancode = 19
{
//only get key down
if(fKeyUp == FALSE)
SetEvent(evtBLKeyPress);
return cEvents;
}*/ //wsf 20080924
//v_pIOPregs->rGPFCON |= 0x01;//GPF0 OUTPUT

// if (fKeyUp==FALSE)
// v_pIOPregs->rGPFDAT &= ~(1 << 1); /* LED 0 On */
// else
// v_pIOPregs->rGPFDAT |= (1 << 1); /* LED 0 Off */

// 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;
//按键有效,而且键值相同,auto-repeat
//if ( (scInProgress == scPrevious) && (fKeyUp == FALSE) )
//{
// mdd handles auto-repeat so ignore auto-repeats from keybd
//}
//else
//{
// Not a repeated key. This is the real thing.
scPrevious = scInProgress;

rguiScanCode[cEvents] = scInProgress;
rgfKeyUp[cEvents] = fKeyUp;
++cEvents;
//}
//send a user input event to backlight driver!
SetEvent(evtUserInput);

return cEvents;
}
shuiyan 2009-03-13
  • 打赏
  • 举报
回复
    #if 0
cEvents = (*pKeybdIst->pfnGetKeybdEvent)(pKeybdIst->uiPddId, rguiScanCode, rgfKeyUp);

for (UINT iEvent = 0; iEvent < cEvents; ++iEvent) {
(*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId,rguiScanCode[iEvent], rgfKeyUp[iEvent]);
}
// cEvents could be 0 if this was a partial scan code, like 0xE0
#endif


怎么这么复杂?键盘芯片不是直接通过I2C读寄存器吗?怎么还需要循环cEvents次?cEvents一般是多少?
for里面的(*pKeybdIst->pfnKeybdEvent)到底执行什么功能?


btw:你怎么用goto来实现WaitForSingleObject的死循环呢?极其少见呀。
gooogleman 2009-03-13
  • 打赏
  • 举报
回复
不行啊,我已经把驱动的很多延时都删除了,还是不能响应弹起中断。

咋整的啊。

真是知道原因就是搞不定。
gooogleman 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 guetcw 的回复:]
搞定没有
[/Quote]

修改IST,自己加入键盘弹起标志,没有照着正常的方法做。
加载更多回复(45)

19,504

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧