Patch from Anders Blomdell <anders.blomdell@control.lth.se>, fixes
authorFrank Mori Hess <fmhess@speakeasy.net>
Thu, 28 Jun 2007 01:20:21 +0000 (01:20 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Thu, 28 Jun 2007 01:20:21 +0000 (01:20 +0000)
quadrature encoder counting with NI M-series boards.

comedi/comedi_fops.c
comedi/drivers/ni_mio_common.c
comedi/drivers/ni_tio.c
comedi/drivers/ni_tio.h
include/linux/comedi.h

index 2f5a3fa615d518a0ab9b3590d7a029a5c8bcb2e6..824297c84129d8273562c2bd8d32148564afcab3 100644 (file)
@@ -638,6 +638,7 @@ static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
        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;
index ee4e889e5fe99de3506ab32d17fcdae139236f4b..4caaf5add0fe7e0560442e1fc87a84b5bf29fa29 100644 (file)
@@ -3371,6 +3371,13 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, enum
        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:
index c1898e77f5d09c921c1976399250da7b09373347..67f3739e764e3cf1e5c1d94b1640f510f8e04fed 100644 (file)
@@ -322,6 +322,23 @@ static inline enum ni_gpct_register NITIO_Gi_DMA_Config_Reg(int counter_index)
        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
@@ -1607,6 +1624,41 @@ static int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, lsa
        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;
@@ -1875,6 +1927,9 @@ int ni_tio_insn_config(struct ni_gpct *counter,
        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;
index e561088a9eb1adfad09be496b2fb51683dffcf0d..bd32398b5082a55181d74da270c3119424da4939 100644 (file)
@@ -86,6 +86,8 @@ enum ni_gpct_register
        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,
 };
 
index c4b31c18370c643edbd61b7ac061a0050c0a4293..7014fc46401207e0a9c7ef2678a341035dec4a21 100644 (file)
@@ -250,6 +250,8 @@ enum configuration_ids
        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,
@@ -643,6 +645,32 @@ static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)
        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