免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2694 | 回复: 8
打印 上一主题 下一主题

新手问一个触摸屏驱动中关于中断的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-22 11:38 |只看该作者 |倒序浏览
最近在弄触摸屏的驱动,但发现一些基本的问题还没有弄明白:
  1.在中断服务程序中,需要直接操作S3C2410_INTMSK等寄存器吗?以前弄按键驱动的时候好像没处理,中断发生正常!为什么?(在裸机的程序中是要往对应位写1的啊!)
2:现在在弄的触摸屏驱动,中断可以注册,cat /proc/interrupt 里也有相关中断信息。但程序进不了中断。
这是为什么? 还有那些地方要设置吗?(看到一些程序中,要开ADC模块的时钟。现在需要吗?)
麻烦高手们,帮我想一想。我实在不知道怎么解决了!  谢谢!

[ 本帖最后由 vincent_zs 于 2009-3-23 21:35 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-03-22 12:41 |只看该作者

呼呼~~~~~~~

  在线等啊~~~~~~~~~~~

论坛徽章:
0
3 [报告]
发表于 2009-03-23 00:05 |只看该作者
半年没摸ARM了 = =

忘记得差不多了 Orz  不好意思~

论坛徽章:
0
4 [报告]
发表于 2009-03-23 14:02 |只看该作者
有一个UPDOWN 的位,你设置为抬起的话也不会进入中断,

论坛徽章:
5
5 [报告]
发表于 2009-03-23 14:28 |只看该作者
原帖由 star316 于 2009/3/23 14:02 发表
有一个UPDOWN 的位,你设置为抬起的话也不会进入中断,


边缘触发中断?

论坛徽章:
0
6 [报告]
发表于 2009-03-23 21:31 |只看该作者

呼呼~~~~~~~

具体是先检测down的中断 ,然后进入中断,再开始AD转换
转换完成。就可以读值了。也可以在AD转换完成后,再检测个up的中断
当做是松手检测。
今晚又抽空,调了一下程序,现在的情况是:还没有注册中断,中断就发生了!
另外可能寄存器的设置还有点问题。
在有的程序中,是用input子系统写的这个驱动程序的,但我还是想用简单的纯字符设备驱动的思路来写这个程序。 有做过这个的朋友,帮帮小弟好吗?
最近比较忙,只能慢慢的抽时间琢磨这个了 .......呼呼~~~~~

[ 本帖最后由 vincent_zs 于 2009-3-23 21:34 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2009-03-24 00:01 |只看该作者
注册中断之前应该关闭中断吧

论坛徽章:
0
8 [报告]
发表于 2009-03-24 09:11 |只看该作者
我以前写了个,已经测试过了,可以用

/*
* main.c -- the bare test char module
*
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
* Copyright (C) 2001 O'Reilly & Associates
*
* The source code in this file can be freely used, adapted,
* and redistributed in source or binary form, so long as an
* acknowledgment appears in derived source files.  The citation
* should list that the code comes from the book "Linux Device
* Drivers" by Alessandro Rubini and Jonathan Corbet, published
* by O'Reilly & Associates.   No warranty is attached;
* we cannot take responsibility for errors or fitness for use.
*
*/

//#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/interrupt.h>   // tasklet
#include <linux/kernel.h>        /* printk() */
#include <linux/slab.h>                /* kmalloc() */
#include <linux/fs.h>                /* everything... */
#include <linux/errno.h>        /* error codes */
#include <linux/types.h>        /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h>        /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/poll.h>
//#include <linux/sp__raw_readlock.h>
#include <linux/delay.h>


#include <linux/sched.h>        // wait_event_interruptible, wake_up_interruptible

#include <asm/semaphore.h>
#include <asm/system.h>                /* cli(), *_flags */
#include <asm/uaccess.h>        /* copy_*_user */
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/uncompress.h>
#include <asm/arch/regs-adc.h>
#include <asm/arch/regs-gpio.h>



int test_major =   220;
int test_minor =   0;
int test_nr_devs = 1;        /* number of bare test devices */



static struct cdev *test_devices;
static struct semaphore sem;         
static wait_queue_head_t mywait;


module_param(test_major, int, S_IRUGO);
module_param(test_minor, int, S_IRUGO);
module_param(test_nr_devs, int, S_IRUGO);


MODULE_AUTHOR("Alessandro Rubini, Jonathan Corbet";
MODULE_LICENSE("Dual BSD/GPL";



void __iomem * base_addr;       

#define WAIT4INT(x)  (((x)<< | S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_XY_PST(3))

#define AUTOPST         (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))

#define AD_COUNT 5

unsigned int Gabs[AD_COUNT];
unsigned long xp;
unsigned long yp;

void Startad(void)
{
   writel((S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST), base_addr+S3C2410_ADCTSC);
   writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
   printk("<1> start ad conveting\n";
        }

irqreturn_t stylus_updown(int irq,void * dev_id,struct pt_regs * regs)
{
        int temp_updown;
        temp_updown=__raw_readl(base_addr+S3C2410_ADCDAT0)&(1<<15);
        if (temp_updown==0)       // stylus down
                {
                printk("<1>the stylus is down,state=%d\n",temp_updown);
                Startad();
                        }
        else
                {               
                printk("<1>the stylus is up,state=%d\n",temp_updown);
                writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
                }
        printk("<1> in interrupt\n";
        return IRQ_HANDLED;


}

irqreturn_t ad_action(int irq,void * dev_id,struct pt_regs * regs)
{
    unsigned long data0;
    unsigned long data1;
    static char counter=0;                      // AD计算次数
    data0 = readl(base_addr+S3C2410_ADCDAT0);
    data1 = readl(base_addr+S3C2410_ADCDAT1);
    counter++;
    xp+=(data1&0x3ff);
    yp+=(data0&0x3ff);
    if (counter>AD_COUNT)
            {
         xp=xp/AD_COUNT;
         yp=yp/AD_COUNT;
         
         writel(WAIT4INT(1), base_addr+S3C2410_ADCTSC);
         printk("<1> xp_average=%d,yp_average=%d,counter=%d\n",xp,yp,counter);
         counter=0;
         xp=0;
         yp=0;
         return IRQ_HANDLED;
                }
       
        printk("<1> xp=%d,yp=%d,\n",xp,yp);
        Startad();
        
        return IRQ_HANDLED;


}

int test_open(struct inode *inode, struct file *filp)
{

       
        struct clk *clk;
        clk=clk_get(NULL,"adc";
        if(IS_ERR(clk))  panic("error to get adc clock\n";       
        clk_enable(clk);
        
       

        try_module_get(THIS_MODULE);
       
        printk(KERN_EMERG"device opening\n";
       
       
        s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPIO_OUTPUT);               // LED
       
            s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
            s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
            s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);
            s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
       
        base_addr=ioremap(S3C2410_PA_ADC,0X100);
        if (base_addr == NULL) {
        printk(KERN_ERR "Failed to remap register block\n";
        return -ENOMEM;
    }
            __raw_writel(1<<14|55<<6,base_addr+S3C2410_ADCCON);         // prescale
            __raw_writel(20000,base_addr+S3C2410_ADCDLY);              // adcdly
        writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);          // 设置updown=0,等待触摸笔点击状态
printk(KERN_EMERG"device opening over \n";
                                                             
       
       
        return 0;          /* success */
}

int test_release(struct inode *inode, struct file *filp)
{
        module_put(THIS_MODULE);
         
        iounmap(base_addr);
        printk(KERN_EMERG"device closeing now\n";
       
       
        return 0;
}
/*
* Follow the list
*/


ssize_t test_read(struct file *filp, int __user *buf, size_t count,
                loff_t *f_pos)
{

       
        ssize_t retval = 0;
       
        char b[5]={0};
       
       
        if (down_interruptible(&sem))
                return -ERESTARTSYS;
       
        /*
        if (copy_to_user(buf, &test_value, sizeof(test_value))) {
                retval = -EFAULT;
                printk("<1> read error");
                goto out;
        }
        */
       






       
       
        retval = count;
        printk(KERN_EMERG"device reading\n,b[0]=%d,b[1]=%d\n",b[0],b[1]);
  out:
        up(&sem);
        return retval;
}





struct file_operations test_fops = {
        .owner =    THIS_MODULE,
        .read =     test_read,
        .open =     test_open,
        .release =  test_release,
       
};

/*
* Finally, the module stuff
*/

/*
* The cleanup function is used to handle initialization failures as well.
* Thefore, it must be careful to work correctly even if some of the items
* have not been initialized
*/
void test_cleanup_module(void)
{
       
        dev_t devno = MKDEV(test_major, test_minor);

        if (test_devices) {
                       
                cdev_del(test_devices);
               
        }

        free_irq(IRQ_TC,NULL);
           free_irq(IRQ_ADC,NULL);
        unregister_chrdev_region(devno, 1);

}


/*
* Set up the char_dev structure for this device.
*/
static void test_setup_cdev(struct cdev *dev, int index)           
{
        int err, devno = MKDEV(test_major, test_minor + index);
   
            dev=cdev_alloc();
        cdev_init(dev, &test_fops);                                       
        dev->owner = THIS_MODULE;
        dev->ops = &test_fops;
        err = cdev_add (dev, devno, 1);                               
       
        if (err)
                printk(KERN_NOTICE "Error %d adding test%d", err, index);
}


int test_init_module(void)
{
        int result;
        dev_t dev = 0;


        if (test_major)
                {
                dev = MKDEV  (test_major,test_minor);                                                       
                result = register_chrdev_region(dev, 1, "test");         
                }
                else
                {                                                                                                                                               
                        result = alloc_chrdev_region(&dev, test_minor, 1,       
                                        "test");
                        test_major = MAJOR(dev);                                       
                }
        if (result < 0) {
                printk(KERN_WARNING "test: can't get major %d\n", test_major);
                return result;
        }

                init_MUTEX(&sem);                           
                test_setup_cdev(test_devices, 0);
                init_waitqueue_head(&mywait);

        /* At this point call the init function for any friend device */
           dev = MKDEV(test_major, test_minor);
        printk("<1>hello,i am coming\n");
       
         if (request_irq(IRQ_ADC, ad_action,IRQF_SAMPLE_RANDOM, "s3c2410_action", NULL))
      {
        printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");
        iounmap(base_addr);
        return -EIO;
      }
       if (request_irq(IRQ_TC, stylus_updown,IRQF_SAMPLE_RANDOM, "s3c2410_action", NULL))
      {
        printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");
        iounmap(base_addr);
        return -EIO;
      }
      

        return 0; /* succeed */

  fail:
        test_cleanup_module();
        return result;
}

module_init(test_init_module);
module_exit(test_cleanup_module);

评分

参与人数 1可用积分 +6 收起 理由
yidou + 6

查看全部评分

论坛徽章:
0
9 [报告]
发表于 2009-03-24 13:56 |只看该作者
感谢LS的前辈,这正是我想要的!  
  看了下整个程序,思路和我的差不多。 太感谢了。 拿你的代码我再去琢磨琢磨。
一定要找到出错的原因!也感谢上面所有回帖的朋友们。thanks
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP