patch from Anders Blomdell
authorDavid Schleef <ds@schleef.org>
Tue, 23 May 2000 17:44:37 +0000 (17:44 +0000)
committerDavid Schleef <ds@schleef.org>
Tue, 23 May 2000 17:44:37 +0000 (17:44 +0000)
comedi/Config.in
comedi/drivers.c
comedi/drivers/Makefile
comedi/drivers/ni_atmio.c
comedi/drivers/ni_atmio16d.c
comedi/drivers/ni_mio_common.c
comedi/drivers/ni_stc.h

index 1714c95935e46289e792f4b5bddf63b88e951c73..21f8feddc861193f4873bf00520f4fc90ab0aaa9 100644 (file)
@@ -74,6 +74,7 @@ tristate 'Advantech PCL-812PG, PCL-813B' CONFIG_COMEDI_PCL812
 tristate 'Analog Devices RTI-800/815' CONFIG_COMEDI_RTI800
 tristate 'Analog Devices RTI-802' CONFIG_COMEDI_RTI802
 tristate 'Intelligent Instrumentation PCI-20001C' CONFIG_COMEDI_II_PCI20KC
+tristate 'IOtech DaqBoard/2000' CONFIG_COMEDI_DAQBOARD2000
 
 if [ "$CONFIG_COMEDI_RT" = "y" ];then
        comment 'Virtual device drivers'
index f769a1a445db80fc67d487c86242366871b5d723..e1f6ce82327cf8c63e46c8e0980f4536655ba40e 100644 (file)
@@ -400,6 +400,9 @@ void init_drivers(void)
 #ifdef CONFIG_COMEDI_PCL812
        REG(driver_pcl812);
 #endif
+#ifdef CONFIG_COMEDI_DAQBOARD2000
+       REG(driver_daqboard2000);
+#endif
 #endif
 }
 
index 9de4c4794c614fd29da4932d9b3b86b7383137d8..f87ee31d477cd9bc9299bbef5383a30ef570113b 100644 (file)
@@ -15,6 +15,8 @@ obj-  :=
 
 obj-$(CONFIG_COMEDI_8255)              += 8255.o
 
+obj-$(CONFIG_COMEDI_DAQBOARD2000)      += daqboard2000.o
+
 obj-$(CONFIG_COMEDI_DAS08)             += das08.o
 obj-$(CONFIG_COMEDI_DAS08JR)           += das08jr.o
 obj-$(CONFIG_COMEDI_DAS16)             += das16.o
index ffb60364bb764ea01a1f2dc930a3b44deb97307f..475a45d86e79e3425efa972b47d93ffe258be51e 100644 (file)
@@ -99,6 +99,7 @@ static ni_board ni_boards[]={
                ao_fifo_depth:  2048,
                ao_unipolar:    1,
                has_8255:       0,
+               n_gpct:         0,
                caldac:         type1,
        },
        {       device_id:      25,
@@ -114,6 +115,7 @@ static ni_board ni_boards[]={
                ao_fifo_depth:  2048,
                ao_unipolar:    1,
                has_8255:       0,
+               n_gpct:         0,
                caldac:         type1,
        },
        {       device_id:      36,
@@ -129,6 +131,7 @@ static ni_board ni_boards[]={
                ao_fifo_depth:  0,
                ao_unipolar:    1,
                caldac:         type1,
+               n_gpct:         2,
                has_8255:       0,
        },
        {       device_id:      37,
@@ -144,6 +147,7 @@ static ni_board ni_boards[]={
                ao_fifo_depth:  0,
                ao_unipolar:    1,
                caldac:         type1,
+               n_gpct:         0,
                has_8255:       1,
        },
        {       device_id:      38,
@@ -159,6 +163,7 @@ static ni_board ni_boards[]={
                ao_fifo_depth:  2048,
                ao_unipolar:    1,
                has_8255:       0,
+               n_gpct:         0,
                caldac:         type1,
        },
        {       device_id:      39,
@@ -174,6 +179,7 @@ static ni_board ni_boards[]={
                ao_fifo_depth:  0,
                ao_unipolar:    0,
                caldac:         type2,
+               n_gpct:         0,
                has_8255:       0,
        },
        {       device_id:      50,
@@ -189,6 +195,7 @@ static ni_board ni_boards[]={
                ao_fifo_depth:  0,      /* unknown */
                ao_unipolar:    0,      /* unknown */
                caldac:         type2,
+               n_gpct:         0,
                has_8255:       0,
        },
        {       device_id:      51,
@@ -205,6 +212,7 @@ static ni_board ni_boards[]={
                aorangelkup:    0,
                ao_unipolar:    0,
                caldac:         type2,
+               n_gpct:         0,
                has_8255:       0,
        }
 };
@@ -253,6 +261,12 @@ typedef struct{
        unsigned short ao_cmd2;
        unsigned short ao_cmd3;
        unsigned short ao_trigger_select;
+       unsigned short gpct_mode0;
+       unsigned short gpct_mode1;
+       unsigned short gpct_command0;
+       unsigned short gpct_command1;
+       unsigned short gpct_input_select0;
+       unsigned short gpct_input_select1;
 }ni_private;
 #define devpriv ((ni_private *)dev->private)
 
index 6c8d175ea029a2d167aa12df7913be661ac140b2..c43d54fd26358370ef17f01d6957d06d189221d1 100644 (file)
@@ -60,7 +60,7 @@
 /* Analog Input Registers */
 #define MUX_CNTR_REG           0x04    /* wo 16 */
 #define MUX_GAIN_REG           0x06    /* wo 16 */
-#define AD_FIFO_REG                    0x16    /* ro 16 */
+#define AD_FIFO_REG            0x16    /* ro 16 */
 #define DMA_TC_INT_CLR_REG     0x16    /* wo 16 */
 /* AM9513A Counter/Timer Registers */
 #define AM9513A_DATA_REG       0x18    /* rw 16 */
index 648a87cc847201fb124e1b7ef0bbfe48d24fe58a..d7306f85b2db178b757ba6502b0b4bc16c6a6264 100644 (file)
@@ -158,6 +158,9 @@ static int ni_8255_callback(int dir,int port,int data,void *arg);
 
 static int ni_ns_to_timer(int *nanosec,int round_mode);
 
+static int gpct_setup(comedi_device *dev,comedi_subdevice *s);
+static int ni_gpct(comedi_device *dev,comedi_subdevice *s,comedi_trig *it);
+
 #undef DEBUG
 
 #define AIMODE_NONE            0
@@ -1418,6 +1421,46 @@ static int ni_dio(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
 }
 
 
+/*
+       HACK! 
+
+        general purpose timer counter (CLO)
+        This reads the value of the counter
+
+*/
+static int ni_gpct(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
+{
+       int data,mask;
+       int i;
+       int temp;
+
+       /* rt stuff */
+       temp=win_save();
+
+       if(it->flags & TRIG_CONFIG){
+               data=s->io_bits;
+               for(i=0;i<it->n_chan;i++){
+                       mask=1<<CR_CHAN(it->chanlist[i]);
+                       data&= ~mask;
+                       if(it->data[i])
+                               data|=mask;
+               }
+               s->io_bits=data;
+               win_out(s->io_bits,DIO_Control_Register);
+       }else{
+               if(it->flags & TRIG_WRITE){
+                       do_pack(&s->state,it);
+                       win_out(s->state,DIO_Output_Register);
+               }else{
+                       data=win_in(DIO_Input_Register);
+                       di_unpack(data,it);
+               }
+       }
+
+       win_restore(temp);
+
+       return it->n_chan;
+}
 
 
 static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
@@ -1490,10 +1533,17 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
        }
        /* XXX */
        
-       /* timer/counter device */
+       /* general purpose counter/timer device */
+       /* CLO */
        s=dev->subdevices+4;
-       s->type=COMEDI_SUBD_UNUSED;
-       s->trig[0]=NULL;
+       if(boardtype.n_gpct){
+           gpct_setup(dev,s);
+           s->type=COMEDI_SUBD_COUNTER;
+           s->trig[0]=ni_gpct;
+       }else{
+           s->type=COMEDI_SUBD_UNUSED;
+           s->trig[0]=NULL;
+       }
        /* XXX */
        
        /* calibration subdevice -- ai and ao */
@@ -1747,6 +1797,7 @@ static void pfi_setup(comedi_device *dev)
        win_out(IO_Bidirection_Pin_Register,0);
 }
 
+#endif
 
 
 /*
@@ -1758,6 +1809,187 @@ static void pfi_setup(comedi_device *dev)
 
 /* event counting */
 
+/*
+        Initialize the general purpose counter timers. (CLO)
+
+        Everything after the word HACK is a HACK because I don't
+        properly understand how to work within the comedi
+        architecture!
+
+ */
+int gpct_setup(comedi_device *dev,comedi_subdevice *s)
+{
+       unsigned short tmpreg;  /* For handling strobe writes */
+        unsigned short int msb, lsb;
+       unsigned short counter_init = 10000;
+
+        /* basic initialization of both counters, from section 4.6.1.3
+           of the DAQ-STC manul */
+
+       /* we track several write only register values in software */
+
+       /* G(i)_Reset = 1 (strobe) */
+       win_out(G0_Reset,Joint_Reset_Register);
+       win_out(G1_Reset,Joint_Reset_Register);
+
+       /* G(i)_Mode_Register = 0 */
+       devpriv->gpct_mode0 = 0x0000;
+       devpriv->gpct_mode1 = 0x0000;
+       win_out(devpriv->gpct_mode0,G_Mode_Register(0));
+       win_out(devpriv->gpct_mode1,G_Mode_Register(1));
+
+       /* G(i)_Command_Register = 0 */
+       devpriv->gpct_command0 = 0x0000;
+        devpriv->gpct_command1 = 0x0000;
+       win_out(devpriv->gpct_command0,G_Command_Register(0));
+       win_out(devpriv->gpct_command1,G_Command_Register(1));
+
+       /* G(i)_Input_Select_Register = 0 */
+       devpriv->gpct_input_select0 = 0x0000;
+       devpriv->gpct_input_select1 = 0x0000;
+       win_out(devpriv->gpct_input_select0,G_Input_Select_Register(0));
+       win_out(devpriv->gpct_input_select1,G_Input_Select_Register(1));
+
+       /* G(i)_Autoincrement = 0 (write) */
+       /* G(i)_Autoincrement_Register = 0 */
+       win_out(G_Autoincrement(0x00),G_Autoincrement_Register(0));
+       win_out(G_Autoincrement(0x00),G_Autoincrement_Register(1));
+
+       /* XXX - for now we ignore interrupts */
+       /* G(i)_TC_Interrupt_Enable = 0 (write)*/
+       /* G(i)_Gate_Interrupt_Enable = 0 (write) */
+       /* win_out(0x0000,Interrupt_A_Enable_Register); */
+       /* win_out(0x0000,Interrupt_B_Enable_Register); */
+
+       /* G(i)_Synchronized_Gate = 1 (write) */
+       devpriv->gpct_command0 |= G0_Synchronized_Gate;
+       devpriv->gpct_command1 |= G1_Synchronized_Gate;
+       win_out(devpriv->gpct_command0,G_Command_Register(0));
+       win_out(devpriv->gpct_command1,G_Command_Register(1));
+
+       /* XXX - for now we leave this in, but perhaps we could do without
+           if it causes problems elsewhere? */
+       /* G(i)_Gate_Error_Confirm = 1 (strobe) */
+       /* G(i)_TC_Error_Confirm = 1 (strobe) */
+       /* G(i)_TC_Interrupt_Ack = 1 (strobe) */
+       /* G(i)_Gate_Interrupt_Ack = 1 (strobe) */
+       win_out(G0_Gate_Error_Confirm|G0_TC_Error_Confirm|G0_TC_Interrupt_Ack|
+               G0_Gate_Interrupt_Ack,Interrupt_A_Ack_Register);
+       win_out(G1_Gate_Error_Confirm|G1_TC_Error_Confirm|G1_TC_Interrupt_Ack|
+               G1_Gate_Interrupt_Ack,Interrupt_B_Ack_Register);
+
+       /********************************************************************/
+
+       /* HACK - What follows is a hack.  This puts counter #0 in
+           "relative position sensing" mode and then arms it */
+  
+       /* G(i)_Load_Source_Select = 0 (write) */
+       devpriv->gpct_mode0 &= ~G0_Load_Source_Select;
+       win_out(devpriv->gpct_mode0,G_Mode_Register(0));
+
+       /* G(i)_Load_A = initial counter value (write) */
+       msb = counter_init>>16;
+       lsb = counter_init - msb;
+       win_out(msb,G_Load_A_Register_High(0));
+       win_out(lsb,G_Load_A_Register_Low(0));
+
+       /* FLUSH */
+
+       /* G(i)_Load = 1 (strobe) */
+       tmpreg = devpriv->gpct_command0 | G0_Load;
+       win_out(tmpreg,G_Command_Register(0));
+
+       /* FLUSH */
+
+       /* G(i)_Source_Select = PFI0 (write) */
+       devpriv->gpct_input_select0 &= (0xffff & G_Source_Select(0x00));
+       devpriv->gpct_input_select0 |= G_Source_Select(0x01);
+
+       /* G(i)_Source_Polarity = 0 (count rising edges) (write) */
+       devpriv->gpct_input_select0 &= ~G0_Source_Polarity;
+
+       /* G(i)_Gate_select = 0 (write) */
+       devpriv->gpct_input_select0 &= (0xffff & G_Gate_Select(0x00));
+       devpriv->gpct_input_select0 |= G_Gate_Select(0x00);
+
+       /* G(i)_OR_Gate = 0 (write) */
+       devpriv->gpct_input_select0 &= ~G0_OR_Gate;
+
+       /* G(i)_Output_Polarity = 0 (write) */
+       devpriv->gpct_input_select0 &= ~G0_Output_Polarity;
+
+       /* G(i)_Gate_Select_Load_Source = 0 (write) */
+       devpriv->gpct_input_select0 &= ~G0_Gate_Select_Load_Source;
+
+       /* G(i)_Gate_Polarity = 0 (write) */
+       devpriv->gpct_mode0 &= ~G0_Gate_Polarity;
+
+       /* G(i)_Output_Mode = 1 (one clock cycle output) (write) */
+       devpriv->gpct_mode0 &= (0xffff & G_Output_Mode(0x00));
+       devpriv->gpct_mode0 |= G_Output_Mode(0x01);
+
+       /* G(i)_Reload_Source_Switching = 1 (write) */
+       devpriv->gpct_mode0 |= G0_Reload_Source_Switching;
+
+       /* G(i)_Loading_On_Gate = 0 (write) */
+       devpriv->gpct_mode0 &= ~G0_Loading_On_Gate;
+
+       /* G(i)_Gating_Mode = 2 (write) */
+       devpriv->gpct_mode0 &= (0xffff & G_Gating_Mode(0x00));
+       devpriv->gpct_mode0 |= G_Gating_Mode(0x02);
+
+       /* G(i)_Gate_On_Both_Edges = 0 (write) */
+       devpriv->gpct_mode0 &= ~G0_Gate_On_Both_Edges;
+
+       /* G(i)_Trigger_Mode_For_Edge_Gate = 3 (write) */
+       devpriv->gpct_mode0 &= (0xffff & G_Trigger_Mode_For_Edge_Gate(0x00));
+       devpriv->gpct_mode0 |= G_Trigger_Mode_For_Edge_Gate(0x03);
+
+       /* G(i)_Stop_Mode = 0 */
+       devpriv->gpct_mode0 &= (0xffff & G0_Stop_Mode(0x00));
+       devpriv->gpct_mode0 |= G0_Stop_Mode(0x00);
+
+       /* G(i)_Counting_Once = 0 (write) */
+       devpriv->gpct_mode0 &= (0xffff & G0_Counting_Once(0x00));
+       devpriv->gpct_mode0 |= G0_Counting_Once(0x00);
+
+       /* G(i)_Up_Down = 2 (hardware controlled) (write) */
+       devpriv->gpct_command0 &= (0xffff & G_Up_Down(0x00));
+       devpriv->gpct_command0 |= G_Up_Down(0x02);
+
+       /* G(i)_Bank_Switch_Enable = 0 (write) */
+       devpriv->gpct_command0 &= ~G0_Bank_Switch_Enable;
+
+       /* G(i)_Bank_Switch_Mode = 0 (write) */
+       devpriv->gpct_command0 &= ~G0_Bank_Switch_Mode;
+
+       /* XXX - for now we ignore interrupts */
+       /* G(i)_TC_Interrupt_Enable = 0 (write) */
+       /* win_out(0x0000,Interrupt_A_Enable_Register); */
+
+       /* XXX - for now we ignore interrupts */
+       /* G(i)_Gate_Interrupt_Enable = 0 (write) */
+       /* win_out(0x0000,Interrupt_A_Enable_Register); */
+
+       /* actually write out the registers */
+       win_out(devpriv->gpct_input_select0,G_Input_Select_Register(0));
+       win_out(devpriv->gpct_mode0,G_Mode_Register(0));
+       win_out(devpriv->gpct_command0,G_Command_Register(0));
+
+       /********************************************************************/
+
+       /* HACK - What follows continues my hack of configuring the
+           counter in a specific mode.  Arming the counter instructs
+           it to start running with our configuration */
+
+       /* Arm the counter 0 (stobe) */
+       tmpreg = devpriv->gpct_command0 | G0_Arm;
+       win_out(tmpreg,G_Command_Register(0));
+
+       return 0;
+}
+
+#if 0
 int gpct_start(comedi_device *dev,int chan)
 {
        /* select load source */
@@ -1831,7 +2063,6 @@ static int gpct_sp(comedi_device *dev,comedi_param *it)
        }
        return -EINVAL;
 }
-
 #endif
 
 static int ni_8255_callback(int dir,int port,int data,void *arg)
@@ -1845,4 +2076,3 @@ static int ni_8255_callback(int dir,int port,int data,void *arg)
                return ni_readb(25+2*port);
        }
 }
-
index 899a1edf12348f02721f93c503872502e7e7a567..613fe1f7ba9251bb5bb9c9865e62a5f1d8cc12dc 100644 (file)
 
 #define G_Autoincrement_Register(a)    (68+(a))
 #define G_Command_Register(a)          (6+(a))
-#define G_HW_Save_Register1(a)         (8+(a)*2)
-#define G_HW_Save_Register2(a)         (9+(a)*2)
+#define G_HW_Save_Register_High(a)     (8+(a)*2)
+#define G_HW_Save_Register_Low(a)      (9+(a)*2)
 #define G_Input_Select_Register(a)     (36+(a))
-#define G_Load_A_Register1(a)          (28+(a)*4)
-#define G_Load_A_Register2(a)          (29+(a)*4)
-#define G_Load_B_Register1(a)          (30+(a)*4)
-#define G_Load_B_Register2(a)          (31+(a)*4)
+#define G_Load_A_Register_High(a)      (28+(a)*4)
+#define G_Load_A_Register_Low(a)       (29+(a)*4)
+#define G_Load_B_Register_High(a)      (30+(a)*4)
+#define G_Load_B_Register_Low(a)       (31+(a)*4)
 #define G_Mode_Register(a)             (26+(a))
-#define G_Save_Register1(a)            (12+(a)*2)
-#define G_Save_Register2(a)            (13+(a)*2)
+#define G_Save_Register_High(a)                (12+(a)*2)
+#define G_Save_Register_Low(a)         (13+(a)*2)
 #define G_Status_Register              4
 
 /* command register */
 #define G_Disarm_Copy                  _bit15          /* strobe */
 #define G_Save_Trace_Copy              _bit14
 #define G_Arm_Copy                     _bit13          /* strobe */
-#define G_Bank_Switch_Enable           _bit12
-#define G_Bank_Switch_Mode             _bit11
+#define G0_Bank_Switch_Enable          _bit12
+#define G1_Bank_Switch_Enable          _bit12
+#define G0_Bank_Switch_Mode            _bit11
+#define G1_Bank_Switch_Mode            _bit11
 #define G_Bank_Switch_Start            _bit10          /* strobe */
 #define G_Little_Big_Endian            _bit9
 #define G_Synchronized_Gate            _bit8
 #define G_Up_Down(a)                   (((a)&0x03)<<5)
 #define G_Disarm                       _bit4           /* strobe */
 #define G_Analog_Trigger_Reset         _bit3           /* strobe */
-#define G_Load                         _bit2           /* strobe */
+#define G0_Load                                _bit2           /* strobe */
+#define G1_Load                                _bit2           /* strobe */
 #define G_Save_Trace                   _bit1
 #define G_Arm                          _bit0           /* strobe */
 
 /* input select register */
-#define G_Source_Polarity              _bit15
-#define G_Output_Polarity              _bit14
-#define G_OR_Gate                      _bit13
-#define G_Gate_Select_Load_Source      _bit12
+#define G0_Source_Polarity             _bit15
+#define G1_Source_Polarity             _bit15
+#define G0_Output_Polarity             _bit14
+#define G1_Output_Polarity             _bit14
+#define G0_OR_Gate                     _bit13
+#define G1_OR_Gate                     _bit13
+#define G0_Gate_Select_Load_Source     _bit12
+#define G1_Gate_Select_Load_Source     _bit12
 #define G_Gate_Select(a)               (((a)&0x1f)<<7)
 #define G_Source_Select(a)             (((a)&0x1f)<<2)
 #define G_Write_Acknowledges_Irq       _bit1
 #define G_Read_Acknowledges_Irq                _bit0
 
 /* mode register */
-#define G_Reload_Source_Switching      _bit15
-#define G_Loading_On_Gate              _bit14
-#define G_Gate_Polarity                        _bit13
+#define G0_Load_Source_Select          _bit7
+#define G1_Load_Source_Select          _bit7
+
+#define G0_Reload_Source_Switching     _bit15
+#define G1_Reload_Source_Switching     _bit15
+#define G0_Loading_On_Gate             _bit14
+#define G1_Loading_On_Gate             _bit14
+#define G0_Gate_Polarity               _bit13
+#define G1_Gate_Polarity               _bit13
 #define G_Loading_On_TC                        _bit12
-#define G_Counting_Once(a)             (((a)&0x03)<<10)
+#define G0_Counting_Once(a)            (((a)&0x03)<<10)
+#define G1_Counting_Once(a)            (((a)&0x03)<<10)
 #define G_Output_Mode(a)               (((a)&0x03)<<8)
-#define G_Load_Source_Select           _bit7
-#define G_Stop_Mode(a)                 (((a)&0x03)<<5)
+#define G0_Stop_Mode(a)                        (((a)&0x03)<<5)
+#define G1_Stop_Mode(a)                        (((a)&0x03)<<5)
 #define G_Trigger_Mode_For_Edge_Gate(a)        (((a)&0x03)<<3)
-#define G_Gate_On_Both_Edges           _bit1
+#define G0_Gate_On_Both_Edges          _bit1
+#define G1_Gate_On_Both_Edges          _bit1
 #define G_Gating_Mode(a)               (((a)&0x03)<<0)
 
-
+/* CLO */
+/* general purpose counter timer */
+#define G0_Reset                        _bit2
+#define G1_Reset                        _bit3
+#define G0_TC_Interrupt_Enable          _bit6
+#define G1_TC_Interrupt_Enable          _bit9
+#define G0_Gate_Interrupt_Enable        _bit8
+#define G1_Gate_Interrupt_Enable        _bit10
+#define G0_Synchronized_Gate            _bit8
+#define G1_Synchronized_Gate            _bit8
+#define G0_Gate_Error_Confirm           _bit5
+#define G1_Gate_Error_Confirm           _bit1
+#define G0_TC_Error_Confirm             _bit6
+#define G1_TC_Error_Confirm             _bit2
+#define G0_TC_Interrupt_Ack             _bit14
+#define G1_TC_Interrupt_Ack             _bit14
+#define G0_Gate_Interrupt_Ack           _bit15
+#define G1_Gate_Interrupt_Ack           _bit15
+#define G_Autoincrement(a)              ((a)<<0)
+#define G_Autoincrement(a)              ((a)<<0)
+#define G0_Arm                          _bit0
+#define G1_Arm                          _bit0
 
 /* Additional windowed registers unique to E series */
 
@@ -457,6 +493,8 @@ typedef struct ni_board_struct{
        
        int has_8255;
 
+        int n_gpct;            /* CLO */
+
        struct caldac_struct **caldac;
 }ni_board;