主题 : 请教一下AD驱动的问题 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 2177
精华: 0
发帖: 70
金钱: 620 两
威望: 463 点
综合积分: 140 分
注册时间: 2008-10-30
最后登录: 2015-01-12
楼主  发表于: 2009-03-27 10:37

 请教一下AD驱动的问题

AD驱动读函数:
/* ADC驱动的读函数 */  
static ssize_t s3c2440adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)  
{  
    unsigned long result = 0;  
    unsigned int data;
    if (down_interruptible(&s3c2440adc_dev.lock))   /* 进入临界区 */
        return -ERESTARTSYS;  

    /* 启动AD转换 */
    iowrite32(START_ADC(s3c2440adc_dev.channel, s3c2440adc_dev.prescale), base_addr + S3C2410_ADCCON);    
  
    do  {
        result = ioread32(base_addr + S3C2410_ADCCON);  /* 读取控制寄存器 */  
    }while((unsigned int)result & 0x01);                /* 确认AD转换开始 */
    
    do  {
        result = ioread32(base_addr + S3C2410_ADCCON);  /* 读取控制寄存器 */  
    }while(!(((unsigned int)result) & 0x8000));         /* 直到AD转换完成 */

    data = ioread32(base_addr + S3C2410_ADCDAT0) & 0x3ff;   /* 保留转换数据寄存器的低10位 */  
    DPRINTK("AIN[%d] = %d mv\n", s3c2440adc_dev.channel, data*3300/1024;
  
    copy_to_user(buffer, &data, sizeof(data));      /* 复制到用户空间 */  
  
    up(&s3c2440adc_dev.lock);   /* 退出临界区 */  
  
    return sizeof(result);  
}  

其中#define START_ADC(ch, prescale) S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(prescale) \
                                | S3C2410_ADCCON_SELMUX(ch) | S3C2410_ADCCON_ENABLE_START

channel初始化为0;prescale为255;调节滑动电阻,打印出来的电压值一直在1000mv与1200mv之间,读取的电压值应该有误,不知道程序哪里出错了。
-
级别: 侠客
UID: 2177
精华: 0
发帖: 70
金钱: 620 两
威望: 463 点
综合积分: 140 分
注册时间: 2008-10-30
最后登录: 2015-01-12
1楼  发表于: 2009-03-27 19:10
问题解决了,原来我移植的内核带触摸屏驱动,触摸屏不停在响应,写ADCDAT0,得到的是触摸屏转换的值。但源代码已经加了信号量进行互斥访问,为什么还得不到AD的转换值呢?后来我改用自旋锁,电压值就正常了。不过还是不明白自旋锁能够实现而信号量不行呢?不明白
-
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
2楼  发表于: 2009-03-27 21:00
spin_lock本身在非SMP系统上其实是什么都不做的, 要排除触摸屏的干扰, 你需要的是在AD转换前关中断, 转换后恢复中断。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2009-03-27 21:05
另外, 信号量只能用于两个进程的互斥, 不能用于中断处理函数这种不能阻塞的情况。 如果触摸屏的驱动中,AD转换是在触摸屏中断处理函数中发起的, 你不可能用信号量作互斥。
关于信号量和spin lock的用法, 参考Linux Device Driver 3rd edition, 里面有很详细的介绍。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 侠客
UID: 2177
精华: 0
发帖: 70
金钱: 620 两
威望: 463 点
综合积分: 140 分
注册时间: 2008-10-30
最后登录: 2015-01-12
4楼  发表于: 2009-03-28 09:53
谢谢版主,原来如此啊!
-
USR组织-奉献、分享、合作、自律
级别: 新手上路
UID: 4067
精华: 0
发帖: 17
金钱: 180 两
威望: 180 点
综合积分: 34 分
注册时间: 2009-02-23
最后登录: 2009-04-30
5楼  发表于: 2009-03-28 18:44
在下做触屏驱动,但是adc中断不好用,进不到stylus_action函数里面去。楼主知道是什么原因吗?
级别: 新手上路
UID: 23464
精华: 0
发帖: 9
金钱: 45 两
威望: 9 点
综合积分: 18 分
注册时间: 2010-06-20
最后登录: 2013-07-27
6楼  发表于: 2010-07-14 14:30
楼主还在不?,能把AD的驱动程序和应用程序能给我分享一下吗,我的邮箱是xyxst5@126.com