comedi_insn *insn,lsampl_t *data);
static int ni_gpctr_insn_config(comedi_device *dev,comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data);
-static int ni_gpctr_insn_bits(comedi_device *dev,comedi_subdevice *s,
- comedi_insn *insn,lsampl_t *data);
#undef DEBUG
s->insn_read= ni_gpctr_insn_read;
s->insn_write= ni_gpctr_insn_write;
s->insn_config=ni_gpctr_insn_config;
- s->insn_bits= ni_gpctr_insn_bits;
s->n_chan=2;
s->maxdata=1;
GPCTR_Reset(dev,0);
* it easier to access them.
*/
void GPCTR_Load_A(comedi_device *dev, int chan, long value){
- win_out( (value>>16) & 0x00ff, G_Load_A_Register_High(0));
- win_out( value & 0xffff, G_Load_A_Register_Low(0));
+ win_out( (value>>16) & 0x00ff, G_Load_A_Register_High(chan));
+ win_out( value & 0xffff, G_Load_A_Register_Low(chan));
}
void GPCTR_Load_B(comedi_device *dev, int chan, long value){
- win_out( (value>>16) & 0x00ff, G_Load_B_Register_High(0));
- win_out( value & 0xffff, G_Load_B_Register_Low(0));
+ win_out( (value>>16) & 0x00ff, G_Load_B_Register_High(chan));
+ win_out( value & 0xffff, G_Load_B_Register_Low(chan));
}
/* Load a value into the counter, using register A as the intermediate step.
devpriv->gpctr_mode[chan] &= (~G_Load_Source_Select);
win_out( devpriv->gpctr_mode[chan],G_Mode_Register(chan));
GPCTR_Load_A(dev,chan,value);
- win_out( devpriv->gpctr_mode[chan]|G_Load,G_Command_Register(chan));
-}
-
-/*
-* Begin simple event counting. This function should eventually do quadrature
-* encoding too.
-*/
-int GPCTR_Begin_Event_Counting(comedi_device *dev, int chan, int value) {
-
- GPCTR_Load_Using_A(dev, chan, value);
-
- devpriv->gpctr_mode[chan] |= G_Gating_Mode(1);
- devpriv->gpctr_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
- devpriv->gpctr_mode[chan] |= G_Gate_Polarity;
-
- devpriv->gpctr_input_select[chan] = 0; //reset it
- devpriv->gpctr_input_select[chan] |= G_Gate_Select(31);
-
-
- devpriv->gpctr_command[chan] = 0; //reset it
- devpriv->gpctr_command[chan] = G_Up_Down(1);
-
- win_out( devpriv->gpctr_mode[chan],G_Mode_Register(chan));
- win_out( devpriv->gpctr_command[chan],G_Command_Register(chan));
- win_out( devpriv->gpctr_input_select[chan],G_Input_Select_Register(chan));
-
- return 0;
+ win_out( devpriv->gpctr_command[chan]|G_Load,G_Command_Register(chan));
}
/* Don't use this by itself! The read is not atomic and quite unsafe.
void GPCTR_Disarm(comedi_device *dev, int chan){
- win_out( G_Disarm,G_Command_Register(chan));
+ win_out( devpriv->gpctr_command[chan] | G_Disarm,G_Command_Register(chan));
}
void GPCTR_Arm(comedi_device *dev, int chan){
- win_out( G_Arm,G_Command_Register(chan));
+ win_out( devpriv->gpctr_command[chan] | G_Arm,G_Command_Register(chan));
}
int GPCTR_Set_Source(comedi_device *dev,int chan ,int source){
printk("GPCTR_Set_Source...");
return -EINVAL;
}
win_out(devpriv->gpctr_input_select[chan], G_Input_Select_Register(chan));
- printk("exit GPCTR_Set_Source");
+ printk("exit GPCTR_Set_Source\n");
return 1;
}
int GPCTR_Set_Gate(comedi_device *dev,int chan ,int gate){
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:
+ printk("Error direction=0x%08x..",direction);
return -EINVAL;
}
win_out(devpriv->gpctr_command[chan], G_Command_Register(chan));
win_out(devpriv->gpctr_mode[chan], G_Mode_Register(chan));
printk("exit GPCTR_Set_Direction\n");
- return 1;
+ return 2;
}
void GPCTR_Event_Counting(comedi_device *dev,int chan) {
static int ni_gpctr_insn_config(comedi_device *dev,comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data)
{
+ //printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);
switch(data[0]){
case GPCTR_RESET:
if(insn->n!=1)return -EINVAL;
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);
+ switch(data[1]){
+ case GPCTR_SIMPLE_EVENT:
+ GPCTR_Event_Counting(dev,insn->chanspec);
+ break;
+ default:
+ printk("unsupported GPCTR operation!\n");
+ }
break;
case GPCTR_ARM:
if(insn->n!=1)return -EINVAL;
return -EINVAL;
}
- return 1;
+ return insn->n;
}
static int ni_gpctr_insn_read(comedi_device *dev,comedi_subdevice *s,
return 1;
}
-/*Error, the user insn_bits doesn't do anything for a counter. */
-static int ni_gpctr_insn_bits(comedi_device *dev,comedi_subdevice *s,
- comedi_insn *insn,lsampl_t *data) {
-
- return -EINVAL;
-}
-
//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);
EXPORT_SYMBOL(GPCTR_G_Watch);
-EXPORT_SYMBOL(GPCTR_Begin_Event_Counting);
EXPORT_SYMBOL(GPCTR_Arm);
EXPORT_SYMBOL(GPCTR_Disarm);
EXPORT_SYMBOL(GPCTR_Reset);
#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_OPERATION 12
-#define GPCTR_ARM 13
-#define GPCTR_DISARM 14
+#define GPCTR_RESET 0x0001
+#define GPCTR_SET_SOURCE 0x0002
+#define GPCTR_SET_GATE 0x0004
+#define GPCTR_SET_DIRECTION 0x0008
+#define GPCTR_SET_OPERATION 0x0010
+#define GPCTR_ARM 0x0020
+#define GPCTR_DISARM 0x0040
+
+#define GPCTR_INT_CLOCK 0x0001
+#define GPCTR_EXT_PIN 0x0002
+#define GPCTR_NO_GATE 0x0004
+#define GPCTR_UP 0x0008
+#define GPCTR_DOWN 0x0010
+#define GPCTR_HWUD 0x0020
+#define GPCTR_SIMPLE_EVENT 0x0040
+#define GPCTR_SINGLE_PERIOD 0x0080
+#define GPCTR_SINGLE_PW 0x0100
+#define GPCTR_CONT_PULSE_OUT 0x0200
+#define GPCTR_SINGLE_PULSE_OUT 0x0400
/* instructions */