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

📄 ps2_kbd.c

📁 Embest EudKit-II教学系统配Samsung S3C44B0处理器的部分测试程序。
💻 C
字号:
/*********************************************************************************************
* File:	ps2_kbd.c
* Author:	embest
* Desc:	ps2 keyboard test program
* History:
*********************************************************************************************/
#include "ps2.h"
#include "44blib.h"


#define IS_EXTEND(c)	(c==0xe0)
#define IS_EXTEND1(c)	(c==0xe1)
#define IS_BREAK(c)		(c==0xf0)
#define IS_SCAN(c)		(c&0x100)


static short scan_table[256] =
{
	/*00*/0x0100, /*01*/0x0101, /*02*/0x0102, /*03*/0x0103, /*04*/0x0104, /*05*/0x0105, /*06*/0x0106, /*07*/0x0107,
	/*08*/0x0108, /*09*/0x0109, /*0A*/0x010A, /*0B*/0x010B, /*0C*/0x010C, /*0D*/0x0009, /*0E*/0x0060, /*0F*/0x010F,
	/*10*/0x0110, /*11*/0x0111, /*12*/0x0112, /*13*/0x0113, /*14*/0x0114, /*15*/0x0071, /*16*/0x0031, /*17*/0x0117,
	/*18*/0x0118, /*19*/0x0119, /*1A*/0x007A, /*1B*/0x0073, /*1C*/0x0061, /*1D*/0x0077, /*1E*/0x0032, /*1F*/0x011F,
	/*20*/0x0120, /*21*/0x0063, /*22*/0x0078, /*23*/0x0064, /*24*/0x0065, /*25*/0x0034, /*26*/0x0033, /*27*/0x0127,
	/*28*/0x0128, /*29*/0x0020, /*2A*/0x0076, /*2B*/0x0066, /*2C*/0x0074, /*2D*/0x0072, /*2E*/0x0035, /*2F*/0x012F,
	/*30*/0x0130, /*31*/0x006E, /*32*/0x0062, /*33*/0x0068, /*34*/0x0067, /*35*/0x0079, /*36*/0x0036, /*37*/0x0137,
	/*38*/0x0138, /*39*/0x0139, /*3A*/0x006D, /*3B*/0x006A, /*3C*/0x0075, /*3D*/0x0037, /*3E*/0x0038, /*3F*/0x013F,
	/*40*/0x0140, /*41*/0x002C, /*42*/0x006B, /*43*/0x0069, /*44*/0x006F, /*45*/0x0030, /*46*/0x0039, /*47*/0x0147,
	/*48*/0x0148, /*49*/0x002E, /*4A*/0x002F, /*4B*/0x006C, /*4C*/0x003B, /*4D*/0x0070, /*4E*/0x002D, /*4F*/0x014F,
	/*50*/0x0150, /*51*/0x0151, /*52*/0x0027, /*53*/0x0153, /*54*/0x005B, /*55*/0x003D, /*56*/0x0156, /*57*/0x0157,
	/*58*/0x0158, /*59*/0x0159, /*5A*/0x000D, /*5B*/0x005D, /*5C*/0x015C, /*5D*/0x005C, /*5E*/0x015E, /*5F*/0x015F,
	/*60*/0x0160, /*61*/0x0161, /*62*/0x0162, /*63*/0x0163, /*64*/0x0164, /*65*/0x0165, /*66*/0x0008, /*67*/0x0167,
	/*68*/0x0168, /*69*/0x0031, /*6A*/0x016A, /*6B*/0x0034, /*6C*/0x0037, /*6D*/0x016D, /*6E*/0x016E, /*6F*/0x016F,
	/*70*/0x0030, /*71*/0x002E, /*72*/0x0032, /*73*/0x0035, /*74*/0x0036, /*75*/0x0038, /*76*/0x001B, /*77*/0x0177,
	/*78*/0x0178, /*79*/0x002B, /*7A*/0x0033, /*7B*/0x002D, /*7C*/0x002A, /*7D*/0x0039, /*7E*/0x017E, /*7F*/0x017F,
	/*80*/0x0180, /*81*/0x0181, /*82*/0x0182, /*83*/0x0183, /*84*/0x0184, /*85*/0x0185, /*86*/0x0186, /*87*/0x0187,
	/*88*/0x0188, /*89*/0x0189, /*8A*/0x018A, /*8B*/0x018B, /*8C*/0x018C, /*8D*/0x018D, /*8E*/0x018E, /*8F*/0x018F,
	/*90*/0x0190, /*91*/0x0191, /*92*/0x0192, /*93*/0x0193, /*94*/0x0194, /*95*/0x0195, /*96*/0x0196, /*97*/0x0197,
	/*98*/0x0198, /*99*/0x0199, /*9A*/0x019A, /*9B*/0x019B, /*9C*/0x019C, /*9D*/0x019D, /*9E*/0x019E, /*9F*/0x019F,
	/*A0*/0x01A0, /*A1*/0x01A1, /*A2*/0x01A2, /*A3*/0x01A3, /*A4*/0x01A4, /*A5*/0x01A5, /*A6*/0x01A6, /*A7*/0x01A7,
	/*A8*/0x01A8, /*A9*/0x01A9, /*AA*/0x01AA, /*AB*/0x01AB, /*AC*/0x01AC, /*AD*/0x01AD, /*AE*/0x01AE, /*AF*/0x01AF,
	/*B0*/0x01B0, /*B1*/0x01B1, /*B2*/0x01B2, /*B3*/0x01B3, /*B4*/0x01B4, /*B5*/0x01B5, /*B6*/0x01B6, /*B7*/0x01B7,
	/*B8*/0x01B8, /*B9*/0x01B9, /*BA*/0x01BA, /*BB*/0x01BB, /*BC*/0x01BC, /*BD*/0x01BD, /*BE*/0x01BE, /*BF*/0x01BF,
	/*C0*/0x01C0, /*C1*/0x01C1, /*C2*/0x01C2, /*C3*/0x01C3, /*C4*/0x01C4, /*C5*/0x01C5, /*C6*/0x01C6, /*C7*/0x01C7,
	/*C8*/0x01C8, /*C9*/0x01C9, /*CA*/0x01CA, /*CB*/0x01CB, /*CC*/0x01CC, /*CD*/0x01CD, /*CE*/0x01CE, /*CF*/0x01CF,
	/*D0*/0x01D0, /*D1*/0x01D1, /*D2*/0x01D2, /*D3*/0x01D3, /*D4*/0x01D4, /*D5*/0x01D5, /*D6*/0x01D6, /*D7*/0x01D7,
	/*D8*/0x01D8, /*D9*/0x01D9, /*DA*/0x01DA, /*DB*/0x01DB, /*DC*/0x01DC, /*DD*/0x01DD, /*DE*/0x01DE, /*DF*/0x01DF,
	/*E0*/0x01E0, /*E1*/0x01E1, /*E2*/0x01E2, /*E3*/0x01E3, /*E4*/0x01E4, /*E5*/0x01E5, /*E6*/0x01E6, /*E7*/0x01E7,
	/*E8*/0x01E8, /*E9*/0x01E9, /*EA*/0x01EA, /*EB*/0x01EB, /*EC*/0x01EC, /*ED*/0x01ED, /*EE*/0x01EE, /*EF*/0x01EF,
	/*F0*/0x01F0, /*F1*/0x01F1, /*F2*/0x01F2, /*F3*/0x01F3, /*F4*/0x01F4, /*F5*/0x01F5, /*F6*/0x01F6, /*F7*/0x01F7,
	/*F8*/0x01F8, /*F9*/0x01F9, /*FA*/0x01FA, /*FB*/0x01FB, /*FC*/0x01FC, /*FD*/0x01FD, /*FE*/0x01FE, /*FF*/0x01FF
};


static short shift_scan_table[256] =
{
	/*00*/0x0100, /*01*/0x0101, /*02*/0x0102, /*03*/0x0103, /*04*/0x0104, /*05*/0x0105, /*06*/0x0106, /*07*/0x0107,
	/*08*/0x0108, /*09*/0x0109, /*0A*/0x010A, /*0B*/0x010B, /*0C*/0x010C, /*0D*/0x0009, /*0E*/0x007E, /*0F*/0x010F,
	/*10*/0x0110, /*11*/0x0111, /*12*/0x0112, /*13*/0x0113, /*14*/0x0114, /*15*/0x0051, /*16*/0x0021, /*17*/0x0117,
	/*18*/0x0118, /*19*/0x0119, /*1A*/0x005A, /*1B*/0x0053, /*1C*/0x0041, /*1D*/0x0057, /*1E*/0x0040, /*1F*/0x011F,
	/*20*/0x0120, /*21*/0x0043, /*22*/0x0058, /*23*/0x0044, /*24*/0x0045, /*25*/0x0024, /*26*/0x0023, /*27*/0x0127,
	/*28*/0x0128, /*29*/0x0020, /*2A*/0x0056, /*2B*/0x0046, /*2C*/0x0054, /*2D*/0x0052, /*2E*/0x0025, /*2F*/0x012F,
	/*30*/0x0130, /*31*/0x004E, /*32*/0x0042, /*33*/0x0048, /*34*/0x0047, /*35*/0x0059, /*36*/0x005E, /*37*/0x0137,
	/*38*/0x0138, /*39*/0x0139, /*3A*/0x004D, /*3B*/0x004A, /*3C*/0x0055, /*3D*/0x0026, /*3E*/0x002A, /*3F*/0x013F,
	/*40*/0x0140, /*41*/0x003C, /*42*/0x004B, /*43*/0x0049, /*44*/0x004F, /*45*/0x0029, /*46*/0x0028, /*47*/0x0147,
	/*48*/0x0148, /*49*/0x003E, /*4A*/0x003F, /*4B*/0x004C, /*4C*/0x003A, /*4D*/0x0050, /*4E*/0x005F, /*4F*/0x014F,
	/*50*/0x0150, /*51*/0x0151, /*52*/0x0022, /*53*/0x0153, /*54*/0x007B, /*55*/0x002B, /*56*/0x0156, /*57*/0x0157,
	/*58*/0x0158, /*59*/0x0159, /*5A*/0x000D, /*5B*/0x007D, /*5C*/0x015C, /*5D*/0x007C, /*5E*/0x015E, /*5F*/0x015F,
	/*60*/0x0160, /*61*/0x0161, /*62*/0x0162, /*63*/0x0163, /*64*/0x0164, /*65*/0x0165, /*66*/0x0008, /*67*/0x0167,
	/*68*/0x0168, /*69*/0x0031, /*6A*/0x016A, /*6B*/0x0034, /*6C*/0x0037, /*6D*/0x016D, /*6E*/0x016E, /*6F*/0x016F,
	/*70*/0x0030, /*71*/0x002E, /*72*/0x0032, /*73*/0x0035, /*74*/0x0036, /*75*/0x0038, /*76*/0x001B, /*77*/0x0177,
	/*78*/0x0178, /*79*/0x002B, /*7A*/0x0033, /*7B*/0x002D, /*7C*/0x002A, /*7D*/0x0039, /*7E*/0x017E, /*7F*/0x017F,
	/*80*/0x0180, /*81*/0x0181, /*82*/0x0182, /*83*/0x0183, /*84*/0x0184, /*85*/0x0185, /*86*/0x0186, /*87*/0x0187,
	/*88*/0x0188, /*89*/0x0189, /*8A*/0x018A, /*8B*/0x018B, /*8C*/0x018C, /*8D*/0x018D, /*8E*/0x018E, /*8F*/0x018F,
	/*90*/0x0190, /*91*/0x0191, /*92*/0x0192, /*93*/0x0193, /*94*/0x0194, /*95*/0x0195, /*96*/0x0196, /*97*/0x0197,
	/*98*/0x0198, /*99*/0x0199, /*9A*/0x019A, /*9B*/0x019B, /*9C*/0x019C, /*9D*/0x019D, /*9E*/0x019E, /*9F*/0x019F,
	/*A0*/0x01A0, /*A1*/0x01A1, /*A2*/0x01A2, /*A3*/0x01A3, /*A4*/0x01A4, /*A5*/0x01A5, /*A6*/0x01A6, /*A7*/0x01A7,
	/*A8*/0x01A8, /*A9*/0x01A9, /*AA*/0x01AA, /*AB*/0x01AB, /*AC*/0x01AC, /*AD*/0x01AD, /*AE*/0x01AE, /*AF*/0x01AF,
	/*B0*/0x01B0, /*B1*/0x01B1, /*B2*/0x01B2, /*B3*/0x01B3, /*B4*/0x01B4, /*B5*/0x01B5, /*B6*/0x01B6, /*B7*/0x01B7,
	/*B8*/0x01B8, /*B9*/0x01B9, /*BA*/0x01BA, /*BB*/0x01BB, /*BC*/0x01BC, /*BD*/0x01BD, /*BE*/0x01BE, /*BF*/0x01BF,
	/*C0*/0x01C0, /*C1*/0x01C1, /*C2*/0x01C2, /*C3*/0x01C3, /*C4*/0x01C4, /*C5*/0x01C5, /*C6*/0x01C6, /*C7*/0x01C7,
	/*C8*/0x01C8, /*C9*/0x01C9, /*CA*/0x01CA, /*CB*/0x01CB, /*CC*/0x01CC, /*CD*/0x01CD, /*CE*/0x01CE, /*CF*/0x01CF,
	/*D0*/0x01D0, /*D1*/0x01D1, /*D2*/0x01D2, /*D3*/0x01D3, /*D4*/0x01D4, /*D5*/0x01D5, /*D6*/0x01D6, /*D7*/0x01D7,
	/*D8*/0x01D8, /*D9*/0x01D9, /*DA*/0x01DA, /*DB*/0x01DB, /*DC*/0x01DC, /*DD*/0x01DD, /*DE*/0x01DE, /*DF*/0x01DF,
	/*E0*/0x01E0, /*E1*/0x01E1, /*E2*/0x01E2, /*E3*/0x01E3, /*E4*/0x01E4, /*E5*/0x01E5, /*E6*/0x01E6, /*E7*/0x01E7,
	/*E8*/0x01E8, /*E9*/0x01E9, /*EA*/0x01EA, /*EB*/0x01EB, /*EC*/0x01EC, /*ED*/0x01ED, /*EE*/0x01EE, /*EF*/0x01EF,
	/*F0*/0x01F0, /*F1*/0x01F1, /*F2*/0x01F2, /*F3*/0x01F3, /*F4*/0x01F4, /*F5*/0x01F5, /*F6*/0x01F6, /*F7*/0x01F7,
	/*F8*/0x01F8, /*F9*/0x01F9, /*FA*/0x01FA, /*FB*/0x01FB, /*FC*/0x01FC, /*FD*/0x01FD, /*FE*/0x01FE, /*FF*/0x01FF
};


/*
* function key state
*/
static int key_shift;
static int key_ctrl;
static int key_alt;

/*
* keyboard led state
*/
static int led_num;
static int led_caps;
static int led_scroll;


/*
* name:		convert_asii
* func:		convert scan code to asii code
* para:		scan	---input, scan code
* ret:		asii or scan code
* comment:		
*/
static short convert_asii(unsigned char scan)
{
	short ret;

	if(!led_num)
	{
		if( scan == 0x69 || scan == 0x70 ||
			scan == 0x71 || scan == 0x72 ||
			scan == 0x73 || scan == 0x74 ||
			scan == 0x75 || scan == 0x7A ||
			scan == 0x7D || scan == 0x6B || scan == 0x6C)
		{
			ret = scan | 0x100;
			return ret;
		}
	}
			
	if(key_shift)
	{
		ret = shift_scan_table[scan];
	}
	else
	{
		ret = scan_table[scan];
	}
	if(!IS_SCAN(ret) && isalpha(ret) && led_caps)
	{
		if(key_shift)
			ret = tolower(ret);
		else
			ret = toupper(ret);
	}
	return ret;	
}


/*
* name:		wait_for_write
* func:		waiting, until write buffer is empty
* para:		none
* ret:		1/wait successful, 0/failed
* comment:		
*/
static int wait_for_write(void)
{
	unsigned char sta;

	for(;;)
	{
		sta = reg_read(REG_STATUS);
		if(!(sta & BS_OBF)) return 1;
		if(sta & BS_TO) break;
	}

	return 0;
}


/*
* name:		wait_for_read
* func:		waiting, until read buffer is full
* para:		none
* ret:		1/wait successful, 0/failed
* comment:		
*/
static int wait_for_read(void)
{
	unsigned char sta;

	for(;;)
	{
		sta = reg_read(REG_STATUS);
		if(sta & BS_IBF) return 1;
		if(sta & BS_TO) break;
	}

	return 0;
}


/*
* name:		kbd_reset
* func:		reset keyboard
* para:		none
* ret:		1/successful, 0/failed
* comment:		
*/
static int kbd_reset(void)
{
	if(!wait_for_write()) return 0;

	reg_write(REG_DATA, 0xFF);				// reset PS/2 keyboard

	if(!wait_for_read()) return 0;

	if(reg_read(REG_DATA) != 0xFA) return 0;// check if 0xFF sended successful
	
	if(!wait_for_read()) return 0;

	return (reg_read(REG_DATA) == 0xAA);	// check if init success
}


/*
* name:		kbd_reset
* func:		test keyboard TX/RX data
* para:		none
* ret:		1/successful, 0/failed
* comment:		
*/
static int kbd_test(void)
{
	if(!wait_for_write()) return 0;

	reg_write(REG_DATA, 0xEE);

	if(!wait_for_read()) return 0;

	return (reg_read(REG_DATA) != 0xEE);
	
}


/*
* name:		kbd_led
* func:		control keyboard led
* para:		none
* ret:		1/successful, 0/failed
* comment:		
*/
static int kbd_led(void)
{
	unsigned char led = 0;

	if(led_caps) led |= 0x04;
	if(led_num) led |= 0x02;
	if(led_scroll) led |= 0x01;

	if(!wait_for_write()) return 0;

	reg_write(REG_DATA, 0xED);

	if(!wait_for_read()) return 0;

	if(reg_read(REG_DATA) != 0xFA) return 0;

	if(!wait_for_write()) return 0;

	reg_write(REG_DATA, led);

	if(reg_read(REG_DATA) != 0xFA) return 0;

	return 1;
}


/*
* name:		KbdInit
* func:		initialize keyboard test example
* para:		none
* ret:		1/successful, 0/failed
* comment:		
*/
int KbdInit(void)
{
	init_ps2();

	if(!kbd_reset())
		return 0;

	key_shift = 0;
	key_ctrl = 0;
	key_alt = 0;

	led_num = 0;
	led_caps = 0;
	led_scroll = 0;

	if(!kbd_test())
		return 0;

	return 1;
}


/*
* name:		KbdClose
* func:		close keyboard test example
* para:		none
* ret:		none
* comment:		
*/
void KbdClose(void)
{
	close_ps2();
}


/*
* name:		KbdInit
* func:		keyboard test example routine
* para:		none
* ret:		1/successful exit, 0/failed exit
* comment:		
*/
int KbdTest(void)
{
	int i, brk, ext;
	short ch;

	uart_printf("Press ESC to exit test...\n");

	brk = 0;
	ext = 0;

	for(;;)
	{
		if(!wait_for_read()) return 0;
		ch = reg_read(REG_DATA);

		if(IS_EXTEND1(ch))
		{
			/* PAUSE key */
			for(i=0; i<7; i++)
			{
				if(!wait_for_read()) return 0;
				ch = reg_read(REG_DATA);
			}
		}
		else if(IS_EXTEND(ch))
		{
			ext = 1;
			continue;
		}
		else
		{
			if(ext)
			{
				/* PRNT SCRN */
				if(ch == 0x12)
				{
					for(i=0; i<2; i++)
					{
						if(!wait_for_read()) return 0;
						ch = reg_read(REG_DATA);
					}
					ext = 0;
					continue;
				}
				/* U D L R arrow key */
				if( ch == 0x69 || ch == 0x70 ||
					ch == 0x71 || ch == 0x72 ||
					ch == 0x73 || ch == 0x74 ||
					ch == 0x75 || ch == 0x7A ||
					ch == 0x7D || ch == 0x6B || ch == 0x6C)

				{
					ext = 0;
					continue;
				}
			}
					

			if(IS_BREAK(ch))
			{
				brk = 1;
				continue;
			}


			if(brk)
			{
				switch(ch)
				{
				case 0x12:
				case 0x59: key_shift = 0; break;
				case 0x14: key_ctrl = 0;  break;
				case 0x11: key_alt = 0;   break;
				/* PRNT SCRN */
				case 0x7C:
					for(i=0; i<3; i++)
					{
						if(!wait_for_read()) return 0;
						ch = reg_read(REG_DATA);
					}
					break;
				}
				brk = 0;
				ext = 0;
				continue;
			}

			ch = convert_asii(ch);
			if(ext)
			{
			 	if(ch == '?' && key_shift)
					ch = '/';
		
				ext = 0;
			}

			if(IS_SCAN(ch))
			{
				ch &= 0xFF;
				switch(ch)
				{
				case 0x58:
					led_caps = !led_caps;
					kbd_led();
					break;
				case 0x7e:
					led_scroll = !led_scroll;
					kbd_led();
					break;
				case 0x77:
					led_num = !led_num;
					kbd_led();
					break;
				case 0x12:
				case 0x59: key_shift = 1; break;
				case 0x14: key_ctrl = 1;  break;
				case 0x11: key_alt = 1;   break;
				}
				continue;
			}

			if(ch == 0x1b) /* ESC */
			{
				uart_printf("\n Exit test.\n");
				break;
			}

			uart_printf("%c", ch);
			if(ch == '\r')
				uart_printf("\n");
		}
	}

	return 1;
}

⌨️ 快捷键说明

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