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

📄 ps2_kbd.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================
//
//      ps2_kbd.c
//
//      PS/2 Keyboard Controller Code
//
// Author(s):    Michael Kelly, Cogent Computer Systems, Inc.
// Contributors: 
// Date:         02/05/2002
// Description:  This file contains Code to intialize the Holtek HT6542
//				 Keyboard Controller for keyboard operation as well
//				 as a basic scan code to ascii converter suitable as an
//				 input device
//
//--------------------------------------------------------------------------

#include "config.h"
#if INCLUDE_PS2KBD
#include "cpuio.h"
#include "stddefs.h"
#include "genlib.h"
#include "ps2_kbd.h"

//--------------------------------------------------------------------------
// Function Prototypes
//
int ps2_kbd_init(void);
void ps2_kbd_test(void);
void ps2_kbd_obf_flush(void);
vulong wait_ps2_kbd_ibf_clr(void);
vulong wait_ps2_kbd_ibf_set(void);
vulong wait_ps2_kbd_obf_clr(void);
vulong wait_ps2_kbd_obf_set(void);
vulong ps2_gotachar(void);
vuchar ps2_getchar(void); 
vuchar ps2_scan(void);
int ps2_tst(void);

//--------------------------------------------------------------------------
// Global to hold the state of the interface
//
static vulong ps2_kbd_ok;
static vuchar ps2_ctl_flag, ps2_alt_flag, ps2_shift_flag;
static vuchar ps2_led_flag, ps2_break_c;

//--------------------------------------------------------------------------
// Globals to hold the ps2 character and status
//
static vuchar ps2_char, ps2_char_ok;

//--------------------------------------------------------------------------
// ps2_kbd_init()
// 
// The following function initializes the PS/2 Controller and performs a
// a simple self test.  The global, ps2_kbd_ok, will be set based
// on the results.  This allows the ascii routine to determine
// if a keyboard (or even the keyboard controller) is present.
//
// Notes:
//
// 1. There are two peripherals we are communicating with.  The first
//    is the PS/2 controller itself located on the motherboard.  The
//    second is the PS/2 keyboard connected via the Data/Clock pin.
//
// 2. The term "output buffer" refers to the buffer that the PS/2
//    controller uses to send data to the CPU.  From our sw point
//    of view it is the input to us.  But to prevent even more
//    confusion, we maintain that designation.  Likewise, the
//    "input buffer" refers to the location where the host places
//    commands to the PS/2 controller.
//
// 3. The keyboard is communicated with via the Data port when we
//    have established communication with a keyboard
//

int ps2_kbd_init()
{
	
	vuchar temp8;
	int retry;

	ps2_kbd_ok = 0;

	retry = 10;
	while(retry)
	{
		// flush the output buffer first
		ps2_kbd_obf_flush();

		// turn the keyboard port off then on
		if (wait_ps2_kbd_ibf_clr()) return -1;
	    PS2_REG(PS2_CMD) = PS2_CMD_KBD_OFF;
		monDelay (100);

		if (wait_ps2_kbd_ibf_clr()) return -1;
	    PS2_REG(PS2_CMD) = PS2_CMD_KBD_ON;
		ps2_kbd_obf_flush();

#ifdef PS2_DEBUG
	    printf("PS2 Controller Self Test - Sent: %02x\n", PS2_CMD_DIAG);
#endif
	    // Send the Diagnostic Command
		if (wait_ps2_kbd_ibf_clr()) return -1;
	    PS2_REG(PS2_CMD) = PS2_CMD_DIAG;

		// check the results
		if (wait_ps2_kbd_obf_set()) return -1;
		temp8 = PS2_REG(PS2_DATA);
	    if (temp8 != PS2_KBD_STAT_DIAG_OK) {
	        printf("PS2 Controller Self Test - Fail: %x\n", temp8);
			return -1;
	    }
#ifdef PS2_DEBUG
	    printf("PS2 Controller Self Test - Pass: %02x\n", temp8);
	    printf("PS2 Controller Enable Keyboard: %02x\n", PS2_CMD_KBD_ON);
#endif

	    // Enable the Keyboard Port on the PS controller itself
		if (wait_ps2_kbd_ibf_clr()) return -1;
	    PS2_REG(PS2_CMD) = PS2_CMD_KBD_ON;
		ps2_kbd_obf_flush();

	    // Send a Reset command to the keyboard
		if (wait_ps2_kbd_ibf_clr()) return -1;
	    PS2_REG(PS2_DATA) = PS2_KBD_CMD_RST;

		// wait until we get a response, then check for timeout
		if (wait_ps2_kbd_obf_set()) return -1;
		temp8 = PS2_REG(PS2_STAT);
		if (temp8 & (PS2_STAT_TX | PS2_STAT_RX)){
			// did we get a re-send?
			temp8 = PS2_REG(PS2_DATA);
    		if (temp8 != PS2_KBD_STAT_RESEND) continue;
		}
		else
		{
			// now check for ack
			temp8 = PS2_REG(PS2_DATA);
		    if (temp8 == PS2_KBD_STAT_ACK) break;	
		}
#ifdef PS2_DEBUG
    	printf("PS2 Keyboard - Re-sending Reset\n");
#endif
		retry--;

	} // while retry

	if (retry == 0){
#ifdef PS2_DEBUG
		printf("Keyboard Reset Failed. No Keyboard Connected?\n");
#endif
		return -1;
	}

	// If we got an ACK, the next byte should be Reset OK
	if (wait_ps2_kbd_obf_set()) return -1;
	temp8 = PS2_REG(PS2_DATA);
    if (temp8 != PS2_KBD_STAT_RST_OK)
     {
#ifdef PS2_DEBUG
        printf("Keyboard Reset Failed - Expected Reset OK: got: %02x\n", temp8);
#endif
        return -1;
    }

#ifdef PS2_DEBUG
    printf("PS2 Keyboard Reset - Received OK\n");
#endif
    // Set the keyboard to scan mode 1
    // First Flush the Output Buffer - The keyboard may have
    // sent us scan codes already
	ps2_kbd_obf_flush();

	if (wait_ps2_kbd_ibf_clr()) return -1;
    PS2_REG(PS2_DATA) = PS2_KBD_CMD_MODE;

    // Again, flush the Input Buffer
	ps2_kbd_obf_flush();

	if (wait_ps2_kbd_ibf_clr()) return -1;
    PS2_REG(PS2_DATA) = PS2_KBD_CMD_MODE_SCAN1;
        
	printf("PS/2 Keyboard found and initialized.\n");
	// initialize the globals
    ps2_kbd_ok = 1;
	ps2_char = 0;
	ps2_char_ok = 0;
	ps2_shift_flag = 0;
	ps2_alt_flag = 0;
	ps2_ctl_flag = 0;
	ps2_led_flag = 0;

    return 0;
}

//--------------------------------------------------------------------------
// wait_ps2_kbd_ibf_set()
//
// This routine waits until the Input Buffer Flag is Set,
// or time's out.  
vulong wait_ps2_kbd_ibf_set()
{
	int timeout;

	// check the results
    timeout = PS2_TIMEOUT;
	while(timeout){
		// delay before each check
		monDelay(1);
		if(PS2_REG(PS2_STAT) & PS2_STAT_IBF) break; 
   		timeout--;
    }
	if (timeout == 0){
		ps2_kbd_ok = 0;
        printf("PS2 Wait for Input Buffer Flag Set Timed Out - Controller Failure?\n");
		return 1;	
	}
	return 0;
}
	

//--------------------------------------------------------------------------
// wait_ps2_kbd_ibf_clr()
//
// This routine waits until the Input Buffer Flag is Clear,
// or time's out.  
vulong wait_ps2_kbd_ibf_clr()
{
	int timeout;

	// check the results
    timeout = PS2_TIMEOUT;
	while(timeout){
		// delay before each check
		monDelay(1);
		if((PS2_REG(PS2_STAT) & PS2_STAT_IBF) == 0) break; 
   		timeout--;
    }
	if (timeout == 0){
		ps2_kbd_ok = 0;
        printf("PS2 Wait for Input Buffer Flag Clear Timed Out - Controller Failure?\n");
		return 1;	
	}
	return 0;
}
	

//--------------------------------------------------------------------------
// ps2_kbd_obf_flush()
//
// This routine waits until the Output Buffer Flag is Clear,
// by reading the data port continuously
void ps2_kbd_obf_flush()
{
    // Clear the Output Buffer
    while ((PS2_REG(PS2_STAT) & PS2_STAT_OBF)) {
        PS2_REG(PS2_DATA);
    }
}
	

//--------------------------------------------------------------------------
// wait_ps2_kbd_obf_clr()
//
// This routine waits until the Output Buffer Flag is Cleared,
// or time's out
vulong wait_ps2_kbd_obf_clr()
{
	int timeout;

	// check the results
    timeout = PS2_TIMEOUT;
	while(timeout){
		// delay before each check
		monDelay(1);
		if ((PS2_REG(PS2_STAT) & PS2_STAT_OBF) == 0) break;
   		timeout--;
    }
	if (timeout == 0){
		ps2_kbd_ok = 0;
        printf("PS2 Wait for Output Buffer Flag Clear Timed Out - Controller Failure?\n");
		return -1;	
	}

⌨️ 快捷键说明

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