s3c2440kbd.cpp
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:13k
源码类别:
Windows CE
开发平台:
Windows_Unix
- /*++
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- PARTICULAR PURPOSE.
- Copyright (c) 2002. Samsung Electronics, co. ltd All rights reserved.
- Module Name:
- Abstract:
- This file implements the S3C2440 Keyboard function
- rev:
- 2002.4.4 : First S3C2410 version (kwangyoon LEE, kwangyoon@samsung.com)
- 2002.1.31 : CE.NET port (kwangyoon LEE, kwangyoon@samsung.com)
- Notes:
- --*/
- #include <windows.h>
- #include <ceddk.h>
- #include <nkintr.h>
- #include <drv_glob.h>
- #undef ZONE_INIT
- #include <keybddbg.h>
- #include <keybddr.h>
- #include <keybdpdd.h>
- #include <keybdist.h>
- #include "s3c2440kbd.hpp"
- #include "S2440.h"
- // Pointer to device control registers
- volatile IOPreg *v_pIOPregs;
- volatile SSPreg *v_pSSPregs;
- // Pointer to driver globals area
- PDRIVER_GLOBALS v_pDriverGlobals;
- DWORD dwSysIntr_Keybd;
- // Scan code consts
- static const UINT8 scE0Extended = 0xe0;
- static const UINT8 scE1Extended = 0xe1;
- static const UINT8 scKeyUpMask = 0x80;
- UINT32
- ScanCodeToVKeyEx(
- UINT32 ScanCode,
- KEY_STATE_FLAGS KeyStateFlags,
- UINT32 VKeyBuf[16],
- UINT32 ScanCodeBuf[16],
- KEY_STATE_FLAGS KeyStateFlagsBuf[16]
- );
- // There is really only one physical keyboard supported by the system.
- Ps2Keybd *v_pp2k;
- extern void ReadRegDWORD( LPCWSTR szKeyName, LPCWSTR szValueName, LPDWORD pdwValue );
- void WINAPI KeybdPdd_PowerHandler(BOOL bOff)
- {
- // DEBUGMSG(1, (TEXT("++KeybdPdd_PowerHandlerrn")));
- if (!bOff) {
- v_pp2k->KeybdPowerOn();
- }
- else {
- v_pp2k->KeybdPowerOff();
- }
- // DEBUGMSG(1, (TEXT("--KeybdPdd_PowerHandlerrn")));
- return;
- }
- #define ONEBIT 0x1
- int putcToKBCTL(UCHAR c)
- {
- UINT i;
- // UINT rxbuf[10];
- // UINT x;
- v_pIOPregs->rGPBDAT &= ~(ONEBIT << 6); //Set _SS signal to low (Slave Select)
- while((v_pSSPregs->rSPSTA1 & ONEBIT)==0); // wait while busy
- v_pSSPregs->rSPTDAT1 = c; // write left justified data
- while((v_pSSPregs->rSPSTA1 & ONEBIT)==0); // wait while busy
- v_pIOPregs->rGPBDAT |= (ONEBIT << 6); //Set _SS signal to high (Slave Select)
- i = v_pSSPregs->rSPRDAT1;
- return(i);
- }
- void getsFromKBCTL(UINT8 *m, int cnt) {
- int i, j;
- volatile tmp = 1;
- for(j = 0; j < 3; j++)
- tmp += tmp;
- for(j = 0; j < 250 * 30; j++)
- tmp += tmp;
- for(i = 0; i < cnt; i++) {
- m[i] = putcToKBCTL(0xFF);
- for(j = 0; j < 400; j++)
- tmp+= tmp;
- }
- }
- void putsToKBCTL(UINT8 *m, int cnt)
- {
- int i, j, x;
- volatile tmp = 1;
- for(j = 0; j < 3; j++)
- x = j;
- for(j = 0; j < 3; j++)
- tmp += tmp;
- for(j = 0; j < 250 * 30; j++)
- tmp += tmp;
- for(i = 0; i < cnt; i++) {
- j = putcToKBCTL(m[i]);
- for(j = 0; j < 400; j++)
- tmp+= tmp;
- for(j = 0; j < 400; j++)
- x = j;
- }
- }
- char lrc(UINT8 *buffer, int count)
- {
- char lrc;
- int n;
- lrc = buffer[0] ^ buffer[1];
- for (n = 2; n < count; n++)
- {
- lrc ^= buffer[n];
- }
- if (lrc & 0x80)
- lrc ^= 0xC0;
- return lrc;
- }
- int USAR_WriteRegister(int reg, int data)
- {
- UINT8 cmd_buffer[4];
- cmd_buffer[0] = 0x1b; //USAR_PH_WR;
- cmd_buffer[1] = (unsigned char)reg;
- cmd_buffer[2] = (unsigned char)data;
- cmd_buffer[3] = lrc((UINT8 *)cmd_buffer,3);
- putsToKBCTL((UINT8 *)cmd_buffer,4);
- return TRUE;
- }
- BOOL
- KeybdDriverInitializeAddresses(
- void
- )
- {
- bool RetValue = TRUE;
- DWORD dwIOBase;
- DWORD dwSSPBase;
- DEBUGMSG(1,(TEXT("++KeybdDriverInitializeAddressesrn")));
- ReadRegDWORD(TEXT("HARDWARE\DEVICEMAP\KEYBD"), _T("IOBase"), &dwIOBase );
- if(dwIOBase == 0) {
- DEBUGMSG(1, (TEXT("Can't fount registry entry : HARDWARE\DEVICEMAP\KEYBD\IOBasern")));
- goto error_return;
- }
- DEBUGMSG(1, (TEXT("HARDWARE\DEVICEMAP\KEYBD\IOBase:%xrn"), dwIOBase));
- ReadRegDWORD(TEXT("HARDWARE\DEVICEMAP\KEYBD"), _T("SSPBase"), &dwSSPBase );
- if(dwSSPBase == 0) {
- DEBUGMSG(1, (TEXT("Can't fount registry entry : HARDWARE\DEVICEMAP\KEYBD\SSPBasern")));
- goto error_return;
- }
- DEBUGMSG(1, (TEXT("HARDWARE\DEVICEMAP\KEYBD\SSPBase:%xrn"), dwSSPBase));
- v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
- if(v_pIOPregs == NULL) {
- DEBUGMSG(1,(TEXT("[KBD] v_pIOPregs : VirtualAlloc failed!rn")));
- goto error_return;
- }
- else {
- if(!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(dwIOBase), sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE ))
- {
- DEBUGMSG(1,(TEXT("[KBD] v_pIOPregs : VirtualCopy failed!rn")));
- goto error_return;
- }
- }
- DEBUGMSG(1, (TEXT("[KBD] v_pIOPregs mapped at %xrn"), v_pIOPregs));
- v_pSSPregs = (volatile SSPreg *)VirtualAlloc(0, sizeof(SSPreg), MEM_RESERVE, PAGE_NOACCESS);
- if (v_pSSPregs == NULL) {
- DEBUGMSG(1, (TEXT("[KBD] v_pSSPregs : VirtualAlloc failed!rn")));
- goto error_return;
- }
- else {
- if (!VirtualCopy((PVOID)v_pSSPregs, (PVOID)(dwSSPBase), sizeof(SSPreg), PAGE_READWRITE | PAGE_NOCACHE))
- {
- DEBUGMSG(1, (TEXT("[KBD] v_pSSPregs : VirtualCopy failed!rn")));
- goto error_return;
- }
- }
- DEBUGMSG(1, (TEXT("[KBD] v_pSSPregs mapped at %xrn"), v_pSSPregs));
- v_pDriverGlobals = (PDRIVER_GLOBALS)VirtualAlloc(0, DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
- MEM_RESERVE, PAGE_NOACCESS);
- if (v_pDriverGlobals == NULL)
- {
- DEBUGMSG(1, (TEXT("[KBD] v_pDriverGlobals : VirtualAlloc failed!rn")));
- goto error_return;
- }
- if (!VirtualCopy((PVOID)v_pDriverGlobals,
- (PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
- DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
- PAGE_READWRITE|PAGE_NOCACHE))
- {
- DEBUGMSG(1, (TEXT("[KBD] v_pDriverGlobals : VirtualCopy failed!rn")));
- goto error_return;
- }
- DEBUGMSG(1,(TEXT("--KeybdDriverInitializeAddressesrn")));
- return TRUE;
- error_return:
- if ( v_pIOPregs )
- VirtualFree((PVOID)v_pIOPregs, 0, MEM_RELEASE);
- if ( v_pSSPregs )
- VirtualFree((PVOID)v_pSSPregs, 0, MEM_RELEASE);
- if ( v_pDriverGlobals )
- VirtualFree((PVOID)v_pDriverGlobals, 0, MEM_RELEASE);
- v_pIOPregs = 0;
- v_pSSPregs = 0;
- v_pDriverGlobals = 0;
- DEBUGMSG(1,(TEXT("--KeybdDriverInitializeAddresses[FAILED!!!]rn")));
- return FALSE;
- }
- static UINT KeybdPdd_GetEventEx2(UINT uiPddId, UINT32 rguiScanCode[16], BOOL rgfKeyUp[16])
- {
- SETFNAME(_T("KeybdPdd_GetEventEx2"));
- UINT32 scInProgress = 0;
- static UINT32 scPrevious;
- BOOL fKeyUp;
- UINT8 ui8ScanCode;
- UINT cEvents = 0;
- DEBUGCHK(rguiScanCode != NULL);
- DEBUGCHK(rgfKeyUp != NULL);
- getsFromKBCTL(&ui8ScanCode, 1);
- DEBUGMSG(ZONE_SCANCODES,
- (_T("%s: scan code 0x%08x, code in progress 0x%08x, previous 0x%08xrn"),
- pszFname, 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;
- } else {
- fKeyUp = FALSE;
- }
- rguiScanCode[cEvents] = scInProgress;
- rgfKeyUp[cEvents] = fKeyUp;
- ++cEvents;
- }
- return cEvents;
- }
- void WINAPI KeybdPdd_ToggleKeyNotification(KEY_STATE_FLAGS KeyStateFlags)
- {
- unsigned int fLights;
- DEBUGMSG(1, (TEXT("KeybdPdd_ToggleKeyNotificationrn")));
- 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;
- }
- BOOL Ps2Keybd::IsrThreadProc()
- {
- DWORD dwPriority;
- // 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 = 145; // default value is 145
- dwPriority = 240; // default value is 145
- }
- DEBUGMSG(1, (TEXT("IsrThreadProc:rn")));
- m_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL);
- if (m_hevInterrupt == NULL) {
- DEBUGMSG(1, (TEXT("IsrThreadProc: InterruptInitializern")));
- goto leave;
- }
- ReadRegDWORD( TEXT("HARDWARE\DEVICEMAP\KEYBD"), _T("SysIntr"), &dwSysIntr_Keybd );
- if( !dwSysIntr_Keybd ) {
- goto leave;
- }
- if (!InterruptInitialize(dwSysIntr_Keybd,m_hevInterrupt,NULL,0)) {
- DEBUGMSG(1, (TEXT("IsrThreadProc: KeybdInterruptEnablern")));
- goto leave;
- }
- // update the IST priority
- CeSetThreadPriority(GetCurrentThread(), (int)dwPriority);
- #if 0
- while (1)
- {
- if ( WaitForSingleObject(m_hevInterrupt, INFINITE) == WAIT_TIMEOUT )
- DEBUGMSG(1, (TEXT("timeoutrn")));
- else
- DEBUGMSG(1, (TEXT("I got onern")));
- InterruptDone(dwSysIntr_Keybd);
- }
- #endif
- extern UINT v_uiPddId;
- extern PFN_KEYBD_EVENT v_pfnKeybdEvent;
- KEYBD_IST keybdIst;
- keybdIst.hevInterrupt = m_hevInterrupt;
- keybdIst.dwSysIntr_Keybd = dwSysIntr_Keybd;
- keybdIst.uiPddId = v_uiPddId;
- keybdIst.pfnGetKeybdEvent = KeybdPdd_GetEventEx2;
- keybdIst.pfnKeybdEvent = v_pfnKeybdEvent;
- KeybdIstLoop(&keybdIst);
- leave:
- return 0;
- }
- DWORD Ps2KeybdIsrThread(Ps2Keybd *pp2k)
- {
- DEBUGMSG(1,(TEXT("Ps2KeybdIsrThread:rn")));
- pp2k->IsrThreadProc();
- return 0;
- }
- BOOL Ps2Keybd::IsrThreadStart()
- {
- HANDLE hthrd;
- DEBUGMSG(1,(TEXT("IsrThreadStart:rn")));
- hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Ps2KeybdIsrThread,this,0,NULL);
- // Since we don't need the handle, close it now.
- CloseHandle(hthrd);
- return TRUE;
- }
- BOOL Ps2Keybd::Initialize()
- {
- DEBUGMSG(1,(TEXT("Ps2Keybd::Initializern")));
- DEBUGMSG(1,(TEXT("Ps2Keybd::Initialize Donern")));
- return TRUE;
- }
- BOOL Ps2Keybd::KeybdPowerOn()
- {
- UINT8 msg[5];
- int t;
- char dummy = (char)0xff;
- DEBUGMSG(1,(TEXT("++Ps2Keybd::KeybdPowerOnrn")));
- // Setup IO port for SPI interface & Keyboard
- // Setup EINT1 (KBDINT)
- v_pIOPregs->rGPFCON &= ~(0x3 << 2); // Clear GPF1
- v_pIOPregs->rGPFCON |= (0x2 << 2); // Set GPF1 to EINT1 for Keyboard interrupt
- v_pIOPregs->rEXTINT0 &= ~(0x7 << 4); // Clear EINT1
- v_pIOPregs->rEXTINT0 |= (0x2 << 4); // fallig edge triggered for EINT1
- // setup SPI interface
- // GPG5 : SPIMISO (KBDSPIMISO)
- // GPG6 : SPIMOSI (KBDSPIMOSI)
- // GPG7 : SPICLK (KBDSPICLK)
- v_pIOPregs->rGPGCON &= ~((0x3 << 10) | (0x3 << 12) | (0x3 << 14)); // Clear GPG5,6,7
- v_pIOPregs->rGPGCON |= ((0x3 << 10) | (0x3 << 12) | (0x3 << 14));
- // setup _SS signal(nSS_KBD)
- v_pIOPregs->rGPBCON &= ~(0x3 << 12); // Clear GPB6
- v_pIOPregs->rGPBCON |= (ONEBIT << 12); // Set Port GPB6 to output for nSS signal
- // setup _PWR_OK signal (KEYBOARD)
- v_pIOPregs->rGPBCON &= ~(0x3 << 0); // Clear GPB0
- v_pIOPregs->rGPBCON |= (ONEBIT << 0); // Set Port GPB0 to output for _PWR_OK signal
- v_pIOPregs->rGPDDAT &=~(ONEBIT << 0); // set _PWR_OK to 0
- // Setup SPI registers
- // Interrupt mode, prescaler enable, master mode, active high clock, format B, normal mode
- v_pSSPregs->rSPCON1 = (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_pSSPregs->rSPPRE1 = 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->rGPFDAT & 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);
- DEBUGMSG(1,(TEXT("--Ps2Keybd::KeybdPowerOnrn")));
- return(TRUE);
- }
- BOOL Ps2Keybd::KeybdPowerOff()
- {
- DEBUGMSG(1,(TEXT("++Ps2Keybd::KeybdPowerOffrn")));
- DEBUGMSG(1,(TEXT("--Ps2Keybd::KeybdPowerOffrn")));
- return(TRUE);
- }
English
