⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keymatrix.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
*	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 + -