#include "ps2.h"
extern int8u RevData[5];
extern int8u gs_RevCnt;
extern bool gs_RevSuc;
/*
*** 函数名: PS2_DevReadPC_KB()
*** 入口: 读取数据的地址
*** 出口: true--成功,false--失败
*** 调用全局变量: 无
*** 功能描述: 从PC机上读取一个字节数据
*/
bool PS2_DevReadPC_KB(int8u *PTemp)
{
DDRC &=~(bit0+bit1);
int8u i=0;
int8u Parity_Temp=1;
int8u Temp = 0;
int8u Parity=0;
while((PINC&bit0)!=bit0)//等待主机释放时钟
{
i++;
if(i>250) return 2;
NOP();
}
// read 8bit data
PORTC |= bit0;
DDRC |= bit0; //时钟线为输出
for(i=0;i<8;i++)
{
Delay(US20); //延时20US
PS2SCK_L;
Delay(US40);
PS2SCK_H;
Delay(US20);
if((PINC&bit1)==bit1)
{
if(Parity_Temp==1) Parity_Temp=0;
else Parity_Temp=1;
Temp|= 1<<i;
}
else
{
Temp&= ~(1<<i);
}
}
// read parity bit
Delay(US20);
PS2SCK_L;
Delay(US40);
PS2SCK_H;
Delay(US20);
if((PINC&bit1)==bit1)
{
Parity= 1;
}
else
{
Parity= 0;
}
// read stop bit
Delay(US20);
PS2SCK_L;
Delay(US40);
PS2SCK_H;
Delay(US20);
if((PINC&bit1)!=bit1)
{
return 3;
}
// ack
Delay(US20);
PS2SDA_L;
Delay(US20);
PS2SCK_L;
Delay(US20);
PS2SCK_H;
Delay(US20);
PS2SDA_H;
DDRC &= ~(bit0+bit1); //释放总线
// check data
if (Parity==Parity_Temp)
{
*PTemp= Temp;
return true;
}
else
{
return 4;
}
}
/*
*** 函数名: PS2_DevWritePC_KB()
*** 入口: 要写的数据
*** 出口: true--成功,false--失败
*** 调用全局变量: 无
*** 功能描述: 向PC机发送一个字节的数据
*/
bool PS2_DevWritePC_KB(int8u data)
{
int8u i;
int8u p = 1;
int8u MaskCord=1;
// check if the bus is busy
if((PINC&bit0)!= bit0)
{
Delay(US20);
if((PINC&bit0)!=bit0)
{
return false;
}
}
Delay(US20);
if((PINC&bit1)!=bit1) //判断CLOCK是否为高
{
return false;
}
// --- start transmit --- //
DDRC |= bit0+bit1; //设为输出
Delay(10);
// tx start bit
PS2SDA_L;
Delay(US20);
PS2SCK_L;
Delay(US40);
PS2SCK_H;
Delay(US20);
// tx 8bit data
for(i=0;i<8;i++)
{
if((data&MaskCord)==MaskCord)
{
if(p==1) p = 0;
else p = 1;
PS2SDA_H;
}
else
{
PS2SDA_L;
}
Delay(US20);
PS2SCK_L;
Delay(US40);
PS2SCK_H;
Delay(US20);
MaskCord=MaskCord<<1;
}
// tx parity bit
if( p )
{
PS2SDA_H;
}
else
{
PS2SDA_L;
}
Delay(US20);
PS2SCK_L;
Delay(US40);
PS2SCK_H;
Delay(US20);
// stop bit
PS2SDA_H;
Delay(US20);
PS2SCK_L;
Delay(US40);
PS2SCK_H;
DDRC &= ~(bit0+bit1);//设为输入
Delay(300);
return true;
}
/*
*** 函数名: ProcessPS2()
*** 入口: 读取数据的地址
*** 出口: 无
*** 调用全局变量: 无
*** 功能描述: 主机数据接收数据处理
*/
void ProcessHost(void)
{
if((RevData[0]==0x16)&&(RevData[1]==0xf0)&&(RevData[2]==0x16))
{
PORTA^=bit0;
}
else if((RevData[0]==0x1e)&&(RevData[1]==0xf0)&&(RevData[2]==0x1e))
{
PORTA^=bit1;
}
else if((RevData[0]==0x26)&&(RevData[1]==0xf0)&&(RevData[2]==0x26))
{
PORTA^=bit2;
}
else if((RevData[0]==0x25)&&(RevData[1]==0xf0)&&(RevData[2]==0x25))
{
gs_RevCnt=0;
memset(RevData,0,5);
PORTA^=bit3;
}
else if((RevData[0]==0x2e)&&(RevData[1]==0xf0)&&(RevData[2]==0x2e))
{
PORTA^=bit4;
}
else if((RevData[0]==0x36)&&(RevData[1]==0xf0)&&(RevData[2]==0x36))
{
PORTA^=bit5;
}
gs_RevSuc=false;
gs_RevCnt=0;
memset(RevData,0,5);
}
/*
*** 函数名: ProcessPS2()
*** 入口: 读取数据的地址
*** 出口: 无
*** 调用全局变量: 无
*** 功能描述: 数据处理
*/
void ProcessPS2(int8u *Pdata)
{
int8u Data=*Pdata;
switch (Data)
{
case 0xf0://设置扫描码
{
PS2_DevWritePC_KB(0XFA);
Delay(BYBEDELAY);
PS2_DevWritePC_KB(0XAB);
Delay(BYBEDELAY);
PS2_DevWritePC_KB(0X83);
PORTA ^= bit0;
break;
}
case 0xf2:
{
PS2_DevWritePC_KB(0XFA);
PORTA ^= bit1;
break;
}
case 0xf3://设置扫描速度
{
PS2_DevWritePC_KB(0XFA);
PORTA ^= bit2;
break;
}
case 0XF4://使能键盘
{
PS2_DevWritePC_KB(0XFA);
PORTA ^= bit3;
break;
}
case 0XF5://禁止键盘
{
PS2_DevWritePC_KB(0XFA);
PORTA ^= bit4;
break;
}
case 0x00:
{
PS2_DevWritePC_KB(0XFA);
break;
}
case 0x02:
{
PS2_DevWritePC_KB(0XFA);
break;
}
case 0x20:
{
PS2_DevWritePC_KB(0XFA);
break;
}
case 0xED://设置指示灯
{
PS2_DevWritePC_KB(0xFA);
break;
}
case 0xEE:
{
PS2_DevWritePC_KB(0xEE);
break;
}
case 0xFE://重发最后一个字节
{
break;
}
case 0xFF://复位键盘
{
PS2_DevWritePC_KB(0xFA);
Delay(BYBEDELAY);
PS2_DevWritePC_KB(0xaa);
PORTA ^= bit5;
break;
}
case 0x2d:
{
PS2_DevWritePC_KB(0xFA);
PORTA ^= bit7;
}
default : break;
}
}
/*
*** 函数名: PS2_PCReadDev_KB()
*** 入口: 数据存放地址
*** 出口: 读取数据是否成功
*** 调用全局变量: 无
*** 功能描述: 主机读取从机数据
*/
bool PS2_PCReadDev_KB(int8u *temp)
{
int8u i,j;
int8u Parity=0;
int16u data=0;
while((PINC&bit0)==bit0) //等时钟拉低
{
j++;
if(j>200) return 1;
}
j=0;
for (i=0;i<10;i++)
{
while((PINC&bit0)!=bit0) //等时钟被拉高
{
j++;
if(j>200) return 2;
NOP();
}
j=0;
Delay(READDELAY);
if((PINC&bit0)!=bit0)
{
if((PINC&bit1)==bit1)
{
data |=(1<<i);
if(i<8)
{
Parity++;
}
}
else
{
data &= ~(1<<i);
}
}
else return 3;
}
if(((data&bit8)!=bit8)&&((Parity%2)==0)) return 4;
else if (((data&bit8)==bit8)&&((Parity%2)!=0)) return 5; //奇偶校验是否正确
if ((data&bit9)!=bit9) return 6; //停止位是否正确
*temp=(int8u)data;
return 0;
}
/*
*** 函数名: PS2_PCWhiteDev_KB()
*** 入口: 要发送的数据
*** 出口: 读取数据是否成功
*** 调用全局变量: 无
*** 功能描述: 主机发送数据给从机
*/
bool PS2_PCWhiteDev_KB(int8u data)
{
int8u i,j;
int8u Parity=0;
int8u maskcode=0x01;
DDRC|=bit0+bit1;
PORTC |= bit0+bit1;
// PS2SCK_L;
PORTC &= ~bit0;
Delay(100); //时钟拉低100uS
DDRC&=~bit0; //时钟设为输入
while((PINC&bit0)!=bit0) //等待设备把时钟变高
{
j++;
if(j>200)
return false;
NOP();
}
PS2SDA_L; //拉低数据线准备发送
while((PINC&bit0)==bit0) //等待设备把时钟拉低
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
for(i=0;i<8;i++)
{
if((data&maskcode)==maskcode)
{
PS2SDA_H;
Parity++;
}
else PS2SDA_L;
while((PINC&bit0)!=bit0) //等待时钟变高
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
while((PINC&bit0)==bit0) //等待设备把时钟拉低
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
maskcode=maskcode<<1;
}
//发送校验位
if (Parity%2==0)
{
PS2SDA_H;
while((PINC&bit0)!=bit0) //等待时钟变高
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
while((PINC&bit0)==bit0) //等待设备把时钟拉低
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
}
else
{
PS2SDA_L;
while((PINC&bit0)!=bit0) //等待时钟变高
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
while((PINC&bit0)==bit0) //等待设备把时钟拉低
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
}
/*
//发送结束位
PS2SDA_H;
while((PINC&bit0)!=bit0) //等待时钟变高
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
while((PINC&bit0)==bit0) //等待设备把时钟拉低
{
j++;
if(j>200)
return false;
NOP();
}
j=0;
*/
DDRC&=~bit1;
return true;
}