设为首页收藏本站
查看: 11194|回复: 0

mx28 ADC驱动与测试

[复制链接]

34

主题

9

回帖

363

积分

中级会员

积分
363
conway 发表于 2015-5-26 17:48:46 | 显示全部楼层 |阅读模式
本帖最后由 conway 于 2015-5-26 18:20 编辑

默认情况下ADC驱动没有将接口导出到用户空间,它只是应用于电阻触屏,若要使用别的ADC通道还得另外实现驱动,下面是一个简单的ADC驱动及测试程序:
lradc.c:
[mw_shl_code=applescript,true]#include<linux/module.h>                                                /* module                       */
#include<linux/fs.h>                                                    /* file operation               */
#include<asm/uaccess.h>                                                 /* get_user()                   */
#include<linux/miscdevice.h>                                            /* miscdevice                   */
#include<asm/io.h>                                                      /* ioctl                        */
#include <mach/regs-lradc.h>                                                /* #define                      */


static void __iomem *adc_base = NULL;


static int adc_open (struct inode *inode, struct file *fp)
{

        try_module_get(THIS_MODULE);
        writel(0xC0000000, adc_base + HW_LRADC_CTRL0_CLR);              /* 开启CLK,关闭复位模式        */
        writel(0x18430000, adc_base + HW_LRADC_CTRL1_CLR);              /* 关闭0-1-6通道及按键中断      */
        writel(0x30000000, adc_base + HW_LRADC_CTRL3_SET);              /* 忽略上电前三次采集数据       */     
        writel(0x76543210, adc_base + HW_LRADC_CTRL4);                  /* 设置对应的数据存放位置       */
       
        printk("adc open!\n");
        return 0;
}
static int adc_release (struct inode *inode, struct file *fp)
{
        module_put(THIS_MODULE);
   
        printk("adc closed!\n");
        return 0;
}
/*********************************************************************************************************
**   cmd:
**        10:CH0             11:CH1            16:CH6           17:Vbat(内部除4)          
**      20:CH0(开启除2) 21:CH1(开启除2) 26::CH6(开启除2)
**
**   被注释部分为3.0以上内核函数定义形式
*********************************************************************************************************/

//static int adc_ioctl(struct file *fp, struct file *flip, unsigned int cmd, unsigned long arg)
static int adc_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
{
            int iRes;
        int iTmp;
       
        if(cmd <10 || cmd >27){
                return -1;
        }

        iTmp = cmd % 10;
                  
        if(cmd == 20){
                writel(0x01000000, adc_base + HW_LRADC_CTRL2_SET);
        }
        if(cmd == 10){       
                writel(0x01000000, adc_base + HW_LRADC_CTRL2_CLR);
        }
        if(cmd == 21){
                writel(0x02000000, adc_base + HW_LRADC_CTRL2_SET);
        }
        if(cmd == 11){       
                writel(0x02000000, adc_base + HW_LRADC_CTRL2_CLR);
        }
        if(cmd == 26){       
                writel(0x40000000, adc_base + HW_LRADC_CTRL2_SET);
        }
        if(cmd == 16){       
                writel(0x40000000, adc_base + HW_LRADC_CTRL2_CLR);
        }
       
        writel(0x00000001 << iTmp, adc_base + HW_LRADC_CTRL0_SET);
        
            while(!( readl(adc_base + HW_LRADC_STATUS) & ((1 << 16) << iTmp) ));
                   
        iRes = readl(adc_base + HW_LRADC_CHn(iTmp));

        iRes = iRes & 0x0003FFFF;       
   
           copy_to_user((void *)arg, (void *)(&iRes), sizeof(int));
   
            return 0;
}
/*********************************************************************************************************
Device Struct
*********************************************************************************************************/
struct file_operations adc_fops =
{
        .owner                = THIS_MODULE,
        .open                = adc_open,
        .release        = adc_release,
            .ioctl              = adc_ioctl,
};
static struct miscdevice adc_miscdev =
{
        .minor                = MISC_DYNAMIC_MINOR,
           .name                = "simple-adc",
            .fops                = &adc_fops,
};
/*********************************************************************************************************
Module Functions
*********************************************************************************************************/
static int __init adcModule_init (void)
{
            int iRet=0;
            printk("\nadc module init!\n");
       
        adc_base = ioremap(0x80050000, 0x180*4);   
       
            iRet = misc_register(&adc_miscdev);
        if (iRet) {
                printk("register failed!\n");
        }
        return iRet;
}
static void __exit adcModule_exit (void)                                /* warning:return void          */
{
        printk("\nadc module exit!\n");
        misc_deregister(&adc_miscdev);
}
/*********************************************************************************************************
Driver Definitions
*********************************************************************************************************/
module_init(adcModule_init);
module_exit(adcModule_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("abcdczj@163.com");
MODULE_DESCRIPTION("imx28x LRADC");
/*********************************************************************************************************
End File
*********************************************************************************************************/
[/mw_shl_code]

lradc_test.c:
[mw_shl_code=applescript,true]#include<stdio.h>        /* using printf()        */
#include<stdlib.h>      /* using sleep()         */
#include<fcntl.h>       /* using file operation  */
#include<sys/ioctl.h>   /* using ioctl()         */

int main(int argc, char *argv[])
{
        int fd;
        int iRes;
        int time = 100;
        double val;

        fd = open("/dev/simple-adc", 0);
        if(fd < 0){
                printf("open error by APP- %d\n",fd);
                close(fd);
                return 0;
        }

        while(time--){
                sleep(1);               

                ioctl(fd, 20, &iRes);                        /* 开启除2     CH0    */
                val = (iRes * 3.7) / 4096.0;
                printf("CH0:%.2f\t", val);

                ioctl(fd, 11, &iRes);                   /* 不开除2     CH1    */
                val = (iRes * 1.85) / 4096.0;
                       printf("CH1:%.2f\t", val);

                ioctl(fd, 26, &iRes);                   /* 开启除2     CH6    */
                val = (iRes * 3.7) / 4096.0;
                printf("CH6:%.2f\t", val);

                ioctl(fd, 17, &iRes);                   /* 电池电压默认除4    */
                val = (iRes * 7.4) / 4096.0;
                printf("Vbat:%.2f\t", val);

                printf("\n");
        }
        close(fd);
}[/mw_shl_code]
回复

使用道具 举报

您需要登录后才可以回帖 登录

本版积分规则

Archiver|手机版|小黑屋|米尔科技论坛   

GMT+8, 2024-12-23 19:34 , Processed in 0.043362 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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