DM6446之GPIO中断


[html]
  view plain copy
  1. /* drivers/char/davinci_dm644x_button.c*/  
  2.   
  3.   
  4. /*******************************************************************************  
  5.  * HEADER FILES  
  6.  */  
  7. #include <linux/device.h>  
  8. #include <linux/module.h>  
  9. #include <linux/moduleparam.h>  
  10. #include <linux/init.h>  
  11. #include <linux/sched.h>  
  12. #include <linux/kernel.h>  
  13. #include <linux/fs.h>  
  14. #include <linux/err.h>  
  15. #include <linux/kdev_t.h>  
  16. #include <linux/slab.h>  
  17. #include <linux/mm.h>  
  18. #include <linux/io.h>  
  19. #include <linux/platform_device.h>  
  20. #include <linux/types.h>  
  21. #include <linux/cdev.h>  
  22. #include <asm/arch/hardware.h>  
  23. #include <asm/arch/clock.h>  
  24. #include <asm/arch/psc.h>  
  25. #include <linux/delay.h>  
  26. #include <asm/arch/gpio.h>  
  27. #include <asm/delay.h>  
  28. #include <linux/errno.h>  
  29. #include <asm/arch/gpio.h>  
  30. #include <linux/interrupt.h>  
  31. #include <linux/irq.h>                     //define for irq number  
  32. #include <asm-arm/arch-davinci/irqs.h>  
  33. #include <asm-arm/arch-davinci/clock.h>  
  34. #include <asm/arch-davinci/gpio.h>  
  35. //#include <linux/interrupt.h>   
  36. #include <asm/uaccess.h>  
  37. #include <asm/io.h>  
  38.   
  39.   
  40. /*******************************************************************************  
  41.  * LOCAL DEFINES  
  42.  */  
  43. #define DEVICE_NAME "buttontest"   /*定义设备驱动的名字,或设备节点名称*/  
  44. #define BUTTON_MAJOR 200 /*使用 cat /proc/devices查看不要和存在的char节点重复*/   
  45.   
  46.   
  47. /*my app gpio define*/  
  48. #define DM644X_GPIO_BUTTON         3    /*GPIO3*/  
  49. //#define DM644X_GPIO_INIT IRQ_GPIO3  
  50. #define DM644X_GPIO_INIT 51  
  51.   
  52. /* 中断事件标志, 中断服务程序将它置1,buttons_read将它清0 */  
  53. static int value=1;  //按键的电平值,按下为0  
  54.   
  55.   
  56. /*******************************************************************************  
  57.  * FUNCTION DEFINITIONS  
  58.  */  
  59. /***************************************************************************  
  60.  * Function             - gpio_demux_pins  
  61.  * Functionality        - interrupt register set  
  62.  * Input Params - None  
  63.  * Return Value - None  
  64.  * Note                 - None  
  65.  ****************************************************************************/  
  66. void gpio_demux_pins(void)  
  67. {  
  68. /* PINMUX address in dm6446 */  
  69. unsigned long pmux0;  
  70.   
  71. int addr = IO_ADDRESS(0x01c40000);  
  72. pmux0 = inl(addr)&0xfd7fffff;  
  73. outl(pmux0,addr);  
  74. printk("The PINMUX0 value is %x\n!",inl(addr));  
  75.   
  76. /*ARM INTERRUPT CONTROLLER REGISTER*/  
  77.   
  78. int io_add = IO_ADDRESS(0x01c48000);  
  79.   
  80. int irq = inl(io_add + 0x0c)|0x00800000;  
  81. outl(irq,io_add + 0x0c);  
  82. printk("irq value is %x\n",inl(io_add + 0x0c));  
  83.   
  84. int eint = inl(io_add + 0x1c)|0x80000;  
  85. outl(eint,io_add + 0x1c);  
  86. printk("eint value is %x\n",inl(io_add + 0x1c));  
  87.   
  88. /* GPIO3 interrupt controller register*/  
  89. int io_addr = IO_ADDRESS(0x01c67000);  
  90.   
  91. /*set GPIO3 interrupt enable*/  
  92. int binen = inl(io_addr + 0x08)|0x01;  
  93. outl(binen,io_addr+0x08);  
  94. printk("binen value is %x\n",inl(io_addr + 0x08));  
  95.   
  96. /*set GPIO3 direction*/  
  97. int dir = inl(addr + 0x10)|0x08;  
  98. outl(dir,addr+0x10);  
  99. printk("dir value is %x\n",inl(addr + 0x10));  
  100.   
  101. /*set GPIO3 raising disable*/  
  102. int ris_clr = inl(io_addr + 0x28)|0x08;  
  103. outl(ris_clr,io_addr+0x28);  
  104. printk("ris_clr value is %x\n",inl(io_addr + 0x28));  
  105.   
  106. /*set GPIO3 raising set*/  
  107. int ris = inl(io_addr + 0x24)|0x08;  
  108. outl(ris,io_addr+0x24);  
  109. printk("ris value is %x\n",inl(io_addr + 0x24));  
  110.   
  111. /*the GPIO3 status*/  
  112. printk("insta value is %x\n",inl(io_addr + 0x34));  
  113. }  
  114.    
  115.    
  116. static irqreturn_t buttons_interrupt(int irq, void *dev_id,struct pt_regs *regs)  
  117. {  
  118.     value = gpio_get_value(DM644X_GPIO_BUTTON);  
  119. printk(KERN_INFO "key is pressed!\n");    
  120.   
  121. printk("test, value = %d\n", value);  
  122.     return IRQ_HANDLED;  
  123. }  
  124. static int buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)  
  125. {  
  126. value = gpio_get_value(DM644X_GPIO_BUTTON);  
  127. printk("In kernel key_read()!\n");   //打印调试信息  
  128.         
  129.        /* 将按键状态复制给用户 */   
  130.      
  131.  copy_to_user(buff, (void *)&value, sizeof(value));  
  132. // ev_press = 0;  
  133.        printk("this is at kernel, value = %d\n", value);         
  134.        return  0;  
  135. }  
  136.   
  137.   
  138.   
  139.   
  140. static int buttons_open(struct inode *inode, struct file *file)  
  141. {  
  142.          
  143. int result;              
  144.     int value;   
  145.     
  146. gpio_direction_input(DM644X_GPIO_BUTTON);  
  147.     set_irq_type(DM644X_GPIO_INIT, IRQ_TYPE_EDGE_RISING);     //RISING   or  Edge Falling type  
  148. disable_irq(DM644X_GPIO_INIT);  
  149. enable_irq(DM644X_GPIO_INIT);  
  150. result = request_irq(DM644X_GPIO_INIT,buttons_interrupt,IRQ_DISABLED,"buttontest","key");  
  151.     if (result < 0)  
  152.     {  
  153.         printk(KERN_INFO "Cannot initialize IRQ \n");  
  154.         return result;  
  155.     }  
  156.     printk(KERN_INFO "initialize IRQ successful, result = %d\n", result);  
  157.     value = gpio_get_value(DM644X_GPIO_BUTTON);     
  158.     disable_irq(DM644X_GPIO_INIT);  
  159. enable_irq(DM644X_GPIO_INIT);    
  160.     printk(KERN_INFO "value = %d\n", value);   
  161.     return 0;  
  162. }  
  163.   
  164.   
  165.    
  166.   
  167.   
  168. static int buttons_close(struct inode *inode,struct file *filp)  
  169. {  
  170.     free_irq(DM644X_GPIO_INIT, "key");  
  171. disable_irq(DM644X_GPIO_INIT);  
  172. gpio_free(DM644X_GPIO_BUTTON);  
  173.     return 0;  
  174. }   
  175.   
  176.   
  177. /*定义驱动设备文件API,在linux系统当中,任何设备都可以当做文件的方式操作,这一点和单片机和MCU有很大差别*/  
  178.   
  179.   
  180. static const struct file_operations davinci_dm644x_gpio_fileops = {  
  181.     .owner   = THIS_MODULE,  
  182.     .open    = buttons_open,  
  183.     .release = buttons_close,  
  184.     .read    = buttons_read,   
  185.        //.ioctl   = buttons_ioctl,    
  186. };   
  187.   
  188.   
  189. static int __init davinci_dm644x_button_open(void) /*内核初始化会调用该函数*/  
  190. {  
  191.     int ret;    
  192. int test;  
  193.   
  194. gpio_demux_pins();  
  195.   
  196. gpio_direction_input(DM644X_GPIO_BUTTON);  
  197.   
  198. if(gpio_is_valid(DM644X_GPIO_BUTTON) < 0)  
  199. {  
  200. printk("gpio is invalid\n");  
  201. return -EINVAL;  
  202. }  
  203. printk("gpio is valid\n");  
  204.     test = gpio_request(DM644X_GPIO_BUTTON, "buttons_interrupt");  
  205. if(test < 0 )  
  206. {  
  207. printk("failed to request gpio\n");  
  208. return -EINVAL;  
  209. }  
  210. printk("request gpio ok!\n");  
  211.          
  212.     ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &davinci_dm644x_gpio_fileops);  
  213.     if(ret < 0)  
  214.     {  
  215.         printk(KERN_INFO "dm644x_button register falid!\n");  
  216.         return ret;  
  217.     }  
  218.     printk(KERN_INFO "dm644x_button initialized\n");  
  219.     return ret;  
  220. }  
  221.   
  222. static void __exit davinci_dm644x_button_exit(void)  
  223. {  
  224.     unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);  
  225. printk(KERN_INFO "dm644x_button:exit\n");  
  226. }  
  227.   
  228. module_init(davinci_dm644x_button_open);  
  229. module_exit(davinci_dm644x_button_exit);   
  230.   
  231.   
  232. MODULE_AUTHOR("azhgul");  
  233. MODULE_LICENSE("Dual BSD/GPL");  

这里选用GPIO3作为中断源,包括设置相应中断控制寄存器,bank0中断使能, RISING     or    Edge Falling type,已经GPIO管脚复用等问题。
DM6446之GPIO中断_第1张图片

应用程序如下所示。

[html]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <sys/ioctl.h>  
  5. #include <sys/types.h>  
  6. #include <sys/stat.h>  
  7. #include <fcntl.h>   
  8. #include <sys/select.h>  
  9. #include <sys/time.h>   
  10. #include <errno.h> /  
  11.   
  12. int main(void)  
  13. {  
  14.     int fd,key_value,ret;  
  15.     fd=open("/dev/key",0);   
  16.     if(fd<0){  
  17.         perror("open /dev/key error!\n");  
  18.         exit(1);  
  19.     }  
  20.     printf("open /dev/key sucessfully!\n");  
  21.     while(1){  
  22.         ret=read(fd,&key_value,sizeof(key_value));   
  23.         printf("In main(),key_value is '%d'\n\n",key_value);  
  24.     }  
  25.    close(fd);  
  26.     return 0;  
  27. }  

你可能感兴趣的:(DM6446之GPIO中断)