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

📄 ps2port.cpp

📁 Ep93XX TionProV2 BSP
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*

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.

*/

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

#include "ps2port.hpp"
#include "ps2mouse.hpp"
#include "ps2keybd.hpp"


#include <nkintr.h>
#include <oalintr.h>
#include <hwdefs.h>
#include <haluser.h>



void DelayInuSec(DWORD uS);

#define udelay		DelayInuSec


// Commands sent to the keyboard.
//
static const UINT8 cmdKeybdReset	= 0xFF;
static const UINT8 cmdKeybdLights	= 0xED;

//
// Commands sent to the mouse.
//
static const UINT8 cmdMouseReadId			= 0xF2;
static const UINT8 cmdMouseSetReportRate	= 0xF3;
static const UINT8 cmdMouseEnable			= 0xF4;

//
// Mouse and Keyboard Response
//
static const UINT8 response8042Ack				= 0xFA;
static const UINT8 response8042Resend			= 0xFE;
static const UINT8 response8042IntelliMouseId	= 0x03;



/*++

Ps2Port::
KeyboardInterfaceTest:

Writes the keyboard interface test command to the 8042 command register
and reads the response.

Returns true if the success response is read.


--*/
BOOL
Ps2Port::
KeyboardInterfaceTest(
	void
	)
{
	BOOL	bRet = false;

	bRet = true;

	return bRet;
}	



/*++

Ps2Port::
KeyboardCommandPut:

Writes a command to the keyboard and reads the response.

Returns true if the success response code is read.


--*/
BOOL
Ps2Port::
KeyboardCommandPut(
	UINT8	ui8Cmd
	)
{
	BOOL	bRet = false;
	UINT8	ui8Data;
	int		iTries = 0;

	EnterCriticalSection(&m_csWrite);

	while( iTries++ < 3 ){

		WritePort(ui8Cmd);

		if( !ReadPort(&ui8Data) ){

			break;
		}

		if( ui8Data == response8042Ack ){

			bRet = true;
			break;
		}

		// resend command if keyboard microcontroller asked for a resend 
		// otherwise break and return false
		if( ui8Data != response8042Resend )	{
			
			ASSERT(0);
			break;
		}
	}

	LeaveCriticalSection(&m_csWrite);
	return bRet;
}



/*++

Ps2Port::
KeyboardReset:

Sends the keyboard reset command to the keyboard and reads the response.

Returns true if the success response is read.


--*/
BOOL
Ps2Port::
KeyboardReset(
	void
	)
{
	BOOL	bRet = false;
	UINT8	ui8Data;

	EnterCriticalSection(&m_csWrite);

	if ( !KeyboardCommandPut(cmdKeybdReset) )
		{
		goto leave;
		}

	if ( !ReadPort(&ui8Data) )
		{
		goto leave;
		}

	if ( ui8Data != 0xAA )
		{
		ASSERT(0);
		goto leave;
		}

	bRet = true;

leave:
	LeaveCriticalSection(&m_csWrite);
	return bRet;
}	



/*++

Ps2Port::
KeyboardLights:

Sets the keyboard indicator lights.


--*/
void
Ps2Port::
KeyboardLights(
	unsigned int	fLights
	)
{
//    unsigned char ucLEDparity=0,ucNumber;

	EnterCriticalSection(&m_csWrite);

	WritePort( cmdKeybdLights );

	Sleep(4);

	WritePort(  fLights );
      
	Sleep(4);

	LeaveCriticalSection(&m_csWrite);
}


BOOL
Ps2Port::
MouseTest(
	void
	)
{
	BOOL	bRet = false;
	UINT8	ui8Data;

	EnterCriticalSection(&m_csWrite);

	m_bIntelliMouseFound=0;

	WritePort(cmdMouseReadId);
	
	//ui8Data should contain response8042Ack   
	if ( !ReadPort(&ui8Data) ) {
	
		goto leave;
	}

	//ui8Data should contain mouse ID
	if ( !ReadPort(&ui8Data) ) {

		 goto leave;
	}
	bRet = true;

	SetModeIntelliMouse();
	if( response8042IntelliMouseId == MouseId() ) {

		RETAILMSG(1,(TEXT("****IntelliMouseId mouse***\r\n")));
		m_bIntelliMouseFound = true;
	}         

leave:
	LeaveCriticalSection(&m_csWrite);

	if ( !bRet ) 
		RETAILMSG(1,(TEXT("MouseTest fails.  Mouse probably not present.\r\n")));

	return bRet;
}	


/*++

Ps2Port::
SetModeIntelliMouse:

Set mouse to IntelliMouse mode.  If an IntelliMouse is present:
	1. mouse ID becomes response8042IntelliMouseId
	2. the motion report format changes 
If IntelliMouse not present the mouse ID and motion report format remain at the default values

--*/
void
Ps2Port::
SetModeIntelliMouse(
	void
	)
{
	
	EnterCriticalSection(&m_csWrite);

	// IntelliMouse(R) is uniquely identified by issuing the specific series of Set Report Rate commands:
	// 200Hz (0xC8), then 100Hz (0x64), then 80Hz (0x50).  The Set Report Rate commands are valid and we 
	// therefore have to set the report rate back to the default 100Hz (this is done be MouseId() ).
	WritePort(cmdMouseSetReportRate);
	WritePort(0xC8);
	WritePort(cmdMouseSetReportRate);
	WritePort(0x64);
	WritePort(cmdMouseSetReportRate);
	WritePort(0x50);

	LeaveCriticalSection(&m_csWrite);
}	


UINT8	Ps2Port::MouseId(void	)
{
	UINT8	ui8MouseId=0;

	EnterCriticalSection(&m_csWrite);
	
	WritePort(cmdMouseReadId);
	ReadPort(&ui8MouseId);
	ASSERT(ui8MouseId == response8042Ack);
	
	ReadPort(&ui8MouseId);

	// Set the report rate back to the default 100Hz
	WritePort(cmdMouseSetReportRate);
	WritePort(0x64);

	LeaveCriticalSection(&m_csWrite);

	return ui8MouseId;

}

BOOL 	Ps2Port::ReadPort( PUCHAR pui8Data )
{
	return KernelIoControl( IOCTL_HAL_PS2_GET, NULL, 0, pui8Data, 1, NULL);
}

BOOL	Ps2Port::MouseDataRead(	UINT8	*pui8Data	)
{
	return ReadPort( pui8Data);
}

BOOL	Ps2Port::KeybdDataRead(	UINT8	*pui8Data	)
{
	 return ReadPort( pui8Data);
}


void 	Ps2Port::WritePort(  UINT8	data )
{
	int iTry=0;

	for( iTry=0; iTry<5; iTry ++ )
	{
		 if( KernelIoControl( IOCTL_HAL_PS2_SEND, &data, 1, NULL, 0, NULL) )
			 break;

		 RETAILMSG(1, (TEXT("PS2 write failed %d\r\n "),iTry) );
		 Sleep(1 );
	}
}


BOOL   Ps2Port::bIntelliMouseFound( void )
{
	return m_bIntelliMouseFound; 
}

BOOL
Ps2Port::
Initialize(
	unsigned int	iopBase
	)
{
	BOOL	bRet = false;

	RETAILMSG(ZONE_TEST, (TEXT(" PS2 port init %x---%x\r\n "), this,iopBase) );

	InitializeCriticalSection(&m_csWrite);

	m_bIntelliMouseFound = false;
	m_fEnableWake = FALSE;


	m_hDevEvent=CreateEvent(NULL, FALSE, FALSE, NULL);

	if( !m_hDevEvent )
		goto leave;

	if ( !InterruptInitialize(SYSINTR_PS2_PORT, m_hDevEvent, NULL, 0) ){

		RETAILMSG(ZONE_ERROR, (TEXT(" PS2 port Init interrupt failed \r\n ")) );
		goto leave;
	}

	bRet = true;

leave:
	return bRet;
}

void  Ps2Port::InterruptDone( void )
{
	::InterruptDone( SYSINTR_PS2_PORT);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -