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

📄 ps2_kbd_kernel.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 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 + -