📄 ad.c
字号:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/signal.h>#include <linux/errno.h>#include <linux/random.h>#include <linux/miscdevice.h>#include <linux/fs.h>#include <linux/interrupt.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/string.h>#include <linux/types.h>#include <linux/wait.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/uaccess.h>#include <asm/segment.h>//#include <asm/MC68VZ328.h>#include <asm/arch/s3c44b0x.h>/*#define AD_DEBUG*/int ad_major = 60; /* Select 0 for Dynamic adressing *///int count1=2000;#if 0void delay1(int time){ while (time--);}#endif #define my_get(a) (*(volatile unsigned char*) (a))#define my_put(v, a) (*(volatile unsigned char*) (a) = (v))#define BUF_SIZE 500#define AD_BASE 0x04000000#define QUERY_FREQ (HZ/100)#undef DEBUG_FROM_AIRstatic int ready = 0;static int start = 0;static unsigned char AdcValue[BUF_SIZE];static int channel = 0;static int udelay_n = (128 + 2);static int mdelay_n = 0;static int buf_n = 100;wait_queue_head_t Adc0809Wait;static void start_ad_convert(void);/* We use kernel timer here */struct timer_list ad_timer;void ad_timeout(unsigned long ptr){ /* We capture 100 data here and dump to the buffer */ int i; if(!start) { ready = 0; goto out; } for(i = 0; i < buf_n; i++) {#ifdef DEBUG_FROM_AIR udelay(20); AdcValue[i] = i + 20; ready = 1; } AdcValue[99] = '\0';#else start_ad_convert(); udelay(udelay_n); mdelay(mdelay_n); AdcValue[i] = my_get(AD_BASE + channel * 2); }#endif ready = 1; out: mod_timer(&ad_timer, jiffies + QUERY_FREQ); // Change the timer timeout value return; }void ad_run_timer(void){ init_timer(&ad_timer); ad_timer.function = ad_timeout; ad_timer.data = (unsigned long) 0; ad_timer.expires = jiffies + QUERY_FREQ; add_timer(&ad_timer); } /* Open-Funktion des Devices */static int ad_open(struct inode *inode, struct file *file){#ifdef AD_DEBUG printk("\n adc0809 is open\n");#endif start = 0; return 0;}/* Close-Funktion des Devices */static int ad_close(struct inode *inode, struct file *file){ #ifdef AD_DEBUG printk("\n adc0809 is closed\n");#endif start = 0; return 0;} static ssize_t ad_read(struct file *file, char *buffer, size_t count, loff_t *offset){ if(!ready) return -EAGAIN; // printk("count = %d, size = %d\n", count, sizeof(AdcValue)); if(count < 0) { printk("invalid count!\n"); return -EINVAL; } // printk("AdcValue is : %s\n", AdcValue); copy_to_user(buffer, AdcValue, min((size_t)buf_n, count)); ready = 0; return min((size_t)buf_n, count); }static unsigned int ad_select(struct file *filp, struct poll_table_struct *wait){ unsigned int mask = 0; start = 1; poll_wait(filp, &Adc0809Wait, wait); if(ready) mask |= POLLIN | POLLRDNORM; printk("ready::%d\n", ready); return mask;}static int ad_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ switch (cmd) { case 0: channel = arg; break; default: break; } return 1;}struct file_operations ad_fops ={ read: ad_read, poll: ad_select, open: ad_open, ioctl: ad_ioctl, release: ad_close,};static void start_ad_convert(void){ /* enable convert channel */ my_put(0x0, AD_BASE + channel * 2); //my_put(0x0, AD_BASE + channel);}static int check_param(void){ if(channel < 0 || channel > 7) { printk("invalidate channel number: %d! it must between 0-7.\n", channel); return -1; } if(udelay_n < 0 || udelay_n > 1000) { printk("invalidate short delay number: %d! it must between 0-1000.\n", udelay_n); return -1; } if(mdelay_n < 0 || mdelay_n > 1000) { printk("invalidate long delay number: %d! it must between 0-1000.\n", mdelay_n); return -1; } if(buf_n < 0 || buf_n > BUF_SIZE) { printk("invalidate buffer size: %d! it must between 0-%d.\n", buf_n, BUF_SIZE); return -1; } return 0;} int insert_ad(void){ int rc; rc=register_chrdev(ad_major, "ad", &ad_fops); if(rc<0) {#ifdef AD_DEBUG printk("Panic! Could not register AD-Driver\n");#endif return rc; }; return 0;}int ad_init(void){ int rc; init_waitqueue_head(&Adc0809Wait); rc = check_param(); if(rc < 0) { return rc; } rc = insert_ad(); if(rc) {#ifdef AD_DEBUG printk("Panic! AD-driver could not be loaded!\n");#endif } else {#ifdef AD_DEBUG printk("AD-driver init OK\n");#endif } ad_run_timer(); return rc;}static void ad_exit(void){ del_timer_sync(&ad_timer); unregister_chrdev(ad_major,"ad");#ifdef AD_DEBUG printk("AD-driver exit OK\n");#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -