ndac_drv.c
来自「华颐公司的以AT91RM9200为CPU的9200F 开发板在linux开发环」· C语言 代码 · 共 174 行
C
174 行
/*****************************************************************************
;Institue of Automation, Chinese Academy of Sciences
;www.hyesco.com
;Description: DAC driver on Linux for H9200F
;Date: 2005-11-17
;Author:
;E_mail:
*****************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h> //including irq number
#include <asm/arch/AT91RM9200_SYS.h>
/*
DAC基地址,与硬件电路相关,H9200F的DAC电路包含一个通道,
地址为:0x7000,0060,由NCS6选择,当用户改变跳线时,基地
址需要做相应的修改。
*/
#define EBI_BASE_ADDRESS 0x70000000L
#define EBI_OFFSET_ADDRESS 0x60
#define DA_sys_offset EBI_BASE_ADDRESS + EBI_OFFSET_ADDRESS
#define DA_Size 0x40
struct _DA_ADDR
{
//CH1和CH0间隔4×8=32字节,对应于偏移地址0x60和0x80,但系统目前仅用到0x60。
unsigned int AT91C_DAC_CH1;
unsigned int Reserved0[7];
unsigned int AT91C_DAC_CH0;
};
typedef struct _DA_PARA
{
int Channel;
int Adc_value;
} AT91_DA_PARA;
//全局变量,常量;
static int major=249;
static char s_name[]="ndac";
struct _DA_ADDR *Dac_Addr;
int DA_CH,DA_value;
//函数定义;
static int s_open(struct inode * s_node,struct file * s_file);
static int s_release(struct inode * s_node,struct file * s_file);
static int s_write(struct file*s_file, const char*w_buf,int len,loff_t* loff);
static int DA_mem();
struct file_operations Tmint_fops_DAC=
{
write : (void(*)) s_write,
open : (void(*)) s_open,
release: (void(*)) s_release,
};
//地址空间申请与检测函数;
static int DA_mem()
{
//申请内存区域,以检测该地址空间是否被使用;
if (!request_mem_region(DA_sys_offset,DA_Size,"DAC_REG"))
printk("Error request mem DAC_REG \n");
//进行内存区域的映射,把物理地址映射为逻辑地址;
Dac_Addr = ioremap(DA_sys_offset,DA_Size);
return 0;
};
//延时函数;
void Delay(unsigned int x)
{
unsigned int i,j,k;
for(i=0;i<=x;i++)
for(j=0;j<2;j++)
for(k=0;k<2;k++);
}
//初始化模块函数;
static int __init s_init_module(void)
{
int retv;
//注册模块;
retv=register_chrdev(major,s_name,&Tmint_fops_DAC);
if(retv<0)
{
printk("<1>Register Fail!\n");
return retv;
}
DA_mem();
printk("init DAC module is ok!\n");
return 0;
}
//清除模块函数;
static void __exit s_cleanup_module(void)
{
int retv;
//注销模块;
retv=unregister_chrdev(major,s_name);
//取消内存区域映射;
iounmap(Dac_Addr);
//释放申请的内存区域;
release_mem_region(DA_sys_offset,DA_Size);
if(retv<0)
{
printk("<1>ADC UnRegister Fail!\n");
return ;
}
printk("<1>DAC:Good Bye!\n");
}
//open函数
static int s_open(struct inode * s_node,struct file * s_file)
{
MOD_INC_USE_COUNT;
//定义EBI控制寄存器的读写参数,参考AT91RM9200用户手册P190;
AT91_SYS->EBI_SMC2_CSR[6]= AT91C_SMC2_NWS| AT91C_SMC2_WSEN
| AT91C_SMC2_TDF | AT91C_SMC2_BAT | AT91C_SMC2_DBW_16
| AT91C_SMC2_RWHOLD|AT91C_SMC2_ACSS_3_CYCLES ;
return 0;
}
//write函数
static int s_write(struct file*s_file, const char *w_buf,int len,loff_t* loff)
{
AT91_DA_PARA dac_para;
if(copy_from_user(&dac_para,w_buf,sizeof(AT91_DA_PARA)))
return -EFAULT;
DA_CH = dac_para.Channel;
DA_value = dac_para.Adc_value;
switch(DA_CH)
{
case 0:
Dac_Addr->AT91C_DAC_CH0=DA_value; //选择通道A输出
break;
case 1:
Dac_Addr->AT91C_DAC_CH1=DA_value; //选择通道B输出
break;
}
Delay(10);
return sizeof(unsigned int );
}
//release函数
static int s_release(struct inode * s_node,struct file * s_file)
{
MOD_DEC_USE_COUNT;
return 0;
}
module_init(s_init_module);
module_exit(s_cleanup_module);
MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?