⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2.c

📁 ARM7芯片S3C44B0x的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 + -