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

📄 keyscan.c

📁 arm9.rar
💻 C
字号:
/**************************************************************
4*4 Key Scan
**************************************************************/
#include "def.h"
#include "2410addr.h"
#include "config.h"
#include "board.h"
#include "utils.h"
#include "timer.h"

#define	KEY_ROW_R	*(volatile U16 *)( 0x38001002 )		//nGCS7

/*
static void __irq Key_ISR(void)
{
	if(rINTPND==BIT_EINT8_23) {
		ClearPending(BIT_EINT8_23);
		if(rEINTPEND&(1<<11)) {
			puts("eint11\n");
			rEINTPEND |= 1<< 11;
		}
		if(rEINTPEND&(1<<19)) {
			puts("eint19\n");		
			rEINTPEND |= 1<< 19;
		}
	}
	if(rINTPND==BIT_EINT0) {
		puts("eint0\n");
		ClearPending(BIT_EINT0);
	}
	if(rINTPND==BIT_EINT2) {
		puts("eint2\n");
		ClearPending(BIT_EINT2);
	}
}

void KeyScanInit(void)
{
	puts("\nKey Scan Test\n");	

	rGPGCON &= ~((3<<12)|(3<<4));
	rGPGCON |= (1<<12)|(1<<4);		//GPG6,2 output 0
	rGPGDAT &= ~((1<<6)|(1<<2));
	
	rGPECON &= ~((3<<26)|(3<<22));
	rGPECON |= (1<<26)|(1<<22);		//GPE13,11 output 0
	rGPEDAT &= ~((1<<13)|(1<<11));
	
	
	rEXTINT0 &= ~(7|(7<<8));	
	rEXTINT0 |= (2|(2<<8));	//set eint0,2 falling edge int
	rEXTINT1 &= ~(7<<12);
	rEXTINT1 |= (2<<12);	//set eint11 falling edge int
	rEXTINT2 &= ~(0xf<<12);
	rEXTINT2 |= (2<<12);	//set eint19 falling edge int

	rEINTPEND |= (1<<11)|(1<<19);		//clear eint 11,19
	rEINTMASK &= ~((1<<11)|(1<<19));	//enable eint11,19
	ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);
	pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR;
	EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);	

	rGPGCON &= ~(3<<20);
	rGPGUP  &= ~(1<<10);
}
*/

//#define	PLATFORM_S3C2410_VER_10
#define	PLATFORM_S3C2410_VER_20

static U8 key_ch[16] = {	'7',  '8',  '9',  0x1b, 
							'4',  '5',  '6',  'y',
							'1',  '2',  '3',  'n',
							'0', '+',  '-', 0xd};

static U8 key_matrix[256];

static U32 down_key;

U8 ScanKeyDown(void)
{
	//if(down_key)
	//	printf("key down %c\n", down_key);
	return down_key?1:0;
}

U8 GetScanKey(void)
{
	U8 k;
	
	k = down_key;
	down_key = 0;
	return k;
}

#ifdef	PLATFORM_S3C2410_VER_10

static __inline void set_io1(void)
{
	// GPF0,GPF2 input with pull-up
	rGPFCON &= ~(3 | (3<<4));
	rGPFUP  &= ~(1 | (1<<2));
	// GPG3,GPG11 input, GPG2,GPG6 output
	rGPGCON = (rGPGCON & ~((3<<6) | (3<<22) | (3<<4) | (3<<12))) | (1<<4) | (1<<12);
	rGPGUP  = (rGPGUP & ~((1<<3) | (1<<11))) | (1<<2) | (1<<6);
	// GPE11,GPG13 output
	rGPECON = (rGPECON & ~((3<<22) | (3<<26))) | (1<<22) | (1<<26);
	rGPEUP |= (1<<11) | (1<<13);

	rGPGDAT &= ~((1<<2)  | (1<<6));		//output 0
	rGPEDAT &= ~((1<<11) | (1<<13));	//output 0
}

static __inline void set_io2(void)
{
	// GPF0,GPF2 output
	rGPFCON = (rGPFCON & ~(3 | (3<<4))) | 1 | (1<<4);
	rGPFUP |= 1 | (1<<2);
	// GPG3,GPG11 output, GPG2,GPG6 input
	rGPGCON = (rGPGCON & ~((3<<6) | (3<<22) | (3<<4) | (3<<12))) | (1<<6) | (1<<22);
	rGPGUP  = (rGPGUP & ~((1<<2) | (1<<6))) | (1<<3) | (1<<11);
	// GPE11,GPE13 input with pull-up
	rGPECON &= ~((3<<22) | (3<<26));
	rGPEUP  &= ~((1<<11) | (1<<13));

	rGPFDAT &= ~(1 | (1<<2));		//output 0
	rGPGDAT &= ~((1<<3) | (1<<11));	//output 0
}

static __inline U32 get_io1(void)
{
	U32 val = -1;

	if(!(rGPFDAT&1))
		val &= ~1;
	if(!(rGPFDAT&(1<<2)))
		val &= ~2;
	if(!(rGPGDAT&(1<<3)))
		val &= ~4;
	if(!(rGPGDAT&(1<<11)))
		val &= ~8;

	return val;
}

static __inline U32 get_io2(void)
{
	U32 val = -1;

	if(!(rGPEDAT&(1<<11)))
		val &= ~0x10;
	if(!(rGPEDAT&(1<<13)))
		val &= ~0x20;
	if(!(rGPGDAT&(1<<2)))
		val &= ~0x40;
	if(!(rGPGDAT&(1<<6)))
		val &= ~0x80;
	
	return val;
}

static void key_scan_proc(U32 dummy)
{
	static U32 last = -1, key_r = -1, cnt, scan_idx, val;
	static U32 led_flash;
	U32 i = 3, pre, vary;
	
	led_flash++;
	if(led_flash>=50) {
		led_flash = 0;
		LedSet(LedGet()^1);
	}
	
	while(i) {
	
		if(scan_idx&1) {
			val |= 0xf<<4;
			val &= get_io2();
		}
		else
			val  = get_io1();

		if(i==3) {
			pre = val;
		} else {
			if(val!=pre)
				break;
		}
		i--;
	}
	
	if(i)
		return;
	
	if(scan_idx++&1)
		set_io1();
	else {
		set_io2();
		return;
	}
	
	//printf("%x,%x\n", key_r, val);
	cnt++;
	if(last!=val)
			cnt = 0;
	last = val;
	if(cnt==3) {
		vary = (key_r^val)&0xff&key_r;
		if(vary) {
			down_key = key_matrix[vary];		
			//printf("%x,%c\n", vary, down_key);
		}
		//printf("%x,%x\n", key_r, val);
		key_r = val;
	}
}

void KeyScanInit(void)
{
	int r, c;
	
	down_key = 0;
	for(r=0; r<256; r++)
		key_matrix[r] = 0;
	for(r=0; r<4; r++)
		for(c=0; c<4; c++)
			key_matrix[(1<<(r+4))+(1<<c)] = key_ch[r*4+c];
			
	set_io1();
	
	RequestBiosTimerEvent(1,  key_scan_proc);
}

#endif

#ifdef	PLATFORM_S3C2410_VER_20

static __inline void set_io(void)
{
	// GPF0,GPF2 input with pull-up
	rGPFCON &= ~(3 | (3<<4));
	rGPFUP  &= ~(1 | (1<<2));
	// GPG3,GPG11 input with pull-up
	rGPGCON = rGPGCON & ~((3<<6) | (3<<22));
	rGPGUP  = rGPGUP & ~((1<<3) | (1<<11));

	KEY_ROW_R = 0xf;
}

static void key_scan_proc(U32 dummy)
{
	static int led_flash, key_r, key_r_cnt, key_last = -1;
	int i, j, key = 0xffff;
	
	led_flash++;
	if(led_flash>=50) {
		led_flash = 0;
		LedSet(LedGet()^1);
	}
	
	for(i=0; i<4; i++)
	{
		KEY_ROW_R = ~(1<<i);
		for(j=0; j<24; j++);
		
		if(!(rGPFDAT&(1<<0)))
			key &= ~(1<<i);
		if(!(rGPFDAT&(1<<2)))
			key &= ~(1<<(i+4));
		if(!(rGPGDAT&(1<<3)))
			key &= ~(1<<(i+8));
		if(!(rGPGDAT&(1<<11)))
			key &= ~(1<<(i+12));
	}
	
	key_r_cnt++;
	if(key!=key_r)
	{
		key_r = key;
		key_r_cnt = 0;
	}
	if(key_r_cnt==3)	//30ms
	{
		int tmp;
		
		tmp  = key^key_last;
		tmp &= key_last;
		
		key_last = key;
		if(tmp)
		{
			for(i=0; i<16; i++)
				if(tmp&(1<<i))
				{
					down_key = key_ch[i];
					//printf("key 0x%x %c down!\n", tmp, down_key);
					break;
				}
		}
	}

}

void KeyScanInit(void)
{
	int r, c;
	
	down_key = 0;
	for(r=0; r<256; r++)
		key_matrix[r] = 0;
	for(r=0; r<4; r++)
		for(c=0; c<4; c++)
			key_matrix[(1<<(r+4))+(1<<c)] = key_ch[r*4+c];
			
	set_io();
	
	RequestBiosTimerEvent(1,  key_scan_proc);
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -