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

📄 kbd.c

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 C
字号:
/*
 * File      : kbd.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006, 2007, 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
 * 2007-03-24     Bernard      the first version
 */

#include <rtthread.h>
#include <rthw.h>
#include <pxa270.h>
#include "gpio.h"

#define AKITA_KEY_STROBE_NUM		(11)
#define AKITA_KEY_SENSE_NUM			(7)

#define AKITA_GPIO_G0_STROBE_BIT	0x0f800000
#define AKITA_GPIO_G1_STROBE_BIT	0x00100000
#define AKITA_GPIO_G2_STROBE_BIT	0x01000000
#define AKITA_GPIO_G3_STROBE_BIT	0x00041880
#define AKITA_GPIO_G0_SENSE_BIT		0x00021000
#define AKITA_GPIO_G1_SENSE_BIT		0x000000d4
#define AKITA_GPIO_G2_SENSE_BIT		0x08000000
#define AKITA_GPIO_G3_SENSE_BIT		0x00000000

#define AKITA_GPIO_KEY_STROBE0		88
#define AKITA_GPIO_KEY_STROBE1		23
#define AKITA_GPIO_KEY_STROBE2		24
#define AKITA_GPIO_KEY_STROBE3		25
#define AKITA_GPIO_KEY_STROBE4		26
#define AKITA_GPIO_KEY_STROBE5		27
#define AKITA_GPIO_KEY_STROBE6		52
#define AKITA_GPIO_KEY_STROBE7		103
#define AKITA_GPIO_KEY_STROBE8		107
#define AKITA_GPIO_KEY_STROBE9		108
#define AKITA_GPIO_KEY_STROBE10		114

#define AKITA_GPIO_KEY_SENSE0		12
#define AKITA_GPIO_KEY_SENSE1		17
#define AKITA_GPIO_KEY_SENSE2		91
#define AKITA_GPIO_KEY_SENSE3		34
#define AKITA_GPIO_KEY_SENSE4		36
#define AKITA_GPIO_KEY_SENSE5		38
#define AKITA_GPIO_KEY_SENSE6		39

#define AKITA_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)

static int spitz_strobes[] = 
{
	AKITA_GPIO_KEY_STROBE0,
	AKITA_GPIO_KEY_STROBE1,
	AKITA_GPIO_KEY_STROBE2,
	AKITA_GPIO_KEY_STROBE3,
	AKITA_GPIO_KEY_STROBE4,
	AKITA_GPIO_KEY_STROBE5,
	AKITA_GPIO_KEY_STROBE6,
	AKITA_GPIO_KEY_STROBE7,
	AKITA_GPIO_KEY_STROBE8,
	AKITA_GPIO_KEY_STROBE9,
	AKITA_GPIO_KEY_STROBE10,
};

static int spitz_senses[] = {
	AKITA_GPIO_KEY_SENSE0,
	AKITA_GPIO_KEY_SENSE1,
	AKITA_GPIO_KEY_SENSE2,
	AKITA_GPIO_KEY_SENSE3,
	AKITA_GPIO_KEY_SENSE4,
	AKITA_GPIO_KEY_SENSE5,
	AKITA_GPIO_KEY_SENSE6,
};

rt_inline void rt_hw_kbd_discharge_all(void)
{
	/* STROBE All HiZ */
	PXA2X0_GPIO_GPCR0  =  AKITA_GPIO_G0_STROBE_BIT;
	PXA2X0_GPIO_GPDR0 &= ~AKITA_GPIO_G0_STROBE_BIT;
	PXA2X0_GPIO_GPCR1  =  AKITA_GPIO_G1_STROBE_BIT;
	PXA2X0_GPIO_GPDR1 &= ~AKITA_GPIO_G1_STROBE_BIT;
	PXA2X0_GPIO_GPCR2  =  AKITA_GPIO_G2_STROBE_BIT;
	PXA2X0_GPIO_GPDR2 &= ~AKITA_GPIO_G2_STROBE_BIT;
	PXA2X0_GPIO_GPCR3  =  AKITA_GPIO_G3_STROBE_BIT;
	PXA2X0_GPIO_GPDR3 &= ~AKITA_GPIO_G3_STROBE_BIT;
}

static inline void rt_hw_kbd_activate_all(void)
{
	/* STROBE ALL -> High */
	PXA2X0_GPIO_GPSR0  =  AKITA_GPIO_G0_STROBE_BIT;
	PXA2X0_GPIO_GPDR0 |=  AKITA_GPIO_G0_STROBE_BIT;
	PXA2X0_GPIO_GPSR1  =  AKITA_GPIO_G1_STROBE_BIT;
	PXA2X0_GPIO_GPDR1 |=  AKITA_GPIO_G1_STROBE_BIT;
	PXA2X0_GPIO_GPSR2  =  AKITA_GPIO_G2_STROBE_BIT;
	PXA2X0_GPIO_GPDR2 |=  AKITA_GPIO_G2_STROBE_BIT;
	PXA2X0_GPIO_GPSR3  =  AKITA_GPIO_G3_STROBE_BIT;
	PXA2X0_GPIO_GPDR3 |=  AKITA_GPIO_G3_STROBE_BIT;
}

static inline void rt_hw_kbd_activate_col(int col)
{
	int gpio = spitz_strobes[col];
	PXA2X0_GPIO_GPDR0 &= ~AKITA_GPIO_G0_STROBE_BIT;
	PXA2X0_GPIO_GPDR1 &= ~AKITA_GPIO_G1_STROBE_BIT;
	PXA2X0_GPIO_GPDR2 &= ~AKITA_GPIO_G2_STROBE_BIT;
	PXA2X0_GPIO_GPDR3 &= ~AKITA_GPIO_G3_STROBE_BIT;
	PXA2X0_GPIO_GPSR(gpio) = PXA2X0_GPIO_BIT(gpio);
	PXA2X0_GPIO_GPDR(gpio) |= PXA2X0_GPIO_BIT(gpio);
}

static inline void rt_hw_kbd_reset_col(int col)
{
	int gpio = spitz_strobes[col];
	PXA2X0_GPIO_GPDR0 &= ~AKITA_GPIO_G0_STROBE_BIT;
	PXA2X0_GPIO_GPDR1 &= ~AKITA_GPIO_G1_STROBE_BIT;
	PXA2X0_GPIO_GPDR2 &= ~AKITA_GPIO_G2_STROBE_BIT;
	PXA2X0_GPIO_GPDR3 &= ~AKITA_GPIO_G3_STROBE_BIT;
	PXA2X0_GPIO_GPCR(gpio) = PXA2X0_GPIO_BIT(gpio);
	PXA2X0_GPIO_GPDR(gpio) |= PXA2X0_GPIO_BIT(gpio);
}

static inline int rt_hw_kbd_get_row_status(int col)
{
	return ((PXA2X0_GPIO_GPLR0 >> 12) & 0x01) | ((PXA2X0_GPIO_GPLR0 >> 16) & 0x02)
		   | ((PXA2X0_GPIO_GPLR2 >> 25) & 0x04) | ((PXA2X0_GPIO_GPLR1 << 1) & 0x08)
		   | ((PXA2X0_GPIO_GPLR1 >> 0) & 0x10) | ((PXA2X0_GPIO_GPLR1 >> 1) & 0x60);
}

int rt_hw_kbd_scankeyboard(void)
{
	rt_uint32 row, col, rowd;
	rt_uint32 num_pressed, pwrkey;
	int ret = -1;

	num_pressed = 0;
	pwrkey = ((PXA2X0_GPIO_GPLR(AKITA_GPIO_ON_KEY) & PXA2X0_GPIO_BIT(AKITA_GPIO_ON_KEY)) != 0);

	for (col = 0; col < KB_COLS; col++)
	{
		rt_hw_kbd_discharge_all();

		rt_hw_kbd_activate_col(col);

		rowd = rt_hw_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_hw_kbd_reset_col(col);
	}

	rt_hw_kbd_activate_all();

	/* clear keyboard interrupt */
	for (row = 0; row < KB_ROWS; row++)
	{
		PXA2X0_GPIO_GEDR(spitz_senses[row]) = PXA2X0_GPIO_BIT(spitz_senses[row]);
	}

	if (pwrkey) return -2;

	return ret;
}

void rt_hw_kbd_init(void)
{
	int i;
	
	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
	for (i = 0; i < AKITA_KEY_SENSE_NUM; i++)
	{
		rt_uint32 gfer, grer;
		rt_uint32 pin;
		
		pin = spitz_senses[i];
		
		rt_hw_gpio_set_function(pin, PXA2X0_GPIO_IN);
		
		gfer = PXA2X0_GPIO_GFER(pin);
		gfer &= ~(PXA2X0_GPIO_BIT(pin));
		PXA2X0_GPIO_GFER(pin) = gfer;
		
		grer = PXA2X0_GPIO_GRER(pin);
		grer |= PXA2X0_GPIO_BIT(pin);
		PXA2X0_GPIO_GRER(pin) = grer;
		
		/* set interrupt status */
		PXA2X0_GPIO_GEDR(pin) = PXA2X0_GPIO_BIT(spitz_senses[i]);
	}

	/* Set Strobe lines as outputs - set high */
	for (i = 0; i < AKITA_KEY_STROBE_NUM; i++)
	{
		rt_hw_gpio_set_function(spitz_strobes[i], PXA2X0_GPIO_OUT | PXA2X0_GPIO_SET);
	}

	rt_hw_gpio_set_function(AKITA_GPIO_ON_KEY, PXA2X0_GPIO_IN);
}

⌨️ 快捷键说明

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