Exynos4412 ADC 设备驱动开发
来源:互联网 发布:windows无法正常启动 编辑:程序博客网 时间:2024/06/05 19:18
具体ADC硬件知识及裸机驱动请看: Exynos4412裸机开发 —— A/D转换器
1、原理图如下:
2、相关寄存器信息
ADC_BASE 0x126C0000
ADCCON 0x0000 1<<0 | 1<<14 | 0X1<<16 | 0XFF<<6
ADCDLY 0x0008
ADCDAT 0x000C &0XFFF
CLRINTADC 0x0018
ADCMUX 0x001C
ADCDAT 0x000C &0XFFF
CLRINTADC 0x0018
ADCMUX 0x001C
3、大体驱动编写流程如下
read()
{
1、向adc设备发送要读取的命令
ADCCON 1<<0 | 1<<14 | 0X1<<16 | 0XFF<<6
2、读取不到数据就休眠
wait_event_interruptible();
3、等待被唤醒读数据
havedata = 0;
}
adc_handler()
{
1、清中断 ADC使用中断来通知转换数据完毕的
2、状态位置位;
havedata=1;
3、唤醒阻塞进程
wake_up()
}
probe()
{
1、 读取中断号,注册中断处理函数
2、读取寄存器的地址,ioremap
3、字符设备的操作
}
4、设备树中的节点编写
fs4412-adc{ compatible = "fs4412,adc"; reg = <0x126C0000 0x20>; interrupt-parent = <&combiner>; interrupts = <10 3>;};
5、驱动编写
driver.c
#include <linux/module.h>#include <linux/device.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <linux/fs.h>#include <linux/wait.h>#include <linux/sched.h>#include <asm/uaccess.h>#include <asm/io.h>static int major = 250;static wait_queue_head_t wq;static int have_data = 0;static int adc;static struct resource *res1;static struct resource *res2;static void *adc_base;#define ADCCON 0x0000 #define ADCDLY 0x0008 #define ADCDAT 0x000C #define CLRINTADC 0x0018#define ADCMUX 0x001Cstatic irqreturn_t adc_handler(int irqno, void *dev){have_data = 1;printk("11111\n");/*清中断*/writel(0x12,adc_base + CLRINTADC);wake_up_interruptible(&wq);return IRQ_HANDLED;}static int adc_open (struct inode *inod, struct file *filep){return 0;}static ssize_t adc_read(struct file *filep, char __user *buf, size_t len, loff_t *pos){ writel(0x3,adc_base + ADCMUX);writel(1<<0 | 1<<14 | 0X1<<16 | 0XFF<<6 ,adc_base +ADCCON );wait_event_interruptible(wq, have_data==1);/*read data*/adc = readl(adc_base+ADCDAT)&0xfff;if(copy_to_user(buf,&adc,sizeof(int))){return -EFAULT;}have_data = 0;return len;}static int adc_release(struct inode *inode, struct file *filep){return 0;}static struct file_operations adc_ops ={.open = adc_open,.release = adc_release,.read = adc_read,};static int hello_probe(struct platform_device *pdev){int ret;printk("match 0k \n");res1 = platform_get_resource(pdev,IORESOURCE_IRQ, 0); res2 = platform_get_resource(pdev,IORESOURCE_MEM, 0); ret = request_irq(res1->start,adc_handler,IRQF_DISABLED,"adc1",NULL); adc_base = ioremap(res2->start,res2->end-res2->start);register_chrdev( major, "adc", &adc_ops);init_waitqueue_head(&wq);return 0;}static int hello_remove(struct platform_device *pdev){free_irq(res1->start,NULL);free_irq(res2->start,NULL);unregister_chrdev( major, "adc");return 0;}static struct of_device_id adc_id[]={{.compatible = "fs4412,adc" },};static struct platform_driver hello_driver={.probe = hello_probe,.remove = hello_remove,.driver ={.name = "bigbang",.of_match_table = adc_id,},};static int hello_init(void){printk("hello_init");return platform_driver_register(&hello_driver);}static void hello_exit(void){platform_driver_unregister(&hello_driver);printk("hello_exit \n");return;}MODULE_LICENSE("GPL");module_init(hello_init);module_exit(hello_exit);
test.c
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>main(){int fd,len;int adc;fd = open("/dev/hello",O_RDWR);if(fd<0){perror("open fail \n");return ;}while(1){read(fd,&adc,4);printf("adc%0.2f V \n",(1.8*adc)/4096);}close(fd);}
1 0
- Exynos4412 ADC 设备驱动开发
- Exynos4412 ADC 设备驱动开发
- Lnux设备驱动开发——2.了解Exynos4412芯片
- exynos4412开发板设备注册与驱动注册剖析
- linux字符设备驱动-ADC
- N32905 adc字符设备驱动
- Linux设备驱动ADC部分:
- mini2440 ADC可调电阻设备驱动开发源代码(宋宝华设备驱动框架)
- ADC 驱动实例开发
- ADC 驱动实例开发
- Exynos4412 中断驱动开发(三)—— 设备树中中断节点的创建
- Exynos4412 中断驱动开发(三)—— 设备树中中断节点的创建
- linux 混杂设备驱动之adc驱动
- linux 混杂设备驱动之adc驱动
- linux 混杂设备驱动之adc驱动
- Exynos4412 中断驱动开发相关问题总结
- Exynos4412 中断驱动开发相关问题总结
- ADC驱动实例开发讲解
- hdu1010
- 从阿里到网易,一位非985/211本科应届生的一年求职路
- gdb命令使用
- seajs进阶
- 【IPC】互斥锁与条件变量及生产者-消费者问题
- Exynos4412 ADC 设备驱动开发
- C++实验2-标准体重
- Unity3D中基本GUI控件介绍
- KMS模拟器VLMCSD再次更新
- java常见的几种排序
- 1005 problem F
- Help Hanzo(素数筛)
- 哨兵元素的应用总结
- Greenplum 源码编译安装教程