• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
主题 : adc 驱动问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 1790
精华: 0
发帖: 33
金钱: 350 两
威望: 222 点
综合积分: 66 分
注册时间: 2008-09-28
最后登录: 2015-08-07
楼主  发表于: 2009-03-08 12:59

 adc 驱动问题

我的adc驱动加载后,显示成功
major: 253
devno: 265289728
adc init and setup!!!

编写一个小的应用程序后.打开时总是出现这句!
open device adc: No such file or directory

有能知道是什么原因么?
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2009-03-08 14:02
把源代码贴出来
"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: 1790
精华: 0
发帖: 33
金钱: 350 两
威望: 222 点
综合积分: 66 分
注册时间: 2008-09-28
最后登录: 2015-08-07
2楼  发表于: 2009-03-09 10:24
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/wait.h>


#include <linux/device.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch-s3c2410/regs-adc.h>
#include <asm/arch-s3c2410/regs-clock.h>
#include <asm-arm/arch-s3c2410/map.h>

#include <asm/hardware/clock.h>



#define DEVICE_NAME    "adctest"

static void __iomem *base_addr;

static int adc_major = 0  /*主设备号*/

static struct clk    *adc_clock;

struct ADC_DEV
{
    int channel;
    int prescale;
};

static ssize_t adc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
    int data;
    unsigned long tmp;
    //start ADC
    tmp = readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START;
    writel( tmp, base_addr+S3C2410_ADCCON);
    //state
    do
    {
        tmp = readl(base_addr+S3C2410_ADCCON);
    }while(!(((unsigned int)tmp)&0x8000));   // ADCCON [15].是否转换结束
    //read data
    data = readl(base_addr+S3C2410_ADCDAT0) & 0x3ff; // ADCDAT0 0~0x3ff .
    if(copy_to_user(buf, &data, sizeof(int)))   //把data的值复制到用户空间
            return -EFAULT;
    return (sizeof(int));
}

static ssize_t adc_write(struct file * file, const char __user * buf, size_t count, loff_t * off)
{
    unsigned long tmp;
    struct ADC_DEV adcdev;
    
/*自己加的,分频和通道数.*/
    adcdev.prescale=49;
    adcdev.channel=0;
    
    copy_from_user(&adcdev,(struct ADC_DEV *)buf,sizeof(struct ADC_DEV));
    
    //S3C2410_CLKCON
    writel((readl(S3C2410_CLKCON) | S3C2410_CLKCON_ADC),S3C2410_CLKCON);
    
    //S3C2410_ADCTSC
    tmp = readl(base_addr+S3C2410_ADCTSC);
    tmp &= (~S3C2410_ADCTSC_AUTO_PST) | S3C2410_ADCTSC_XY_PST(S3C2410_NOP_MODE); /*ADCTSC [2]设为0为普通模式*/
    writel(tmp , base_addr+S3C2410_ADCTSC);
    //S3C2410_ADCCON
    tmp = readl(base_addr+S3C2410_ADCCON);
    /*设置频率和通道*/
  tmp = S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(adcdev.prescale)|S3C2410_ADCCON_SELMUX(adcdev.channel);
    writel( tmp, base_addr+S3C2410_ADCCON);
    return 0;
}

static int adc_open(struct inode * inode, struct file * filp)
{
    return 0;
}

static int adc_release(struct inode * inode, struct file * filp)
{
    
        if (adc_clock) {
        clk_disable(adc_clock);
        clk_unuse(adc_clock);
        clk_put(adc_clock);
        adc_clock = NULL;
    }
    return 0;
}

static struct file_operations adc_fops = {
    
    .owner = THIS_MODULE,
    .write = adc_write,
    .read = adc_read,
    .open  = adc_open,    
    .release=adc_release,
};

static int __init adc_init(void)
{
    int ret;
    
    
    // adc_clock
    adc_clock = clk_get(NULL, "adc");
    if (!adc_clock) {
        printk(KERN_ERR "failed to get adc clock source\n");
        return -ENOENT;
    }
    clk_use(adc_clock);
    clk_enable(adc_clock);
    
    ret = register_chrdev(adc_major,DEVICE_NAME,&adc_fops);
      if(ret < 0)
    {
        printk("adc: can't get major number\n");
           return ret;
    }
    
    adc_major = ret;

#ifdef CONFIG_DEVFS_FS  
    ret = devfs_mk_cdev(MKDEV(adc_major,0),  S_IFCHR | S_IRUGO | S_IWUSR,DEVICE_NAME);
    if(ret)
    {
        unregister_chrdev(adc_major,DEVICE_NAME);
        printk("adc: can't make char device fo devfs\n");
        return ret;
    }
#endif
    
    base_addr=ioremap(S3C2410_PA_ADC,4);
    if (base_addr == NULL)
    {
        printk(KERN_ERR "Failed to remap register block\n");
        return -ENOMEM;
    }
    
    printk("s3c2410_adc driver initial\n");
    
    return 0;
}

static void __exit adc_exit(void)
{
#ifdef CONFIG_DEVFS_FS
    devfs_remove(DEVICE_NAME);
#endif  
    unregister_chrdev(adc_major,DEVICE_NAME);
    
    iounmap(base_addr);
    
    printk("s3c2410_adc driver removed\n");
}

module_init(adc_init);
module_exit(adc_exit);

MODULE_ALIAS("adc");
MODULE_DESCRIPTION("ADC IOIO Driver");
MODULE_AUTHOR("LIANXJ");
MODULE_LICENSE("GPL");
级别: 新手上路
UID: 1790
精华: 0
发帖: 33
金钱: 350 两
威望: 222 点
综合积分: 66 分
注册时间: 2008-09-28
最后登录: 2015-08-07
3楼  发表于: 2009-03-09 10:25
以为是 在开机时,adc的时钟没打开,

所以加了几句,但结果还是一样
级别: 新手上路
UID: 1790
精华: 0
发帖: 33
金钱: 350 两
威望: 222 点
综合积分: 66 分
注册时间: 2008-09-28
最后登录: 2015-08-07
4楼  发表于: 2009-03-09 10:27
测试程序是这样的

int main(int argc,char **argv)
{
  int fd;
//  int on;
//  int adc_no;
  int value;

  /*if(argc !=3 || sscanf(argv[1],"%d",&adc_no)!=1 || sscanf(argv[2],"%d,&on")!=1 || on<0||on>1||adc_no<0||adc_no>3){
    fprintf(stderr,"Usage:adc adc_no 0|1\n");
    exit(1);

}*/

  fd=open("/dev/adcray",0);
  if(fd<0){
  perror("open device adc");
  exit(1);
  }

ioctl(fd,1,0);
    
  for(;;){
      fd_set rds;
      int ret;
      float vo;
      int t;
      
      FD_ZERO(&rds);
      FD_SET(fd,&rds);
      
      ret = select(fd+1,&rds,NULL,NULL,NULL);
       if(ret<0)
       {
            perror("adc select");
            exit(1);
       }
       if(ret==0)
       {
         printf("Timeout \n");
       }
       else if(FD_ISSET(fd,&rds)){      
       ret = read(fd,value,sizeof value);
        if(ret !=sizeof value)
         if(errno !=EAGAIN)
         {
           perror("Can't read adc\n");
           continue;
         }
        else{
            float vo=((float)value*3.3)/1024.0;
            int t=(vo-(int)vo)*1000;

         printf("AIN0 = %d.%-3d V \r",(int)vo,t);
        }
       }
    }
   close(fd);
   return 0;
}
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
5楼  发表于: 2009-03-09 12:02
驱动加载后用mknod /dev/adcray c <adc major returned by driver, 比如253> 0, 确保测试程序所需要的/dev/adcray节点存在
"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: 1790
精华: 0
发帖: 33
金钱: 350 两
威望: 222 点
综合积分: 66 分
注册时间: 2008-09-28
最后登录: 2015-08-07
6楼  发表于: 2009-03-09 12:55
现在可以打开驱动了,但只输出

Can't read adc
: Bad address
Can't read adc
: Bad address
Can't read adc
: Bad address
Can't
[root@FriendlyARM plg]#
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
7楼  发表于: 2009-03-09 13:05
复制代码
  1.   ret = read(fd,value,sizeof value);


read()系统调用的声明是

复制代码
  1. ssize_t read(int fd, void *buf, size_t count);
"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: 1790
精华: 0
发帖: 33
金钱: 350 两
威望: 222 点
综合积分: 66 分
注册时间: 2008-09-28
最后登录: 2015-08-07
8楼  发表于: 2009-03-09 14:39
那返回的 value 的值怎么得到?
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
9楼  发表于: 2009-03-09 14:57
引用第8楼chase1011于2009-03-09 14:39发表的  :
那返回的 value 的值怎么得到?

C语言基础知识, 正确的用法是这样
复制代码
  1.        ret = read(fd,&value,sizeof(value));
  2.         if(ret !=sizeof(value)
  3.         {
  4.             if(errno !=EAGAIN)
  5.             {
  6.                 perror("Can't read adc\n");
  7.                 continue;
  8.             }
  9.         }
  10.         else
  11.         {
  12.             float vo=((float)value*3.3)/1024.0;
  13.             int t=(vo-(int)vo)*1000;



            ....
       }
"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."
  • «
  • 1
  • 2
  • »
  • Pages: 1/2     Go