#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h> // error codes
#include <linux/types.h> // size_t
#include <linux/delay.h> // mdelay
#include <linux/proc_fs.h>
#include <asm/uaccess.h> // to copy to/from userspace
#include <asm/hardware.h>
#include <asm/arch-s3c2410/s3c2410.h>
#include <asm-arm/arch-s3c2410/irqs.h>
#include <linux/wait.h>
#include <linux/signal.h>
#include <linux/ioctl.h>
#define adc_CTL_BASE io_p2v(0x58000000) //???
#define S3C2410_ADCCON (adc_CTL_BASE + 0x0)
#define S3C2410_ADCDAT (adc_CTL_BASE + 0xC)
#define PCLK 50700000 //???
#define ADC_FREQ 2500000 //???
#define START_ADC 0x0304 // the command of starting adc 数值任意
//#define MY_ADC_SIG 51
static int global; // recieve the value of adc
//static int pid; // the pid of the user process
//static int my_send_sig(void); // send signal to the user process
struct unit {
u32 *ADC_CON;
u32 *ADC_DAT;
};
static struct unit adc_unit = {
.ADC_CON = (u32 *)S3C2410_ADCCON,
.ADC_DAT = (u32 *)S3C2410_ADCDAT,
};
//int send_sig(); // send signal to the user process
/*static int my_send_sig(void)
{
siginfo_t info;
struct task_struct * p;
info.si_signo = MY_ADC_SIG;
info.si_code = -1;
info.si_int = 0x8;
read_lock(&tasklist_lock);
for_each_task(p)
{
if(p->pid == pid)
{
read_unlock(&tasklist_lock);
goto find_ps;
}
}
read_unlock(&tasklist_lock);
printk("can not find process\n");
return -1;
find_ps:
send_sig_info(MY_ADC_SIG,&info,p);
//printk("pid is : %d\n",pid);
//printk("send adc-sig to user space!\n");
return 0;
}
*/
static void adcdone_int_handler(int irq, void *dev_id, struct pt_regs *reg)
{
//printk("in adc int handler!\n");
global =( (int)*adc_unit.ADC_DAT & 0x3FF); //得到转换后的数据
//my_send_sig();
}
ssize_t adc_open(struct inode * inode, struct file * file)
{
MOD_INC_USE_COUNT;
file->private_data = &adc_unit;
return 0;
}
ssize_t adc_release(struct inode * inode, struct file * file)
{
MOD_DEC_USE_COUNT;
return 0;
}
ssize_t adc_read(struct file * file, char * buf, size_t count, loff_t * offset)
{
int ret;
int temp;
temp = global;
ret = copy_to_user(buf, &temp, count); //把转换后的值送用户
if(ret!=0)
{
printk("The copy to user error!\n");
return -EFAULT;
}
return ret;
}
//adc_write()没用
ssize_t adc_write(struct file * file, const char * buf, size_t count, loff_t * offset)
{
int ret,temp;
ret = copy_from_user(&temp,buf,count);
if(ret!=0)
{
printk("The copy from user error!\n");
return -EFAULT;
}
//pid = temp;
//printk("in adc-write, the pid is : %d\n",pid);
return ret;
}
int adc_ioctl(struct inode * inode, struct file * filp,unsigned int cmd,unsigned long arg)
{
switch(cmd)
{
case START_ADC: *adc_unit.ADC_CON |= 0x1; break; //位0:置1,启动AD
default:
{
printk("the ioctl error!\n");
break;
}
}
return 0;
}
struct file_operations adc_Ctl_ops =
{
open: adc_open,
read: adc_read,
write: adc_write,
ioctl: adc_ioctl,
release: adc_release,
};
static devfs_handle_t devfs_handle,devfs_adc_dir;
static void __init init_hardware(struct unit *unit)
{
char preScaler = PCLK/ADC_FREQ - 1;
//14: AD converter prescaler enable 1(enable)
//6-13: AD converter prescaler value 取值1-255
//3-5: analog input channel select 010: AIN2
*unit->ADC_CON = (1<<14) | (preScaler<<6) | (1<<4); //有问题 ??
*unit->ADC_DAT = 0x0;
}
static int __init init_adc()
{
int res;
printk("This is my Adc driver!\n");
devfs_register_chrdev(224, "adc", &adc_Ctl_ops);
devfs_adc_dir = devfs_mk_dir(NULL, "adc", NULL);
devfs_handle = devfs_register(devfs_adc_dir, "0", DEVFS_FL_DEFAULT,
224, 0,S_IFCHR | S_IRUSR | S_IWUSR,&adc_Ctl_ops, NULL);
res = request_irq(IRQ_ADC_DONE, adcdone_int_handler, SA_INTERRUPT , "adc", NULL);
if(res < 0)
printk("The IRQ Wrong!\n");
init_hardware(&adc_unit);
return res;
}
static void __exit clean_adc()
{
devfs_unregister_chrdev(224,"adc");
devfs_unregister(devfs_handle);
devfs_unregister(devfs_adc_dir);
free_irq(IRQ_ADC_DONE,NULL);
}
module_init(init_adc);
module_exit(clean_adc);
MODULE_DESCRIPTION("EduKitIII-2410 adc driver");
MODULE_AUTHOR("ssdut");
MODULE_LICENSE("GPL");
adc.rar_adc linux2
版权申诉
178 浏览量
2022-09-20
16:04:06
上传
评论
收藏 4KB RAR 举报
小贝德罗
- 粉丝: 69
- 资源: 1万+
最新资源
- unity开发教程.docx
- 代码使用Pygame库实现了一个简单的烟花模拟 核心逻辑包括烟花和粒子类的定义,处理位置、爆炸、尾迹和绘制等操作
- Matlab Simulink 电力电子仿真-Flyback(反激电路)电路分析
- tudou-android-release.apk
- 数据分析教程.docx
- 基于matlab实现用有限元法计算电磁场的Matlab工具 .rar
- 基于matlab实现有限元算法 计算电磁场问题 边界条件包括第一类边界和第二类边界.rar
- 基于matlab实现用于计算不同车重下的电动汽车动力性和经济性.rar
- 基于matlab实现遗传算法求解多车场车辆路径问题 有多组算例可以用.rar
- 浏览器.apk
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈