started adding an insn interface to GPCTRs.
authorTim Ousley <tim.ousley@ni.com>
Wed, 18 Apr 2001 20:57:09 +0000 (20:57 +0000)
committerTim Ousley <tim.ousley@ni.com>
Wed, 18 Apr 2001 20:57:09 +0000 (20:57 +0000)
comedi/drivers/ni_mio_common.c
include/linux/comedi.h

index 64290c77833622aafb67a140b192d64cb2ddd485..9335ab5bd3fb375810ed072d0f434c8d74a89929 100644 (file)
@@ -2503,6 +2503,77 @@ void GPCTR_Disarm(comedi_device *dev, int chan){
 void GPCTR_Arm(comedi_device *dev, int chan){
        win_out( G_Arm,G_Command_Register(chan));
 }
+int GPCTR_Set_Source(comedi_device *dev,int chan ,int source){
+       devpriv->gpctr_input_select[chan] &= ~G_Source_Select(0x1f);//reset gate to 0
+       switch(source) {\r       case GPCTR_INT_CLOCK:
+               devpriv->gpctr_input_select[chan] |= G_Source_Select(0);//INT_TIMEBASE
+               break;
+       case GPCTR_EXT_PIN:
+               if(chan==0)
+                       devpriv->gpctr_input_select[chan] |= G_Source_Select(9);//PFI8
+               else
+                       devpriv->gpctr_input_select[chan] |= G_Source_Select(4);//PFI3
+               break;
+       default:
+               return -EINVAL;
+       }
+       win_out(devpriv->gpctr_input_select[chan], G_Input_Select_Register(chan));
+       return 1;
+}
+int GPCTR_Set_Gate(comedi_device *dev,int chan ,int gate){
+       devpriv->gpctr_input_select[chan] &= ~G_Gate_Select(0x1f);//reset gate to 0
+       switch(gate) {\r case GPCTR_NO_GATE:
+               devpriv->gpctr_input_select[chan] |= G_Gate_Select(31);//Low
+               devpriv->gpctr_mode[chan] |= G_Gate_Polarity;
+               break;
+       case GPCTR_EXT_PIN:
+               devpriv->gpctr_mode[chan] &= ~G_Gate_Polarity;
+               if(chan==0)
+                       devpriv->gpctr_input_select[chan] |= G_Gate_Select(10);//PFI9
+               else
+                       devpriv->gpctr_input_select[chan] |= G_Gate_Select(5);//PFI4
+               break;
+       default:
+               return -EINVAL;
+       }
+       win_out(devpriv->gpctr_input_select[chan], G_Input_Select_Register(chan));
+       win_out(devpriv->gpctr_mode[chan], G_Mode_Register(chan));
+       return 1;
+}
+
+
+int GPCTR_Set_Direction(comedi_device *dev,int chan,int direction) {
+       devpriv->gpctr_command[chan] &= ~G_Up_Down(0x3);
+       switch (direction) {
+               case GPCTR_UP:
+                       devpriv->gpctr_command[chan] |= G_Up_Down(1);
+                       break;
+               case GPCTR_DOWN:
+                       devpriv->gpctr_command[chan] |= G_Up_Down(0);
+                       break;
+               case GPCTR_HWUD:
+                       devpriv->gpctr_command[chan] |= G_Up_Down(2);
+                       break;
+               case GPCTR_INV_HWUD:
+                       devpriv->gpctr_command[chan] |= G_Up_Down(2);
+                       devpriv->gpctr_mode[chan] |= G_Gate_Polarity;
+                       break;
+               default:
+                       return -EINVAL;
+       }
+       win_out(devpriv->gpctr_command[chan], G_Command_Register(chan));
+       win_out(devpriv->gpctr_mode[chan], G_Mode_Register(chan));
+       return 1;
+}
+
+void GPCTR_Event_Counting(comedi_device *dev,int chan) {
+       
+       devpriv->gpctr_mode[chan] |= G_Gating_Mode(1);
+       devpriv->gpctr_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
+
+       win_out( devpriv->gpctr_mode[chan],G_Mode_Register(chan));
+}
+
 void GPCTR_Reset(comedi_device *dev, int chan){
        unsigned long irqflags;
        int temp_ack_reg=0;
@@ -2546,6 +2617,53 @@ void GPCTR_Reset(comedi_device *dev, int chan){
        win_out( devpriv->gpctr_input_select[chan],G_Input_Select_Register(chan));
        win_out( 0,G_Autoincrement_Register(chan)); 
 }
+
+static int ni_gpctr_insn_config(comedi_device *dev,comedi_subdevice *s,
+       comedi_insn *insn,lsampl_t *data)
+{
+       switch(data[0]){
+       case GPCTR_RESET:
+               if(insn->n!=1)return -EINVAL;
+               GPCTR_Reset(dev,insn->chanspec);
+               break;
+       case GPCTR_SET_SOURCE:
+               if(insn->n!=2)return -EINVAL;
+               GPCTR_Set_Source(dev,insn->chanspec,data[1]);
+               break;
+       case GPCTR_SET_GATE:
+               if(insn->n!=2)return -EINVAL;
+               GPCTR_Set_Gate(dev,insn->chanspec,data[1]);
+               break;
+       case GPCTR_SET_DIRECTION:
+               if(insn->n!=2)return -EINVAL;
+               GPCTR_Set_Direction(dev,insn->chanspec,data[1]);
+               break;
+       case GPCTR_SET_VALUE:
+               if(insn->n!=2)return -EINVAL;
+               GPCTR_Load_Using_A(dev,insn->chanspec,data[1]);
+               break;
+       case GPCTR_SET_OPERATION:
+               if(insn->n!=2)return -EINVAL;
+                       //there should be a second switch statement here
+                       //to choose the operation
+               GPCTR_Event_Counting(dev,insn->chanspec);
+               break;
+       case GPCTR_ARM:
+               if(insn->n!=1)return -EINVAL;
+               GPCTR_Arm(dev,insn->chanspec);
+               break;
+       case GPCTR_DISARM:
+               if(insn->n!=1)return -EINVAL;
+               GPCTR_Disarm(dev,insn->chanspec);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 1;
+}
+
+
 //note: EXPORT_SYMTAB must have been defined for this to work.
 //this is mostly for testing inside the kernel
 EXPORT_SYMBOL(GPCTR_Load_Using_A);
@@ -2557,14 +2675,6 @@ EXPORT_SYMBOL(GPCTR_Reset);
 
 #endif
 
-/*
-*  This is code from the EDAQ driver NI used to recommend for Linux, I'm using it
-* as a reference to build new GPCTR functions.  Some of it is from the E series RLPM.
-* Ignore the code in the #if 0...#endif
-*
-*/
-#if 0
-#endif
 
 static int ni_8255_callback(int dir,int port,int data,void *arg)
 {
index 81f51bfbf81967af6bb94ac12f3773f7c458efe7..4e2568b33c49fad6408b1bf1c95c761280010f16 100644 (file)
@@ -62,6 +62,24 @@ typedef unsigned short sampl_t;
 #define AREF_DIFF      0x02            /* analog ref = differential */
 #define AREF_OTHER     0x03            /* analog ref = other (undefined) */
 
+/* counters -- these are arbitrary values */
+#define GPCTR_INT_CLOCK                1
+#define GPCTR_EXT_PIN          2
+#define GPCTR_NO_GATE          3
+#define GPCTR_UP               4
+#define GPCTR_DOWN             5
+#define GPCTR_HWUD             6
+#define GPCTR_INV_HWUD         7
+#define GPCTR_RESET            8
+#define GPCTR_SET_SOURCE       9
+#define GPCTR_SET_GATE         10
+#define GPCTR_SET_DIRECTION    11
+#define GPCTR_SET_VALUE                12
+#define GPCTR_SET_OPERATION    13
+#define GPCTR_ARM              14
+#define GPCTR_DISARM           15
+
+
 /* instructions */
 
 #define INSN_MASK_WRITE                0x8000000