📄 keymatrix.cpp
字号:
/*****************************************************************************
* Function Name : KScan_ProcIO
* Function Desc : Scan code
* Read KEYIF
*
*/
void KScan_ProcIO(void)
{
int i;
// KBC_0 ~ KBC_7
for(i = 0 ; i < SIZE_COLS; i++)
{
KEYIF_Column_Set(0x0);
// select a column
KEYIF_Column_Bitset(false,i);
Sleep(1);
ChangeState[i] = KeyState[i]^((~ KEYIF_Row_Read())&0xff);
//RETAILMSG(1, (TEXT("[KSCAN](%d)-%x\r\n"), i, ChangeState[i]));
Sleep(1);
}
KEYIF_Column_Set(0x0);
}
/****************************************************************************/
/*****************************************************************************
* Function Name : KScan_SetINTMode
* Function Desc : Initialize the H/W
*
*/
void KScan_SetINTMode(void)
{
//RETAILMSG(1,(TEXT("+Select all column\r\n")));
// select all column - Set Keypad column GPIO to output(low)
GPIO_CtrlHandler(ENUM_COL, ENUM_AUXFUNC);
// GPIO_PuEnable(ENUM_COL, false);
KEYIF_Column_Set(0x0);
// configure - Set Keypad row GPIO to [Key PAD ROW]
GPIO_CtrlHandler(ENUM_ROW, ENUM_AUXFUNC);
// GPIO_PuEnable(ENUM_ROW, false);
// unmask the key interrupt
KEYIF_Status_Clear();
}
/****************************************************************************/
/*****************************************************************************
* Function Name : KeybdPdd_ToggleKeyNotification
* Function Desc : Toggle Key
*
*/
void WINAPI KeybdPdd_ToggleKeyNotification(KEY_STATE_FLAGS KeyStateFlags)
{
unsigned int fLights;
DEBUGMSG(1, (TEXT("KeybdPdd_ToggleKeyNotification\r\n")));
fLights = 0;
if (KeyStateFlags & KeyShiftCapitalFlag)
{
fLights |= 0x04;
}
if (KeyStateFlags & KeyShiftNumLockFlag)
{
fLights |= 0x2;
}
/*
Keyboard lights is disabled once driver is installed because the
PS2 controller sends back a response which goes to the IST and corrupts
the interface. When we figure out how to disable the PS2 response we
can re-enable the lights routine below
*/
return;
}
/****************************************************************************/
/*****************************************************************************
* Function Name : IsrThreadProc
* Function Desc : IST of KeyBD D/D
* Create IST
* Wait for Event according to the KEYPAD INT
* KScan_SetIOMode() : Handle H/W
* KScan_ProcIO() :
* _KScan_ProcState() :
*
*/
extern UINT v_uiPddId;
extern PFN_KEYBD_EVENT v_pfnKeybdEvent;
BOOL KeyMatrix::IsrThreadProc()
{
DWORD dwPriority;
DWORD i, step;
DWORD rguiScanCode[SIZE_KEY];
BOOL rgfKeyUp[SIZE_KEY];
UINT cEvents;
DWORD ret;
DWORD timeout;
HANDLE gEventIntr;
DWORD irq, sysintr;
ReadRegDWORD( TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("Priority256"), &dwPriority );
if(dwPriority == 0)
{
dwPriority = 145;
}
RETAILMSG( INIT_MSG, (TEXT("+[KEYBD]IsrThreadProc\r\n")));
// update the IST priority
CeSetThreadPriority(GetCurrentThread(), (int)dwPriority);
irq = IRQ_KEYPAD;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(UINT32), &sysintr, sizeof(UINT32), NULL))
{
ERRORMSG( 1, (TEXT("ERROR: Failed to request the IRQ_KEY sysintr.\r\n")));
sysintr = SYSINTR_UNDEFINED;
return(FALSE);
}
gEventIntr = CreateEvent(NULL, FALSE, FALSE, NULL);
if( NULL == gEventIntr )
{
ERRORMSG( 1, (TEXT("Event is not created\r\n")));
return(FALSE);
}
if( InterruptInitialize(sysintr, gEventIntr, NULL, 0) == FALSE )
{
ERRORMSG( 1, (TEXT("interrupt is not initialized\n\r")));
return(FALSE);
}
timeout = INFINITE;
RETAILMSG( INIT_MSG, (TEXT("+[KEYBD]Enter Infinite Loop\r\n")));
while(1) // INFINITE LOOP ____________________________________________________________________
{
ret = WaitForSingleObject(gEventIntr, timeout); // Wait for Interrupt Event ________________________
if( ret == WAIT_OBJECT_0 )
{
//RETAILMSG( 1,(TEXT("Object : WAIT_OBJECT_0\r\n")));
timeout = TIME_KEYSCAN;
}
// WAIT_TIMEOUT
if(g_bHandleWakeup)
{
PowerPolicyNotify(PPN_POWERBUTTONPRESSED, 0);
g_bHandleWakeup=FALSE;
RETAILMSG(1,(TEXT("IsrThreadProc: WakeUp\r\n")));
}
// Clear Pressed/Released Interrupt
KEYIF_Status_Clear();
// Read the Matrix
KScan_ProcIO();
for( i=0, step=0; i< SIZE_COLS; i++, step+=SIZE_ROWS)
{
cEvents = _KScan_ProcState( i, step, rguiScanCode, rgfKeyUp);
if( cEvents )
{
for (UINT iEvent = 0; iEvent < cEvents; ++iEvent)
{
v_pfnKeybdEvent(v_uiPddId, rguiScanCode[iEvent], rgfKeyUp[iEvent]);
//RETAILMSG(1,(TEXT("PddID : %x, ScanCode : %x, KeyUp : %d\r\n"),v_uiPddId, rguiScanCode[iEvent], rgfKeyUp[iEvent]));
}
}
}
if( TRUE == AreAllKeysUp() )
{
RETAILMSG(0,(TEXT("Key all up\r\n")));
timeout = INFINITE;
}
InterruptDone(sysintr);
}// INFINITE LOOP ____________________________________________________________________
}
/****************************************************************************/
/*****************************************************************************
* Function Name : KBDISRThread
* Function Desc : Keybd IST Wrapper
* Call KeyMatrix.IsrThreadProc()
*
*/
DWORD KBDISRThread(KeyMatrix *pp2k)
{
RETAILMSG(INIT_MSG,(TEXT("[KEYBD]KBDISRThread:\r\n")));
pp2k->IsrThreadProc();
return 0;
}
/****************************************************************************/
/*****************************************************************************
* Function Name : IsrThreadStart
* Function Desc : IST start function
*
*/
BOOL KeyMatrix::IsrThreadStart()
{
HANDLE hthrd;
RETAILMSG(INIT_MSG,(TEXT("+[KEYBD]IsrThreadStart:\r\n")));
hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)KBDISRThread,this,0,NULL);
// Since we don't need the handle, close it now.
CloseHandle(hthrd);
RETAILMSG(INIT_MSG,(TEXT("-[KEYBD]IsrThreadStart:\r\n")));
return TRUE;
}
/****************************************************************************/
/*****************************************************************************
* Function Name : KeybdPowerOn
* Function Desc : Power on function
* Key array (mask, cnt) initialization, GPIO, Interrupt Initialization
*
*/
BOOL KeyMatrix::KeybdPowerOn()
{
RETAILMSG(INIT_MSG,(TEXT("++[KEYBD]KeyMatrix::KeybdPowerOn\r\n")));
//
// enable the Keypad Clock (PCLK)
//
Keypad_Clock_On(TRUE);
pKeyPadReg->KEYIFCON = INT_F_DISABLE|INT_R_ENABLE|DF_EN_EN|FC_EN_EN;
//Keypad interfae debouncing filter clock division register
pKeyPadReg->KEYIFFC = FC_DIV_VAL(FT_CLK_DIV);
#if (MATRIX_LAYOUT == LAYOUT0)
pKeyPadReg->KEYIFCOL = (0x00<<8);
#else
pKeyPadReg->KEYIFCOL = (0x3f<<8);
#endif
VarInit();
KScan_SetINTMode();
RETAILMSG(INIT_MSG,(TEXT("--[KEYBD]KeyMatrix::KeybdPowerOn\r\n")));
return(TRUE);
}
/****************************************************************************/
/*****************************************************************************
* Function Name : KeybdPowerOff
* Function Desc : Power off function
* Mask KEYIF INT, Column Low
*
*/
BOOL KeyMatrix::KeybdPowerOff()
{
DEBUGMSG(1,(TEXT("++KeyMatrix::KeybdPowerOff\r\n")));
// Clear Pressed/Released Interrupt
KEYIF_Status_Clear();
// select all column - Set Keypad column GPIO to output(low)
GPIO_CtrlHandler(ENUM_COL, ENUM_AUXFUNC);
KEYIF_Column_Set(0x0);
// configure - Set Keypad row GPIO to [Key PAD ROW]
GPIO_CtrlHandler(ENUM_ROW, ENUM_AUXFUNC);
//Clock Off
Keypad_Clock_On(FALSE);
DEBUGMSG(1,(TEXT("--KeyMatrix::KeybdPowerOff\r\n")));
return(TRUE);
}
/****************************************************************************/
/*****************************************************************************
* 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
*
*/
/**
[iClass] 0: Column, 1: Row
[bFlag] 0: Pull up Enable, 1 : Pull up Disable
*/
static void GPIO_PuEnable(ENUM_COL_ROW iClass, bool bFlag)
{
if(iClass == ENUM_COL) // Column setting
{
if(bFlag) // Pull up Enable
{
pGPIOReg->GPLPUD = pGPIOReg->GPLPUD | (0xaaaa<<0); // KBC_0~7
}
else // Pull up Disable
{
pGPIOReg->GPLPUD = pGPIOReg->GPLPUD & ~ (0xffff<<0); // KBC_0~7
}
}
else // Row Setting
{
if(bFlag) // Pull up Enable
{
pGPIOReg->GPKPUD = pGPIOReg->GPKPUD | (0xaaaa<<16); // KBR_0~7
}
else // Pull up Disable
{
pGPIOReg->GPKPUD = pGPIOReg->GPKPUD & ~ (0xffff<<16); // KBR_0~7
}
}
}
/**
[iClass] 0: Column, 1: Row
[iLevel] 0: INPUT, 1 : OUTPUT, 2 : Aux. Function, 3 : Reserved
*/
static void GPIO_CtrlHandler(ENUM_COL_ROW iClass, ENUM_GPIO_FUNC iLevel)
{
#if (MATRIX_LAYOUT == LAYOUT0)
if(iClass == ENUM_COL) // Column setting
{
switch(iLevel)
{
case ENUM_INPUT :
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xffffffff<<0)) | (0x0<<0); //KBC_0(GPL0)~ KBC_8(GPL7)
break;
case ENUM_OUTPUT :
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xffffffff<<0)) | (0x11111111<<0); //KBC_0(GPL0)~ KBC_8(GPL7)
break;
case ENUM_AUXFUNC :
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xffffffff<<0)) | (0x33333333<<0); //KBC_0(GPL0)~ KBC_8(GPL7)
break;
default : //ENUM_RESERVED
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xffffffff<<0)) | (0x44444444<<0); //KBC_0(GPL0)~ KBC_8(GPL7)
break;
}
}
else if(iClass == ENUM_ROW) // Row Setting
{
switch(iLevel)
{
case ENUM_INPUT :
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x0<<0); //row break;
break;
case ENUM_OUTPUT :
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x11111111<<0); //row break;
break;
case ENUM_AUXFUNC :
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x33333333<<0); //KBR_0(GPK8)~ KBR_7(GPK15)
break;
default : //ENUM_RESERVED
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x44444444<<0); //KBR_0(GPK8)~ KBR_7(GPK15)
break;
}
}
else
{
DEBUGMSG(1,(TEXT("Invalid Parameter\r\n")));
}
#else
if(iClass == ENUM_COL) // Column setting
{
switch(iLevel)
{
case ENUM_INPUT :
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xff<<24)) | (0x0<<24); //KBC_6(GPL6)~ KBC_7(GPL7)
break;
case ENUM_OUTPUT :
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xff<<24)) | (0x11<<24); //KBC_6(GPL6)~ KBC_7(GPL7)
break;
case ENUM_AUXFUNC :
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xff<<24)) | (0x33<<24); //KBC_6(GPL6)~ KBC_7(GPL7)
break;
default : //ENUM_RESERVED
pGPIOReg->GPLCON0=
(pGPIOReg->GPLCON0 & ~(0xff<<24)) | (0x44<<24); //KBC_6(GPL6)~ KBC_7(GPL7)
break;
}
}
else if(iClass == ENUM_ROW) // Row Setting
{
switch(iLevel)
{
case ENUM_INPUT :
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x0<<0); //row break;
break;
case ENUM_OUTPUT :
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x11111111<<0); //row break;
break;
case ENUM_AUXFUNC :
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x33333333<<0); //KBR_0(GPK8)~ KBR_7(GPK15)
break;
default : //ENUM_RESERVED
pGPIOReg->GPKCON1=
(pGPIOReg->GPKCON1 & ~(0xffffffff<<0)) | (0x44444444<<0); //KBR_0(GPK8)~ KBR_7(GPK15)
break;
}
}
else
{
DEBUGMSG(1,(TEXT("Invalid Parameter\r\n")));
}
#endif
}
/**
[dVal] Value of KBC
*/
static void KEYIF_Column_Set(DWORD dVal)
{
pKeyPadReg->KEYIFCOL = (dVal & 0xff);
}
static void KEYIF_Column_Bitset(bool bVal, int cIdx)
{
#if (MATRIX_LAYOUT == LAYOUT0)
if(bVal)
{
pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0x1 << cIdx);
}
else
{
pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0xff & ~(0x1 << cIdx));
}
#else
if(bVal)
{
pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0x1 << (cIdx+6));
}
else
{
pKeyPadReg->KEYIFCOL = pKeyPadReg->KEYIFCOL | (0xff & ~(0x1 << (cIdx+6)));
}
#endif
}
static DWORD KEYIF_Row_Read(void)
{
return pKeyPadReg->KEYIFROW;
}
static void KEYIF_Status_Clear(void)
{
pKeyPadReg->KEYIFSTSCLR = CLEAR_P_INT|CLEAR_R_INT; // Clear Pressed/Released Interrupt
}
void Keypad_Clock_On(BOOL bOn)
{
if (bOn)
{
pSysConReg->PCLK_GATE |= KEY_POWER_ON;
}
else
{
pSysConReg->PCLK_GATE &= ~KEY_POWER_ON;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -