天嵌 ARM开发社区

 找回密码
 注册
查看: 1954|回复: 6

关于ADC驱动的问题

[复制链接]
yuziqiang 发表于 2010-5-10 15:10:12 | 显示全部楼层 |阅读模式
我自己做了一个ADC的驱动程序,不知道怎么回事,总是读不到数据,程序如下
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <asm/io.h>

#include <asm/irq.h>
#include <asm/uaccess.h>

#define READ_START        (0<<1)

#define ADC_START        (1)   
#define ADC_READY        (1<<15)

#define PRSCEN                (1<<14)

#define PRSCVL                (24<<6)

#define SEL_MUX                (0<<3)

#define ADCCON                (READ_START|PRSCEN|PRSCVL|SEL_MUX)

#define AUTO_PST        (~(1<<2))

#define DLY                (5000)



#define rADCCON_PA        0x58000000

#define rADCTSC_PA        0x58000004

#define rADCDLY_PA        0x58000008

#define rADCDAT0_PA        0x5800000c

#define rADCDAT1_PA        0x58000010

#define rADCUPDN_PA        0x58000014
#define rADCCON                (*(volatile unsigned long *)ioremap(rADCCON_PA,4))

#define rADCTSC                (*(volatile unsigned long *)ioremap(rADCTSC_PA,4))

#define rADCDLY                (*(volatile unsigned long *)ioremap(rADCDLY_PA,4))

#define rADCDAT0        (*(volatile unsigned long *)ioremap(rADCDAT0_PA,4))

#define rADCDAT1        (*(volatile unsigned long *)ioremap(rADCDAT1_PA,4))

#define rADCUPDN        (*(volatile unsigned long *)ioremap(rADCUPDN_PA,4))

#define irq_adc                80
#define dev_name        "adc"
#define dev_major        202

static DECLARE_WAIT_QUEUE_HEAD(adc_waitq);
static irqreturn_t adc_interrupt(int irq,void *dev_id);
static int adcready=0 ;
unsigned  int adc_dat;

static int open_adc(struct inode *inode,struct file *filp)  {
int err;
  rADCCON = ADCCON;
  rADCTSC &=AUTO_PST;
  rADCDLY =DLY;
err= request_irq(irq_adc , adc_interrupt ,IRQF_SHARED , "adc",&err);

  if(err!=0) {

     printk("adc_int request fail");

     return err;     }
  printk("adc_initialized ");

return 0;

}
static ssize_t read_adc(struct file *filp, char __user *buff,size_t count,loff_t * offp ){
        int err;
        //int value;
      
        printk("\n NOW IS IN READ_ADC");
        rADCCON |=ADC_START;

        while(rADCCON & ADC_START);

        printk("\n adc is on ");
        //while(rADCCON & ADC_READY);
        //printk("\n adc is finished ");
        //value = rADCDAT0;
        //value        &= 0x3ff;
        //adc_dat=value;
      
        if(adcready==0)
        {
        printk("\n adc is going to sleep");
        wait_event_interruptible(adc_waitq, adcready);
        }

        printk("adc value is(this message is from kernel) :%4d",adc_dat);
        err = copy_to_user(buff, (const void *)&adc_dat, sizeof(adc_dat));
        if(err!=sizeof(adc_dat))
                return -1;
         //memset((void *)adc_dat, 0, sizeof(adc_dat));
        return 0;
}

static int close(struct inode *inode,struct file *filp) {
  free_irq (irq_adc,NULL);
  return 0;
}

static irqreturn_t adc_interrupt(int irq, void *dev_id )
{

unsigned  int value;
  value = rADCDAT0;
  value &= 0x3ff;
  printk("\nadc ready :%u",value);

  adc_dat=value;

  adcready=1;
  wake_up_interruptible(&adc_waitq);
return 0;
}

static struct file_operations adc_ops={
        owner        : THIS_MODULE,
        open          : open_adc,
        read        : read_adc,
        release        : close
};

static int __init adc_int(void)
{
int err;
err=register_chrdev(dev_major,dev_name,& adc_ops);
if(err)
{
   printk("\ncan't register adc device");
  return err;
}
printk("\n adc device register success");
return 0;
}

static void __exit adc_exit(void )
{
unregister_chrdev(dev_major,dev_name);
}
module_init(adc_int);
module_exit(adc_exit);
MODULE_AUTHOR("yuziqiang");            
MODULE_DESCRIPTION("S3C2410/S3C2440 ADC Driver");   
MODULE_LICENSE("GPL");  
问题是按照上面的代码来的话中断不会发生,我把中断相关代码注销掉的话,在read里面改用查询的话每一回读到的数据都是0,
按理来说应该有一个数据值才对,因为我用关盘里面测试程序试过,是有值的,
我的内核版本为2.6.32.9
谢谢指教

当我去掉中断的部分,在read中采用查询的时候,运行测试程序后,等待1分钟左右,出现上面的错误代码
当我采用中断的话中断就不会发生,也不会有结果,
 楼主| yuziqiang 发表于 2010-5-10 15:12:06 | 显示全部楼层
自己顶一下,希望能得到高手的帮助,谢谢了
亚瑟王 发表于 2010-5-10 16:32:54 | 显示全部楼层
建议你看一下天嵌科技提供的ADC驱动。2.6.30.4的,他能用于2.6.32.9。
 楼主| yuziqiang 发表于 2010-5-10 16:59:54 | 显示全部楼层
3# 亚瑟王

谢谢版主提醒,但是我在光盘中没有找到,不知道社区上有没有下载的啊?
亚瑟王 发表于 2010-5-10 21:04:20 | 显示全部楼层
论坛有下载的,在内核的drivers/char/目录下,EmbedSky_adc.c
07xli10 发表于 2010-5-11 20:02:00 | 显示全部楼层
提下建议:在read函数里好像并没有查询ADCCON的最高位,也就是AD转换状态标志位,而且在逻辑上应该在中断函数里是先查询知否转换结束而不是一进入中断就读取数据,还有要定义AD通道。我做过一个AD转换的,其实简单点以为是可以实现的。
upc_zongchao 发表于 2010-6-15 01:22:07 | 显示全部楼层
求救管理员,ad驱动程序还是有些地方不大理解,为了更好的掌握,能不能把ad驱动程序的应用测试程序发给我?  非常感谢  zongchao2008@126.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2024-9-20 02:55 , Processed in 1.019570 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表