}
return 0;
}
+static inline unsigned Gi_Prescale_X2_Bit(enum ni_gpct_variant variant)
+{
+ switch(variant)
+ {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_Prescale_X2_Bit;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_Prescale_X2_Bit;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
static inline unsigned Gi_Prescale_X8_Bit(enum ni_gpct_variant variant)
{
switch(variant)
#define Gi_Source_Select_Shift 2
#define Gi_Gate_Select_Shift 7
-/*FIXME: these gates are 660x specific. See m-series example code for its gates/sources*/
enum Gi_Input_Select_Bits
{
Gi_Source_Select_Mask = 0x7c,
}
}
-static void ni_tio_set_second_source_select(struct ni_gpct *counter, lsampl_t clock_source)
+static void ni_tio_set_source_subselect(struct ni_gpct *counter, lsampl_t clock_source)
{
const unsigned second_gate_reg = NITIO_Gi_Second_Gate_Reg(counter->counter_index);
/*FIXME: add support for prescale in counting mode register */
/*FIXME: add support for prescale x2*/
-/*FIXME: is clock period specified before or after prescaling? */
+/*FIXME: is clock period specified before or after prescaling? I'm going to say after. */
/*FIXME: validate clock source */
counter->regs[input_select_reg] &= ~Gi_Source_Select_Mask;
switch(counter->variant)
else
counter->regs[input_select_reg] &= ~Gi_Source_Polarity_Bit;
counter->write_register(counter, counter->regs[input_select_reg], input_select_reg);
- ni_tio_set_second_source_select(counter, clock_source);
+ ni_tio_set_source_subselect(counter, clock_source);
if(ni_tio_counting_mode_registers_present(counter))
{
const unsigned counting_mode_reg = NITIO_Gi_Counting_Mode_Reg(counter->counter_index);
+ const unsigned prescaling_mode = clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
- if(clock_source & NI_GPCT_PRESCALE_CLOCK_SRC_BIT)
- counter->regs[counting_mode_reg] |= Gi_Prescale_X8_Bit(counter->variant);
- else
+ switch(prescaling_mode)
+ {
+ case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
+ counter->regs[counting_mode_reg] &= ~(Gi_Prescale_X2_Bit(counter->variant) | Gi_Prescale_X8_Bit(counter->variant));
+ break;
+ case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+ counter->regs[counting_mode_reg] |= Gi_Prescale_X2_Bit(counter->variant);
counter->regs[counting_mode_reg] &= ~Gi_Prescale_X8_Bit(counter->variant);
+ break;
+ case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+ counter->regs[counting_mode_reg] |= Gi_Prescale_X8_Bit(counter->variant);
+ counter->regs[counting_mode_reg] &= ~Gi_Prescale_X2_Bit(counter->variant);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
counter->write_register(counter, counter->regs[counting_mode_reg], counting_mode_reg);
}
ni_tio_update_clock_period(counter, clock_source, period_ns);
if(counter->regs[input_select_reg] & Gi_Source_Polarity_Bit)
bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
+ if(counter->regs[counting_mode_reg] & Gi_Prescale_X2_Bit(counter->variant))
+ bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
if(counter->regs[counting_mode_reg] & Gi_Prescale_X8_Bit(counter->variant))
- bits |= NI_GPCT_PRESCALE_CLOCK_SRC_BIT;
+ bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
return bits;
}
* INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */
enum ni_gpct_clock_source_bits
{
- NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x2f,
+ NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x1f,
NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
- /* modifier bits */
- NI_GPCT_PRESCALE_CLOCK_SRC_BIT = 0x20000000, /* divide source by 8 */
+ NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
+ NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
+ NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, /* divide source by 2 */
+ NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, /* divide source by 8 */
NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
};
static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) /* NI 660x-specific */