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

📄 kbd.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
字号:
/*
 * File      : kbd.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006, RT-Thread Develop Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://openlab.rt-thread.com/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2006-10-26     Bernard      the first version
 */

#include <rt-thread.h>
#include <rt-hw.h>
#include <pxa270.h>

#define C1K_KEY_STROBE_NUM		(11)
#define C1K_KEY_SENSE_NUM		(7)

#define C1K_GPIO_G0_STROBE_BIT	0x0f800000
#define C1K_GPIO_G1_STROBE_BIT	0x00100000
#define C1K_GPIO_G2_STROBE_BIT	0x01000000
#define C1K_GPIO_G3_STROBE_BIT	0x00041880
#define C1K_GPIO_G0_SENSE_BIT	0x00021000
#define C1K_GPIO_G1_SENSE_BIT	0x000000d4
#define C1K_GPIO_G2_SENSE_BIT	0x08000000
#define C1K_GPIO_G3_SENSE_BIT	0x00000000

#define C1K_GPIO_KEY_STROBE0	88
#define C1K_GPIO_KEY_STROBE1	23
#define C1K_GPIO_KEY_STROBE2	24
#define C1K_GPIO_KEY_STROBE3	25
#define C1K_GPIO_KEY_STROBE4	26
#define C1K_GPIO_KEY_STROBE5	27
#define C1K_GPIO_KEY_STROBE6	52
#define C1K_GPIO_KEY_STROBE7	103
#define C1K_GPIO_KEY_STROBE8	107
#define C1K_GPIO_KEY_STROBE9	108
#define C1K_GPIO_KEY_STROBE10	114

#define C1K_GPIO_KEY_SENSE0		12
#define C1K_GPIO_KEY_SENSE1		17
#define C1K_GPIO_KEY_SENSE2		91
#define C1K_GPIO_KEY_SENSE3		34
#define C1K_GPIO_KEY_SENSE4		36
#define C1K_GPIO_KEY_SENSE5		38
#define C1K_GPIO_KEY_SENSE6		39

#define C1K_GPIO_ON_KEY			(95)

#define KB_ROWS					7
#define KB_COLS					11
#define KB_ROWMASK(r)			(1 << (r))
#define SCANCODE(r,c)			(((r)<<4) + (c) + 1)
#define	NR_SCANCODES			((KB_ROWS<<4) + 1)

#define SCAN_INTERVAL			(50) 	/* ms */
#define HINGE_SCAN_INTERVAL		(150) 	/* ms */

#define KB_DISCHARGE_DELAY		10
#define KB_ACTIVATE_DELAY		10

static int spitz_strobes[] = {
	C1K_GPIO_KEY_STROBE0,
	C1K_GPIO_KEY_STROBE1,
	C1K_GPIO_KEY_STROBE2,
	C1K_GPIO_KEY_STROBE3,
	C1K_GPIO_KEY_STROBE4,
	C1K_GPIO_KEY_STROBE5,
	C1K_GPIO_KEY_STROBE6,
	C1K_GPIO_KEY_STROBE7,
	C1K_GPIO_KEY_STROBE8,
	C1K_GPIO_KEY_STROBE9,
	C1K_GPIO_KEY_STROBE10,
};

static int spitz_senses[] = {
	C1K_GPIO_KEY_SENSE0,
	C1K_GPIO_KEY_SENSE1,
	C1K_GPIO_KEY_SENSE2,
	C1K_GPIO_KEY_SENSE3,
	C1K_GPIO_KEY_SENSE4,
	C1K_GPIO_KEY_SENSE5,
	C1K_GPIO_KEY_SENSE6,
};

rt_inline void rt_kbd_discharge_all(void)
{
	/* STROBE All HiZ */
	GPCR0  =  C1K_GPIO_G0_STROBE_BIT;
	GPDR0 &= ~C1K_GPIO_G0_STROBE_BIT;
	GPCR1  =  C1K_GPIO_G1_STROBE_BIT;
	GPDR1 &= ~C1K_GPIO_G1_STROBE_BIT;
	GPCR2  =  C1K_GPIO_G2_STROBE_BIT;
	GPDR2 &= ~C1K_GPIO_G2_STROBE_BIT;
	GPCR3  =  C1K_GPIO_G3_STROBE_BIT;
	GPDR3 &= ~C1K_GPIO_G3_STROBE_BIT;
}

static inline void rt_kbd_activate_all(void)
{
	/* STROBE ALL -> High */
	GPSR0  =  C1K_GPIO_G0_STROBE_BIT;
	GPDR0 |=  C1K_GPIO_G0_STROBE_BIT;
	GPSR1  =  C1K_GPIO_G1_STROBE_BIT;
	GPDR1 |=  C1K_GPIO_G1_STROBE_BIT;
	GPSR2  =  C1K_GPIO_G2_STROBE_BIT;
	GPDR2 |=  C1K_GPIO_G2_STROBE_BIT;
	GPSR3  =  C1K_GPIO_G3_STROBE_BIT;
	GPDR3 |=  C1K_GPIO_G3_STROBE_BIT;

	udelay(KB_DISCHARGE_DELAY);
}

static inline void rt_kbd_activate_col(int col)
{
	int gpio = spitz_strobes[col];
	GPDR0 &= ~C1K_GPIO_G0_STROBE_BIT;
	GPDR1 &= ~C1K_GPIO_G1_STROBE_BIT;
	GPDR2 &= ~C1K_GPIO_G2_STROBE_BIT;
	GPDR3 &= ~C1K_GPIO_G3_STROBE_BIT;
	GPSR(gpio) = GPIO_bit(gpio);
	GPDR(gpio) |= GPIO_bit(gpio);
}

static inline void rt_kbd_reset_col(int col)
{
	int gpio = spitz_strobes[col];
	GPDR0 &= ~C1K_GPIO_G0_STROBE_BIT;
	GPDR1 &= ~C1K_GPIO_G1_STROBE_BIT;
	GPDR2 &= ~C1K_GPIO_G2_STROBE_BIT;
	GPDR3 &= ~C1K_GPIO_G3_STROBE_BIT;
	GPCR(gpio) = GPIO_bit(gpio);
	GPDR(gpio) |= GPIO_bit(gpio);
}

static inline int rt_kbd_get_row_status(int col)
{
	return ((GPLR0 >> 12) & 0x01) | ((GPLR0 >> 16) & 0x02)
		   | ((GPLR2 >> 25) & 0x04) | ((GPLR1 << 1) & 0x08)
		   | ((GPLR1 >> 0) & 0x10) | ((GPLR1 >> 1) & 0x60);
}

static int rt_kbd_scankeyboard(void)
{
	rt_uint32 row, col, rowd;
	rt_uint32 num_pressed, pwrkey = ((GPLR(C1K_GPIO_ON_KEY) & GPIO_bit(C1K_GPIO_ON_KEY)) != 0);
	int ret = -1;

	num_pressed = 0;
	for (col = 0; col < KB_COLS; col++)
	{
		rt_kbd_discharge_all();
		udelay(KB_DISCHARGE_DELAY);

		rt_kbd_activate_col(col);
		udelay(KB_ACTIVATE_DELAY);

		rowd = rt_kbd_get_row_status(col);
		for (row = 0; row < KB_ROWS; row++)
		{
			unsigned int scancode, pressed;

			scancode = SCANCODE(row, col);
			pressed = rowd & KB_ROWMASK(row);

			if (pressed)
				ret = scancode;
		}
		rt_kbd_reset_col(col);
	}

	rt_kbd_activate_all();

	if (pwrkey) return -2;

	return ret;
}

void rt_kbd_init(void)
{
	int i;

	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
	for (i = 0; i < C1K_KEY_SENSE_NUM; i++)
		rt_gpio_setmode(spitz_senses[i] | GPIO_IN);

	/* Set Strobe lines as outputs - set high */
	for (i = 0; i < C1K_KEY_STROBE_NUM; i++)
		rt_gpio_setmode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);

	rt_gpio_setmode(C1K_GPIO_ON_KEY | GPIO_IN);
}

⌨️ 快捷键说明

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