S3C6410 KeyPad驱动(下)
S3C6410 KeyPad驱动(下)
1.1 按键中断处理流程
1.1.1 按键扫描的处理流程
在初始状态,所有的列线(输出)处于低电平,当没有按键按下的状态时,所有的行线(输入)都是高电平(使用上拉功能)。当任何按键按下时,相应的行和列线连接在一起,并且相应的行被驱动为低电平,此时产生一个键盘中断。接着CPU(软件)通过写列数据输出寄存器KEYIFCOL向一列写入低电平,而向其他列写入高电平。在每次写入的时候,CPU读取行数据输入寄存器KEYIFRO来相应的列按键是按下,这样,当扫描处理完成后,就可以找到按下的一个或多个按键。
图24 键盘扫描初始化状态
下面假设按下按键27,是如何确定此按键的流程:
1) 当按下27键的时候,它所在的第3行输入低电平,也即GPK11输入低电平,这可通过读取KEYIFROW寄存器获知。
2) CPU通过写KEYIFCOL寄存器来写第0位为低电平,第1到第第7位为高电平,然后来读取KEYIFROW寄存器的值,这时读取到的值为11111111,没有其中一行输入为低电平,说明,按键的按键不在第0列,见下图
图25 键盘扫描处理流程II
3) 直到CPU向KEYIFCOL寄存器低八位写入11110111,这时读取到KEYIFROW寄存器低八位的值为11110111,可知第3行输入为低电平,此时对应的是扫描条件时第3列输入低电平,这样就可以判断按键在第3行和第3列交叉处的按键,从而判断了具体的按键。
4) 对于多个按键,扫描原理一样,见下图的说明。
图26键盘扫描处理流程III
1.1.2 PDD的IST处理
下面来看IST线程KeyMatrix::IsrThreadProc()的主要处理部分:、
图27 IST线程KeyMatrix::IsrThreadProc()
此IST对按键的处理流程有下面一些情况:
下面分别介绍调用到的一些函数:
1) KScan_ProcIO函数
图28 KScan_ProcIO函数体
按下第3行第3列的按键时,ChangeState[3]=0x8,这里的3是指第3列,而0x8的二进制数是00001000,表示第3行,由此根据ChangeState[3]=0x8,可以知道是按下第3行第3列的按键被按下,其他idx对应的ChangeState[idx]值是0;同理,对于按下第3行第2列的按键时有ChangeState[2]=0x8,但如果同时按下这两个按键,这ChangeState[3:2]=0x8。也就是说ChangeState数组中的idx值用来指示是哪一列的按键,而ChangeState[idx]的值(非零)用来指示是哪一行的按键。
备注:下面基于4*4的键盘来描述,其中采用了低4行(GPK8~GPK11)和高四列(GPL4~GPL7)。
2) KeybdEventCallback函数
PDD层通过调用KeybdEventCallback函数把当前device layout按下的按键的扫描码和按键状态发送给MDD层,此函数体如下:
图29 KeybdEventThreadProc函数
3) KeybdEventThreadProc线程
接收来之KeybdEventThreadProc函数发送过来的键盘事件,把扫描码转换为虚拟键码,然后发送重新映射的键盘事件给GWES,此线程主要部分如下:
图30 KeybdEventThreadProc线程
键盘驱动就先介绍到这里了,其实还有很多内容的,大家可以深入MDD层部分。