您的位置:首页 > 其它

基于S5pc100 处理器的ADC驱动

2014-09-12 22:11 369 查看
基于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
调节变阻器,终端会打印如下信息:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: