根据需要,需要搞一个6*5的矩阵键盘,6行5列。行接的是GPIOK8~GPIOK13,列接的是GPIOL0~GPIOL4

研究了一下6410的键盘驱动后,修改如下:


一、 添加按键定义

添加“扫描”按键的定义。

1、在C:\WINCE600\OSDesigns\S3C6410_DEMO\S3C6410_DEMO\SDKs\SDK1\obj\TE6410Board\Include\ARMV4I\winuser.h文件中添加如下定义:(橙色字体部分)

#define VK_CLEAR          0x0C
#define VK_RETURN         0x0D
// *** [SOF] you add ***
#define VK_SCAN           0x0E
// *** [EOF] you add ***


2、在C:\WINCE600\PUBLIC\COMMON\SDK\INC\winuserm.h文件中同样添加如下定义:(橙色字体部分)

// ***
// *** [SOF] you disable ***
//#define VK_TSTAR    VK_F8               // *           
//#define VK_TPOUND   VK_F9               // #   
// *** [EOF] you disable ***
// ***

// ***
// *** [SOF] you add ***
#define VK_TSTAR    L'*'               // *           
#define VK_TPOUND   L'#'               // #   
// *** [EOF] you add ***
// ***

// App keys
#define VK_APP1     0xC1 
#define VK_APP2     0xC2 
#define VK_APP3     0xC3
#define VK_APP4     0xC4
#define VK_APP5     0xC5
#define VK_APP6     0xC6

// *** [SOF] you add ***
// Scan key
#define VK_SCAN           0x0E
// *** [EOF] you add ***

3、添加按键类型定义:

在C:\WINCE600\PLATFORM\SMDK6410\SRC\INC\bsp_cfg.h文件中添加定义:(具体可参考驱动目录下的bsp_cfg.h文件)

#define LAYOUT3                (3)        // Self Define Key	// *** you add ***
//#define MATRIX_LAYOUT        (LAYOUT1)	// *** you disable ***
#define MATRIX_LAYOUT        (LAYOUT3)		// *** you add ***



二、 添加虚拟按键映射

具体可参考驱动目录下相应的文件。

1、扫描键值映射虚拟按键定义:(如下)

// *** [SOF] you add ***
#elif (MATRIX_LAYOUT == LAYOUT3)
#define ScanCodeTableFirst  0x00
#define ScanCodeTableLast   0x1d

UINT8 ScanCodeToVKeyTable[] =
{
	VK_RETURN,			// scan code 0		// 确定、回车
	VK_SCAN,			// scan code 1		// 扫描
	VK_ESCAPE,			// scan code 2		// 取消
	VK_DELETE,			// scan code 3		// 删除
	VK_BACK,			// scan code 4		// 退格
	VK_UP,				// scan code 5		// 上
	VK_RIGHT,			// scan code 6		// 右
	VK_DOWN,			// scan code 7		// 下
	VK_LEFT,			// scan code 8		// 左
	VK_TEND,			// scan code 9		// 结束通话
	VK_TTALK,			// scan code 10		// 通话
	VK_T3,				// scan code 11		// 3
	VK_T2,				// scan code 12		// 2
	VK_T1,				// scan code 13		// 1
	VK_T6,				// scan code 14		// 6
	VK_T5,				// scan code 15		// 5
	VK_T4,				// scan code 16		// 4
	VK_T9,				// scan code 17		// 9
	VK_T8,				// scan code 18		// 8
	VK_T7,				// scan code 19		// 7
	VK_TPOUND,			// scan code 20		// #
	VK_T0,				// scan code 21		// 0
	VK_TSTAR,			// scan code 22		// *
	VK_SPACE,			// scan code 23		// 空格
	VK_F1,				// scan code 24		// F1
	0,					// scan code 25
	0,					// scan code 26
	0,					// scan code 27
	0,					// scan code 28
	0,					// scan code 29
};
// *** [EOF] you add ***



2、添加ScanCodeToVKeyExtTable定义:(如下)

// *** [SOF] you add ***
#elif (MATRIX_LAYOUT == LAYOUT3)
#define ScanCodeTableExtFirst  0xE000
#define ScanCodeTableExtLast   0xE01d

UINT8 ScanCodeToVKeyExtTable[] =
{ 
	VK_RETURN,			// scan code 0		// 确定、回车
	VK_SCAN,			// scan code 1		// 扫描
	VK_ESCAPE,			// scan code 2		// 取消
	VK_DELETE,			// scan code 3		// 删除
	VK_BACK,			// scan code 4		// 退格
	VK_UP,				// scan code 5		// 上
	VK_RIGHT,			// scan code 6		// 右
	VK_DOWN,			// scan code 7		// 下
	VK_LEFT,			// scan code 8		// 左
	VK_TEND,			// scan code 9		// 结束通话
	VK_TTALK,			// scan code 10		// 通话
	VK_T3,				// scan code 11		// 3
	VK_T2,				// scan code 12		// 2
	VK_T1,				// scan code 13		// 1
	VK_T6,				// scan code 14		// 6
	VK_T5,				// scan code 15		// 5
	VK_T4,				// scan code 16		// 4
	VK_T9,				// scan code 17		// 9
	VK_T8,				// scan code 18		// 8
	VK_T7,				// scan code 19		// 7
	VK_TPOUND,			// scan code 20		// #
	VK_T0,				// scan code 21		// 0
	VK_TSTAR,			// scan code 22		// *
	VK_SPACE,			// scan code 23		// 空格
	VK_F1,				// scan code 24		// F1
	0,					// scan code 25
	0,					// scan code 26
	0,					// scan code 27
	0,					// scan code 28
	0,					// scan code 29
};
// *** [EOF] you add ***



三、 添加扫描按键相关处理

主要操作C:\WINCE600\PLATFORM\SMDK6410\src\drivers\Keybd\keypad\.\keymatrix.cpp文件。(具体参考驱动下面相应的文件)

1、添加不同类型键盘的行列定义:(橙色字体部分为需要添加或修改的)

#if ((MATRIX_LAYOUT == LAYOUT0)||(MATRIX_LAYOUT == LAYOUT2))   //***********************  modify by alexlee	// *** you enable ***
//#if 1		// *** you disable ***
#define SIZE_BITS   8
#define SIZE_COLS   8
#define SIZE_ROWS   8
#elif (MATRIX_LAYOUT == LAYOUT1)
#define SIZE_BITS   2
#define SIZE_COLS   5
#define SIZE_ROWS   2
// *** [SOF] you add ***
#elif (MATRIX_LAYOUT == LAYOUT3)
#define SIZE_BITS   6
#define SIZE_COLS   5
#define SIZE_ROWS   6
// *** [EOF] you add ***
#endif


2、添加扫描键值定义:(橙色字体部分为需要添加或修改的)

#if (MATRIX_LAYOUT == LAYOUT0) //*************  modify by alexlee	// *** you enable ***
//#if (1)	// *** you disable *** 
struct KSTATE KeyChange[SIZE_KEY];
struct KCODE KeyCode[SIZE_KEY] =
{
    {KCODE_TYPE_NORMAL , 0x0000 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0001 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0002 , 0, 0},
…省略N多,具体请看相应的文件

// *** [SOF] you add ***
#elif (MATRIX_LAYOUT == LAYOUT3)
struct KSTATE KeyChange[SIZE_KEY];
struct KCODE KeyCode[SIZE_KEY] =
{
    {KCODE_TYPE_NORMAL , 0x0000 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0001 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0002 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0003 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0004 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0005 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0006 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0007 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0008 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0009 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x000a , 0, 0},
    {KCODE_TYPE_NORMAL , 0x000b , 0, 0},
    {KCODE_TYPE_NORMAL , 0x000c , 0, 0},
    {KCODE_TYPE_NORMAL , 0x000d , 0, 0},
    {KCODE_TYPE_NORMAL , 0x000e , 0, 0},
    {KCODE_TYPE_NORMAL , 0x000f , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0010 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0011 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0012 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0013 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0014 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0015 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0016 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0017 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0018 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x0019 , 0, 0},
    {KCODE_TYPE_NORMAL , 0x001a , 0, 0},
    {KCODE_TYPE_NORMAL , 0x001b , 0, 0},
    {KCODE_TYPE_NORMAL , 0x001c , 0, 0},
    {KCODE_TYPE_NORMAL , 0x001d , 0, 0}
};
// *** [EOF] you add ***
#endif

3、添加上电初始化处理:

在BOOL KeyMatrix::KeybdPowerOn()函数中,添加修改如下:(橙色字体部分为修改或添加部分)

#if ((MATRIX_LAYOUT == LAYOUT0)||(MATRIX_LAYOUT == LAYOUT2))   //***********   modify by AlexLee 	// *** you enable ***
//#if 1		// *** you disable ***
    pKeyPadReg->KEYIFCOL = (0x00<<8);
#elif (MATRIX_LAYOUT == LAYOUT1)
    pKeyPadReg->KEYIFCOL = (0x7<<8);
// *** [SOF] you add ***
#elif (MATRIX_LAYOUT == LAYOUT3)
	pKeyPadReg->KEYIFCOL = (0x00<<8);	// *** *** not make sure *** ***
// *** [EOF] you add ***
#endif

4、修改GPIO_CtrlHandler函数中的处理:

修改static void

#if ((MATRIX_LAYOUT == LAYOUT0)||(MATRIX_LAYOUT == LAYOUT2))  //***********   modify by AlexLee		// *** you enable ***
//#if 1	// *** you disable ***

中间部分省略。。。
// *** [SOF] you add ***
#elif (MATRIX_LAYOUT == LAYOUT3)
    if(iClass == ENUM_COL)    // Column setting
    {
        switch(iLevel)
        {
        case ENUM_INPUT :
            pGPIOReg->GPLCON0=
                (pGPIOReg->GPLCON0 & ~(0xfffff<<0)) | (0x00000<<0);    //KBC_0(GPL0)~ KBC_4(GPL4)
            break;
        case ENUM_OUTPUT :
            pGPIOReg->GPLCON0=
                (pGPIOReg->GPLCON0 & ~(0xfffff<<0)) | (0x11111<<0);    //KBC_0(GPL0)~ KBC_4(GPL4)
            break;
        case ENUM_AUXFUNC :
            pGPIOReg->GPLCON0=
                (pGPIOReg->GPLCON0 & ~(0xfffff<<0)) | (0x33333<<0);    //KBC_0(GPL0)~ KBC_4(GPL4)
            break;
        default :    //ENUM_RESERVED
            pGPIOReg->GPLCON0=
                (pGPIOReg->GPLCON0 & ~(0xfffff<<0)) | (0x44444<<0);    //KBC_0(GPL0)~ KBC_4(GPL4)
            break;
        }
    }
    else if(iClass == ENUM_ROW)        // Row Setting
    {
        switch(iLevel)
        {
        case ENUM_INPUT :
            pGPIOReg->GPKCON1=
                (pGPIOReg->GPKCON1 & ~(0xffffff<<0)) | (0x000000<<0);    //KBR_0(GPK8)~ KBR_5(GPK13)
            break;
        case ENUM_OUTPUT :
            pGPIOReg->GPKCON1=
                (pGPIOReg->GPKCON1 & ~(0xffffff<<0)) | (0x111111<<0);    //KBR_0(GPK8)~ KBR_5(GPK13)
            break;
        case ENUM_AUXFUNC :
            pGPIOReg->GPKCON1=
                (pGPIOReg->GPKCON1 & ~(0xffffff<<0)) | (0x333333<<0);    //KBR_0(GPK8)~ KBR_5(GPK13)
            break;
        default :    //ENUM_RESERVED
            pGPIOReg->GPKCON1=
                (pGPIOReg->GPKCON1 & ~(0xffffff<<0)) | (0x444444<<0);    //KBR_0(GPK8)~ KBR_5(GPK13)
            break;
        }
    }
    else
    {
        DEBUGMSG(1,(TEXT("Invalid Parameter\r\n")));
    }
// *** [EOF] you add ***
#endif
}

5、修改KEYIF_Column_Bitset函数中的处理:

修改tatic void KEYIF_Column_Bitset(bool bVal, int

static void KEYIF_Column_Bitset(bool bVal, int cIdx)
{
#if ((MATRIX_LAYOUT == LAYOUT0)||(MATRIX_LAYOUT == LAYOUT2)) //***********   modify by AlexLee	// *** you enable ***
//#if 1		// *** you disable ***
    if(bVal)
    {
        pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0x1 << cIdx);
    }
    else
    {
        pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0xff & ~(0x1 << cIdx));
    }
#elif (MATRIX_LAYOUT == LAYOUT1)
    if(bVal)
    {
        pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0x1 << (cIdx+3));
    }
    else
    {
        pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0xff & ~(0x1 << (cIdx+3)));
    }
// *** [SOF] you add ***
#elif (MATRIX_LAYOUT == LAYOUT3)
    if(bVal)
    {
        pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0x1 << cIdx);	// *** not make sure ***
    }
    else
    {
        pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0xff & ~(0x1 << cIdx));	// *** not make sure ***
    }
// *** [EOF] you add ***
#endif
}

6、修改为自定义按键键码映射:修改_KScan_ProcState函数

把以下这几句:

keybd_event(0x30+idx ,0x30+idx, 0, 0);
Sleep(1);
keybd_event(0x30 + idx ,0x30 + idx, KEYEVENTF_KEYUP, 0);

修改成:


if(ScanCodeToVKeyTable[idx] == VK_TPOUND){// #
	// 模拟 key down
	keybd_event(VK_SHIFT, 0, 0, 0);
	keybd_event(VK_T3, 0, 0, 0);
	Sleep(1);
	// 模拟 key up
	keybd_event(VK_T3, 0, KEYEVENTF_KEYUP, 0);
	keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
}
else if(ScanCodeToVKeyTable[idx] == VK_TSTAR){// *
	// 模拟 key down
	keybd_event(VK_SHIFT, 0, 0, 0);
	keybd_event(VK_T8, 0, 0, 0);
	Sleep(1);
	// 模拟 key up
	keybd_event(VK_T8, 0, KEYEVENTF_KEYUP, 0);
	keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
}
else{
	keybd_event(ScanCodeToVKeyTable[idx] ,idx, 0, 0);
	Sleep(1);
	keybd_event(ScanCodeToVKeyTable[idx] ,idx, KEYEVENTF_KEYUP, 0);
}

当然,在该函数前头要添加引用外部变量:(由于该处引用到了按键键值,所以需要添加头文件:#include"winuserm.h")

extern

注意:应用层再使用到*和#这两个按键的时候,需要对应到VK_TSTAR和VK_TPOUND键值



到这里基本结束了,编译一下这个键盘驱动就OK。


上述已经测试通过,在此备忘一下。