📄 keyscan.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 + -