From d1f9e8a9c19a73c27ce29e7f4824aeb758e9ad1f Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 23 May 2000 17:44:37 +0000 Subject: [PATCH] patch from Anders Blomdell --- comedi/Config.in | 1 + comedi/drivers.c | 3 + comedi/drivers/Makefile | 2 + comedi/drivers/ni_atmio.c | 14 ++ comedi/drivers/ni_atmio16d.c | 2 +- comedi/drivers/ni_mio_common.c | 240 ++++++++++++++++++++++++++++++++- comedi/drivers/ni_stc.h | 84 ++++++++---- 7 files changed, 317 insertions(+), 29 deletions(-) diff --git a/comedi/Config.in b/comedi/Config.in index 1714c959..21f8fedd 100644 --- a/comedi/Config.in +++ b/comedi/Config.in @@ -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' diff --git a/comedi/drivers.c b/comedi/drivers.c index f769a1a4..e1f6ce82 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -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 } diff --git a/comedi/drivers/Makefile b/comedi/drivers/Makefile index 9de4c479..f87ee31d 100644 --- a/comedi/drivers/Makefile +++ b/comedi/drivers/Makefile @@ -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 diff --git a/comedi/drivers/ni_atmio.c b/comedi/drivers/ni_atmio.c index ffb60364..475a45d8 100644 --- a/comedi/drivers/ni_atmio.c +++ b/comedi/drivers/ni_atmio.c @@ -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) diff --git a/comedi/drivers/ni_atmio16d.c b/comedi/drivers/ni_atmio16d.c index 6c8d175e..c43d54fd 100644 --- a/comedi/drivers/ni_atmio16d.c +++ b/comedi/drivers/ni_atmio16d.c @@ -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 */ diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index 648a87cc..d7306f85 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -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;in_chan;i++){ + mask=1<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); } } - diff --git a/comedi/drivers/ni_stc.h b/comedi/drivers/ni_stc.h index 899a1edf..613fe1f7 100644 --- a/comedi/drivers/ni_stc.h +++ b/comedi/drivers/ni_stc.h @@ -334,24 +334,26 @@ #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 @@ -359,34 +361,68 @@ #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; -- 2.26.2