quadrature encoder counting with NI M-series boards.
case INSN_CONFIG_GET_GATE_SRC:
case INSN_CONFIG_SET_CLOCK_SRC:
case INSN_CONFIG_GET_CLOCK_SRC:
+ case INSN_CONFIG_SET_OTHER_SRC:
case INSN_CONFIG_GET_COUNTER_STATUS:
if(insn->n == 3) return 0;
break;
case NITIO_G1_Second_Gate_Reg:
ni_writew(bits, M_Offset_G1_Second_Gate);
break;
+ case NITIO_G0_ABZ_Reg:
+ ni_writew(bits, M_Offset_G0_MSeries_ABZ);
+ break;
+ case NITIO_G1_ABZ_Reg:
+ ni_writew(bits, M_Offset_G1_MSeries_ABZ);
+ break;
+
/* 32 bit registers */
case NITIO_G0_LoadA_Reg:
case NITIO_G1_LoadA_Reg:
return 0;
}
+static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index)
+{
+ switch(counter_index)
+ {
+ case 0:
+ return NITIO_G0_ABZ_Reg;
+ break;
+ case 1:
+ return NITIO_G1_ABZ_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
enum Gi_Auto_Increment_Reg_Bits
{
Gi_Auto_Increment_Mask = 0xff
return 0;
}
+static int ni_tio_set_other_src(struct ni_gpct *counter,
+ unsigned index, lsampl_t source)
+{
+ if (counter->variant == ni_gpct_variant_m_series &&
+ (index == NI_GPCT_SOURCE_ENCODER_A ||
+ index == NI_GPCT_SOURCE_ENCODER_B ||
+ index == NI_GPCT_SOURCE_ENCODER_Z)) {
+ unsigned int abz_reg, shift, mask;
+ abz_reg = NITIO_Gi_ABZ_Reg(counter->counter_index);
+
+ switch(index) {
+ case NI_GPCT_SOURCE_ENCODER_A:
+ shift = 10;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_B:
+ shift = 5;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_Z:
+ shift = 0;
+ break;
+ }
+ mask = 0x1f << shift;
+ if (source > 0x1f) {
+ /* Disable gate */
+ source = 0x1f;
+ }
+ counter->regs[abz_reg] &= ~mask;
+ counter->regs[abz_reg] |= source << shift;
+ counter->write_register(counter, counter->regs[abz_reg], abz_reg);
+ printk("%s %x %d %d\n", __FUNCTION__, counter->regs[abz_reg], index, source);
+ return 0;
+ }
+ return -EINVAL;
+}
+
static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned ni_660x_gate_select)
{
unsigned i;
case INSN_CONFIG_GET_GATE_SRC:
return ni_tio_get_gate_src(counter, data[1], &data[2]);
break;
+ case INSN_CONFIG_SET_OTHER_SRC:
+ return ni_tio_set_other_src(counter, data[1], data[2]);
+ break;
case INSN_CONFIG_RESET:
ni_tio_reset_count_and_disarm(counter);
return 0;
NITIO_G1_DMA_Status_Reg,
NITIO_G2_DMA_Status_Reg,
NITIO_G3_DMA_Status_Reg,
+ NITIO_G0_ABZ_Reg,
+ NITIO_G1_ABZ_Reg,
NITIO_Num_Registers,
};
INSN_CONFIG_GET_GATE_SRC = 2002, // Get gate source
INSN_CONFIG_SET_CLOCK_SRC = 2003, // Set master clock source
INSN_CONFIG_GET_CLOCK_SRC = 2004, // Get master clock source
+ INSN_CONFIG_SET_OTHER_SRC = 2005, // Set other source
+// INSN_CONFIG_GET_OTHER_SRC = 2006, // Get other source
INSN_CONFIG_SET_COUNTER_MODE = 4097,
INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */
INSN_CONFIG_8254_READ_STATUS = 4098,
return 0x202 + n;
}
+/* Possibilities for setting a source with
+INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */
+enum ni_gpct_other_index {
+ NI_GPCT_SOURCE_ENCODER_A,
+ NI_GPCT_SOURCE_ENCODER_B,
+ NI_GPCT_SOURCE_ENCODER_Z
+};
+enum ni_gpct_other_select
+{
+ /* m-series gates */
+ // Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT
+ NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
+};
+static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)
+{
+ if (n < 10) {
+ return 0x1 + n;
+ } else if (n < 16) {
+ return 0xb + n;
+ } else {
+ // Really should report this error somehow
+ return NI_GPCT_DISABLED_OTHER_SELECT;
+ }
+}
+
+
/* start sources for ni general-purpose counters for use with
INSN_CONFIG_ARM */
enum ni_gpct_arm_source