📄 ps2.c
字号:
#include "../inc/44blib.h"
#include "../inc/44b.h"
#include "ps2.h"
#define MAX_PS2_BUF (20)
#define PS2DATA (rPDATG & 0x40)
unsigned int buf_w_pt, buf_r_pt;
unsigned char ps2_buffer[MAX_PS2_BUF];
KEYBOARD_STRUCT key1_lut[]=
{
0x16, 0x31, 0x21, 0, 0, // { 1 } { ! }
0x1e, 0x32, 0x40, 0, 0, // { 2 } { @ }
0x26, 0x33, 0x23, 0, 0, // { 3 } { # }
0x25, 0x34, 0x24, 0, 0, // { 4 } { $ }
0x2e, 0x35, 0x25, 0, 0, // { 5 } { % }
0x36, 0x36, 0x5e, 0, 0, // { 6 } { ^ }
0x3d, 0x37, 0x26, 0, 0, // { 7 } { & }
0x3e, 0x38, 0x2a, 0, 0, // { 8 } { * }
0x46, 0x39, 0x28, 0, 0, // { 9 } { ( }
0x45, 0x30, 0x29, 0, 0, // { 0 } { ) }
0x1c, 0x61, 0x41, 0, 0, // { a } { A }
0x32, 0x62, 0x42, 0, 0, // { b } { B }
0x21, 0x63, 0x43, 0, 0, // { c } { C }
0x23, 0x64, 0x44, 0, 0, // { d } { D }
0x24, 0x65, 0x45, 0, 0, // { e } { E }
0x2b, 0x66, 0x46, 0, 0, // { f } { F }
0x34, 0x67, 0x47, 0, 0, // { g } { G }
0x33, 0x68, 0x48, 0, 0, // { h } { H }
0x43, 0x69, 0x49, 0, 0, // { i } { I }
0x3b, 0x6a, 0x4a, 0, 0, // { j } { J }
0x42, 0x6b, 0x4b, 0, 0, // { k } { K }
0x4b, 0x6c, 0x4c, 0, 0, // { l } { L }
0x3a, 0x6d, 0x4d, 0, 0, // { m } { M }
0x31, 0x6e, 0x4e, 0, 0, // { n } { N }
0x44, 0x6f, 0x4f, 0, 0, // { o } { O }
0x4d, 0x70, 0x50, 0, 0, // { p } { P }
0x15, 0x71, 0x51, 0, 0, // { q } { Q }
0x2d, 0x72, 0x52, 0, 0, // { r } { R }
0x1b, 0x73, 0x53, 0, 0, // { s } { S }
0x2c, 0x74, 0x54, 0, 0, // { t } { T }
0x3c, 0x75, 0x55, 0, 0, // { u } { U }
0x2a, 0x76, 0x56, 0, 0, // { v } { V }
0x1d, 0x77, 0x57, 0, 0, // { w } { W }
0x22, 0x78, 0x58, 0, 0, // { x } { X }
0x35, 0x79, 0x59, 0, 0, // { y } { Y }
0x1a, 0x7a, 0x5a, 0, 0, // { z } { Z }
0x0e, 0x60, 0x7e, 0, 0, // { ` } { ~ }
0x4e, 0x2d, 0x5f, 0, 0, // { - } { _ }
0x55, 0x3d, 0x2b, 0, 0, // { = } { + }
0x5d, 0x5c, 0x7c, 0, 0, // { \ } { | }
0x54, 0x5b, 0x7b, 0, 0, // { [ } { { }
0x5b, 0x5d, 0x7d, 0, 0, // { ] } { } }
0x4c, 0x3b, 0x3a, 0, 0, // { ; } { : }
0x52, 0x27, 0x22, 0, 0, // { ' } { " }
0x41, 0x2c, 0x3c, 0, 0, // { , } { < }
0x49, 0x2e, 0x3e, 0, 0, // { . } { > }
0x4a, 0x2f, 0x3f, 0, 0, // { / } { ? }
0x5a, 0x0a, 0, 0, 0, // { enter }
0x29, 0x20, 0, 0, 0, // { space }
0x05, 0, 0, 0, "F1",
0x06, 0, 0, 0, "F2",
0x04, 0, 0, 0, "F3",
0x0c, 0, 0, 0, "F4",
0x03, 0, 0, 0, "F5",
0x0b, 0, 0, 0, "F6",
0x83, 0, 0, 0, "F7",
0x0a, 0, 0, 0, "F8",
0x01, 0, 0, 0, "F9",
0x09, 0, 0, 0, "F10",
0x78, 0, 0, 0, "F11",
0x07, 0, 0, 0, "F12",
0x66, 0, 0, 0, "BKSP",
0x0d, 0, 0, 0, "TAB",
0x14, 0, 0, 0, "L_CTRL",
0xe01f, 0, 0, 0, "L_GUI",
0x11, 0, 0, 0, "L_ALT",
0xe014, 0, 0, 0, "R_CTRL",
0xe027, 0, 0, 0, "R_GUI",
0xe011, 0, 0, 0, "R_ALT",
0xe02f, 0, 0, 0, "APPS",
0x76, 0, 0, 0, "ESC",
0xe070, 0, 0, 0, "Ins",
0xe06c, 0, 0, 0, "Home",
0xe07d, 0, 0, 0, "PgUP",
0xe071, 0, 0, 0, "Del",
0xe069, 0, 0, 0, "End",
0xe07a, 0, 0, 0, "PgDn",
0xe075, 0, 0, 0, "U_ARROW",
0xe06b, 0, 0, 0, "L_ARROW",
0xe072, 0, 0, 0, "D_ARROW",
0xe074, 0, 0, 0, "R_ARROW",
0xe04a, 0, 0, 0, "KP_/",
0x7c, 0, 0, 0, "KP_*",
0x7b, 0, 0, 0, "KP_-",
0x79, 0, 0, 0, "KP_+",
0xe05a, 0, 0, 0, "KP_EN",
0x71, 0, 0, 0, "KP_.",
0x70, 0, 0, 0, "KP_0",
0x69, 0, 0, 0, "KP_1",
0x72, 0, 0, 0, "KP_2",
0x7a, 0, 0, 0, "KP_3",
0x6b, 0, 0, 0, "KP_4",
0x73, 0, 0, 0, "KP_5",
0x74, 0, 0, 0, "KP_6",
0x6c, 0, 0, 0, "KP_7",
0x75, 0, 0, 0, "KP_8",
0x7d, 0, 0, 0, "KP_9",
0xe037, 0, 0, 0, "Power",
0xe03f, 0, 0, 0, "Sleep",
0xe05e, 0, 0, 0, "Wake",
0, 0, 0, 0, 0,
};
#define KEY_LSHIFT_MASK (0x12)
#define KEY_RSHIFT_MASK (0x59)
#define KEY_CAPS_MASK (0x58)
#define KEY_NUM_MASK (0x77)
#define KEY_LSHIFT_INDEX (0)
#define KEY_RSHIFT_INDEX (1)
#define KEY_CAPS_INDEX (2)
#define KEY_NUM_INDEX (3)
KEYBOARD_STRUCT keys_lut[]=
{
KEY_LSHIFT_MASK, 0, 0, 0, 0, //L_shift
KEY_RSHIFT_MASK, 0, 0, 0, 0, //R_shift
KEY_CAPS_MASK, 0, 0, 0, 0, //caps
KEY_NUM_MASK, 0, 0, 0, 0, //num
0, 0, 0, 0, 0,
};
void ps2_interrupt(void)
{
static unsigned int dat, count;
count++;
dat >>= 1;
if(PS2DATA) dat |= 0x200;
if(count == 11)
{
if((buf_w_pt+1)%MAX_PS2_BUF != buf_r_pt)
{
ps2_buffer[buf_w_pt] = (unsigned char)(dat&0xff);
buf_w_pt = (buf_w_pt+1)%MAX_PS2_BUF;
}
dat = 0;
count = 0;
}
}
void ps2_waitack(unsigned int count, unsigned int *ack)
{
unsigned int i, wait_time;
*ack = 0;
for(i=0;i<count;i++)
{
wait_time = 20000;
while((buf_r_pt == buf_w_pt) && wait_time--);
if(buf_r_pt != buf_w_pt)
{
(*ack) <<= 8;
*ack|=ps2_buffer[buf_w_pt-1];
buf_w_pt = (buf_w_pt-1)%MAX_PS2_BUF;
}
}
}
void ps2_command(unsigned char cmd)
{
unsigned int i, j;
rINTMSK |= BIT_EINT4567;
rPCONG = (rPCONG&(~(0xf<<12))) | (0x5<<12);
rPDATG &= ~(1<<7); //Bring the Clock line low for at least 100 microseconds.
Delay(100);
rPDATG &= ~(1<<6); //Bring the Data line low.
Delay(15);
rPCONG = (rPCONG&(~(0xf<<12))) | (0x1<<12); //Release the Clock line.
while(rPDATG&0x80); //Wait for the device to bring the Clock line low.
for(i=0,j=0;i<8;i++)
{
if(cmd&0x01) //Set/reset the Data line to send the first data bit.
{
rPDATG |= (1<<6);
j++;
}
else
rPDATG &= ~(1<<6);
cmd >>=1;
while(!(rPDATG&0x80)); //Wait for the device to bring Clock high.
while(rPDATG&0x80); //Wait for the device to bring Clock low.
}
if(!(j&0x01)) rPDATG |= (1<<6); //Send parity bit
else rPDATG &= ~(1<<6);
while(!(rPDATG&0x80)); //Wait for the device to bring Clock high.
while(rPDATG&0x80); //Wait for the device to bring Clock low.
rPDATG |= (1<<6); //Send stop bit
while(!(rPDATG&0x80)); //Wait for the device to bring Clock high.
while(rPDATG&0x80); //Wait for the device to bring Clock low.
rPCONG = (rPCONG&(~(0xf<<12))); //Release the Data line.
while(rPDATG&0x40); //Wait for the device to bring Data low.
while(rPDATG&0x80); //Wait for the device to bring Clock low.
while((rPDATG&0xc0)!=0xc0); //Wait for the device to release Data and Clock.
rPCONG = (rPCONG&(~(0xf<<12))) | (0xc<<12);
rINTMSK &= ~BIT_EINT4567;
}
void ps2_buffer_check(void)
{
unsigned short dat, key;
unsigned int i, ps2ack;
static unsigned int end_state, exp_state;
static unsigned char key_led;
//#define KEYBOARD_TEST
#ifdef KEYBOARD_TEST
while(buf_r_pt != buf_w_pt)
{
Uart_Printf("%2.2x ",ps2_buffer[buf_r_pt]);
buf_r_pt = (buf_r_pt+1)%MAX_PS2_BUF;
}
#else
while(buf_r_pt != buf_w_pt)
{
dat = ps2_buffer[buf_r_pt];
if(end_state)
{
switch(dat)
{
case KEY_LSHIFT_MASK :
keys_lut[KEY_LSHIFT_INDEX].state = KEY_UP;
break;
case KEY_RSHIFT_MASK :
keys_lut[KEY_RSHIFT_INDEX].state = KEY_UP;
break;
case KEY_CAPS_MASK :
keys_lut[KEY_CAPS_INDEX].state = KEY_UP;
break;
default :
if(exp_state)
{
dat |= 0xe000;
exp_state = 0;
}
for(i=0;(key1_lut[i].mask!=0)&&(key1_lut[i].mask!=dat);i++);
if(key1_lut[i].mask)
{
key1_lut[i].state = KEY_UP;
if(key1_lut[i].desc)
{
Uart_Printf(key1_lut[i].desc);
Uart_Printf(" Up\n");
}
}
}
buf_r_pt = (buf_r_pt+1)%MAX_PS2_BUF;
end_state = 0;
continue;
}
switch(dat)
{
case 0xf0 :
end_state = 1;
break;
case 0xe0 :
exp_state = 1;
break;
case KEY_LSHIFT_MASK :
keys_lut[KEY_LSHIFT_INDEX].state=KEY_DOWN;
break;
case KEY_RSHIFT_MASK :
keys_lut[KEY_RSHIFT_INDEX].state=KEY_DOWN;
break;
case KEY_CAPS_MASK :
if(!(keys_lut[KEY_CAPS_INDEX].state))
{
buf_r_pt = (buf_r_pt+1)%MAX_PS2_BUF;
if(key_led&0x04) key_led&=0x03;
else key_led|=0x04;
ps2_command(0xed);
ps2_waitack(1, &ps2ack);
ps2_command(key_led);
ps2_waitack(1, &ps2ack);
keys_lut[KEY_CAPS_INDEX].state=KEY_DOWN;
continue;
}
break;
default :
if(exp_state)
{
dat |= 0xe000;
exp_state = 0;
}
for(i=0,key=0;(key1_lut[i].mask!=0)&&(key1_lut[i].mask!=dat);i++);
if(key1_lut[i].mask)
{
key1_lut[i].state=KEY_DOWN;
if(keys_lut[KEY_LSHIFT_INDEX].state||keys_lut[KEY_RSHIFT_INDEX].state)
{
key=key1_lut[i].up_value;
if((key_led&0x04) && (key>='A' && key<='Z'))
key += 0x20;
}
else
{
key=key1_lut[i].value;
if((key_led&0x04) && (key>='a' && key<='z'))
key -= 0x20;
}
if(key1_lut[i].desc)
{
Uart_Printf(key1_lut[i].desc);
Uart_Printf(" Down\n");
}
else
Uart_SendByte(key);
}
}
buf_r_pt = (buf_r_pt+1)%MAX_PS2_BUF;
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -