基于S5pc100 处理器的ADC驱动

基于S5pc100 处理器的ADC驱动


编写一个字符驱动程序获取ADC通道0的电压值

一、开发环境:

1、 主机:Ubuntu 10.10发行版

2目标机:FS_S5PC100平台

3目标机内核版本:2.6.35

4、交叉编译工具:arm-none-linux-gnueabi-4.5.1

二、驱动编写的注意步骤:

1) 字符驱动open函数

打开时钟

中断申请

初始化寄存器

初始化等待队列

struct clk *clk;  

static int myadc_open (struct inode *inode, struct file *file)

   {

        int ret;
               /*打开时钟*/
               clk = clk_get(NULL, "adc");
               clk_enable(clk);
               /*中断申请*/
               if ((ret = request_irq(IRQ_ADC, myadc_irq, IRQF_DISABLED, "adc", NULL)) < 0)
               {
                printk(KERN_INFO "ADC request_irq error\n");
                return ret;
               }
               /*初始化寄存器*/
               adccon = (unsigned int *)ioremap(0xF3000000, 4);
               adcmux = (unsigned int *)ioremap(0xF300001C, 4);
               adcdat = (unsigned int *)ioremap(0xF300000C, 4);
               adcclrint = (unsigned int *)ioremap(0xF3000018, 4);
               writel(1<<0 | 1<<14 | 65<<6 | 1<<16, adccon);
               writel(0, adcmux);
               writel(readl(adcdat) & ~0xFFF, adcdat);
               /*初始化等待队列*/
               init_waitqueue_head(&rwait);
               return 0;

   }

2)关闭时钟

static int myadc_release (struct inode *inode, struct file *file)

   {

        /*关闭时钟*/
               clk_put(clk);
               clk_enable(clk);
               printk (KERN_INFO "myadc closed\n");
               return 0;

3)从寄存器ADCDAT0中取出转换后的值

ssize_t myadc_read (struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)

   {

       ssize_t result = 0;
               /*开始转换ADCCON 1=1<<0*/
               unsigned int data;
               data = readl(adccon);
               data |= 1<<0;
               writel(data, adccon);
               /*从寄存器ADCDAT0中取出转换后的值*/
               wait_event(rwait, value != 0);
               data = readl(adcdat) & 0xFFF;
               if (copy_to_user((void *)buf,(char __user *)&data, count))
                     return -EFAULT;
               else
                     printk (KERN_INFO "read %d bytes\n", count);
               result = count;
               value = 0;
               return result;

4)中断函数

static irqreturn_t myadc_irq(int irq, void *p)

   {

        /*清中断*/
               writel(0, adcclrint);
               value = 1;
               wake_up(&rwait);
               return IRQ_HANDLED;

   }

5)注意事项


由上图可知,该处理器中,触摸屏和ADC中断是共享的,所以保证内核中,没有注册触摸屏驱动。验证方法:cat /proc/interrupts,没有类似“samsung-adc”的内容。

三、测试:

1、编译应用程序

$ arm-none-linux-gnueabi-gcc test.c –o test

2、拷贝驱动及应用程序到目标板上

$ cp s5pc100_adc.ko test /source/rootfs

3、启动开发板后加载模块

# insmod s5pc100_adc.ko

4、创建设备节点

# mknod /dev/adc c 250 0

5、测试

# ./test

调节变阻器,终端会打印如下信息:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值