⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc.c

📁 _计算实用教程Visual C++6.0实用教程
💻 C
字号:
/* ADC.c */

#include<linux/errno.h>
#include<linux/fs.h>
#include<linux/major.h>
#include<linux/kernel.h>
#include<linux/signal.h>
#include<linux/module.h>
#include<linux/sched.h>
#include<asm/io.h>
#include<asm/segment.h>
#include<asm/system.h>

#include "ADC.h"

extern int printk(const char* fmt, ...);
int adc_busy=0;
unsigned short data_port,control_port,status_port;


static int adc_open(struct inode *  inode,struct file * file)
{
unsigned int minor=MINOR(inode->i_rdev);

if (minor>7) return -ENODEV;
if (adc_busy==ADC_BUSY) return -EBUSY;

adc_busy=ADC_BUSY;
return 0;
}

static void adc_close(struct inode * inode,struct file * file)
{
adc_busy=ADC_FREE;
}

static int adc_read(struct inode * inode,struct file * file,char * buf,int count)
{
unsigned char data[16];
int adc_val;
unsigned int temp_val;
int temp1,temp2,temp3;
unsigned int minor=MINOR(inode->i_rdev);

if (count < 1) return -EINVAL;
switch (minor)
{
case CHANNEL_0:
	temp1=0x8f;
	break;
case CHANNEL_1:
	temp1=0xcf;
	break;
case CHANNEL_2:
	temp1=0x9f;
	break;
case CHANNEL_3:
	temp1=0xdf;
	break;
case CHANNEL_4:
	temp1=0xaf;
	break;
case CHANNEL_5:
	temp1=0xef;
	break;
case CHANNEL_6:
	temp1=0xbf;
	break;
case CHANNEL_7:
	temp1=0xff;
	break;
default:
	temp1=0x8f;
	break;
}
cli();
for(temp2=0; temp2<8; temp2++)
{
temp3= (temp1 << temp2) & 0x80;
outb(temp3,data_port);

temp3=temp3 | 1;
outb(temp3,data_port);
outb(temp3,data_port); /* this is to make the clk 50% duty cycle*/
/* Duty cycle as measured with a 66 MHz 486 is 48% */
temp3=temp3 & 0xfe;
outb(temp3,data_port);
}

temp3=temp3 & 0x7f;
outb(temp3,data_port);

for(temp2=0; temp2<16; temp2++)
{
temp3= 01;
outb(temp3,data_port);

data[temp2]=inb(data_port+1)&0x80;

temp3=temp3 & 0xfe;
outb(temp3,data_port);
outb(temp3,data_port);
}
sti();

adc_val=0; 
for(temp2=0; temp2<16; temp2++)
{
temp_val=( (unsigned int) data[temp2] & 0x00ff) << 8;
adc_val= adc_val | ( (temp_val ^ 0x8000) >> temp2);
}
adc_val=adc_val>> 3;
put_fs_word(adc_val,buf);
/* printk("ADC: Input value from port: %d\n",adc_val); */
return 1;
}

static struct file_operations adc_fops={
	NULL,
	adc_read,
	NULL,
	NULL,
	NULL,
        NULL,
	NULL,
	adc_open,
	adc_close,
	NULL
};

int init_module(void)
{
unsigned char ret_val,test_val=0x00;

outb(test_val,PARALLEL_1);
ret_val=inb(PARALLEL_1);
if (ret_val==test_val) 
   {
   data_port=PARALLEL_1;
   }
else
  {
   outb(test_val,PARALLEL_2);
   ret_val=inb(PARALLEL_2);
   if (ret_val==test_val)
      {
      data_port=PARALLEL_2;
      }
   else
      {
      data_port=PARALLEL_3;
      }
   }


printk("ADC: init module \n");
 if (register_chrdev(ADC_MAJOR,"adc",&adc_fops))
 {
   printk("Register_chrdev failed: Quitting\n");
   return -EIO;
   }
else
{
printk("ADC: Device Registered\n");
return 0;
}
}

void cleanup_module(void)
{
int busy=0;
printk("ADC: Cleanup Module \n");

   if (adc_busy==ADC_BUSY) busy=1;
   if (busy) printk("ADC: Device busy, remove later\n");
   if (unregister_chrdev(ADC_MAJOR,"adc")!=0)
     {
     printk("ADC: Clean up module failed\n");
     }
     else
    {
    printk("Clean up module succeeded\n");
    }
}

unsigned short test_parallel(void)
{

unsigned char ret_val,test_val=0x55;
unsigned short dport;

outb(test_val,PARALLEL_3);
ret_val=inb(PARALLEL_3);
if (ret_val==test_val) 
   {
   dport=PARALLEL_3;
   }
else
  {
   outb(test_val,PARALLEL_1);
   ret_val=inb(PARALLEL_1);
   if (ret_val==test_val)
      {
      dport=PARALLEL_1;
      }
   else
      {
   outb(test_val,PARALLEL_2);
   ret_val=inb(PARALLEL_2);
   if (ret_val==test_val) 
{
dport=PARALLEL_1;
}else
{
printk("No Parallel Port Available\n");
return -EIO;
}
      }
   }
return(dport);
}

int test_adc(void)
{
unsigned char cbyte;

cbyte=inb(data_port+2);
cbyte=cbyte&0xfe;
outb(cbyte,data_port+2);
cbyte=inb(data_port+1);
cbyte=cbyte & 0x80;
if (cbyte) return ADC_NOT_AVAILABLE;
cbyte=inb(data_port+2);
cbyte=cbyte|0x01;
outb(cbyte,data_port+2);
cbyte=inb(data_port+1);
cbyte=cbyte&0x80;
if (!cbyte) return ADC_NOT_AVAILABLE;
return ADC_AVAILABLE;
}

int adc_init(void)
{
int adc_stat;

printk("\n\n");
printk("    General Purpose DAS : Gadre and  Engineer \n");
printk("    Copyright 1996  The Peshwe at IUCAA , Pune\n");

data_port=test_parallel();
if (data_port!=0x378 &&  data_port!=0x278 && data_port!=0x3bc) 
{
printk("Parallel Port Not Available\n");
return -EINVAL;
}
printk("The Code detected %x as the parallel port in this machine\n",data_port);
adc_stat=test_adc(); 
if (adc_stat==1)
{
printk("ADC: registering driver\n");
 if (register_chrdev(ADC_MAJOR,"adc",&adc_fops))
  {
   printk("Register_chrdev failed: Quitting\n");
   return -EIO;
   }
else
  {
printk("ADC: Device Registered\n");
printk("   \t\t SanSon DAS  testing Successful \t\t \n\n");
return 0;
  }
}
printk("ADC not connected\n");
printk(" \n\n");
return -EIO;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -