📄 ps2.c
字号:
#include "SN8P2201.h"
#include "sn8_mcu_main.h"
#include "sn8_usb_driver.h"
#include "cmn.h"
//#include "source\ibus.h"
#include "ps2.h"
#include "kb_table.h"
#include "ibus.h"
// ----- definition ---- //
// for Keyboard
#pragma rambank 1
u8 led_sta,codeset; // KB led status, kb codeset
u8 rd_pc_kb_buf[2]; // rd_pc_kb_buf[1] 是上一次接收到的字节的缓存
u8 pc_kb_buf[10]; // send to pc data buffer
u8 pc_kb_bufcnt; // 计数器,总是指向下一空白的buffer
#pragma rambank off
// for mouse
u8 rd_pc_mc_buf[2]; // rd_pc_mc_buf[1] 是上一次接收到的字节的缓存
u8 pc_mc_buf[8]; // send to pc data buffer and counter
u8 pc_mc_bufcnt; // 计数器,总是指向下一空白的buffer
u8 s_rate,mc_mode = STREAM; // 采样速率,模式,default is stream
bit f_mc_enb; // until recv 0xf4, set the f_mc_enb
// for makecoe, breakcode
bit f_lc_mc,f_ls_mc,f_la_mc,f_lg_mc,f_rc_mc,f_rs_mc,f_ra_mc,f_rg_mc;
bit f_k1_mc,f_k1_ext,f_k1_spc,f_k2_mc,f_k2_ext,f_k2_spc,f_k3_mc,f_k3_ext,f_k3_spc;
bit f_type_dly,f_need_type;
u8 k1_buf,k2_buf,k3_buf;
bit f_key_press,f_need_type;
u8 type_dlycnt, typecnt,type_buf,last_key;
//
bit f_first_f4 = 0;
void add_type_buf( u8 data );
void ps2_init(void)
{
KB_CKM = 0;
KB_DAM = 0;
MC_CKM = 0;
MC_DAM = 0;
FPS2ENB = 1;
#if(ICE_MODE == 1)
FP61M = 1;
FP61 = 1;
#endif
}
void ps2_disable(void)
{
FPS2ENB = 0;
#if(ICE_MODE == 1)
FP61 = 0;
#endif
}
/*F**************************************************************************
* NAME: rd_pc_kb
*----------------------------------------------------------------------------
* PARAMS: None
*
* return: True or fail
*
*----------------------------------------------------------------------------
* PURPOSE: read one byte data from pc, suppose the start status has been
* betected by main
*----------------------------------------------------------------------------
*****************************************************************************/
bool rd_pc_kb(void)
{
u8 x,temp;
bit p = 1,p_temp;
temp = 0;
KB_CKM = 1;
KB_DAM = 0;
// read 8bit data
for(x=0;x<8;x++)
{
dly_20us();
KB_CK = 0;
dly_40us();
KB_CK = 1;
dly_10us(); // dly_20us // 因为下面的语句要使用20+条汇编,要占用时间,so用dly10us差不多了
if(KB_DA == 1)
{
//p = ~p;
if(p) p = 0;
else p = 1;
temp |= 0x01u<<x;
}
else
{
temp &= ~(0x01u<<x);
}
}
// read parity bit
dly_20us();
KB_CK = 0;
dly_40us();
KB_CK = 1;
dly_20us();
if(KB_DA == 1)
{
p_temp = 1;
}
else
{
p_temp = 0;
}
// read stop bit
dly_20us();
KB_CK = 0;
dly_40us();
KB_CK = 1;
dly_20us();
if(KB_DA == 0)
{
return fail;
}
// ack
dly_10us();
dly_5us();
KB_DAM = 1;
KB_DA = 0;
dly_5us();
KB_CKM = 1;
KB_CK = 0;
dly_40us();
KB_CK = 1;
dly_5us();
KB_DA = 1;
KB_DAM = 0;
KB_CKM = 0;
// check data
if (p == p_temp)
{
rd_pc_kb_buf[0] = temp;
return true;
}
else
{
return fail;
}
}
/*F**************************************************************************
* NAME: bool wr_pc_kb
*----------------------------------------------------------------------------
* PARAMS: None
*
* return: True or fail
*
*----------------------------------------------------------------------------
* PURPOSE:
*
*----------------------------------------------------------------------------
*****************************************************************************/
bool wr_pc_kb(u8 data)
{
u8 x;
bit p = 1;
KB_CKM = 0;
KB_DAM = 0;
// check if the bus is busy
if(KB_CK == 0)
{
dly_20us();
if(KB_CK == 0)
{
return fail;
}
}
dly_40us();
dly_5us();
if(KB_CK == 0)
{
return fail;
}
if(KB_DA == 0)
{
return fail;
}
// --- start transmit --- //
KB_CKM = 1;
KB_DAM = 1;
// tx start bit
KB_DA = 0;
dly_20us();
KB_CK = 0;
dly_40us();
KB_CK = 1;
dly_20us();
// tx 8bit data
for(x=0;x<8;x++)
{
//if( (data&(0x01<<x)) == 1 ) // 小心!
//if( data&(0x01<<x))
if(data&0x01)
{
//p = ~p;
if(p) p = 0;
else p = 1;
KB_DA = 1;
}
else
{
KB_DA = 0;
}
dly_10us();
KB_CK = 0;
dly_40us();
KB_CK = 1;
dly_20us();
// test if host driven the ck
KB_CKM = 0;
if(KB_CK == 0)
{
KB_CKM = 0;
KB_DAM = 0;
return fail;
}
KB_CKM = 1;
data = data>>0x01;
}
// tx parity bit
if( p )
{
KB_DA = 1;
}
else
{
KB_DA = 0;
}
dly_20us();
KB_CK = 0;
dly_40us();
KB_CK = 1;
dly_20us();
KB_CKM = 0;
if(KB_CK == 0)
{
KB_CKM = 0;
KB_DAM = 0;
return fail;
}
KB_CKM = 1;
// stop bit
KB_DA = 1;
dly_20us();
KB_CK = 0;
dly_40us();
KB_CK = 1;
KB_CKM = 0;
dly_20us();
KB_DAM = 0;
//dly_40us();
//dly_10us();
// dly50us太少了,在Vista里会出错,但是XP就不会
dly_100us();
dly_100us();
dly_100us();
dly_100us();
dly_100us();
dly_100us();
return true;
}
/*F**************************************************************************
* NAME: pc_kb_prc
*----------------------------------------------------------------------------
* PARAMS: None
*
* return: None
*
*----------------------------------------------------------------------------
* PURPOSE:
* 处理从PC收到的数据
*----------------------------------------------------------------------------
*****************************************************************************/
void pc_kb_prc(void)
{
u8 data;
data = rd_pc_kb_buf[0];
if( data == 0xfe ) // resend
{
return;
}
else if(data == 0xee) //echo
{
add_pc_kb_buf(0xee);
}
else if( data == 0xf2 )
{
add_pc_kb_buf(0xfa);
add_pc_kb_buf(0xab);
add_pc_kb_buf(0x83);
f_led_rpt_enb = 0;
// boot
f_boot = 1;
bootcnt= 0;
}
else if( data == 0xf4 )
{
f_led_rpt_enb = 0;
// boot
f_boot = 1;
bootcnt= 0;
}
else if( data < 0x08u )
{
if(rd_pc_kb_buf[1] == 0xed)
{
led_sta = data;
set_report_byte_0 = 0; // 为了适应USB KB,统一转成USB的格式
if(led_sta & 0x01) set_report_byte_0 |= 0x04; // Scroll Lock
if(led_sta & 0x02) set_report_byte_0 |= 0x01; // Number Lock
if(led_sta & 0x04) set_report_byte_0 |= 0x02; // Caps Lock
f_led_sta_new = 1;
//led_times++;
//if(led_times > 1)
//{
// f_led_rpt_enb = 1;
//}
}
else if(rd_pc_kb_buf[1] == 0xf0)
{
if(data < 0x04u )
{
codeset = data;
}
}
add_pc_kb_buf(0xfa);
}
else if(data == 0xff)
{
pc_kb_bufcnt = 0; // clear buffer
add_pc_kb_buf(0xfa);
add_pc_kb_buf(0xaa);
f_led_rpt_enb = 0;
// boot
f_boot = 1;
bootcnt= 0;
}
else // 暂时不处理其它的数据
{
add_pc_kb_buf(0xfa);
}
rd_pc_kb_buf[1] = data; // 暂存收到的数据以便下一次分析
}
/*F**************************************************************************
* NAME:
*----------------------------------------------------------------------------
* PARAMS: None
*
* return: None
*
*----------------------------------------------------------------------------
* PURPOSE:
*
*----------------------------------------------------------------------------
*****************************************************************************/
void add_pc_kb_buf( u8 data )
{
pc_kb_buf[pc_kb_bufcnt] = data;
pc_kb_bufcnt++;
if(pc_kb_bufcnt == 10) // if overflow, 删掉前面的缓冲
{
//pc_kb_bufcnt = 7;
rm_pc_kb_buf();
}
}
// 从缓冲区删除最前面那一个byte
void rm_pc_kb_buf(void)
{
/* u8 x;
// 编译出错,为什么?
for(x=0;x<7;x++)
{
pc_kb_buf[x] = pc_kb_buf[x+1];
}
pc_kb_buf[7] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -