📄 s3c2410kbd.cpp
字号:
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;
}
/*
按键3个:
S1 KBD1---- EINT1/GPF1 VK_NUMPAD1
S2 KBD2---- EINT2/GPF2 VK_NUMPAD2
S3 KBD3---- EINT3/GPF3 VK_NUMPAD3
*/
BOOL check_key_updown(int event)
{
UINT32 level_data;
if(event<4)
{/*EINT 1~3*/
level_data=v_pIOPregs->rGPFDAT;
if(level_data&(1<<(event)))
return TRUE;
}
return FALSE;
}
BOOL KeybdIstLoop(PKEYBD_IST pKeybdIst,DWORD index )
{
SETFNAME(_T("KeybdIstLoop"));
UINT32 rguiScanCode[16];
BOOL rgfKeyUp[16];
DWORD event_signaled;
UINT32 scInProgress = 0;
/*
VK_NUMPAD1 ------ 0x0061
VK_NUMPAD2 ------ 0x0062
VK_NUMPAD3 ------ 0x0063
*/
UINT16 HDKEY_ScanCode[]={0x0061,0x0062,0x0063};
UINT32 scPrevious;
BOOL fKeyUp;
UINT8 ui8ScanCode;
UINT cEvents = 0;
DWORD waittime = INFINITE ;
DEBUGCHK(pKeybdIst->hevInterrupt != NULL);
DEBUGCHK(pKeybdIst->pfnKeybdEvent != NULL);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
while(1)
{
event_signaled=WaitForSingleObject(pKeybdIst->hevInterrupt, waittime);
// if(event_signaled ==WAIT_OBJECT_0)
{
// cEvents = (*pKeybdIst->pfnGetKeybdEvent)
// (pKeybdIst->uiPddId, rguiScanCode, rgfKeyUp);
ui8ScanCode = HDKEY_ScanCode[index];
ui8ScanCode=check_key_updown(index)?ui8ScanCode|scKeyUpMask:ui8ScanCode;
// RETAILMSG(1,
// (_T("scan code 0x%08x, code in progress 0x%08x, previous 0x%08x\r\n"),
// ui8ScanCode, scInProgress, scPrevious));
scInProgress = ui8ScanCode;
if (scInProgress == scPrevious) {
// mdd handles auto-repeat so ignore auto-repeats from keybd
} else {
// Not a repeated key. This is the real thing.
scPrevious = scInProgress;
if (ui8ScanCode & scKeyUpMask) {
fKeyUp = TRUE;
scInProgress &= ~scKeyUpMask;
waittime = INFINITE;
} else {
fKeyUp = FALSE;
waittime = 1000;
}
rguiScanCode[0] = scInProgress;
rgfKeyUp[0] = fKeyUp;
// for (UINT iEvent = 0; iEvent < cEvents; ++iEvent) {
(*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId,
rguiScanCode[0], rgfKeyUp[0]);
}
// cEvents could be 0 if this was a partial scan code, like 0xE0
if(event_signaled ==WAIT_OBJECT_0)
InterruptDone(g_dwSysIntr_Keybd[index]);
}
}
ERRORMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating.\r\n")));
return TRUE;
}
BOOL Ps2Keybd::IsrThreadProc(DWORD index)
{
DWORD dwPriority;
DWORD dwIrq_Keybd = dwIrq_Keybdbuf[index];
HANDLE m_hevInterrupt;
// int i;
// look for our priority in the registry -- this routine sets it to zero if
// it can't find it.
ReadRegDWORD( TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("Priority256"), &dwPriority );
if(dwPriority == 0) {
dwPriority = 240; // default value is 145
}
DEBUGMSG(1, (TEXT("IsrThreadProc:\r\n")));
// for(i=0;i<MAX_HDKEY;i++)
{
m_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL);
if (m_hevInterrupt == NULL) {
RETAILMSG(1, (TEXT("IsrThreadProc: InterruptInitialize\r\n")));
goto leave;
}
// ReadRegDWORD( TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("Irq"), &dwIrq_Keybd );
// Call the OAL to translate the IRQ into a SysIntr value.
//
#if 0
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIrq_Keybd, sizeof(DWORD), &g_dwSysIntr_Keybd[index], sizeof(DWORD), NULL))
{
RETAILMSG(1, (TEXT("ERROR: Failed to obtain sysintr value for keyboard interrupt.\r\n")));
g_dwSysIntr_Keybd[index] = SYSINTR_UNDEFINED;
goto leave;
}
#endif
if (!InterruptInitialize(g_dwSysIntr_Keybd[index],m_hevInterrupt,NULL,0)) {
RETAILMSG(1, (TEXT("IsrThreadProc: KeybdInterruptEnable\r\n")));
goto leave;
}
RETAILMSG(1,(TEXT("[KBD]m_hevInterrupt[%d]=0x%08x,irq=%d,sysIntr=%d\r\n"),index,m_hevInterrupt,dwIrq_Keybd,g_dwSysIntr_Keybd[index]));
}
// update the IST priority
CeSetThreadPriority(GetCurrentThread(), (int)dwPriority);
extern UINT v_uiPddId;
extern PFN_KEYBD_EVENT v_pfnKeybdEvent;
KEYBD_IST keybdIst;
keybdIst.hevInterrupt = m_hevInterrupt;
keybdIst.dwSysIntr_Keybd = g_dwSysIntr_Keybd[index];
keybdIst.uiPddId = v_uiPddId;
keybdIst.pfnGetKeybdEvent = NULL;//KeybdPdd_GetEventEx2;
keybdIst.pfnKeybdEvent = v_pfnKeybdEvent;
// IsrThreadStart();
KeybdIstLoop(&keybdIst,index);
leave:
return 0;
}
DWORD Ps2KeybdIsrThread(Ps2Keybd *pp2k)
{
DEBUGMSG(1,(TEXT("Ps2KeybdIsrThread:\r\n")));
pp2k->IsrThreadProc(pp2k->key_index);
return 0;
}
BOOL Ps2Keybd::IsrThreadStart()
{
HANDLE hthrd;
DEBUGMSG(1,(TEXT("IsrThreadStart:\r\n")));
while((key_index<(MAX_HDKEY))&&(key_index>=0))
{
hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Ps2KeybdIsrThread,this,0,NULL);
// Since we don't need the handle, close it now.
CloseHandle(hthrd);
Sleep(1);
key_index ++;
}
return TRUE;
}
BOOL Ps2Keybd::Initialize()
{
DEBUGMSG(1,(TEXT("Ps2Keybd::Initialize\r\n")));
DEBUGMSG(1,(TEXT("Ps2Keybd::Initialize Done\r\n")));
return TRUE;
}
BOOL Ps2Keybd::KeybdPowerOn()
{
// UINT8 msg[5];
// int t;
char dummy = (char)0xff;
RETAILMSG(1,(TEXT("++Ps2Keybd::KeybdPowerOn\r\n")));
// Setup IO port for SPI interface & Keyboard
key_index = 0;
// Setup EINT0,1,2,3,8,9 (KBDINT)
// v_pIOPregs->GPFCON &= ~(0x3 << 2); // Clear GPF1
// v_pIOPregs->GPFCON |= (0x2 << 2); // Set GPF1 to EINT1 for Keyboard interrupt
// v_pIOPregs->EXTINT0 &= ~(0x7 << 4); // Clear EINT1
// v_pIOPregs->EXTINT0 |= (0x2 << 4); // fallig edge triggered for EINT1
v_pIOPregs->rGPFCON = (v_pIOPregs->rGPFCON & 0xff00)|(1<<7)|(1<<5)|(1<<3); //GPF1/2/3 = EINT1/2/3
// v_pIOPregs->GPFUP &= 0xf0; //enable pull up
// v_pIOPregs->GPGUP &= 0xfffc;
v_pIOPregs->rEXTINT0 = (v_pIOPregs->rEXTINT0 & 0xffff0000) | 0x6<<12 | 0x6<<8 | 0x6<<4; //EINT1/2/3=both edge triggered
#if 0
// setup SPI interface
// GPG5 : SPIMISO (KBDSPIMISO)
// GPG6 : SPIMOSI (KBDSPIMOSI)
// GPG7 : SPICLK (KBDSPICLK)
v_pIOPregs->GPGCON &= ~((0x3 << 10) | (0x3 << 12) | (0x3 << 14)); // Clear GPG5,6,7
v_pIOPregs->GPGCON |= ((0x3 << 10) | (0x3 << 12) | (0x3 << 14));
// setup _SS signal(nSS_KBD)
v_pIOPregs->GPBCON &= ~(0x3 << 12); // Clear GPB6
v_pIOPregs->GPBCON |= (ONEBIT << 12); // Set Port GPB6 to output for nSS signal
// setup _PWR_OK signal (KEYBOARD)
v_pIOPregs->GPBCON &= ~(0x3 << 0); // Clear GPB0
v_pIOPregs->GPBCON |= (ONEBIT << 0); // Set Port GPB0 to output for _PWR_OK signal
v_pIOPregs->GPDDAT &=~(ONEBIT << 0); // set _PWR_OK to 0
// Setup SPI registers
// Interrupt mode, prescaler enable, master mode, active high clock, format B, normal mode
// v_pSPIregs->SPCON1 = (ONEBIT<<5)|(ONEBIT<<4)|(ONEBIT<<3)|(0x0<<2)|(ONEBIT<<1);
// Developer MUST change the value of prescaler properly whenever value of PCLK is changed.
// v_pSPIregs->SPPRE1 = 255;// 99.121K = 203M/4/2/(255+1) PCLK=50.75Mhz FCLK=203Mhz SPICLK=99.121Khz
for(t=0;t<20000; t++); // delay
msg[0] = (char)0x1b; msg[1] = (char)0xa0; msg[2] = (char)0x7b; msg[3] = (char)0; // Initialize USAR
for(t=0; t < 10; t++) {
dummy = putcToKBCTL(0xff);
}
for(t=0; t<10; t++) { // wait for a while
putsToKBCTL(msg,3);
for(t=0;t<20000; t++);
}
t = 100;
while(t--) {
if((v_pIOPregs->GPFDAT & 0x2)==0) { // Read _ATN
break;
}
} //check _ATN
if(t != 0) {
getsFromKBCTL(msg,3);
}
t=100000;
while(t--); // delay
msg[0] = (char)0x1b; msg[1] = (char)0xa1; msg[2] = (char)0x7a; msg[3] = (char)0; //Initialization complete
putsToKBCTL(msg,3);
#endif
DEBUGMSG(1,(TEXT("--Ps2Keybd::KeybdPowerOn\r\n")));
return(TRUE);
}
BOOL Ps2Keybd::KeybdPowerOff()
{
DEBUGMSG(1,(TEXT("++Ps2Keybd::KeybdPowerOff\r\n")));
DEBUGMSG(1,(TEXT("--Ps2Keybd::KeybdPowerOff\r\n")));
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -