-1. Should I use CONFIG_MODVERSIONS when compiling a Linux kernel?
-
-Short answer: No. Long answer: MODVERSIONS allows you to safely
-use a module on multiple kernel versions. However, making comedi
-work with CONFIG_MODVERSIONS is a real pain. Sometimes it works,
-sometimes it doesn't.
-
-
-2. I get the error message:
+1. I get the error message:
Makefile:14: /usr/src/linux/.config: No such file or directory
make: *** No rule to make target `/usr/src/linux/.config'. Stop.
when you run 'make config', the first step in compiling a kernel.
-3. When compiling programs that use libcomedi, I get error message:
-
-/usr/lib/libcomedi.a(range.o): In function `comedi_from_phys':
-range.o(.text+0x169): undefined reference to `floor'
-
-
-This error messsage indicates that the linker cannot resolve the
-reference to floor(), which is a function in the math library
-that is used in the function comedi_from_phys(). This only
-happens when you link statically. Add '-lm' to your linking
-command.
-
-
-Advantech ACL-8112-DG pcl711
-Advantech ACL-8112-HG pcl711
+ADLink ACL-8112-DG pcl711
+ADLink ACL-8112-HG pcl711
+ADLink ACL-6126 pcl726
+ADLink ACL-6128 pcl726
Advantech PCL-711 pcl711
Advantech PCL-711B pcl711
Advantech PCL-718 pcl818
Advantech PCL-725 pcl725
Advantech PCL-726 pcl726
+Advantech PCL-727 pcl726
+Advantech PCL-728 pcl726
Advantech PCL-812PG pcl812
Advantech PCL-813B pcl812
Advantech PCL-818 pcl818
ComputerBoards CIO-DAS08/JR-AO das08
ComputerBoards CIO-DAS08/JR-AO das08jr
ComputerBoards CIO-DAS08/JR/16 das08
+ComputerBoards CIO-DAS16 das16
+ComputerBoards CIO-DAS16/F das16
+ComputerBoards CIO-DAS16/JR das16
+ComputerBoards CIO-DAS1401/12 das16
+ComputerBoards CIO-DAS1402/12 das16
+ComputerBoards CIO-DAS1402/16 das16
+ComputerBoards CIO-DAS1601/12 das16
+ComputerBoards CIO-DAS1602/12 das16
+ComputerBoards CIO-DAS1602/16 das16
+ComputerBoards CIO-DAS16/330 das16
Data Translation DT21-EZ dt282x
Data Translation DT23-EZ dt282x
Data Translation DT24-EZ dt282x
National Instruments AT-MIO-16XE-10 ni_atmio
National Instruments AT-MIO-16XE-50 ni_atmio
National Instruments AT-MIO-64E-3 ni_atmio
-National Instruments DAQCard-AI-16E-4 * ni_mio_cs
+National Instruments DAQCard-AI-16E-4 ni_mio_cs
National Instruments DAQCard-AI-16XE-50 ni_mio_cs
National Instruments PCI-6023E ni_pcimio
National Instruments PCI-6024E ni_pcimio
CFLAGS = -Wall -O2 -Wstrict-prototypes
CFLAGS += -D__KERNEL__ -I $(LINUXDIR)/include -I $(TOPDIR)/include -I .
+CFLAGS += -D__MODBUILD__
CONFIG_SHELL := sh
comment 'Comedi Features'
+define_bool CONFIG_COMEDI_MODES y
+define_bool CONFIG_COMEDI_MODE0 y
+define_bool CONFIG_COMEDI_MODE_CORE y
+
#bool 'Backwards compatibility' CONFIG_COMEDI_BACKWARDS
if [ "$CONFIG_RTL" = "y" ];then
if [ "$CONFIG_PCI" = "y" ];then
dep_tristate 'IOtech DaqBoard/2000' CONFIG_COMEDI_DAQBOARD2000 $CONFIG_COMEDI
fi
+dep_tristate 'Skeleton driver' CONFIG_COMEDI_SKEL $CONFIG_COMEDI
if [ "$CONFIG_COMEDI_RT" = "y" ];then
comment 'Virtual device drivers'
dep_tristate 'Direct Digital Synthesis' CONFIG_COMEDI_VD_DDS $CONFIG_COMEDI
fi
-
ifeq ($(CONFIG_COMEDI),y)
O_TARGET := comedi.o
- O_OBJS := comedi_fops.o dummy.o proc.o range.o drivers.o kvmem.o
+ O_OBJS := comedi_fops.o proc.o range.o drivers.o kvmem.o
OX_OBJS := comedi_ksyms.o
else
ifeq ($(CONFIG_COMEDI),m)
M_OBJS := comedi.o
- MI_OBJS := comedi_fops.o dummy.o proc.o range.o drivers.o kvmem.o
+ MI_OBJS := comedi_fops.o proc.o range.o drivers.o kvmem.o
MIX_OBJS := comedi_ksyms.o
endif
endif
static int do_devinfo_ioctl(comedi_device *dev,comedi_devinfo *arg);
static int do_subdinfo_ioctl(comedi_device *dev,comedi_subdinfo *arg,void *file);
static int do_chaninfo_ioctl(comedi_device *dev,comedi_chaninfo *arg);
+#ifdef CONFIG_COMEDI_MODE_CORE
static int do_trig_ioctl(comedi_device *dev,void *arg,void *file);
+#endif
static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file);
static int do_lock_ioctl(comedi_device *dev,unsigned int arg,void * file);
static int do_unlock_ioctl(comedi_device *dev,unsigned int arg,void * file);
return do_chaninfo_ioctl(dev,(void *)arg);
case COMEDI_RANGEINFO:
return do_rangeinfo_ioctl(dev,(void *)arg);
+#ifdef CONFIG_COMEDI_MODE_CORE
case COMEDI_TRIG:
return do_trig_ioctl(dev,(void *)arg,file);
+#endif
case COMEDI_LOCK:
return do_lock_ioctl(dev,arg,file);
case COMEDI_UNLOCK:
us->subd_flags |= SDF_FLAGS;
if(s->range_table_list)
us->subd_flags |= SDF_RANGETYPE;
+#ifdef CONFIG_COMEDI_MODE_CORE
if(s->trig[0])
us->subd_flags |= SDF_MODE0;
if(s->trig[1])
us->subd_flags |= SDF_MODE3;
if(s->trig[4])
us->subd_flags |= SDF_MODE4;
+#endif
}
ret=copy_to_user(arg,tmp,dev->n_subdevices*sizeof(comedi_subdinfo));
}
+#ifdef CONFIG_COMEDI_MODE_CORE
/*
COMEDI_TRIG
trigger ioctl
s->buf_user_count=0;
}
+ s->cur_chan=0;
+ s->cur_chanlist_len=s->cur_trig.n_chan;
+
s->cb_mask=COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
if(s->cur_trig.flags & TRIG_WAKE_EOS){
s->cb_mask|=COMEDI_CB_EOS;
return ret;
}
+#endif
/*
}
s->cmd.data_len=s->prealloc_bufsz;
- s->cur_trig.data=s->prealloc_buf;
+#ifdef CONFIG_COMEDI_MODE_CORE
+ s->cur_trig.data=s->prealloc_buf; /* XXX */
s->cur_trig.data_len=s->prealloc_bufsz;
+#endif
s->buf_int_ptr=0;
s->buf_int_count=0;
s->buf_user_count=0;
}
+ s->cb_mask = COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
+ if(s->cmd.flags & TRIG_WAKE_EOS){
+ s->cb_mask |= COMEDI_CB_EOS;
+ }
+
s->runflags=SRF_USER;
#ifdef CONFIG_COMEDI_RT
if(s->cmd.flags & TRIG_RT){
if(s->busy != file)
return -EACCES;
- buf_ptr=s->cur_trig.data;
+#ifdef CONFIG_COMEDI_MODE_CORE
+ buf_ptr=s->cur_trig.data; /* XXX */
buf_len=s->cur_trig.data_len;
+#endif
}
if(!buf_ptr)
if(!s->busy)
return 0;
- if(!s->cur_trig.data || !(s->subdev_flags&SDF_READABLE))
+#ifdef CONFIG_COMEDI_MODE_CORE
+ if(!s->cur_trig.data || !(s->subdev_flags&SDF_READABLE)) /* XXX */
return -EIO;
+#endif
if(s->busy != file)
return -EACCES;
n=nbytes;
m=s->buf_int_count-s->buf_user_count;
- if(m>s->cur_trig.data_len){
+ if(m>s->cur_trig.data_len){ /* XXX MODE */
s->buf_user_count=s->buf_int_count;
s->buf_user_ptr=s->buf_int_ptr;
retval=-EINVAL; /* OVERRUN */
break;
}
- if(s->buf_user_ptr+m > s->cur_trig.data_len){
+ if(s->buf_user_ptr+m > s->cur_trig.data_len){ /* XXX MODE */
m=s->cur_trig.data_len - s->buf_user_ptr;
#if 0
printk("m is %d\n",m);
}
#endif
- if(s->cur_trig.chanlist){
+ if(s->cur_trig.chanlist){ /* XXX wrong? */
kfree(s->cur_trig.chanlist);
s->cur_trig.chanlist=NULL;
}
return comedi_init();
}
-int cleanup_module(void)
+void cleanup_module(void)
{
comedi_cleanup();
}
#include <linux/malloc.h>
#include <linux/errno.h>
#include <comedi.h>
-#ifdef COMEDI_STANDALONE
+#ifdef __MODBUILD__
#include <config.h>
#endif
unsigned int *chanlist; /* driver-owned chanlist (not used) */
+#ifdef CONFIG_COMEDI_MODE_CORE
comedi_trig cur_trig; /* current trig structure */
+#endif
comedi_cmd cmd;
volatile unsigned int buf_int_ptr; /* buffer marker for interrupt */
volatile unsigned int buf_int_count; /* byte count for interrupt */
unsigned int buf_user_count; /* byte count for read() and write() */
unsigned int cur_chan; /* useless channel marker for interrupt */
+ unsigned int cur_chanlist_len;
+#ifdef CONFIG_COMEDI_MODE_CORE
int (*trig[5])(comedi_device *,comedi_subdevice *,comedi_trig *);
+#endif
- int (*insn_read)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *data);
- int (*insn_write)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *data);
+ int (*insn_read)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);
+ int (*insn_write)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);
int (*do_cmd)(comedi_device *,comedi_subdevice *);
int (*do_cmdtest)(comedi_device *,comedi_subdevice *,comedi_cmd *);
void comedi_proc_init(void);
void comedi_proc_cleanup(void);
+#ifdef CONFIG_COMEDI_MODE_CORE
int di_unpack(unsigned int bits,comedi_trig *it);
int do_pack(unsigned int *bits,comedi_trig *it);
+#endif
#ifndef CONFIG_COMEDI_RT
void init_drivers(void)
{
- REG(driver_dummy);
-#if 0
#ifdef CONFIG_COMEDI_DT282x
REG(driver_dt282x);
#endif
#ifdef CONFIG_COMEDI_DAQBOARD2000
REG(driver_daqboard2000);
#endif
-#endif
}
obj-$(CONFIG_COMEDI_RTI800) += rti800.o
obj-$(CONFIG_COMEDI_RTI802) += rti802.o
+obj-$(CONFIG_COMEDI_SKEL) += skel.o
+
#obj-m += $(obj-y)
O_OBJS := $(sort $(filter-out $(export-objs), $(obj-y)))
ni_pcimio.o: ni_mio_common.c
ni_atmio.o: ni_mio_common.c
+ni_mio_cs.o: ni_mio_common.c
*/
-static int das08_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das08_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das08_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das08jr_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das08jr_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das08jr_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das08ao_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
+static int das08_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das08_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das08_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das08jr_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das08jr_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das08jr_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das08ao_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
static comedi_lrange range_das08_pgl = { 9, {
BIP_RANGE(10),
#define TIMEOUT 1000
-static int das08_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das08_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
int i,n;
int chan;
return n;
}
-static int das08_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das08_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
insn->data[0]=DAS08_IP(inb(dev->iobase+DAS08_STATUS));
return 1;
}
-static int das08_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das08_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
/* XXX race with ai */
return 1;
}
-static int das08jr_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das08jr_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
insn->data[0]=inb(dev->iobase+DAS08JR_DIO);
return 1;
}
-static int das08jr_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das08jr_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
outb(insn->data[0],dev->iobase+DAS08JR_DIO);
return 1;
}
-static int das08jr_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das08jr_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
int n;
int lsb,msb;
* a different method to force an update.
*
*/
-static int das08ao_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das08ao_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
int n;
int lsb,msb;
&range_das1x02_bip,
};
-static int das16_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das16_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das16_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
-static int das16_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn);
+static int das16_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das16_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das16_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int das16_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
struct das16_board_struct{
char *name;
#define thisboard ((struct das16_board_struct *)(dev->board_ptr))
-static int das16_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das16_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
int i,n;
int range;
msb = inb(dev->iobase + DAS16_AI_MSB);
lsb = inb(dev->iobase + DAS16_AI_LSB);
if(thisboard->ai_nbits==12){
- insn->data[n] = (lsb>>4) | (msb << 4);
+ data[n] = (lsb>>4) | (msb << 4);
}else{
- insn->data[n] = lsb | (msb << 8);
+ data[n] = lsb | (msb << 8);
}
}
return n;
}
-static int das16_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das16_di_rbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
- insn->data[0]=inb(dev->iobase+DAS16_DIO)&0xf;
+ data[0]=inb(dev->iobase+DAS16_DIO)&0xf;
return 1;
}
-static int das16_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das16_do_wbits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
- outb(insn->data[0],dev->iobase+DAS16_DIO);
+ outb(data[0],dev->iobase+DAS16_DIO);
return 1;
}
-static int das16_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn)
+static int das16_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
int n;
int lsb,msb;
int chan;
if(thisboard->ao_nbits==12){
- lsb=(insn->data[0]<<4)&0xff;
- msb=(insn->data[0]>>4)&0xff;
+ lsb=(data[0]<<4)&0xff;
+ msb=(data[0]>>4)&0xff;
}else{
- lsb=insn->data[0]&0xff;
- msb=(insn->data[0]>>8)&0xff;
+ lsb=data[0]&0xff;
+ msb=(data[0]>>8)&0xff;
}
chan=CR_CHAN(insn->chanspec);
-static void das16_init(comedi_device *dev)
-{
- outb(DAS16_IRQ(dev->irq),dev->iobase+DAS16_CONTROL);
- outb(0,DAS16_PACER);
-
-}
-
static int detect_ao(comedi_device *dev)
{
int in_aa;
printk("comedi%d: das16:",dev->minor);
+ if((ret=alloc_private(dev,sizeof(struct das16_private_struct)))<0)
+ return ret;
+
+ dev->board = das16_probe(dev);
+
dev->board_ptr = das16_boards + dev->board;
dev->board_name = thisboard->name;
dev->n_subdevices = 5;
if((ret=alloc_subdevices(dev))<0)
return ret;
- if((ret=alloc_private(dev,sizeof(struct das16_private_struct)))<0)
- return ret;
if(thisboard->size<0x400){
request_region(dev->iobase,thisboard->size,"das16");
s->type = COMEDI_SUBD_UNUSED;
}
+ outb(DAS16_IRQ(dev->irq),dev->iobase+DAS16_CONTROL);
+ outb(0,DAS16_PACER);
+
return 0;
}
return 0;
}
+#ifdef CONFIG_COMEDI_MODES
static int dt282x_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
{
int timer;
return 0;
}
}
+#endif
static int dt282x_ai_cancel(comedi_device * dev, comedi_subdevice * s)
{
return 1;
}
+static int dt282x_ao_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
+{
+ int err=0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp=cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if(!cmd->start_src && tmp!=cmd->start_src)err++;
+
+ tmp=cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+
+ tmp=cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+
+ tmp=cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+
+ tmp=cmd->stop_src;
+ //cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
+ cmd->stop_src &= TRIG_COUNT; /* XXX */
+ if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+
+ if(err)return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if(cmd->stop_src!=TRIG_COUNT &&
+ cmd->stop_src!=TRIG_NONE)err++;
+
+ if(err)return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if(cmd->start_arg!=0){
+ cmd->start_arg=0;
+ err++;
+ }
+ if(cmd->scan_begin_arg <= 5000 /* XXX unknown */){
+ cmd->scan_begin_arg = 5000;
+ err++;
+ }
+ if(cmd->convert_arg != 0){
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if(cmd->scan_end_arg > 2){
+ /* XXX chanlist stuff? */
+ cmd->scan_end_arg = 2;
+ err++;
+ }
+ if(cmd->stop_src==TRIG_COUNT){
+ /* any count is allowed */
+ }else{
+ /* TRIG_NONE */
+ if(cmd->stop_arg!=0){
+ cmd->stop_arg=0;
+ err++;
+ }
+ }
+
+ if(err)return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp=cmd->scan_begin_arg;
+ dt282x_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);
+ if(tmp!=cmd->scan_begin_arg)err++;
+
+ if(err)return 4;
+
+ return 0;
+
+}
+
+static int dt282x_ao_cmd(comedi_device *dev,comedi_subdevice *s)
+{
+ int size;
+ int timer;
+ comedi_cmd *cmd=&s->cmd;
+
+ devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS1 | DT2821_DDMA;
+ update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_DACINIT);
+
+ devpriv->ntrig=cmd->stop_arg*cmd->chanlist_len;
+ devpriv->nread=devpriv->ntrig;
+
+ devpriv->dma_dir=DMA_MODE_WRITE;
+ devpriv->current_dma_chan=0;
+
+ size=copy_from_buf(dev,s,devpriv->dma[0].buf,devpriv->dma_maxsize*2);
+ prep_ao_dma(dev,0,size/2);
+ enable_dma(devpriv->dma[0].chan);
+
+ size=copy_from_buf(dev,s,devpriv->dma[1].buf,devpriv->dma_maxsize*2);
+ prep_ao_dma(dev,1,size/2);
+ enable_dma(devpriv->dma[1].chan);
+
+ timer=dt282x_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
+ outw(timer, dev->iobase + DT2821_TMRCTR);
+
+ devpriv->dacsr = DT2821_SSEL| DT2821_DACLK | DT2821_IDARDY;
+ update_dacsr(0);
+
+ update_supcsr(DT2821_STRIG);
+
+ return 0;
+}
+
+#ifdef CONFIG_COMEDI_MODES
static int dt282x_ao_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
{
int size;
return 0;
}
+#endif
static int dt282x_ao_cancel(comedi_device * dev, comedi_subdevice * s)
{
s->type=COMEDI_SUBD_AI;
s->subdev_flags=SDF_READABLE|((it->options[opt_diff])?SDF_DIFF:SDF_COMMON);
s->n_chan=(it->options[opt_diff])?boardtype.adchan_di:boardtype.adchan_se;
+#ifdef CONFIG_COMEDI_MODE0
s->trig[0]=dt282x_ai_mode0;
+#endif
+#ifdef CONFIG_COMEDI_MODES
s->trig[1]=dt282x_ai_mode1;
s->trig[4]=dt282x_ai_mode4;
+#endif
s->do_cmdtest=dt282x_ai_cmdtest;
s->do_cmd=dt282x_ai_cmd;
s->cancel=dt282x_ai_cancel;
/* ao subsystem */
s->type=COMEDI_SUBD_AO;
s->subdev_flags=SDF_WRITEABLE;
+#ifdef CONFIG_COMEDI_MODE0
s->trig[0]=dt282x_ao;
+#endif
+#ifdef CONFIG_COMEDI_MODES
s->trig[2]=dt282x_ao_mode2;
+#endif
+ s->do_cmdtest=dt282x_ao_cmdtest;
+ s->do_cmd=dt282x_ao_cmd;
s->cancel=dt282x_ao_cancel;
s->maxdata=(1<<boardtype.dabits)-1;
s->len_chanlist=1; /* XXX could do 2 */
unsigned short gpct_input_select0;
unsigned short gpct_input_select1;
- unsigned int ai_n_chans;
- unsigned int ai_chanlistptr;
unsigned short ai_xorlist[512];
}ni_private;
#define devpriv ((ni_private *)dev->private)
s->buf_int_ptr += sizeof(sampl_t);
s->buf_int_count += sizeof(sampl_t);
- if((++s->cur_chan) >= s->cmd.chanlist_len) { /* one scan done */
+ if((++s->cur_chan) >= s->cur_chanlist_len) { /* one scan done */
s->cur_chan = 0;
- s->cur_trig.flags |= TRIG_WAKE_EOS;
comedi_eos(dev, s);
}
static int ni_dio(comedi_device *dev,comedi_subdevice *s,comedi_trig *it);
-static int ni_read_eeprom(comedi_device *dev,int addr);
-
static int ni_eeprom(comedi_device *dev,comedi_subdevice *s,comedi_trig *it);
static int ni_calib(comedi_device *dev,comedi_subdevice *s,comedi_trig *it);
+
static void caldac_setup(comedi_device *dev,comedi_subdevice *s);
+static int ni_read_eeprom(comedi_device *dev,int addr);
static void ni_handle_fifo_half_full(comedi_device *dev);
return;
}
-#if 0
- /* this is wrong, since we do AO now */
- if(!dev->subdevices->cur_trig.data){
- rt_printk("aiee! cur_trig.data got zapped!\n");
- comedi_done(dev,s);
- return;
- }
-#endif
-
if(status&AI_SC_TC_St){
#ifdef DEBUG
rt_printk("ni-E: SC_TC interrupt\n");
ack|=AI_SC_TC_Interrupt_Ack;
}
- if(status&AI_FIFO_Half_Full_St){
- ni_handle_fifo_half_full(dev);
- }
- if(dev->subdevices->cur_trig.flags&TRIG_WAKE_EOS){
-#if 0
- if(status&AI_START_St){
- /* just ack it */
- ack|=AI_START_Interrupt_Ack;
- }
-#endif
- if(status&AI_STOP_St){
- ni_handle_fifo_dregs(dev);
-
- comedi_eos(dev,dev->subdevices+0);
-
- /* we need to ack the START, also */
- ack|=AI_STOP_Interrupt_Ack|AI_START_Interrupt_Ack;
- }
- }
-#if 0
switch(devpriv->aimode){
- deafult:
+ default:
break;
case AIMODE_HALF_FULL:
if(status&AI_FIFO_Half_Full_St){
break;
case AIMODE_SAMPLE:
ni_handle_fifo_dregs(dev);
- if(s->buf_int_count>=s->cur_chan){
- while(s->buf_int_count>=s->cur_chan)
- s->cur_chan+=s->cur_trig.n_chan*sizeof(sampl_t);
+#if 0
+ if(s->event_mask&COMEDI_CB_EOS){
comedi_eos(dev,dev->subdevices+0);
}
+#endif
break;
}
-#endif
if(b_status&AO_Overrun_St){
printk("ni-E: AO FIFO underrun status=0x%04x status2=0x%04x\n",b_status,ni_readw(AO_Status_2));
unsigned int mask;
mask=(1<<boardtype.adbits)-1;
- j=devpriv->ai_chanlistptr;
+ j=s->cur_chan;
for(i=0;i<n;i++){
d=ni_readw(ADC_FIFO_Data_Register);
d^=devpriv->ai_xorlist[j];
d&=mask;
data[i]=d;
j++;
- if(j>=s->cur_trig.n_chan)j=0;
+ if(j>=s->cur_chanlist_len){
+ j=0;
+ //s->event_mask |= COMEDI_CB_EOS;
+ }
}
- devpriv->ai_chanlistptr=j;
+ s->cur_chan=j;
}
*/
mask=(1<<boardtype.adbits)-1;
- j=devpriv->ai_chanlistptr;
+ j=s->cur_chan;
data=((void *)s->cur_trig.data)+s->buf_int_ptr;
while(1){
n=(s->cur_trig.data_len-s->buf_int_ptr)/sizeof(sampl_t);
d&=mask;
*data=d;
j++;
- if(j>=s->cur_trig.n_chan)j=0;
+ if(j>=s->cur_chanlist_len){
+ j=0;
+ //s->event_mask |= COMEDI_CB_EOS;
+ }
data++;
s->buf_int_ptr+=sizeof(sampl_t);
s->buf_int_count+=sizeof(sampl_t);
data=s->cur_trig.data;
comedi_eobuf(dev,s);
}
- devpriv->ai_chanlistptr=j;
+ s->cur_chan=j;
}
/*
if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
tmp=cmd->convert_src;
- cmd->convert_src &= TRIG_TIMER;
+ cmd->convert_src &= TRIG_TIMER|TRIG_EXT;
if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
/* note that mutual compatiblity is not an issue here */
if(cmd->scan_begin_src!=TRIG_TIMER &&
cmd->scan_begin_src!=TRIG_EXT)err++;
+ if(cmd->convert_src!=TRIG_TIMER &&
+ cmd->convert_src!=TRIG_EXT)err++;
if(err)return 2;
cmd->scan_begin_arg=boardtype.ai_speed;
err++;
}
- if(cmd->scan_begin_arg>TIMER_BASE*0xffff){ /* XXX */
- cmd->scan_begin_arg=TIMER_BASE*0xffff;
+ if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){
+ cmd->scan_begin_arg=TIMER_BASE*0xffffff;
err++;
}
}else{
/* external trigger */
/* should be level/edge, hi/lo specification here */
/* should specify multiple external triggers */
- if(cmd->scan_begin_arg!=0){
- cmd->scan_begin_arg=0;
+ if(cmd->scan_begin_arg>9){
+ cmd->scan_begin_arg=9;
err++;
}
}
- if(cmd->convert_arg<boardtype.ai_speed){
- cmd->convert_arg=boardtype.ai_speed;
- err++;
- }
- if(cmd->convert_arg>TIMER_BASE*0xffff){ /* XXX */
- cmd->convert_arg=TIMER_BASE*0xffff;
- err++;
+ if(cmd->convert_src==TRIG_TIMER){
+ if(cmd->convert_arg<boardtype.ai_speed){
+ cmd->convert_arg=boardtype.ai_speed;
+ err++;
+ }
+ if(cmd->convert_arg>TIMER_BASE*0xffff){
+ cmd->convert_arg=TIMER_BASE*0xffff;
+ err++;
+ }
+ }else{
+ /* external trigger */
+ /* see above */
+ if(cmd->convert_arg>9){
+ cmd->convert_arg=9;
+ err++;
+ }
}
if(cmd->scan_end_arg!=cmd->chanlist_len){
int wsave;
comedi_cmd *cmd=&s->cmd;
int timer;
+ int mode1=0; /* mode1 is needed for both stop and convert */
+ int mode2=0;
wsave = win_save();
/* stage number of scans */
win_out((cmd->stop_arg-1)>>16,AI_SC_Load_A_Registers);
win_out((cmd->stop_arg-1)&0xffff,AI_SC_Load_A_Registers+1);
+
+ mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
+ win_out(mode1,AI_Mode_1_Register);
/* load SC (Scan Count) */
- win_out(0x20,AI_Command_1_Register);
-
- win_out(0x000d,AI_Mode_1_Register);
+ win_out(AI_SC_Load,AI_Command_1_Register);
break;
case TRIG_NONE:
win_out(0,AI_SC_Load_A_Registers);
win_out(0,AI_SC_Load_A_Registers+1);
- /* load SC (Scan Count) */
- win_out(0x20,AI_Command_1_Register);
+ mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
+ win_out(mode1,AI_Mode_1_Register);
- win_out(0x000e,AI_Mode_1_Register);
+ /* load SC (Scan Count) */
+ win_out(AI_SC_Load,AI_Command_1_Register);
break;
}
timer=ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
win_out((timer>>16),AI_SI_Load_A_Registers);
win_out((timer&0xffff),AI_SI_Load_A_Registers+1);
+
/* AI_SI_Initial_Load_Source=A */
- win_out(0,AI_Mode_2_Register);
+ mode2 |= AI_SI_Initial_Load_Source&0;
+ win_out(mode2,AI_Mode_2_Register);
+
/* load SI */
- win_out(0x200,AI_Command_1_Register);
+ win_out(AI_SI_Load,AI_Command_1_Register);
/* stage freq. counter into SI B */
win_out((timer>>16),AI_SI_Load_B_Registers);
break;
case TRIG_EXT:
- win_out(AI_START_Edge|AI_START_Sync|AI_START_Select(1)|
+ win_out(AI_START_Edge|AI_START_Sync|
+ AI_START_Select(1+cmd->scan_begin_arg)|
AI_STOP_Select(19)|AI_STOP_Sync,
AI_START_STOP_Select_Register);
break;
}
- timer=ni_ns_to_timer(&cmd->convert_arg,TRIG_ROUND_NEAREST);
- win_out(timer,AI_SI2_Load_A_Register); /* 0,0 does not work. */
- win_out(timer,AI_SI2_Load_B_Register);
+ switch(cmd->convert_src){
+ case TRIG_TIMER:
+ timer=ni_ns_to_timer(&cmd->convert_arg,TRIG_ROUND_NEAREST);
+ win_out(timer,AI_SI2_Load_A_Register); /* 0,0 does not work. */
+ win_out(timer,AI_SI2_Load_B_Register);
- /* AI_SI2_Reload_Mode = alternate */
- /* AI_SI2_Initial_Load_Source = A */
- win_out(0x0100,AI_Mode_2_Register);
+ /* AI_SI2_Reload_Mode = alternate */
+ /* AI_SI2_Initial_Load_Source = A */
+ win_out((AI_SI2_Initial_Load_Source&0)|
+ (AI_SI2_Reload_Mode),
+ AI_Mode_2_Register);
- /* AI_SI2_Load */
- win_out(0x0800,AI_Command_1_Register);
+ /* AI_SI2_Load */
+ win_out(AI_SI2_Load,AI_Command_1_Register);
- /* AI_SI_Initial_Load_Source=0
- AI_SI_Reload_Mode(0)
- AI_SI2_Reload_Mode = alternate, AI_SI2_Initial_Load_Source = B */
- win_out(0x0300,AI_Mode_2_Register);
+ mode2 |= AI_SI_Reload_Mode(0);
+ mode2 |= 0&AI_SI_Initial_Load_Source;
+ mode2 |= AI_SI2_Reload_Mode; // alternate
+ mode2 |= AI_SI2_Initial_Load_Source; // B
+
+ win_out(mode2,AI_Mode_2_Register);
+
+ break;
+ case TRIG_EXT:
+ mode1 |= AI_CONVERT_Source_Select(1+cmd->convert_arg) |
+ AI_CONVERT_Source_Polarity |
+ AI_Start_Stop;
+ win_out(mode1,AI_Mode_1_Register);
+
+ win_out(mode2 | AI_SI2_Reload_Mode,AI_Mode_2_Register);
+
+ mode2 |= AI_SI_Reload_Mode(0);
+ mode2 |= 0&AI_SI_Initial_Load_Source;
+ mode2 |= AI_SI2_Reload_Mode; // alternate
+ mode2 |= AI_SI2_Initial_Load_Source; // B
+
+ win_out(mode2,AI_Mode_2_Register);
+
+ break;
+ }
if(dev->irq){
int bits;
/* interrupt on FIFO, errors, SC_TC */
- bits=0x00a1;
+ bits=AI_FIFO_Interrupt_Enable|
+ AI_Error_Interrupt_Enable|
+ AI_SC_TC_Interrupt_Enable;
- if(cmd->flags&TRIG_WAKE_EOS){
+ if(s->cb_mask&COMEDI_CB_EOS){
/* wake on end-of-scan */
devpriv->aimode=AIMODE_SCAN;
- }else if(s->cb_mask&COMEDI_CB_EOS){
- devpriv->aimode=AIMODE_SAMPLE;
}else{
devpriv->aimode=AIMODE_HALF_FULL;
}
/* AI_START1_Pulse */
win_out(AI_START1_Pulse,AI_Command_2_Register);
- devpriv->ai_n_chans = s->cur_trig.n_chan;
-#if 0
- /* XXX hack alert */
- s->cur_chan=s->cur_trig.n_chan*sizeof(sampl_t);
-#endif
-
win_restore(wsave);
return 0;
}
AI_SC_TC_Interrupt_Enable;
//bits|=Pass_Thru_0_Interrupt_Enable;
- if(it->flags&TRIG_WAKE_EOS){
+ if(s->cb_mask&COMEDI_CB_EOS){
/* wake on end-of-scan */
devpriv->aimode=AIMODE_SCAN;
- }else if(s->cb_mask&COMEDI_CB_EOS){
- devpriv->aimode=AIMODE_SAMPLE;
}else{
devpriv->aimode=AIMODE_HALF_FULL;
}
rt_printk("START1 pulse\n");
#endif
- /* XXX hack alert */
- s->cur_chan=s->cur_trig.n_chan*sizeof(sampl_t);
-
win_restore(wsave);
return 0;
}
/* interrupt on FIFO, errors, SC_TC */
bits=0x00a1;
- if(it->flags&TRIG_WAKE_EOS){
+ if(s->cb_mask&COMEDI_CB_EOS){
/* wake on end-of-scan */
devpriv->aimode=AIMODE_SCAN;
- }else if(s->cb_mask&COMEDI_CB_EOS){
- devpriv->aimode=AIMODE_SAMPLE;
}else{
devpriv->aimode=AIMODE_HALF_FULL;
}
/* AI_START1_Pulse */
win_out(AI_START1_Pulse,AI_Command_2_Register);
- /* XXX hack alert */
- s->cur_chan=s->cur_trig.n_chan*sizeof(sampl_t);
-
win_restore(wsave);
return 0;
}
*/
/*
- The real guts of the driver is in ni-E.c, which is included
- both here and in pcimio-E.c
-
-
- Interrupt support added by Truxton Fulton <trux@truxton.com>
+ The real guts of the driver is in ni_mio_common.c, which is
+ included by all the E series drivers.
References for specifications:
- 321747b.pdf Register Level Programmer Manual (obsolete)
- 321747c.pdf Register Level Programmer Manual (new)
- DAQ-STC reference manual
-
- Other possibly relevant info:
-
- 320517c.pdf User manual (obsolete)
- 320517f.pdf User manual (new)
- 320889a.pdf delete
- 320906c.pdf maximum signal ratings
- 321066a.pdf about 16x
- 321791a.pdf discontinuation of at-mio-16e-10 rev. c
- 321808a.pdf about at-mio-16e-10 rev P
- 321837a.pdf discontinuation of at-mio-16de-10 rev d
- 321838a.pdf about at-mio-16de-10 rev N
-
- ISSUES:
-
- need to deal with external reference for DAC, and other DAC
- properties in board properties
-
- deal with at-mio-16de-10 revision D to N changes, etc.
+ 341080a.pdf DAQCard E Series Register Level Programmer Manual
*/
static struct caldac_struct *type2[]={&caldac_dac8800,&caldac_dac8043,NULL};
static ni_board ni_boards[]={
- { device_id: 52,
+ { device_id: 0x010d,
name: "DAQCard-ai-16xe-50",
+ // This board apparently doesn't have DIO. Not accounted for.
n_adchan: 16,
adbits: 16,
ai_fifo_depth: 8192,
alwaysdither: 0,
gainlkup: ai_gain_16,
- ai_speed: 800,
+ ai_speed: 50000,
n_aochan: 0,
aobits: 0,
ao_fifo_depth: 0,
has_8255: 0,
caldac: type2,
},
- { device_id: 52,
+ { device_id: 0x0000,
name: "DAQCard-ai-16e-4",
n_adchan: 16,
adbits: 16,
ai_fifo_depth: 8192,
alwaysdither: 0,
gainlkup: ai_gain_16,
- ai_speed: 800,
+ ai_speed: 4000,
n_aochan: 0,
aobits: 0,
ao_fifo_depth: 0,
unsigned short gpct_input_select0;
unsigned short gpct_input_select1;
- unsigned int ai_n_chans;
- unsigned int ai_chanlistptr;
unsigned short ai_xorlist[512];
}ni_private;
#define devpriv ((ni_private *)dev->private)
printk(" %s",ni_boards[dev->board].name);
dev->board_name=ni_boards[dev->board].name;
+ dev->board_ptr = ni_boards+dev->board;
if( (ret=comedi_request_irq(dev->irq,ni_E_interrupt,NI_E_IRQ_FLAGS,"ni_mio_cs",dev))<0 ){
printk(" irq not available\n");
(CardServices(GetTupleData,handle,&tuple) == CS_SUCCESS)){
prodid = le16_to_cpu(buf[1]);
}
- //printk("manfid = 0x%04x, 0x%04x\n",manfid,prodid);
return prodid;
}
}
}
- return -1;
+ printk("unknown board -- pretend it is a ");
+
+ return 0;
}
unsigned short gpct_input_select0;
unsigned short gpct_input_select1;
- unsigned int ai_n_chans;
- unsigned int ai_chanlistptr;
unsigned short ai_xorlist[512];
}ni_private;
#define devpriv ((ni_private *)dev->private)
#define AO_START1_Pulse _bit0
#define DIO_Input_Register 7
+
#define AI_Command_1_Register 8
+#define AI_Analog_Trigger_Reset _bit14
+#define AI_Disarm _bit13
+#define AI_SI2_Arm _bit12
+#define AI_SI2_Load _bit11
+#define AI_SI_Arm _bit10
+#define AI_SI_Load _bit9
+#define AI_DIV_Arm _bit8
+#define AI_DIV_Load _bit7
+#define AI_SC_Arm _bit6
+#define AI_SC_Load _bit5
+#define AI_SCAN_IN_PROG_Pulse _bit4
+#define AI_EXTMUX_CLK_Pulse _bit3
+#define AI_LOCALMUX_CLK_Pulse _bit2
+#define AI_SC_TC_Pulse _bit1
+#define AI_CONVERT_Pulse _bit0
#define AO_Command_1_Register 9
#define AO_Analog_Trigger_Reset _bit15
#define DIO_Output_Register 10
#define DIO_Control_Register 11
+
#define AI_Mode_1_Register 12
+#define AI_CONVERT_Source_Select(a) ((a)<<11)
+#define AI_SI_Source_select(a) ((a)<<6)
+#define AI_CONVERT_Source_Polarity _bit5
+#define AI_Start_Stop _bit3
+#define AI_Mode_1_Reserved _bit2
+#define AI_Continuous _bit1
+#define AI_Trigger_Once _bit0
#define AI_Mode_2_Register 13
#define AI_SC_Gate_Enable _bit15
#define AI_Start_Stop_Gate_Enable _bit14
#define AI_Pre_Trigger _bit13
#define AI_External_MUX_Present _bit12
-#define AI_SI2_Ininial_Load_Source _bit9
+#define AI_SI2_Initial_Load_Source _bit9
#define AI_SI2_Reload_Mode _bit8
#define AI_SI_Initial_Load_Source _bit7
#define AI_SI_Reload_Mode(a) ((a)<<4)
#define AI_START_Select(a) (a)
#define AI_Trigger_Select_Register 63
+#define AI_START1_Polarity _bit15
+#define AI_START2_Polarity _bit14
+#define AI_START2_Sync _bit13
+#define AI_START2_Edge _bit12
+#define AI_START2_Select(a) ((a)<<7)
+#define AI_START1_Sync _bit6
+#define AI_START1_Edge _bit5
+#define AI_START1_Select(a) (a)
+
#define AO_Start_Select_Register 66
+#define AO_UI2_Software_Gate _bit15
+#define AO_UI2_External_Gate_Polarity _bit14
+#define AO_START_Polarity _bit13
+#define AO_AOFREQ_Enable _bit12
+#define AO_UI2_External_Gate_Select(a) ((a)<<7)
+#define AO_START_Sync _bit6
+#define AO_START_Edge _bit5
+#define AO_START_Select(a) (a)
#define AO_Trigger_Select_Register 67
#define AO_UI2_External_Gate_Enable _bit15