📄 ps2_kbd_kernel.c
字号:
#ifdef EP931X_SIMULAT_PS2_KBD
#include <windows.h>
#include <ceddk.h>
#include <oalintr.h>
#include <halether.h>
#include <pkfuncs.h>
#include <iltiming.h>
#include <ethdbg.h>
#include <kitl.h>
//#include <platform.h>
#include <drv_glob.h>
#include <dbt.h>
#include <memorymap.h>
#include <nkintr.h>
#include <hwdefs.h>
#define udelay DelayInuSec
#define disable_irq(IRQ_EXT0) *VIC2_INTCLEAR =INT2_EXT0 ;
#define enable_irq(IRQ_EXT0) *VIC2_INTENABLE = INT2_EXT0;
static void DelayInuSec(ULONG ulMicroSec);
#define inl( addr ) READ_PORT_UCHAR((PUCHAR)(addr));
#define outl(data,addr ) WRITE_PORT_UCHAR((PUCHAR)(addr), (data ));
struct uPS2SendDataStruct {
unsigned char ps2_out_start ;
unsigned char ps2_out_data ;
unsigned char ps2_out_parity ;
unsigned char ps2_out_stop ;
unsigned char ps2_out_getack ;
unsigned char ps2_out_next ;
unsigned char master ;
unsigned char number ;
unsigned char ps2_in_start ;
unsigned char ps2_in_data ;
unsigned char ps2_in_parity ;
unsigned char in_parity ;
unsigned char ps2_in_stop ;
unsigned char slave ;
unsigned char ps2_is_crc_error ;
unsigned char ps2_in_error ;
} p;
static UCHAR g_cPS2Data=0;
static void PS2DataStructInit(void)
{
p.ps2_out_start =0;
p.ps2_out_data =0;
p.ps2_out_parity =0;
p.ps2_out_stop =0;
p.ps2_out_getack =0;
p.ps2_in_start =0;
p.ps2_in_data =0;
p.ps2_in_parity =0;
p.in_parity =0;
p.ps2_in_stop =0;
p.ps2_is_crc_error =0;
p.ps2_in_error =0;
}
static void SetSSPtoPS2(void)
{
unsigned int uiRegTemp;
/*
* Configure EGPIO pins 12 and 14 as outputs because they are used
* as buffer enables for the SPI interface to the ps2 keyboard.
* Clear EGPIO pins 12 and 14, this will enable the SPI keyboard.
*/
uiRegTemp = inl(GPIO_PBDDR);
outl( uiRegTemp | 0x50, GPIO_PBDDR );
uiRegTemp = inl(GPIO_PBDR);
outl( uiRegTemp & ~0x50, GPIO_PBDR );
}
void kdb_write_output_bit_INT(unsigned char ucX)
{
unsigned int uiRegTempData;
/*
*set the gpio12 (keyboard data) data is output
*/
uiRegTempData = inl(GPIO_PBDR);
/*
*
*/
if(ucX==0x00){
outl((0x10) | uiRegTempData, GPIO_PBDR );
}
else{
outl((~0x10) & uiRegTempData, GPIO_PBDR );
}
udelay(60); //I think it's unnecessary Braden
}
void kdb_write_input_bit_INT(unsigned char *ucX)
{
unsigned int uiRegTempData;
/*
*set the gpio12 (keyboard data) data is output
*/
uiRegTempData = inl(GPIO_PBDDR);
outl( (~0x20) & uiRegTempData, GPIO_PBDDR );
uiRegTempData = inl(GPIO_PBDR);
udelay(20);
if((uiRegTempData&0x20)==0x20){
*ucX=0;
}
else{
*ucX=1;
}
udelay(30); //I think it's unnecessary Braden
}
/*
*kbd_write_output_w_INT output a command to keyboard,cpu will call it.
*/
int kbd_write_output_w_INT(unsigned char data,unsigned char parity)
{
unsigned int uiRegTempData,uiRegTempClock;
p.ps2_out_start =0;
p.ps2_out_data =data;
p.ps2_out_parity =parity;
p.ps2_out_stop =0x01;
p.number =10;
p.master =1;
disable_irq(IRQ_EXT0);
/*
*set the
* gpio12 (keyboard data) and
* gpio14 (keyboard clock)
* dirction is output
*/
uiRegTempData = inl(GPIO_PBDDR);
outl( 0x50 | uiRegTempData, GPIO_PBDDR );
outl((~0x20 )& uiRegTempData, GPIO_PBDDR );
/*
*Set the gpio14 (keyboard clock) low 100us
*/
uiRegTempClock = inl(GPIO_PBDR);
outl( ( 0x40 ) | uiRegTempClock, GPIO_PBDR );
udelay(100);
/*
*Set the gpio12 (keyboard data line) low
*/
uiRegTempData = inl(GPIO_PBDR);
outl( ( 0x10 ) | uiRegTempData, GPIO_PBDR );
udelay(5);
/*
*release the clock line,set the gpio14 (keyboard clock line) input
*/
uiRegTempClock = inl(GPIO_PBDR);
outl( ( ~0x40 ) & uiRegTempClock, GPIO_PBDR );
enable_irq(IRQ_EXT0);
/*
*wait the device ACK
*/
return 1;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
/*
* PS2ISR is the interrupt handler routine for the USB.
*/
BOOL EP93XPS2ISR ( void )
//void EP93XPS2ISR (int irq,void * parmer,struct pt_regs *r)
{
BOOL bShouldTrigerInterrupt=FALSE;
unsigned char ucBitX;
unsigned int uiRegTempData;
if(p.master==1){
if(p.number<11){
/* *10 9 8 7 6 5 4 3 clock */
if((p.number>=3)&&(p.number<=10)){
ucBitX=((p.ps2_out_data)&0x01);
p.ps2_out_data=p.ps2_out_data>>1;
kdb_write_output_bit_INT(ucBitX);
}
else if(p.number==2){
ucBitX=p.ps2_out_parity&0x01;
kdb_write_output_bit_INT(ucBitX);
}
else if(p.number==1){
ucBitX=p.ps2_out_stop&0x01;
kdb_write_output_bit_INT(ucBitX);
}
else if(p.number==0){
/*
*release the data line,set the gpio12 (keyboard data line) input
*/
uiRegTempData = inl(GPIO_PBDDR);
outl( (~0x20) & uiRegTempData, GPIO_PBDDR );
uiRegTempData = inl(GPIO_PBDR);
udelay(60);
if((uiRegTempData&0x20)==0x20){
p.ps2_out_getack=1;
}
else{
p.ps2_out_getack=0;
/*printk("PS2 ACK --error:time= %x,get data=%x\n",p.number,uiRegTempData);*/
}
SetSSPtoPS2();
p.number=11+1;
p.master=0;
PS2DataStructInit();
}
/*else
{
printk("number error\n");
} */
p.number--;
}
}
else{
if(p.number==11){
/*START bit should is 0*/
kdb_write_input_bit_INT(&ucBitX);
p.ps2_in_start = ucBitX;
if(p.ps2_in_start==1){
//printk("PS2 input: get the START bit--NOt get\n");
p.number=11+1;
/*p.ps2_in_data=0;
p.in_parity=0;
p.ps2_is_crc_error=0;*/
PS2DataStructInit();
}
}
/* *10 9 8 7 6 5 4 3*/
if((p.number>=3)&&(p.number<=10)){
kdb_write_input_bit_INT(&ucBitX);
p.ps2_in_data = p.ps2_in_data|((ucBitX)<<(10-p.number));
p.in_parity = p.in_parity + ucBitX;
}
else if(p.number==2){
kdb_write_input_bit_INT(&ucBitX);
p.ps2_in_parity = ucBitX;
/*ou shu shout crc is 1*/
if((p.in_parity%2)==0){
if( p.ps2_in_parity !=1){
p.ps2_in_error =1;
p.ps2_is_crc_error=1;
NKDbgPrintfW(L"PS2 input: get the crc bit--error\n");
}
}
/*ji shu crc is 0*/
else if((p.in_parity%2)==1){
if( p.ps2_in_parity !=0){
p.ps2_in_error=1;
p.ps2_is_crc_error=1;
NKDbgPrintfW(L"PS2 input: get the crc bit--error\n");
}
}
}
else if(p.number==1){
kdb_write_input_bit_INT(&ucBitX);
p.ps2_in_stop = ucBitX;
if(p.ps2_in_stop ==0){
p.ps2_in_error =1;
NKDbgPrintfW(L"PS2 input: get the stop bit--error\n");
}
//RETAILMSG(1,(L"%x\n",p.ps2_in_data));
g_cPS2Data=p.ps2_in_data;
SetSSPtoPS2();
p.number=11+1;
PS2DataStructInit();
bShouldTrigerInterrupt=TRUE; //We get a whole char. so let the driver's IST know, and read it out.
//udelay(50); //I think it's not necessary. Braden
}
p.number--;
}
return bShouldTrigerInterrupt;
}
//****************************************************************************
//
// Init The EDB931x USB2.0 Slave Daughter Board Module
// Return 0 sucess
//
//************************************************************************
int init_edb931xPS2(void)
{
RETAILMSG(1,(L"********init_edb931xPS2************\n"));
SetSSPtoPS2();
p.number =11;
p.master =0;
p.ps2_is_crc_error=0;
p.ps2_in_stop=0;
p.ps2_in_data=0;
p.ps2_in_start=0;
p.in_parity=0;
p.ps2_in_error =0;
return(1);
}
static void DelayInuSec(DWORD ulMicroSec)
{
DWORD dwStart;
DWORD dwTime=0;
dwStart=*TIM_DEBUGVALUELOW;
while( dwTime< ulMicroSec )
{
dwTime=*TIM_DEBUGVALUELOW-dwStart;
if( dwTime > 0xFFFFFFF )
{
dwTime=0xFFFFFFFF- dwStart + *TIM_DEBUGVALUELOW;
}
}
}
BOOL SendDataToPS2( PUCHAR lpInBuf , int nInBufSize )
{
unsigned char ucLEDparity=0,ucNumber;
UCHAR cData=*lpInBuf;
for(ucNumber=0;ucNumber<8;ucNumber++){
ucLEDparity=ucLEDparity+( (cData>>(ucNumber))&0x01);
}
// RETAILMSG(1,(L"****SendDataToPS2 %x \n", cData));
if(ucLEDparity%2==0)
kbd_write_output_w_INT(cData,1);
else if(ucLEDparity%2==1)
kbd_write_output_w_INT(cData,0);
return TRUE;
}
BOOL ReadPS2Data( PUCHAR lpOutBuf, int nOutBufSize, LPDWORD lpBytesReturned )
{
// if( !p.ps2_in_error)
{
*lpOutBuf=g_cPS2Data;
if( lpBytesReturned )
*lpBytesReturned=1;
return TRUE;
}
p.ps2_in_error=0;
return FALSE;
}
#endif //#ifdef EP931X_SIMULAT_PS2_KEYBD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -