免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1155 | 回复: 0
打印 上一主题 下一主题

S3C2410 adc驱动(转) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-17 14:58 |只看该作者 |倒序浏览

s3c2410_adc中断方式实现

/*
*    HLG442-S3C2410-ADC_DRV
* /26/03/2008    AUTHOR "machuanlong"
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include    /* printk() */
#include    /* kmalloc() */
#include        /* everything... */
#include     /* error codes */
#include     /* size_t */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "s3c2410-adc.h"
#include
#include

#define DEVICE_NAME "adc"
static int adc_major = 0;
typedef struct {
struct semaphore lock;
wait_queue_head_t wait;
int channel;
int prescale;
}ADC_DEV;
static ADC_DEV adcdev;
static irqreturn_t adcdone_int_handler(int irq,void *dev_id,struct pt_regs *regs)
{
wake_up(&adcdev.wait);
return IRQ_HANDLED ;
}
static ssize_t s3c2410_adc_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
{
return 0;
}
static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
  int ret = 0;
  
if (down_interruptible(&adcdev.lock))
  return -ERESTARTSYS;
writel((readl(S3C2410_CLKCON) | S3C2410_CLKCON_ADC),S3C2410_CLKCON);
writel((1
copy_to_user(buffer, (char *)&ret, sizeof(ret));
up(&adcdev.lock);
return sizeof(ret);
}
static int s3c2410_adc_open(struct inode *inode, struct file *filp)
{
  int ret;
  ret = request_irq(IRQ_ADC, adcdone_int_handler, SA_INTERRUPT, DEVICE_NAME, NULL);
if (ret) {
  return ret;
}
init_MUTEX(&adcdev.lock);
init_waitqueue_head(&(adcdev.wait));
adcdev.channel=0;
adcdev.prescale=255;
return 0;
}
static int s3c2410_adc_release(struct inode *inode, struct file *filp)
{
free_irq(IRQ_ADC, NULL);
printk( "adc closed\n");
return 0;
}
static void adc_setup_cdev(struct cdev *dev, int minor,
  struct file_operations *fops)
{
int err, devno = MKDEV(adc_major, minor);
   
cdev_init(dev, fops);
dev->owner = THIS_MODULE;
dev->ops = fops;
err = cdev_add (dev, devno, 1);
/* Fail gracefully if need be */
if (err)
  printk (KERN_NOTICE "Error %d adding adc %d", err, minor);
}
static struct cdev AdcDevs;
static struct file_operations adc_remap_ops = {
.owner =THIS_MODULE,
.open = s3c2410_adc_open,
.read = s3c2410_adc_read,
.write = s3c2410_adc_write,
.release = s3c2410_adc_release,
};
int __init adc_init(void)
{
/* normal ADC */
writel(0,S3C2410_ADCTSC); //XP_PST(NOP_MODE);
int result;
dev_t dev = MKDEV(adc_major, 0);
/* Figure out our device number. */
if (adc_major)
  result = register_chrdev_region(dev, 1, "adc");
else {
  result = alloc_chrdev_region(&dev, 0, 1, "adc");
  adc_major = MAJOR(dev);
}
if (result
static void adc_cleanup(void)
{
cdev_del(&AdcDevs);
unregister_chrdev_region(MKDEV(adc_major, 0), 1);
printk("adc device uninstalled\n");
}
module_init(adc_init);
module_exit(adc_cleanup);
MODULE_AUTHOR("Machuanlong");
MODULE_LICENSE("Dual BSD/GPL");
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
Makefile(驱动的)
///////////////////////////////////////////////////////////////////////////////////
ifeq ($(KERNELRELEASE),)
#KERNELDIR ?= /source/kernel/linux-2.6.8.1-farsight
KERNELDIR ?= /disk2/linux-2.6.14
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
else
    obj-m := s3c2410_adc.o
endif

///////////////////////////////////////////////////////////////////////////////////
s3c2410-adc.h
///////////////////////////////////////////////////////////////////////////////////
#ifndef _S3C2410_ADC_H_
#define _S3C2410_ADC_H_
#define ADC_WRITE(ch, prescale) ((ch)
#define ADC_WRITE_GETCH(data) (((data)>>16)&0x7)
#define ADC_WRITE_GETPRE(data) ((data)&0xff)
#define ADC_INPUT(x)  (x
#endif /* _S3C2410_ADC_H_ */
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
测试程序:
main.c
///////////////////////////////////////////////////////////////////////////////////
/************************************************\
**HLG442 ADC-TEST
/26/3/2008
Author machuanlong
*      *
\***********************************************/
#include
#include
#include
#include
#include
#include
#include
#include "s3c2410-adc.h"
#define ADC_DEV  "/dev/adc"
static int adc_fd=-1;
static int GetADresult()
{
int data;
read(adc_fd, &data, sizeof(data));
return data;
}
static int stop=0;
int main(void)
{
int i;
float d;
if((adc_fd=open(ADC_DEV, O_RDWR))
while(1){
   d=((float)GetADresult()*3.3)/1024.0;
   printf("a%d=%8.4f\t",0,d);
   printf("\n");
   sleep(1);
   printf("\r");
  
}
close(adc_fd);
return 0;
}
转自:
http://blog.chinaunix.net/u2/66129/showart_525946.html


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/92401/showart_1902584.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP