s3c2416 键盘驱动的代码

本文介绍了一种基于S3C2450处理器的键盘驱动程序实现方法,包括寄存器初始化、中断处理和服务例程等关键部分。通过具体的代码示例展示了如何读写键盘控制器及处理键盘事件。

s3c2450kbd.cpp

 

 

//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//

#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <S3C2450REF_GPIO.h>

#undef ZONE_INIT

#include <keybddbg.h>
#include <keybddr.h>
#include <keybdpdd.h>
#include <keybdist.h>
#include "s3c2450kbd.hpp"
#include <s3c2450.h>

#define KBD 0

//寄存器定义
volatile S3C2450_SPI_REG *v_pSPIregs;
volatile S3C2450_IOPORT_REG *v_pIOPregs;
volatile S3C2450_INTR_REG *v_pIntrRegs;

DWORD g_dwSysIntr_Keybd = SYSINTR_UNDEFINED;

// Scan code consts
static const UINT8 scE0Extended= 0xe0;
static const UINT8 scE1Extended= 0xe1;
static const UINT8 scKeyUpMask= 0x80;
static HANDLE gPendownEvent;

//static const UINT8 scKeyUpMask= 0x20; //powerbutton modified

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)
{
 RETAILMSG(KBD,(TEXT("KeybdPdd_PowerHandler start!!!!******/r/n")));

 if (!bOff) {
  v_pp2k->KeybdPowerOn( );
 }
 else {
  v_pp2k->KeybdPowerOff( );
 }

 RETAILMSG(KBD,(TEXT("KeybdPdd_PowerHandler over!!!!******/r/n")));

 return;
}

#define ONEBIT    0x1


int putcToKBCTL(UCHAR c)
{
 UINT i;

 RETAILMSG(KBD,(TEXT("putcToKBCTL start!!!!******/r/n")));

 v_pSPIregs->SPPIN &= ~( 1<<1);
 v_pIOPregs->GPLDAT &= ~(ONEBIT << 14);       //Set _SS signal to low (Slave Select)

 while((v_pSPIregs->SPSTA & 1)==0); // wait while busy

 v_pSPIregs->SPTDAT = c;                 // write left justified data

 while((v_pSPIregs->SPSTA & 1)==0); // wait while busy

 v_pIOPregs->GPLDAT |= (ONEBIT << 14);        //Set _SS signal to high (Slave Select)
 v_pSPIregs->SPPIN |= (1<<1);

 i = v_pSPIregs->SPRDATB;

 RETAILMSG(KBD,(TEXT("putcToKBCTL over!!!!******/r/n")));

 return(i);
}


void getsFromKBCTL(UINT8 *m, int cnt)
{
 int i, j;
 volatile tmp = 1;

 RETAILMSG(KBD,(TEXT("getsFromKBCTL start!!!!******/r/n")));

 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);

  //直接返回9
  m[i] = 0x41; 
  
  for(j = 0; j < 400; j++)
   tmp+= tmp;
 }

 RETAILMSG(KBD,(TEXT("getsFromKBCTL over!!!!******/r/n")));
}

void putsToKBCTL(UINT8 *m,  int cnt)
{
 int i, j, x;
 volatile tmp = 1;

 RETAILMSG(KBD,(TEXT("putsToKBCTL start!!!!******/r/n")));

 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;
 }

 RETAILMSG(KBD,(TEXT("putsToKBCTL over!!!!******/r/n")));
}

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];

 RETAILMSG(KBD,(TEXT("USAR_WriteRegister start!!!!******/r/n")));

 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);

 RETAILMSG(KBD,(TEXT("USAR_WriteRegister over!!!!******/r/n")));

 return TRUE;
}


BOOL
KeybdDriverInitializeAddresses(
 void
 )
{
 bool RetValue = TRUE;
 DWORD dwIOBase;
 DWORD dwSSPBase;

 RETAILMSG(KBD,(TEXT("KeybdDriverInitializeAddresses start!!******/r/n")));

 ReadRegDWORD(TEXT("HARDWARE//DEVICEMAP//KEYBD"), _T("IOBase"), &dwIOBase );
 if(dwIOBase == 0) {goto error_return;}
 ReadRegDWORD(TEXT("HARDWARE//DEVICEMAP//KEYBD"), _T("SSPBase"), &dwSSPBase );
 if(dwSSPBase == 0) { goto error_return; }

 v_pIOPregs = (volatile S3C2450_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
 if(v_pIOPregs == NULL) {
  goto error_return;
 }
 else {
  if(!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(dwIOBase), sizeof(S3C2450_IOPORT_REG), PAGE_READWRITE|PAGE_NOCACHE )) {
   goto error_return;
  }
 }
 
 v_pSPIregs = (volatile S3C2450_SPI_REG *)VirtualAlloc(0, sizeof(S3C2450_SPI_REG), MEM_RESERVE, PAGE_NOACCESS);
 if (v_pSPIregs == NULL) { goto error_return; }
 else {
  if (!VirtualCopy((PVOID)v_pSPIregs, (PVOID)(dwSSPBase), sizeof(S3C2450_SPI_REG), PAGE_READWRITE | PAGE_NOCACHE)) {
   goto error_return;
  }
 }

 RETAILMSG(KBD,(TEXT("KeybdDriverInitializeAddresses over!!******/r/n")));
 
 return TRUE;

error_return:
 if ( v_pIOPregs )
  VirtualFree((PVOID)v_pIOPregs, 0, MEM_RELEASE);
 if ( v_pSPIregs )
  VirtualFree((PVOID)v_pSPIregs, 0, MEM_RELEASE);
 v_pIOPregs = 0;
 v_pSPIregs = 0;

 return FALSE;
}

static UINT KeybdPdd_GetEventEx2(UINT uiPddId, UINT32 rguiScanCode[16], BOOL rgfKeyUp[16])
{
 SETFNAME(_T("KeybdPdd_GetEventEx2"));

 UINT32   scInProgress = 0;
 static UINT32   scPrevious;
 static BOOL     fKeyUp;
 static UINT8    ui8ScanCode;
 
 UINT     cEvents = 0;

 RETAILMSG(KBD,(TEXT("KeybdPdd_GetEventEx2 start!!!!******/r/n")));

 DEBUGCHK(rguiScanCode != NULL);
 DEBUGCHK(rgfKeyUp != NULL);

 getsFromKBCTL(&ui8ScanCode, 1);
 
 RETAILMSG(KBD,(TEXT("ui8ScanCode:%X/n"),ui8ScanCode));

 scInProgress = ui8ScanCode;

 rguiScanCode[cEvents] = scInProgress;
    rgfKeyUp[cEvents]     = FALSE;
     ++cEvents;
     SetEvent ( gPendownEvent );
 
 rguiScanCode[cEvents] = scInProgress;
     rgfKeyUp[cEvents]     = TRUE;
     ++cEvents;

 RETAILMSG(KBD,(TEXT("KeybdPdd_GetEventEx2 over!!!!****/r/n")));
        return cEvents;
}


void WINAPI KeybdPdd_ToggleKeyNotification(KEY_STATE_FLAGS KeyStateFlags)
{
 unsigned int  fLights;

 RETAILMSG(KBD,(TEXT("KeybdPdd_ToggleKeyNotification start!!!!******/r/n")));
 /*
 fLights = 0;
 if (KeyStateFlags & KeyShiftCapitalFlag) {
  fLights |= 0x04;
 }
 if (KeyStateFlags & KeyShiftNumLockFlag) {
  fLights |= 0x2;
 }
 */
 
 /*
 Keyboard lights is disabled once driver is installed because then 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
 */

 RETAILMSG(KBD,(TEXT("KeybdPdd_ToggleKeyNotification over!!!!******/r/n")));
 
 return;
}


BOOL Ps2Keybd::IsrThreadProc( )
{
 DWORD dwPriority;
 DWORD dwIrq_Keybd = IRQ_EINT14;

 RETAILMSG(KBD,(TEXT("IsrThreadProc******/r/n")));

 
 // 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
 }

 m_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL);
 if (m_hevInterrupt == NULL) {
  goto leave;
 }

 // ReadRegDWORD( TEXT("HARDWARE//DEVICEMAP//KEYBD"), _T("Irq"), &dwIrq_Keybd );

 // Call the OAL to translate the IRQ into a SysIntr value.
 if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIrq_Keybd, sizeof(DWORD), &g_dwSysIntr_Keybd, sizeof(DWORD), NULL))
 {
  RETAILMSG(KBD, (TEXT("ERROR: Failed to obtain sysintr value for keyboard interrupt./r/n")));
  g_dwSysIntr_Keybd = SYSINTR_UNDEFINED;
  goto leave;
 }

 if (!InterruptInitialize(g_dwSysIntr_Keybd,m_hevInterrupt,NULL,0)) {
  RETAILMSG(KBD, (TEXT("InterruptInitialize error!!!/r/n")));
  goto leave;
 }

 // 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;
 keybdIst.uiPddId = v_uiPddId;
 keybdIst.pfnGetKeybdEvent = KeybdPdd_GetEventEx2;
       keybdIst.pfnKeybdEvent = v_pfnKeybdEvent;

 KeybdIstLoop(&keybdIst);

 leave:
  return 0;
}

DWORD Ps2KeybdIsrThread(Ps2Keybd *pp2k)
{
 RETAILMSG(KBD,(TEXT("Ps2KeybdIsrThread******/r/n")));
 pp2k->IsrThreadProc( );
 return 0;
}

BOOL Ps2Keybd::IsrThreadStart( )
{
 HANDLE hthrd;

 RETAILMSG(KBD,(TEXT("IsrThreadStart******/r/n")));
 
 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( )
{
 RETAILMSG(KBD,(TEXT("Ps2Keybd::Initialize******/r/n")));

 ////////////////////////////////////////////////////////////////////////

 //虚拟地址分配
 v_pIOPregs = (volatile S3C2450_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
 VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2450_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE ); 
 v_pIntrRegs = (volatile S3C2450_INTR_REG *)VirtualAlloc(0, sizeof(S3C2450_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
 VirtualCopy((PVOID)v_pIntrRegs, (PVOID)(S3C2450_BASE_REG_PA_INTR >> 8), sizeof(S3C2450_INTR_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE ); 
 //GPG bit6
 v_pIOPregs->GPGDAT  &= ~(0x1 << 6);
 v_pIOPregs->GPGCON  &= ~(0x3 <<12);
 v_pIOPregs->GPGCON  |=  (0x2 << 12);
 // EINT14 下降沿触发
 v_pIOPregs->EXTINT1 = ((v_pIOPregs->EXTINT1) & ~(0xf<<24)) | (0x1 << 27)|(0x2 << 24);

 //////////////////////////////////////////////////////////////////////// 

 RETAILMSG(KBD,(TEXT("Initialize over******/r/n")));
 
 return TRUE;
}


BOOL Ps2Keybd::KeybdPowerOn( )
{
 char dummy = (char)0xff;

 RETAILMSG(KBD,(TEXT("KeybdPowerOn******/r/n")));

 return(TRUE);
}

BOOL Ps2Keybd::KeybdPowerOff( )
{
 RETAILMSG(KBD,(TEXT("KeybdPowerOff******/r/n")));
 return(TRUE);
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OneOnce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值