From a659687019ba9d9be4e065a735c6a8716bdfa08a Mon Sep 17 00:00:00 2001 From: Tim Ousley Date: Fri, 27 Apr 2001 16:00:05 +0000 Subject: [PATCH] insn based counter/timer operations now work, including event counting, period and pulse width measurement, single and continuous pulse generation, and quadrature encoder reading --- comedi/drivers/ni_mio_common.c | 95 +++++++++++++++++++++++++--------- comedi/drivers/ni_stc.h | 8 +++ 2 files changed, 79 insertions(+), 24 deletions(-) diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index 49109123..c8d722c6 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -2475,7 +2475,6 @@ int inline GPCTR_G_Read(comedi_device *dev, int chan) { */ int GPCTR_G_Watch(comedi_device *dev, int chan) { int save1,save2; - int temp; devpriv->gpctr_command[chan] &= ~G_Save_Trace; win_out( devpriv->gpctr_command[chan],G_Command_Register(chan)); @@ -2490,13 +2489,6 @@ int GPCTR_G_Watch(comedi_device *dev, int chan) { if (save1 != save2) { save1 = GPCTR_G_Read(dev,chan); } - - //TIM 4/26/01 debugginh - temp = win_in(Joint_Status_2_Register); - printk("JSR2 = 0x%04x\n",temp); - - - return save1; } @@ -2712,23 +2704,14 @@ void GPCTR_Pulse_Width_Meas(comedi_device *dev, int chan){ //printk("exit GPCTR_Pulse_Width_Meas\n"); } -/* The Gate acts as a trigger */ -void GPCTR_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length){ - int temp; - - printk("GPCTR_Gen_Cont..."); +/* GPCTR_Gen_Single_Pulse() creates pulse of length pulsewidth which starts after the Arm +signal is sent. The pulse is delayed by the value already in the counter. This function could +be modified to send a pulse in response to a trigger event at its gate.*/ +void GPCTR_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length){ + //printk("GPCTR_Gen_Cont..."); devpriv->gpctr_cur_operation[chan] = GPCTR_SINGLE_PULSE_OUT; - //TIM 4/26/01 check current counter value... - //This appears to work correctly, except that the output value does - //not propogate to the output pin. This is done in Analog_Trigger_Etc_Register - //which isn't #def'd yet... - temp = GPCTR_G_Watch(dev,chan); - printk("current counter value is %d\n",temp); - temp = win_in(Joint_Status_2_Register); - printk("JSR2 = 0x%04x\n",temp); - // Set length of the pulse GPCTR_Load_B(dev,chan, length-1); @@ -2771,7 +2754,64 @@ void GPCTR_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length){ win_out( devpriv->gpctr_mode[chan],G_Mode_Register(chan)); win_out( devpriv->gpctr_command[chan],G_Command_Register(chan)); - printk("exit GPCTR_Gen_Cont\n"); + //printk("exit GPCTR_Gen_Cont\n"); +} + +void GPCTR_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length){ + //printk("GPCTR_Gen_Cont..."); + + devpriv->gpctr_cur_operation[chan] = GPCTR_CONT_PULSE_OUT; + + // Set length of the pulse + GPCTR_Load_B(dev,chan, length-1); + + //Load next time using B, This is reset by GPCTR_Load_Using_A() + devpriv->gpctr_mode[chan] |= G_Load_Source_Select; + + devpriv->gpctr_mode[chan] &= ~G_OR_Gate; + devpriv->gpctr_mode[chan] &= ~G_Gate_Select_Load_Source; + + // Output_Mode = 3 + devpriv->gpctr_mode[chan] &= ~(G_Output_Mode(0x3)); + devpriv->gpctr_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3 + + //Gating Mode=0 for untriggered single pulse + devpriv->gpctr_mode[chan] &= ~(G_Gating_Mode(0x3)); + devpriv->gpctr_mode[chan] |= G_Gating_Mode(0); //TIM 4/26/01 was 0 + + // Trigger_Mode_For_Edge_Gate=0 + devpriv->gpctr_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3)); + devpriv->gpctr_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2); + + + devpriv->gpctr_mode[chan] |= G_Reload_Source_Switching; + devpriv->gpctr_mode[chan] &= ~G_Loading_On_Gate; + devpriv->gpctr_mode[chan] |= G_Loading_On_TC; + devpriv->gpctr_mode[chan] &= ~G_Gate_On_Both_Edges; + + // Stop_Mode = 2 + devpriv->gpctr_mode[chan] &= ~(G_Stop_Mode(0x3)); + devpriv->gpctr_mode[chan] |= G_Stop_Mode(0); //TIM 4/26/01 + + // Counting_Once = 2 + devpriv->gpctr_mode[chan] &= ~(G_Counting_Once(0x3)); + devpriv->gpctr_mode[chan] |= G_Counting_Once(0); //TIM 4/26/01 + + // Up_Down = 1 + devpriv->gpctr_command[chan] &= ~(G_Up_Down(0x3)); + devpriv->gpctr_command[chan] |= G_Up_Down(0); + + //TIM 4/26/01 + //This seems pretty unsafe since I don't think it is cleared anywhere. + //I don't think this is working + //devpriv->gpctr_command[chan] &= ~G_Bank_Switch_Enable; + //devpriv->gpctr_command[chan] &= ~G_Bank_Switch_Mode; + + + win_out( devpriv->gpctr_mode[chan],G_Mode_Register(chan)); + win_out( devpriv->gpctr_command[chan],G_Command_Register(chan)); + + //printk("exit GPCTR_Gen_Cont\n"); } void GPCTR_Reset(comedi_device *dev, int chan){ @@ -2795,6 +2835,9 @@ void GPCTR_Reset(comedi_device *dev, int chan){ temp_ack_reg |= G1_TC_Interrupt_Ack; temp_ack_reg |= G0_Gate_Interrupt_Ack; win_out(temp_ack_reg,Interrupt_A_Ack_Register); + + win_out(GPFO_0_Output_Enable|GPFO_0_Output_Select(0), + Analog_Trigger_Etc_Register); break; case 1: win_out(G1_Reset,Joint_Reset_Register); @@ -2807,6 +2850,8 @@ void GPCTR_Reset(comedi_device *dev, int chan){ temp_ack_reg |= G1_TC_Interrupt_Ack; temp_ack_reg |= G1_Gate_Interrupt_Ack; win_out(temp_ack_reg,Interrupt_B_Ack_Register); + + win_out(GPFO_1_Output_Enable, Analog_Trigger_Etc_Register); break; }; @@ -2860,6 +2905,9 @@ static int ni_gpctr_insn_config(comedi_device *dev,comedi_subdevice *s, case GPCTR_SINGLE_PULSE_OUT: GPCTR_Gen_Single_Pulse(dev,insn->chanspec,data[2]); break; + case GPCTR_CONT_PULSE_OUT: + GPCTR_Gen_Cont_Pulse(dev,insn->chanspec,data[2]); + break; default: printk("unsupported GPCTR operation!\n"); return -EINVAL; @@ -2867,7 +2915,6 @@ static int ni_gpctr_insn_config(comedi_device *dev,comedi_subdevice *s, break; case GPCTR_ARM: if(insn->n!=1)return -EINVAL; - printk("arming...\n"); //TIM 4/26/01 debugging retval=GPCTR_Arm(dev,insn->chanspec); break; case GPCTR_DISARM: diff --git a/comedi/drivers/ni_stc.h b/comedi/drivers/ni_stc.h index 2f230207..d3d04ee3 100644 --- a/comedi/drivers/ni_stc.h +++ b/comedi/drivers/ni_stc.h @@ -410,6 +410,7 @@ #define G_Save_Register_High(a) (12+(a)*2) #define G_Save_Register_Low(a) (13+(a)*2) #define G_Status_Register 4 +#define Analog_Trigger_Etc_Register 61 /* command register */ #define G_Disarm_Copy _bit15 /* strobe */ @@ -502,6 +503,13 @@ #define G0_Arm _bit0 #define G1_Arm _bit0 +/*Analog_Trigger_Etc_Register*/ +/*This is mainly a counter/timer register */ +#define GPFO_1_Output_Enable _bit15 +#define GPFO_0_Output_Enable _bit14 +#define GPFO_0_Output_Select(a) ((a)<<11) +#define GPFO_1_Output_Select _bit7 + /* Additional windowed registers unique to E series */ #define Configuration_Memory_Clear 82 -- 2.26.2