📄 ps2.c
字号:
///////////////////////////////////////////////////////////////////////////////
// ps2.c
//
// Copyright (c) 2004, WeiHua Technology Co., Ltd.
// All rights reserved.
//
// Created by:
// Modified by: Chen Huahai 2004-09-03
//
// Desription:
//
// 注: 在接标准键盘时,PC通讯后自动切换,通讯无问题.
// 但接POS键盘时,执行"101-X/TIME"时向POS键盘发数据,常导致切换后无法通讯.
//
// 注2: 在走纸键的处理上,最多只支持5个.
///////////////////////////////////////////////////////////////////////////////
#include "ecrsys.h"
#include "keydef.h"
#include "data.h"
#include "ftype.h"
#include "sysdata.h"
#include <string.h>
// public funtion
byte PS2_ChkKeyIn(word *keyCode);
void PS2_GetFeedCode(void);
void PS2_GetKBScanCode(void); // 调试用.
void PS2_SetPortFunc(byte flag);
// private funtion
void PS2_Init(byte port);
byte PS2_GetKey(word *keyCode);
void PS2_InsKey(byte keyCode);
byte PS2_Decode(byte src);
byte PS2_TransScanCode(byte *scanCode, const word *key);
extern volatile byte SpluKeyIn;
#define PS2_KB_BUF_SIZE 0x3f
static byte ps2UartPort;
static byte ps2KeyIn = 0, ps2KeyOut = 0;
static byte ps2KeyBuf[PS2_KB_BUF_SIZE+1];
static byte port0Func = 0; // default PS2 KeyBoard, support PC communi
static byte keyFeedFlag = 0;
#define MAX_FEED_KEY 5 // 最多同时支持5个走纸键.
static word feedKeyCode[MAX_FEED_KEY]; // POS键盘中的走纸键扫描码.
const word defScanCode[MAX_EXTEND_KEY+1] = { // 1数字为没有意义
0x00*0x100 + 0x1C,
0x00*0x100 + 0x32,
0x00*0x100 + 0x21,
0x00*0x100 + 0x23,
0x00*0x100 + 0x24,
0x00*0x100 + 0x2B,
0x00*0x100 + 0x34,
0x00*0x100 + 0x33,
0x00*0x100 + 0x05,
0x00*0x100 + 0x06,
0xE0*0x100 + 0x70,
0xE0*0x100 + 0x6C,
0xE0*0x100 + 0x7D,
0x11*0x100 + 0x16,
0xE0*0x100 + 0x75,
0xE0*0x100 + 0x6B,
0x00*0x100 + 0x43,
0x00*0x100 + 0x3B,
0x00*0x100 + 0x42,
0x00*0x100 + 0x4B,
0x00*0x100 + 0x3A,
0x00*0x100 + 0x31,
0x00*0x100 + 0x44,
0x00*0x100 + 0x4D,
0x00*0x100 + 0x04,
0x00*0x100 + 0x0C,
0xE0*0x100 + 0x71,
0xE0*0x100 + 0x69,
0xE0*0x100 + 0x7A,
0x11*0x100 + 0x1E,
0xE0*0x100 + 0x72,
0xE0*0x100 + 0x74,
0x00*0x100 + 0x15,
0x00*0x100 + 0x2D,
0x00*0x100 + 0x1B,
0x00*0x100 + 0x2C,
0x00*0x100 + 0x3C,
0x00*0x100 + 0x2A,
0x00*0x100 + 0x1D,
0x00*0x100 + 0x22,
0x00*0x100 + 0x03,
0x00*0x100 + 0x0B,
0x14*0x100 + 0x05,
0x11*0x100 + 0x01,
0x11*0x100 + 0x09,
0x11*0x100 + 0x25,
0x11*0x100 + 0x2E,
0x00*0x100 + 0x7B,
0x00*0x100 + 0x35,
0x00*0x100 + 0x1A,
0x00*0x100 + 0x29,
0x12*0x100 + 0x16,
0x12*0x100 + 0x1E,
0x12*0x100 + 0x26,
0x12*0x100 + 0x25,
0x12*0x100 + 0x2E,
0x00*0x100 + 0x83,
0x00*0x100 + 0x0A,
0x14*0x100 + 0x06,
0x00*0x100 + 0x66,
0x00*0x100 + 0x6C,
0x00*0x100 + 0x75,
0x00*0x100 + 0x7D,
0xE0*0x100 + 0x4A,
0x14*0x100 + 0x01,
0x12*0x100 + 0x3D,
0x12*0x100 + 0x4C,
0x12*0x100 + 0x46,
0x12*0x100 + 0x45,
0x00*0x100 + 0x5D,
0x12*0x100 + 0x4A,
0x00*0x100 + 0x4C,
0x00*0x100 + 0x01,
0x00*0x100 + 0x09,
0x14*0x100 + 0x04,
0x00*0x100 + 0x76,
0x00*0x100 + 0x6B,
0x00*0x100 + 0x73,
0x00*0x100 + 0x74,
0x00*0x100 + 0x79,
0x12*0x100 + 0x49,
0x00*0x100 + 0x41,
0x12*0x100 + 0x4E,
0x00*0x100 + 0x0D,
0x11*0x100 + 0x36,
0x11*0x100 + 0x3D,
0x11*0x100 + 0x3E,
0x11*0x100 + 0x46,
0x00*0x100 + 0x78,
0x00*0x100 + 0x07,
0x14*0x100 + 0x0C,
0x00*0x100 + 0x7C,
0x00*0x100 + 0x69,
0x00*0x100 + 0x72,
0x00*0x100 + 0x7A,
0x00*0x100 + 0x5A,
0x11*0x100 + 0x05,
0x11*0x100 + 0x06,
0x11*0x100 + 0x04,
0x11*0x100 + 0x0C,
0x11*0x100 + 0x03,
0x11*0x100 + 0x0B,
0x11*0x100 + 0x83,
0x11*0x100 + 0x0A,
0x14*0x100 + 0x83,
0x14*0x100 + 0x0B,
0x14*0x100 + 0x03,
0x11*0x100 + 0x45,
0x00*0x100 + 0x70,
// 0x70*0x100 + 0x70, // Double Zero
0x11*0x100 + 0x26, // Double Zero, 改为"Alt+3"
0x00*0x100 + 0x71,
};
///////////////////////////////////////////////////////////////////////////////
// Descript: 获取POS键盘的扫描码,以便在监视POS键盘时处理. 走纸键.
// In Param: void
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void PS2_GetFeedCode(void)
{
word i;
byte cnt = 0;
for (i=0; i< MAX_FEED_KEY; i++)
{
feedKeyCode[i] = 0xEEEE; // 虚键.
}
for (i = 0; i < MAX_EXTEND_KEY; i++)
{
if (KD_FEED == FF_Key_Tabl[i])
{
feedKeyCode[cnt++] = defScanCode[key_logic[i]-0x80];
if (cnt >= MAX_FEED_KEY)
{
break;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: set PORT0 use for PS2 KB or PC Communication
// In Param: flag -- 0 PS2 / 1 PC / 2 ISP
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void PS2_SetPortFunc(byte flag)
{
word baud = 0;
if (flag == 0)
{
port0Func = 0;
PS2_Init(PORT0);
//Uart_WriteByte(PORT0, 0xff); // reset POS KB.
}
else if (flag == 1)
{
port0Func = 1;
switch (Uart_GetBaudRate(PORT0))
{
case 9600: baud = BRG_96; break;
case 19200: baud = BRG_192; break;
case 38400: baud = BRG_384; break;
case 57600:
default: baud = BRG_576; break;
}
Uart_SetBaudRate(PORT0, (BYTE)baud);
ClrRsBuf(PORT0);
}
else if (flag == 2)
{
port0Func = 1;
baud = BRG_576;
Uart_SetBaudRate(PORT0, (BYTE)baud);
ClrRsBuf(PORT0);
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Check PS2 key buffer
// In Param: void
// Out Param: *keyCode -- key value
// Return: OK / NG
///////////////////////////////////////////////////////////////////////////////
byte PS2_ChkKeyIn(word *keyCode)
{
byte tmp;
if (port_sel1 != DEV_TYPE_POSKB && port_sel2 != DEV_TYPE_POSKB) // PC communication Now.
{
return NG;
}
if (keyFeedFlag) // 走纸键处理.
{
key_fd = 1;
}
// if (ps2UartPort == PORT1)
// {
// BarRecFlag = 1;
// SpluKeyIn = 1;
// }
// Uart_WriteByte(PORT0, 0x54);
if (CheckRsBufEmpty(ps2UartPort) != OK) // 将POS键盘发来的数据全部解析出来.
{
Uart_ReadByte(ps2UartPort, &tmp);
PS2_Decode(tmp);
return PS2_GetKey(keyCode);
}
return NG;
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Insert one key to PS2 key buffer
// In Param: keyCode -- key value
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void PS2_InsKey(byte keyCode)
{
if (((ps2KeyIn + 1) % PS2_KB_BUF_SIZE) != ps2KeyOut)
{
ps2KeyBuf[ps2KeyIn] = keyCode;
ps2KeyIn = (ps2KeyIn + 1) % PS2_KB_BUF_SIZE;
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: Get one key to PS2 key buffer
// In Param: void
// Out Param: *keyCode -- key value
// Return: OK / NG
///////////////////////////////////////////////////////////////////////////////
byte PS2_GetKey(word *keyCode)
{
if (ps2KeyIn != ps2KeyOut)
{
*keyCode = ps2KeyBuf[ps2KeyOut];
ps2KeyOut = (ps2KeyOut + 1) % PS2_KB_BUF_SIZE;
return OK;
}
return NG;
}
///////////////////////////////////////////////////////////////////////////////
// Descript: set UART port, baudrate and mode.
// In Param: port
// Out Param: void
// Return: void
///////////////////////////////////////////////////////////////////////////////
void PS2_Init(byte port)
{
if (port == PORT0)
{
ps2UartPort = port;
// Uart_SetBaudRate(ps2UartPort, BRG_96);
// ClrRsBuf(ps2UartPort);
}
else if (port == PORT1)
{
ps2UartPort = port;
// BarRecFlag = 1;
// SpluKeyIn = 1;
// Uart_SetBaudRate(ps2UartPort, BRG_96);
// ClrRsBuf(ps2UartPort);
}
}
///////////////////////////////////////////////////////////////////////////////
// Descript: decode PS2 keyboard input, Pump valid keyin to keybuff
// In Param: src
// Out Param: void
// Return: OK / NG
///////////////////////////////////////////////////////////////////////////////
byte PS2_Decode(byte src)
{
#define CRTL_KEY 0x14
#define ALT_KEY 0x11
#define SHIFT_KEY 0x12
const byte makeOrBreak = 0; // 0 按下时发出 / 1 弹起时发出.
static word lastKey = 0;
static byte ps2KeyBuf[10];
static byte ps2KeyCnt = 0;
static word combKey = 0;
word key;
byte temp[10];
byte scanCode;
byte i;
switch (src)
{
case 0xE0:
case 0xE1:
case 0xF0:
if (ps2KeyCnt < 2)
{
ps2KeyBuf[ps2KeyCnt++] = src;
}
break;
default:
if (ps2KeyCnt < 3)
{
ps2KeyBuf[ps2KeyCnt++] = src;
// 第一次解析按键: 解析出各独立按键.
if (ps2KeyCnt == 1)
{
key = ps2KeyBuf[0];
// if (key == feedKeyCode)
// {
// keyFeedFlag = 1;
// }
if (makeOrBreak == 1) // 弹起时取键值.
{
if (lastKey == key)
{
lastKey = 0;
}
key = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -