打印
[技术问答]

N32916按键中断

[复制链接]
1685|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
itechome|  楼主 | 2015-8-5 15:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
pi, gp, IO, GPIO
各位大神好,最近在N32916上写了个简单的按键驱动,GPG14引脚为nIQR1,但是中断触发后就一直在中断函数内运行,一直唤不醒读程序。请各位指点
static int open_cnt = 0;
static int major;
#define bs83xx_irq W55FA95_IRQ(3)
#define HELLO_CNT 1

static struct cdev bs83xx_cdev;  /* use 1 cdev for all pins */

static struct class *cls;
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
static int ev_press = 0;
static unsigned char key_val;
#define GPIO_GROUP_G 5
//#define GPIO_GROUP_H 6

/* GPIO register offset definition */
//static int __iomem * gpio_reg_dir[7] = { REG_GPIOA_OMD, REG_GPIOB_OMD, REG_GPIOC_OMD, REG_GPIOD_OMD, REG_GPIOE_OMD, REG_GPIOG_OMD, REG_GPIOH_OMD};

//static int __iomem * gpio_reg_out[7] = { REG_GPIOA_DOUT, REG_GPIOB_DOUT, REG_GPIOC_DOUT, REG_GPIOD_DOUT, REG_GPIOE_DOUT, REG_GPIOG_DOUT, REG_GPIOH_DOUT};

static int __iomem * gpio_reg_in[7] = { REG_GPIOA_PIN, REG_GPIOB_PIN, REG_GPIOC_PIN, REG_GPIOD_PIN, REG_GPIOE_PIN, REG_GPIOG_PIN, REG_GPIOH_PIN};
static inline int w55fa95_gpio_get(int group, int num)
{
        return readl(gpio_reg_in[group]) & (1 << num) ? 1:0;
}
static irqreturn_t w55fa95_bs8xx_irq(int irq, void *dev_id)//一直执行这个程序
{
   printk("w55fa95_bs8xx_irq\n");
   int pinval;
   pinval = w55fa95_gpio_get(GPIO_GROUP_G,14);
   printk("pinval = %d\n",pinval);
   if(pinval)
         {
         key_val = 0x01;
         }
   else
         {
         key_val =0x11;
         }
  ev_press = 1;
  wake_up_interruptible(&button_waitq);
  ev_press = 1;
//  enable_irq(bs83xx_irq);
//  writel(readl(REG_IRQTGSRC2) & 0x4000000, REG_IRQTGSRC2); // clear source
  return IRQ_HANDLED;  

}
static ssize_t  bs83xx_read(struct file *file,char __user *buf, size_t count, loff_t *ppos)
{
//  if (count != 1)

//   return -EINVAL;

  printk("read bs83xx_read\n");
  printk(" ev_press = %d\n",ev_press);
  wait_event_interruptible(button_waitq, ev_press);
  printk(" ev_press = %d\n",ev_press);//
   ev_press = 0;
  copy_to_user(buf, &key_val, 1);

//  enable_irq(bs83xx_irq);

  return 1;

}
static int bs83xx_open(struct inode *inode, struct file *file){
          printk("bs83xx_open\n");
        if (open_cnt > 0) {
                goto exit;
        }
        //disable_irq(bs83xx_irq);
        //disable_irq_nosync(bs83xx_irq);
//        w55fa95_gpio_configure(GPIO_GROUP_A, 1);                // GPA1 as ScanGPIO Input
//        w55fa95_gpio_set_input(GPIO_GROUP_A, 1);
//        writel(readl(REG_GPIOA_PUEN) | (BIT1), REG_GPIOA_PUEN);         // port GPA1 pull-up
//        writel(readl(REG_IRQSRCGPA) & ~((0x3 << 2)), REG_IRQSRCGPA); // GPA[1] as nIRQ0 source
//        writel((readl(REG_IRQENGPA)& ~(0x1 << 17)) | (0x1 << 1), REG_IRQENGPA); // falling edge trigger
        //writel((readl(REG_AIC_SCR1)& ~(0x00C70000)) | 0x00470000, REG_AIC_SCR1);
//        writel((1 << TS_IRQ_NUM),  REG_AIC_SCCR); // force clear previous interrupt, if any.
  

       
        writel(readl(REG_GPGFUN) & ~(MF_GPG14), REG_GPGFUN);
        writel (readl(REG_SHRPIN_TOUCH) &~ TP_AEN, REG_SHRPIN_TOUCH);
        writel (readl(REG_GPGFUN) &~ (0x3 << (14<<1)), REG_GPGFUN);//set share pin funcion
        writel (readl(REG_GPIOG_OMD) | (1 << 14), REG_GPIOG_OMD);
       
        writel(readl(REG_GPIOG_OMD) & ~(1 << 14), REG_GPIOG_OMD); // input        
      writel(readl(REG_GPIOG_PUEN) & ~(1 << 14), REG_GPIOG_PUEN); // pull-up   
        writel(readl(REG_IRQSRCGPG) & ~(0x20000000), REG_IRQSRCGPG); // GPG14 as nIRQ1 source
        writel((readl(REG_IRQENGPG)& ~(0x40000000)) | 0x00004000, REG_IRQENGPG); //enable falling edge triggers
        writel((readl(REG_IRQLHSEL)& ~(0x2)) | 0x2, REG_IRQLHSEL);
//         writel((readl(REG_AIC_SCR1)& ~(0xC7000000)) | 0x47000000, REG_AIC_SCR1);
         writel(readl(REG_DBNCECON) |0x71, REG_DBNCECON);
        writel((1 << bs83xx_irq),  REG_AIC_SCCR); // force clear previous interrupt, if any.
        writel(readl(REG_IRQTGSRC2) & 0x4000000, REG_IRQTGSRC2); // clear source
        if (request_irq(bs83xx_irq, w55fa95_bs8xx_irq,IRQF_DISABLED|IRQF_TRIGGER_FALLING, "bs8xx_key",NULL) != 0) {

            printk("register the bs8xx_irq failed!\n");

            return -1;

    }
        disable_irq_nosync(bs83xx_irq);
//        Enable_IRQ(bs83xx_irq);
        enable_irq(bs83xx_irq);
//enable falling edge triggers

//        writel((readl(REG_IRQENGPG)& ~(0x40000000)) | 0x00004000, REG_IRQENGPG);

      //enable_irq(bs83xx_irq);
exit:
        open_cnt++;
        return 0;
}
void bs83xx_close(struct inode *inode, struct file *file) {

        open_cnt--;
        if (open_cnt == 0) {
        //disable falling edge triggers

        writel((readl(REG_IRQENGPG)& ~(0x40004000)), REG_IRQENGPG);

       free_irq(bs83xx_irq,NULL);

        }
        return;
}
static unsigned int bs83xx_poll(struct file *file, poll_table *wait)
{
        unsigned int mask = 0;
       poll_wait(file, &button_waitq, wait);
        if(ev_press)
        {
        mask |= POLLIN | POLLRDNORM;
        }
        return mask;
}

static struct file_operations bs83xx_fops = {

  .owner =THIS_MODULE,

  .open = bs83xx_open,

  .read = bs83xx_read,

  .release = bs83xx_close,

  .poll = bs83xx_poll,

};
static int bs83xx_init(void)
{
  dev_t devid;       

  if (major) {
                devid = MKDEV(major, 0);

               register_chrdev_region(devid, HELLO_CNT, "bs83xx");//(major,0-1)

        } else
        {
                alloc_chrdev_region(&devid, 0, HELLO_CNT, "bs83xx");
                major = MAJOR(devid);
        }

  cdev_init(&bs83xx_cdev, &bs83xx_fops);

  cdev_add(&bs83xx_cdev, devid, HELLO_CNT);

  cls = class_create(THIS_MODULE,"bs83xx");

  device_create(cls,NULL,MKDEV(major,0),NULL,"bs83xx");

//  device_create(cls,NULL,MKDEV(major,1),NULL,"hello1");
  return 0;
}

static void bs83xx_exit(void)
{
  device_destroy(cls,MKDEV(major,0));

  class_destroy(cls);

  unregister_chrdev_region(MKDEV(major, 0), HELLO_CNT);

  cdev_del(&bs83xx_cdev);  
}
module_init(bs83xx_init);
module_exit(bs83xx_exit);  
MODULE_LICENSE("GPL");   
沙发
进击的ic| | 2015-8-5 15:54 | 只看该作者
你清中断标记位没有?

使用特权

评论回复
板凳
itechome|  楼主 | 2015-8-5 16:09 | 只看该作者
writel(readl(REG_IRQTGSRC2) & 0x4000000, REG_IRQTGSRC2); // clear source
<IMG src="file:///C:\Documents and Settings\wanglinxin\feiq\RichOle\1098126653.bmp">

使用特权

评论回复
地板
itechome|  楼主 | 2015-8-5 16:13 | 只看该作者
D:\截图.nmp
按说是清了,我强制初始化ev_press=1,会一直执行读函数,但是一有按键触发中断,就唤不醒读函授了

使用特权

评论回复
5
itechome|  楼主 | 2015-8-5 17:17 | 只看该作者
多谢  进击的ic 提醒,确实在中断里面忘记清理了。谢谢

使用特权

评论回复
6
芙蓉洞| | 2015-8-5 20:42 | 只看该作者
原来楼主忘记了在中断里面清除中断标志位了

使用特权

评论回复
7
仙女山| | 2015-8-6 09:01 | 只看该作者
感觉是进入中断后没有关闭中断造成的

使用特权

评论回复
8
xinba0625| | 2015-8-8 14:52 | 只看该作者
点击链接加入群【Nuvoton   N329xx】:http://jq.qq.com/?_wv=1027&k=XHTbB0

使用特权

评论回复
9
598330983| | 2015-8-9 18:03 | 只看该作者
w55fa95_gpio_configure(GPIO_GROUP_A, 1);                // GPA1 as ScanGPIO Input
这个GPIO_config 是什么作用啊

使用特权

评论回复
10
mintspring| | 2015-8-9 18:19 | 只看该作者
为何ARM一个按键都代码这么复杂呢。

使用特权

评论回复
11
捉虫天师| | 2015-8-10 09:02 | 只看该作者
一个按键中断写的这么复杂抽象。

使用特权

评论回复
12
李香兰| | 2015-8-10 16:46 | 只看该作者
进中断要关中断,出中断前要开中断

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

4

帖子

0

粉丝