📄 ps2_kbd.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 + -