TI中文支持网
TI专业的中文技术问题搜集分享网站

DM6446 GPIO中断

我申请中断,打印的信息显示申请成功,也能看到DM644X_GPIO_BUTTON的变化

但是却在 cat /proc/interrupt中看不到响应的中断号

也无法进入中断例程;请各位指教下~~~

程序如下,打印信息如图所示。

 

/* drivers/char/davinci_dm644x_button.c*/

#include <linux/device.h>

#include <linux/module.h>

#include <linux/moduleparam.h>

#include <linux/init.h>

#include <linux/sched.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/err.h>

#include <linux/kdev_t.h>

#include <linux/slab.h>

#include <linux/mm.h>

#include <linux/io.h>

#include <linux/platform_device.h>

#include <linux/types.h>

#include <linux/cdev.h>

#include <asm/arch/hardware.h>

#include <asm/arch/clock.h>

#include <asm/arch/clock.h>

#include <asm/arch/psc.h>

#include <linux/delay.h>

#include <asm/arch/gpio.h>

#include <asm/delay.h>

#include <linux/errno.h>

#include <asm/arch/gpio.h>

#include <linux/interrupt.h>

#include <linux/irq.h>                     //define for irq number

#include <asm-arm/arch-davinci/irqs.h>

#include <asm-arm/arch-davinci/clock.h>

#include <asm/arch-davinci/gpio.h>

//#include <linux/interrupt.h>

#include <asm/uaccess.h>

#include <asm/io.h>

#define DM6446_GPIO_BASE 0x01C67000

//#define BINTEN (DM6446_GPIO_BASE + 0x8) //GPIO Interrupt Per Bank Enable

#define GPIO_REG(reg) (*(int *__iomem) IO_ADDRESS(reg))

#define IRQ1 0x01C4800C // Interrupt Request Status Register

#define EINT1 0x01C4801C // Interrupt Enable Register

#define INTPRI6 0x01C48048 // Interrupt Proirty

#define EABASE 0x01C48024 // Interrupt Entry Table Base Address

#define IRQENTRY 0x01C48047 // Entry Address for Valid IRQ

#define DEVICE_NAME "buttontest"   /*定义设备驱动的名字,或设备节点名称*/

#define BUTTON_MAJOR 200 /*使用 cat /proc/devices查看不要和存在的char节点重复*/

/*my app gpio define*/

#define DM644X_GPIO_BUTTON         3    /*GPIO3*/

//#define DM644X_GPIO_INIT IRQ_GPIO3

#define DM644X_GPIO_INIT 51

/* 等待队列:

* 当没有按键被按下时,如果有进程调用buttons_read函数,

* 它将休眠

*/

//static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/* 中断事件标志, 中断服务程序将它置1,buttons_read将它清0 */

//static  int ev_press = 0;

static int value=1;  //按键的电平值,按下为0

static irqreturn_t buttons_interrupt(int irq, void *dev_id,struct pt_regs *regs)

{

   value = gpio_get_value(DM644X_GPIO_BUTTON);

printk(KERN_INFO "key is pressed!\n");

   //ev_press = 1;

      //wake_up_interruptible(&button_waitq);   /* 唤醒休眠的进程 */

  printk("test, value = %d\n", value);

      return IRQ_HANDLED;

}

static int buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

{

//unsigned long err;

//int value_test;

//wait: wait_event_interruptible(button_waitq, ev_press);

//value_test = value;

//mdelay(15);

value = gpio_get_value(DM644X_GPIO_BUTTON);

//if(value_test != value)

//{

// ev_press = 0;

// goto wait;

//}

printk("In kernel key_read()!\n");   //打印调试信息

      /* 将按键状态复制给用户 */

     //err = copy_to_user(buff, &ev_press, sizeof(ev_press));

 copy_to_user(buff, (void *)&value, sizeof(value));

// ev_press = 0;

      printk("this is at kernel, value = %d\n", value);

//wait_event_interruptible(button_waitq, ev_press);  

//mdelay(15);

      /* 将按键状态复制给用户 */

     //err = copy_to_user(buff, (void *)&ev_press, sizeof(ev_press));

//err = copy_to_user(buff, &value, sizeof(value));

     // printk(KERN_INFO "this is at kernel, ev_press = %d/n", ev_press);

  //ev_press = 0;

      return  0;

}

//static int buttons_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

//{

//      int value = gpio_get_value(DM644X_GPIO_BUTTON);

//      printk(KERN_INFO "this is kernel, value = %d\n", value);      

//

//       return value;      

//}

static int buttons_open(struct inode *inode, struct file *file)

{

int result;

      //int irq_number;    

      int value;

  gpio_direction_input(DM644X_GPIO_BUTTON);

      set_irq_type(DM644X_GPIO_INIT, IRQ_TYPE_EDGE_RISING);     //RISING   or  Edge Falling type

  disable_irq(DM644X_GPIO_INIT);

  enable_irq(DM644X_GPIO_INIT);

  //set_irq_type(irq_number, IRQ_TYPE_EDGE_FALLING);

  //int test;

//printk("open gpio,here is driver\n");

//if(gpio_is_valid(DM644X_GPIO_BUTTON) < 0)

//{

// printk("gpio is invalid\n");

// return -EINVAL;

//}

//printk("gpio is valid\n");

     // test = gpio_request(DM644X_GPIO_BUTTON, "buttons_interrupt");

 // if(test < 0 )

 // {

// printk("failed to request gpio\n");

// return -EINVAL;

  //}

// printk("request gpio ok!\n");

      //irq_number = gpio_to_irq(DM644X_GPIO_BUTTON);

      //printk(KERN_INFO "irq_number = %d\n", irq_number);

     // gpio_direction_input(DM644X_GPIO_BUTTON);

     // set_irq_type(IRQ_GPIO4, IRQF_TRIGGER_HIGH);     //RISING   or  Edge Falling type

  //set_irq_type(irq_number, IRQ_TYPE_EDGE_FALLING);

      //disable_irq(IRQ_GPIO4);

  //enable_irq(IRQ_GPIO4);

  //gpio_direction_input(DM644X_GPIO_BUTTON);

      //result = request_irq((gpio_to_irq(DM644X_GPIO_BUTTON)), buttons_interrupt, 0, "button", "key");

  //result = request_irq((gpio_to_irq(DM644X_GPIO_BUTTON)), buttons_interrupt, SA_INTERRUPT, DEVICE_NAME, NULL);

  //result = request_irq(DM644X_GPIO_INIT,buttons_interrupt,SA_INTERRUPT,DEVICE_NAME,NULL);

  result = request_irq(DM644X_GPIO_INIT,buttons_interrupt,SA_INTERRUPT,"buttontest","key");

      if (result < 0)

      {

             printk(KERN_INFO "Cannot initialize IRQ \n");

             return result;

      }

      printk(KERN_INFO "initialize IRQ successful, result = %d\n", result);

      value = gpio_get_value(DM644X_GPIO_BUTTON);

      disable_irq(DM644X_GPIO_INIT);

  enable_irq(DM644X_GPIO_INIT);

      printk(KERN_INFO "value = %d\n", value);

      return 0;/*该函数可以什么都不做,也可以加入类似初始化的设置*/

}

static int buttons_close(struct inode *inode,struct file *filp)

{

     //free_irq(DM644X_GPIO_INIT, NULL);   //it will emit error if do not add "key"

 free_irq(DM644X_GPIO_INIT, "key");

 disable_irq(DM644X_GPIO_INIT);

 gpio_free(DM644X_GPIO_BUTTON);

      return 0;

}

/*定义驱动设备文件API,在linux系统当中,任何设备都可以当做文件的方式操作,这一点和单片机和MCU有很大差别*/

static const struct file_operations davinci_dm644x_gpio_fileops = {

      .owner   = THIS_MODULE,

      .open    = buttons_open,

      .release = buttons_close,

      .read    = buttons_read,

      //.ioctl   = buttons_ioctl,  

};

static int __init davinci_dm644x_button_open(void) /*内核初始化会调用该函数*/

{

      int ret;  

  int test;

unsigned long pmux0;

unsigned long pmux1;

//board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO,1);

davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);

//davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN,DAVINCI_LPSC_GPIO,1);

pmux0 = davinci_readl(PINMUX0);

printk(KERN_INFO "test pmux0 = %lx\n",pmux0);

pmux1 = davinci_readl(PINMUX1);

printk(KERN_INFO "test pmux1 = %lx\n",pmux1);

pmux0 &= ~(0x00000001 << 25);

//pmux1 &= ~(0x00000007 << 4);

davinci_writel(pmux0, PINMUX0);

pmux0 = davinci_readl(PINMUX0);

printk(KERN_INFO "pmux0 = %ld;hex = %lx\n",pmux0,pmux0);

/*ARM INTERRUPT CONTROLLER REGISTER*/

int io_add = IO_ADDRESS(0x01c48000);

//GPIO_REG(IRQ1)=0x00800000; //GPIO3 INTERRUPT NUMBER = 51 BIT # 17

//GPIO_REG(IRQ1)=0x00800000; //GPIO0 INTERRUPT NUMBER = 48 BIT # 17

//GPIO_REG(EINT1)=0x00800000; //INTERRUPT ENABLE

//GPIO_REG(INTPRI6) = (GPIO_REG(INTPRI6) & 0xFFFFFFFF ) | ( 0x00000003 ); //INTERRUPT PIRIORITY

//ASP_REG(INTCTL);

/*set GPIO3 interrupt enable*/

//int binen = inl(io_addr + 0x08)|0x01;

//outl(binen,io_addr+0x08);

//printk("fiq value is %x\n",inl(io_add + 0x00));

int irq = inl(io_add + 0x0c)|0x00800000;

outl(irq,io_add + 0x0c);

printk("irq value is %x\n",inl(io_add + 0x0c));

int eint = inl(io_add + 0x1c)|0x00800000;

outl(eint,io_add + 0x1c);

printk("eint value is %x\n",inl(io_add + 0x1c));

int intpr6 = inl(io_add + 0x48)|0x00000003;

outl(intpr6,io_add + 0x48);

printk("intpr6 value is %x\n",inl(io_add + 0x48));

/**/

int io_addr = IO_ADDRESS(0x01c67000);

/*set GPIO3 interrupt enable*/

int binen = inl(io_addr + 0x08)|0x01;

outl(binen,io_addr+0x08);

printk("binen value is %x\n",inl(io_addr + 0x08));

/*set GPIO3 in*/

//int dir = inl(io_addr + 0x10)|0x08;

//outl(dir,io_addr+0x10);

//printk("dir value is %x\n",inl(io_addr + 0x10));

/*set GPIO3 rasing*/

int ris = inl(io_addr + 0x24)|0x08;

outl(ris,io_addr+0x24);

printk("ris value is %x\n",inl(io_addr + 0x24));

/*set GPIO3 status*/

//int insta = inl(io_addr + 0x34)|0x08;

//outl(insta,io_addr+0x34);

printk("insta value is %x\n",inl(io_addr + 0x34));

//

//printk("<1>GPIO_SET_INT: %x\n", GPIO_REG(BINTEN));

//

//davinci_writel(pmux1, PINMUX1)  

gpio_direction_input(DM644X_GPIO_BUTTON);

//

if(gpio_is_valid(DM644X_GPIO_BUTTON) < 0)

{

printk("gpio is invalid\n");

return -EINVAL;

}

printk("gpio is valid\n");

      test = gpio_request(DM644X_GPIO_BUTTON, "buttons_interrupt");

  if(test < 0 )

  {

printk("failed to request gpio\n");

return -EINVAL;

  }

printk("request gpio ok!\n");

      //irq_number = gpio_to_irq(DM644X_GPIO_BUTTON);

      //printk(KERN_INFO "irq_number = %d\n", irq_number);        

//

      ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &davinci_dm644x_gpio_fileops);

      if(ret < 0)

      {

             printk(KERN_INFO "dm644x_button register falid!\n");

             return ret;

      }

      printk (KERN_INFO "dm644x_button initialized\n");

      return ret;

}

static void __exit davinci_dm644x_button_exit(void)

{

      unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);

  printk(KERN_INFO "dm644x_button:exit\n");

}

module_init(davinci_dm644x_button_open);

module_exit(davinci_dm644x_button_exit);

MODULE_AUTHOR("azhgul");

MODULE_LICENSE("Dual BSD/GPL");

Feng Dong:

request中断号不对吧,另外保证gpio module的状态是对的

Feng Dong:

另外通常的逻辑应该是request_gpio,并且设置为input,然后才requet irq

fei wang:

回复 Feng Dong:

你好,谢谢你的回复。我已经申请GPIO资源了,代码已经标注,并且设置input,打印信息显示都可以,而且可以读取相应的GPIO管脚的输入状态,比如,按下按键,可以读取状态值为1等,中断号是查相应技术手册,应该也没有问题的。能不能加你联系方式,向您请教,谢谢,我QQ:364620379,

test = gpio_request(DM644X_GPIO_BUTTON, "buttons_interrupt");

if(test < 0 )

{

printk("failed to request gpio\n");

return -EINVAL;

}

printk("request gpio ok!\n");

 

赞(0)
未经允许不得转载:TI中文支持网 » DM6446 GPIO中断
分享到: 更多 (0)