主题 : 求mini6410按键程序解析 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 26940
精华: 0
发帖: 13
金钱: 65 两
威望: 13 点
综合积分: 26 分
注册时间: 2010-08-17
最后登录: 2018-07-15
楼主  发表于: 2010-09-01 22:38

 求mini6410按键程序解析

管理提醒: 本帖被 arm9home 从 Linux技术交流专区 移动到本区(2010-09-09)
开发板所用到的按键资源:
按键      对应的IO寄 对应的中断
          存器名称    
K1    GPN0    EINT0
K2    GPN1    EINT1
K3    GPN2    EINT2
K4    GPN3    EINT3
K5    GPN4    EINT4
K6    GPN5    EINT5
K7    GPL11    EINT19
K8    GPL12    EINT20

程序清单:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-clock.h>
#include <plat/regs-gpio.h>
#include <plat/gpio-bank-n.h>

#define DEVICE_NAME "buttons"

struct button_irq_desc
{
    int irq;
    int number;
    char *name;
};

static struct button_irq_desc button_irqs [] =
{
    {IRQ_EINT( 0), 0, "KEY0"},
    {IRQ_EINT( 1), 1, "KEY1"},
    {IRQ_EINT( 2), 2, "KEY2"},
    {IRQ_EINT( 3), 3, "KEY3"},
    {IRQ_EINT( 4), 4, "KEY4"},
    {IRQ_EINT( 5), 5, "KEY5"},
    {IRQ_EINT(19), 6, "KEY6"},
    {IRQ_EINT(20), 7, "KEY7"},
};

static volatile char key_values [] = {'0', '0', '0', '0', '0', '0', '0', '0'};

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

static volatile int ev_press = 0;

static irqreturn_t buttons_interrupt(int irq, void *dev_id)
{
    struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
    int down;
    int number;
    unsigned tmp;
    udelay(0);
    number = button_irqs->number;
    switch(number)
    {
    case 0: case 1: case 2: case 3: case 4: case 5:
    tmp = readl(S3C64XX_GPNDAT);
    down = !(tmp & (1<<number));
    break;
    case 6: case 7:
    tmp = readl(S3C64XX_GPLDAT);
    down = !(tmp & (1 << (number + 5)));
    break;
    default:
    down = 0;
    }
    if (down != (key_values[number] & 1))
    {
    key_values[number] = '0' + down;
    ev_press = 1;
    wake_up_interruptible(&button_waitq);
    }
    return IRQ_RETVAL(IRQ_HANDLED);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int s3c64xx_buttons_open(struct inode *inode, struct file *file)
{
    int i;
    int err = 0;
    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)
    {
    if (button_irqs.irq < 0)
    {
    continue;
    }
    err = request_irq(button_irqs.irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,
    button_irqs.name, (void *)&button_irqs);
    if (err)
    break;
    }
    if (err)
    {
    i--;
    for (; i >= 0; i--)
    {
    if (button_irqs.irq < 0)
    {
    continue;
    }
    disable_irq(button_irqs.irq);
    Free_irq(button_irqs.irq, (void *)&button_irqs);
    }
    return -EBUSY;
    }
    ev_press = 1;
    return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int s3c64xx_buttons_close(struct inode *inode, struct file *file)
{
    int i;
    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)
    {
    if (button_irqs.irq < 0)
    {
    continue;
    }
    free_irq(button_irqs.irq, (void *)&button_irqs);
    }
    return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int s3c64xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
    unsigned long err;
    if (!ev_press)
    {
    if (filp->f_flags & O_NONBLOCK)
    return -EAGAIN;
    else
    wait_event_interruptible(button_waitq, ev_press);
    }
    ev_press = 0;
    err = copy_to_user((void *)buff, (const void *)(&key_values), min(sizeof(key_values),
    count));
    return err ? -EFAULT : min(sizeof(key_values), count);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static unsigned int s3c64xx_buttons_poll( struct file *file, struct poll_table_struct *wait)
{
    unsigned int mask = 0;
    poll_wait(file, &button_waitq, wait);
    if (ev_press)
    mask |= POLLIN | POLLRDNORM;
    return mask;
}

static struct file_operations dev_fops =
{
    .owner = THIS_MODULE,
    .open = s3c64xx_buttons_open,
    .release = s3c64xx_buttons_close,
    .read = s3c64xx_buttons_read,
    .poll = s3c64xx_buttons_poll,
};

static struct miscdevice misc =
{
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

static int __init dev_init(void)
{
    int ret;
    ret = misc_register(&misc);
    printk (DEVICE_NAME"\tinitialized\n");
    return ret;
}

static void __exit dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");
自由,自强,共享,共创。
级别: 论坛版主
UID: 12573
精华: 27
发帖: 8838
金钱: 46490 两
威望: 9298 点
综合积分: 18216 分
注册时间: 2010-01-09
最后登录: 2019-07-16
1楼  发表于: 2010-09-01 23:02
可以参考mini2440的buttons分析,原理是一样的
新手如何向我们反馈有效的信息,以便解决问题,见此贴:
http://www.arm9home.net/read.php?tid-14431.html

[注]: 此处签名链接仅为指引方向,而非解答问题本身.
Stuck with TINY6410
级别: 新手上路
UID: 55912
精华: 0
发帖: 16
金钱: 80 两
威望: 16 点
综合积分: 32 分
注册时间: 2011-09-26
最后登录: 2011-12-17
2楼  发表于: 2011-10-25 13:17
I am surprsied that the problem is so old. I have bought thse boards and still not able to get the support for userkey (buttons.exe) program. That buttons.exe is included in the wince image sample but the source is missing. At least some guidelines as to how to use the userkey driver to write the buttons.exe program will be helpful. I am made to wait for so long without any proper response.