📄 keymatrix.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <Pmpolicy.h>
#undef ZONE_INIT
#define INIT_MSG 0
#include <keybddbg.h>
#include <keybddr.h>
#include <keybdpdd.h>
#include <keybdist.h>
#include <oal.h>
#include <s3c6400.h>
#include <DrvLib.h>
#include "keymatrix.hpp"
#define KEY_POWER_ON (1<<11) // PCLKCON
#define FT_CLK_DIV (FIN/32000 - 1)
// Pointer to device control registers
volatile S3C6400_GPIO_REG *pGPIOReg = NULL;
volatile S3C6400_KEYPAD_REG *pKeyPadReg = NULL;
volatile S3C6400_SYSCON_REG *pSysConReg = NULL;
BOOL g_bHandleWakeup=FALSE;
// There is really only one physical keyboard supported by the system.
KeyMatrix *Keyboard;
extern void ReadRegDWORD( LPCWSTR szKeyName, LPCWSTR szValueName, LPDWORD pdwValue );
/*****************************************************************************
* Function Name : GPIO Handling function
* Function Desc : GPIO_PuEnable, GPIO_CtrlHandler
* Pull up Enable/Disable
* GPIO Control register configuration only related to KEYPAD
* GPIO Data register setting only related to KEYPAD
*/
typedef enum {
ENUM_INPUT = 0,
ENUM_OUTPUT,
ENUM_AUXFUNC,
ENUM_RESERVED
} ENUM_GPIO_FUNC;
typedef enum {
ENUM_ROW,
ENUM_COL
} ENUM_COL_ROW;
static void GPIO_PuEnable(ENUM_COL_ROW iClass, bool bFlag);
static void GPIO_CtrlHandler(ENUM_COL_ROW iClass, ENUM_GPIO_FUNC iLevel);
static void KEYIF_Column_Set(DWORD dVal);
static void KEYIF_Column_Bitset(bool bVal, int cIdx);
static DWORD KEYIF_Row_Read(void);
static void KEYIF_Status_Clear(void);
void Keypad_Clock_On(BOOL bOn);
/*****************************************************************************/
/*****************************************************************************
* Function Name : KeybdPdd_PowerHandler
* Function Desc : Power Handler
*
*/
void WINAPI KeybdPdd_PowerHandler(BOOL bOff)
{
if (!bOff)
{
g_bHandleWakeup=TRUE;
Keyboard->KeybdPowerOn();
}
else
{
g_bHandleWakeup=FALSE;
Keyboard->KeybdPowerOff();
}
return;
}
/****************************************************************************/
/*****************************************************************************
* Function Name : KeybdDriverInitializeAddresses
* Function Desc : KeyBoard Driver Initialization
* Read Registry
*
*/
BOOL KeybdDriverInitializeAddresses(void)
{
bool RetValue = TRUE;
DWORD dwSYSCONBase;
DWORD dwIOBase;
DWORD dwIOCTRLBase;
RETAILMSG(INIT_MSG,(TEXT("++[KEYBD]KeybdDriverInitializeAddresses\r\n")));
DEBUGMSG(1,(TEXT("++KeybdDriverInitializeAddresses\r\n")));
ReadRegDWORD(TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("SYSCONBase"), &dwSYSCONBase );
if(dwSYSCONBase == 0)
{
DEBUGMSG(1, (TEXT("Can't fount registry entry : HARDWARE\\DEVICEMAP\\KEYBD\\SYSCONBase\r\n")));
goto error_return;
}
DEBUGMSG(1, (TEXT("HARDWARE\\DEVICEMAP\\KEYBD\\SYSCONBase:%x\r\n"), dwSYSCONBase));
ReadRegDWORD(TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("IOBase"), &dwIOBase );
if(dwIOBase == 0)
{
DEBUGMSG(1, (TEXT("Can't fount registry entry : HARDWARE\\DEVICEMAP\\KEYBD\\IOBase\r\n")));
goto error_return;
}
DEBUGMSG(1, (TEXT("HARDWARE\\DEVICEMAP\\KEYBD\\IOBase:%x\r\n"), dwIOBase));
ReadRegDWORD(TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("IOCTRLBase"), &dwIOCTRLBase );
if(dwIOCTRLBase == 0)
{
DEBUGMSG(1, (TEXT("Can't fount registry entry : HARDWARE\\DEVICEMAP\\KEYBD\\IOCTRLBase\r\n")));
goto error_return;
}
DEBUGMSG(1, (TEXT("HARDWARE\\DEVICEMAP\\KEYBD\\IOCTRLBase:%x\r\n"), dwIOCTRLBase));
// Syscon Virtual alloc
pSysConReg = (S3C6400_SYSCON_REG *)DrvLib_MapIoSpace(dwSYSCONBase, sizeof(S3C6400_SYSCON_REG), FALSE);
if (pSysConReg == NULL)
{
DEBUGMSG(1,(TEXT("[KBD] pSysConReg : DrvLib_MapIoSpace failed!\r\n")));
goto error_return;
}
DEBUGMSG(1, (TEXT("[KBD] pSysConReg mapped at %x\r\n"), pSysConReg));
// GPIO Virtual alloc
pGPIOReg = (S3C6400_GPIO_REG *)DrvLib_MapIoSpace(dwIOBase, sizeof(S3C6400_GPIO_REG), FALSE);
if (pGPIOReg == NULL)
{
DEBUGMSG(1,(TEXT("[KBD] pGPIOReg : DrvLib_MapIoSpace failed!\r\n")));
goto error_return;
}
DEBUGMSG(1, (TEXT("[KBD] pGPIOReg mapped at %x\r\n"), pGPIOReg));
// Keypad Virtual alloc
pKeyPadReg = (S3C6400_KEYPAD_REG *)DrvLib_MapIoSpace(dwIOCTRLBase, sizeof(S3C6400_KEYPAD_REG), FALSE);
if (pKeyPadReg == NULL)
{
DEBUGMSG(1,(TEXT("[KBD] pKeyPadReg : DrvLib_MapIoSpace failed!\r\n")));
goto error_return;
}
DEBUGMSG(1, (TEXT("[KBD] pKeyPadReg mapped at %x\r\n"), pKeyPadReg));
DEBUGMSG(1,(TEXT("--KeybdDriverInitializeAddresses\r\n")));
return TRUE;
error_return:
if ( pSysConReg )
{
DrvLib_UnmapIoSpace((PVOID)pSysConReg);
pSysConReg = NULL;
}
if ( pGPIOReg )
{
DrvLib_UnmapIoSpace((PVOID)pGPIOReg);
pGPIOReg = NULL;
}
if ( pKeyPadReg )
{
DrvLib_UnmapIoSpace((PVOID)pKeyPadReg);
pKeyPadReg = NULL;
}
DEBUGMSG(1,(TEXT("--KeybdDriverInitializeAddresses[FAILED!!!]\r\n")));
return FALSE;
}
/****************************************************************************/
#if (MATRIX_LAYOUT == LAYOUT0)
#define SIZE_BITS 8
#define SIZE_COLS 8
#define SIZE_ROWS 8
#else
#define SIZE_BITS 8
#define SIZE_COLS 2
#define SIZE_ROWS 8
#endif
DWORD ChangeState[SIZE_COLS];
DWORD KeyState[SIZE_COLS];
DWORD FaultKey;
#define KCODE_TYPE_NORMAL 0x0001
#define KCODE_TYPE_SL 0x0002
#define SIZE_KEY SIZE_COLS * SIZE_ROWS
#define CNT_VALIDKEY 1
#define CNT_LONGKEY 30
#define TIME_KEYSCAN 10
#define SCAN_EXT 0xe000
struct KSTATE
{
WORD Mask;
WORD Cnt;
};
struct KCODE
{
DWORD Type;
DWORD Scan;
DWORD TimeoutCnt; // used by KCODE_TYPE_SL
BOOL Fin;
};
#if (MATRIX_LAYOUT == LAYOUT0)
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},
{KCODE_TYPE_NORMAL , 0x001e , 0, 0},
{KCODE_TYPE_NORMAL , 0x001f , 0, 0},
{KCODE_TYPE_NORMAL , 0x0020 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0021 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0022 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0023 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0024 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0025 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0026 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0027 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0028 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0029 , 0, 0},
{KCODE_TYPE_NORMAL , 0x002a , 0, 0},
{KCODE_TYPE_NORMAL , 0x002b , 0, 0},
{KCODE_TYPE_NORMAL , 0x002c , 0, 0},
{KCODE_TYPE_NORMAL , 0x002d , 0, 0},
{KCODE_TYPE_NORMAL , 0x002e , 0, 0},
{KCODE_TYPE_NORMAL , 0x002f , 0, 0},
{KCODE_TYPE_NORMAL , 0x0030 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0031 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0032 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0033 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0034 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0035 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0036 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0037 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0038 , 0, 0},
{KCODE_TYPE_NORMAL , 0x0039 , 0, 0},
{KCODE_TYPE_NORMAL , 0x003a , 0, 0},
{KCODE_TYPE_NORMAL , 0x003b , 0, 0},
{KCODE_TYPE_NORMAL , 0x003c , 0, 0},
{KCODE_TYPE_NORMAL , 0x003d , 0, 0},
{KCODE_TYPE_NORMAL , 0x003e , 0, 0},
{KCODE_TYPE_NORMAL , 0x003f , 0, 0},
};
#else
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}
};
#endif
/*****************************************************************************
* Function Name : VarInit, AreAllKeysUp
* Function Desc : Miscellaneous Function
*
*/
void VarInit(void)
{
int i;
for( i=0; i<SIZE_KEY; i++)
{
KeyChange[i].Mask = 0;
KeyChange[i].Cnt = 0;
}
}
BOOL AreAllKeysUp(void)
{
DWORD tmp = 0, tmp1 = 0, i;
for(i=0;i<SIZE_COLS;i++)
{
tmp |= KeyState[i];
tmp1 |= ChangeState[i];
}
return (tmp || tmp1)? FALSE:TRUE;
}
/****************************************************************************/
/*****************************************************************************
* Function Name : _KScan_ProcState
* Function Desc : Handle KeyMatrix State
*
*/
DWORD _KScan_ProcState(int kidx, int idx, PDWORD key, PBOOL press)
{
int val, i;
DWORD count = 0;
int mask;
val = ChangeState[kidx];
for(i=0;i<SIZE_BITS;i++)
{
mask = 1<<i;
if( (KeyState[kidx] & mask) && (KeyCode[idx].Type == KCODE_TYPE_SL) && (KeyCode[idx].Fin == 0) )
{
if( (KeyCode[idx].TimeoutCnt == CNT_LONGKEY) )
{
// key down
*key++ = KeyCode[idx].Scan | SCAN_EXT;
*press++ = FALSE;
// key up
*key++ = KeyCode[idx].Scan | SCAN_EXT;
*press++ = TRUE;
count+=2;
KeyCode[idx].TimeoutCnt = 0;
KeyCode[idx].Fin = TRUE;
//RETAILMSG(1, (TEXT(">>> KSCAN:LONG[%d] - %d, key - 0x%x\r\n"), idx, KeyCode[idx].Scan,*key));
}
else
{
KeyCode[idx].TimeoutCnt++;
}
}
// state chaned
if( val & mask )
{
// Need to check wheater the key changed really
if( KeyChange[idx].Cnt == 0 ) // in counting
{
KeyChange[idx].Cnt = CNT_VALIDKEY;
KeyChange[idx].Mask = ( KeyState[kidx] & mask )? 0: mask;
}
else
{
// checked key state
if( KeyChange[idx].Mask != (KeyState[kidx] & mask) )
{
if( --KeyChange[idx].Cnt == 0 )
{
if( KeyChange[idx].Mask == 0 )
{
// Key UP
if( KeyCode[idx].Type == KCODE_TYPE_NORMAL )
{
*key++ = KeyCode[idx].Scan;
*press++ = TRUE;
count++;
//RETAILMSG(1, (TEXT(">>> KSCAN:UP [%d] - %d\r\n"), idx, KeyCode[idx].Scan));
}
else
{
// KCODE_TYPE_SL
if( KeyCode[idx].Fin == FALSE )
{
// key down
*key++ = KeyCode[idx].Scan;
*press++ = FALSE;
// key up
*key++ = KeyCode[idx].Scan;
*press++ = TRUE;
count+=2;
KeyCode[idx].Fin = TRUE;
//RETAILMSG(1, (TEXT(">>> KSCAN:SHORT[%d] - %d\r\n"), idx, KeyCode[idx].Scan));
}
}
KeyState[kidx] &= ~mask;
}
else
{
// Key Down
if( KeyCode[idx].Type == KCODE_TYPE_NORMAL )
{
*key++ = KeyCode[idx].Scan;
*press++ = FALSE;
count++;
//RETAILMSG(1, (TEXT(">>> KSCAN:DOWN[%d] - %d\r\n"), idx, KeyCode[idx].Scan));
}
else
{
// KCODE_TYPE_SL
KeyCode[idx].TimeoutCnt = 0;
KeyCode[idx].Fin = FALSE;
}
KeyState[kidx] |= mask;
}
}
}
else
{
KeyChange[idx].Cnt = 0;
RETAILMSG(0, (TEXT(">>> KSCAN:Must be not occurred[%d] %x, %llx, %llx\r\n"), idx,KeyChange[idx].Mask,KeyState,mask));
}
}
}
else
{
if( KeyChange[idx].Cnt ) // in counting
{
KeyChange[idx].Cnt = 0;
RETAILMSG(0, (TEXT(">>> KSCAN:Canceled [%d]\r\n"), idx));
}
}
idx++;
}
return count;
}
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -