return 0;
}
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Status2_Reg(unsigned counter_index)
+{
+ switch(counter_index)
+ {
+ case 0:
+ case 1:
+ return NITIO_G01_Joint_Status2_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Joint_Status2_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
static inline enum ni_gpct_register NITIO_Gxx_Status_Reg(unsigned counter_index)
{
switch(counter_index)
Gi_660x_Prescale_X2_Bit = 0x4000, /* from m-series example code, not documented in 660x register level manual */
Gi_M_Series_Prescale_X2_Bit = 0x8000,
};
-static inline unsigned Gi_Alternate_Sync_Bit(enum ni_gpct_variant variant)
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum ni_gpct_variant variant)
{
switch(variant)
{
}
return 0;
}
-static inline unsigned Gi_Prescale_X2_Bit(enum ni_gpct_variant variant)
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum ni_gpct_variant variant)
{
switch(variant)
{
}
return 0;
}
-static inline unsigned Gi_Prescale_X8_Bit(enum ni_gpct_variant variant)
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum ni_gpct_variant variant)
{
switch(variant)
{
}
return 0;
}
-static inline unsigned Gi_HW_Arm_Select_Mask(enum ni_gpct_variant variant)
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum ni_gpct_variant variant)
{
switch(variant)
{
G0_Gate_Error_Bit = 0x4000,
G1_Gate_Error_Bit = 0x8000
};
-static inline unsigned Gi_Counting_Bit(unsigned counter_index)
+static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index)
{
if(counter_index % 2) return G1_Counting_Bit;
return G0_Counting_Bit;
}
-static inline unsigned Gi_Armed_Bit(unsigned counter_index)
+static inline enum Gxx_Status_Bits Gi_Armed_Bit(unsigned counter_index)
{
if(counter_index % 2) return G1_Armed_Bit;
return G0_Armed_Bit;
}
-static inline unsigned Gi_Next_Load_Source_Bit(unsigned counter_index)
+static inline enum Gxx_Status_Bits Gi_Next_Load_Source_Bit(unsigned counter_index)
{
if(counter_index % 2) return G1_Next_Load_Source_Bit;
return G0_Next_Load_Source_Bit;
}
-static inline unsigned Gi_TC_Error_Bit(unsigned counter_index)
+static inline enum Gxx_Status_Bits Gi_Stale_Data_Bit(unsigned counter_index)
+{
+ if(counter_index % 2) return G1_Stale_Data_Bit;
+ return G0_Stale_Data_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_TC_Error_Bit(unsigned counter_index)
{
if(counter_index % 2) return G1_TC_Error_Bit;
return G0_TC_Error_Bit;
}
-static inline unsigned Gi_Gate_Error_Bit(unsigned counter_index)
+static inline enum Gxx_Status_Bits Gi_Gate_Error_Bit(unsigned counter_index)
{
if(counter_index % 2) return G1_Gate_Error_Bit;
return G0_Gate_Error_Bit;
return 0x1 << (2 + (counter_index % 2));
}
+enum Gxx_Joint_Status2_Bits
+{
+ G0_Output_Bit = 0x1,
+ G1_Output_Bit = 0x2,
+ G0_HW_Save_Bit = 0x1000,
+ G1_HW_Save_Bit = 0x2000,
+ G0_Permanent_Stale_Bit = 0x4000,
+ G1_Permanent_Stale_Bit = 0x8000
+};
+static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned counter_index)
+{
+ if(counter_index % 2) return G1_Permanent_Stale_Bit;
+ return G0_Permanent_Stale_Bit;
+}
+
enum Gi_DMA_Config_Reg_Bits
{
Gi_DMA_Enable_Bit = 0x1,
static const lsampl_t counter_status_mask = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
+static inline void write_register(struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg)
+{
+ counter->counter_dev->write_register(counter, bits, reg);
+}
+static inline unsigned read_register(struct ni_gpct *counter, enum ni_gpct_register reg)
+{
+ return counter->counter_dev->read_register(counter, reg);
+}
+
static int __init ni_tio_init_module(void)
{
return 0;
static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
{
- counter->counter_dev->write_register(counter, Gi_Reset_Bit(counter->counter_index),
+ write_register(counter, Gi_Reset_Bit(counter->counter_index),
NITIO_Gxx_Joint_Reset_Reg(counter->counter_index));
}
ni_tio_reset_count_and_disarm(counter);
/* initialize counter registers */
counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] = 0x0;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)],
NITIO_Gi_Autoincrement_Reg(counter->counter_index));
counter_dev->regs[NITIO_Gi_Command_Reg(counter->counter_index)] = Gi_Synchronize_Gate_Bit;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_Command_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_Command_Reg(counter->counter_index)],
NITIO_Gi_Command_Reg(counter->counter_index));
counter_dev->regs[NITIO_Gi_Mode_Reg(counter->counter_index)] = 0x0;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_Mode_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_Mode_Reg(counter->counter_index)],
NITIO_Gi_Mode_Reg(counter->counter_index));
counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = 0x0;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)],
NITIO_Gi_LoadA_Reg(counter->counter_index));
counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = 0x0;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)],
NITIO_Gi_LoadB_Reg(counter->counter_index));
counter_dev->regs[NITIO_Gi_Input_Select_Reg(counter->counter_index)] = 0x0;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_Input_Select_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_Input_Select_Reg(counter->counter_index)],
NITIO_Gi_Input_Select_Reg(counter->counter_index));
if(ni_tio_counting_mode_registers_present(counter_dev))
{
counter_dev->regs[NITIO_Gi_Counting_Mode_Reg(counter->counter_index)] = 0x0;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_Counting_Mode_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_Counting_Mode_Reg(counter->counter_index)],
NITIO_Gi_Counting_Mode_Reg(counter->counter_index));
}
if(ni_tio_second_gate_registers_present(counter_dev))
{
counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->counter_index)] = 0x0;
- counter_dev->write_register(counter, counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->counter_index)],
+ write_register(counter, counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->counter_index)],
NITIO_Gi_Second_Gate_Reg(counter->counter_index));
}
}
static lsampl_t ni_tio_counter_status(struct ni_gpct *counter)
{
lsampl_t status = 0;
- const unsigned bits = counter->counter_dev->read_register(counter, NITIO_Gxx_Status_Reg(counter->counter_index));
+ const unsigned bits = read_register(counter, NITIO_Gxx_Status_Reg(counter->counter_index));
if(bits & Gi_Armed_Bit(counter->counter_index))
{
status |= COMEDI_COUNTER_ARMED;
{
counter_dev->regs[counting_mode_reg] &= ~Gi_Alternate_Sync_Bit(counter_dev->variant);
}
- counter_dev->write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
+ write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
}
static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
counter_dev->regs[mode_reg] &= ~mode_reg_direct_mask;
counter_dev->regs[mode_reg] |= mode & mode_reg_direct_mask;
- counter_dev->write_register(counter, counter_dev->regs[mode_reg], mode_reg);
+ write_register(counter, counter_dev->regs[mode_reg], mode_reg);
if(ni_tio_counting_mode_registers_present(counter_dev))
{
{
counter_dev->regs[counting_mode_reg] &= ~Gi_Index_Mode_Bit;
}
- counter_dev->write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
+ write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
ni_tio_set_sync_mode(counter, 0);
}
counter_dev->regs[command_reg] &= ~Gi_Up_Down_Mask;
counter_dev->regs[command_reg] |= ((mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << Gi_Up_Down_Shift) & Gi_Up_Down_Mask;
- counter_dev->write_register(counter, counter_dev->regs[command_reg], command_reg);
+ write_register(counter, counter_dev->regs[command_reg], command_reg);
if(mode & NI_GPCT_OR_GATE_BIT)
{
{
counter_dev->regs[input_select_reg] &= ~Gi_Output_Polarity_Bit;
}
- counter_dev->write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
+ write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
return 0;
}
counter_dev->regs[counting_mode_reg] &= ~Gi_HW_Arm_Select_Mask(counter_dev->variant);
hw_arm_select_bits = (start_trigger << Gi_HW_Arm_Select_Shift) & Gi_HW_Arm_Select_Mask(counter_dev->variant);
counter_dev->regs[counting_mode_reg] |= Gi_HW_Arm_Enable_Bit | hw_arm_select_bits;
- counter_dev->write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
+ write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
}else
{
return -EINVAL;
{
command_bits |= Gi_Disarm_Bit;
}
- counter_dev->write_register(counter, command_bits, NITIO_Gi_Command_Reg(counter->counter_index));
+ write_register(counter, command_bits, NITIO_Gi_Command_Reg(counter->counter_index));
return 0;
}
return;
break;
}
- counter_dev->write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
+ write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
}
static int ni_tio_set_clock_src(struct ni_gpct *counter,
counter_dev->regs[input_select_reg] |= Gi_Source_Polarity_Bit;
else
counter_dev->regs[input_select_reg] &= ~Gi_Source_Polarity_Bit;
- counter_dev->write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
+ write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
ni_tio_set_source_subselect(counter, clock_source);
if(ni_tio_counting_mode_registers_present(counter_dev))
{
return -EINVAL;
break;
}
- counter_dev->write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
+ write_register(counter, counter_dev->regs[counting_mode_reg], counting_mode_reg);
}
counter->clock_period_ps = pico_per_nano * period_ns;
ni_tio_set_sync_mode(counter, 0);
{
counter_dev->regs[mode_reg] |= Gi_Level_Gating_Bits;
}
- counter_dev->write_register(counter, counter_dev->regs[mode_reg], mode_reg);
+ write_register(counter, counter_dev->regs[mode_reg], mode_reg);
}
static int ni_660x_set_first_gate(struct ni_gpct *counter, lsampl_t gate_source)
}
counter_dev->regs[input_select_reg] &= ~Gi_Gate_Select_Mask;
counter_dev->regs[input_select_reg] |= Gi_Gate_Select_Bits(ni_660x_gate_select);
- counter_dev->write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
+ write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
return 0;
}
}
counter_dev->regs[input_select_reg] &= ~Gi_Gate_Select_Mask;
counter_dev->regs[input_select_reg] |= Gi_Gate_Select_Bits(ni_m_series_gate_select);
- counter_dev->write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
+ write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
return 0;
}
counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select);
- counter_dev->write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
+ write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
return 0;
}
counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select);
- counter_dev->write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
+ write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
return 0;
}
{
counter_dev->regs[mode_reg] &= ~Gi_Gating_Mode_Mask;
counter_dev->regs[mode_reg] |= Gi_Gating_Disabled_Bits;
- counter_dev->write_register(counter, counter_dev->regs[mode_reg], mode_reg);
+ write_register(counter, counter_dev->regs[mode_reg], mode_reg);
return 0;
}
ni_tio_set_first_gate_modifiers(counter, gate_source);
if(CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT)
{
counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Mode_Bit;
- counter_dev->write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
+ write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg);
return 0;
}
if(gate_source & CR_INVERT)
}
counter_dev->regs[abz_reg] &= ~mask;
counter_dev->regs[abz_reg] |= (source << shift) & mask;
- counter_dev->write_register(counter, counter_dev->regs[abz_reg], abz_reg);
+ write_register(counter, counter_dev->regs[abz_reg], abz_reg);
// rt_printk("%s %x %d %d\n", __FUNCTION__, counter_dev->regs[abz_reg], index, source);
return 0;
}
{
case 0:
counter_dev->regs[command_reg] &= ~Gi_Save_Trace_Bit;
- counter_dev->write_register(counter, counter_dev->regs[command_reg], command_reg);
- counter_dev->write_register(counter, counter_dev->regs[command_reg] | Gi_Save_Trace_Bit,
+ write_register(counter, counter_dev->regs[command_reg], command_reg);
+ write_register(counter, counter_dev->regs[command_reg] | Gi_Save_Trace_Bit,
command_reg);
/* The count doesn't get latched until the next clock edge, so it is possible the count
may change (once) while we are reading. Since the read of the SW_Save_Reg isn't
atomic (apparently even when it's a 32 bit register according to 660x docs),
we need to read twice and make sure the reading hasn't changed. If it has,
a third read will be correct since the count value will definitely have latched by then. */
- first_read = counter_dev->read_register(counter, NITIO_Gi_SW_Save_Reg(counter->counter_index));
- second_read = counter_dev->read_register(counter, NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ first_read = read_register(counter, NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ second_read = read_register(counter, NITIO_Gi_SW_Save_Reg(counter->counter_index));
if(first_read != second_read)
- correct_read = counter_dev->read_register(counter, NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ correct_read = read_register(counter, NITIO_Gi_SW_Save_Reg(counter->counter_index));
else
correct_read = first_read;
data[0] = correct_read;
static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
{
- const unsigned bits = counter->counter_dev->read_register(counter, NITIO_Gxx_Status_Reg(counter->counter_index));
+ const unsigned bits = read_register(counter, NITIO_Gxx_Status_Reg(counter->counter_index));
if(bits & Gi_Next_Load_Source_Bit(counter->counter_index))
{
/* Unsafe if counter is armed. Should probably check status and return -EBUSY if armed. */
/* Don't disturb load source select, just use whichever load register is already selected. */
load_reg = ni_tio_next_load_register(counter);
- counter_dev->write_register(counter, data[0], load_reg);
- counter_dev->write_register(counter, counter_dev->regs[command_reg] | Gi_Load_Bit, command_reg);
+ write_register(counter, data[0], load_reg);
+ write_register(counter, counter_dev->regs[command_reg] | Gi_Load_Bit, command_reg);
/* restore state of load reg to whatever the user set last set it to */
- counter_dev->write_register(counter, counter_dev->regs[load_reg], load_reg);
+ write_register(counter, counter_dev->regs[load_reg], load_reg);
break;
case 1:
counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = data[0];
- counter_dev->write_register(counter, data[0], NITIO_Gi_LoadA_Reg(counter->counter_index));
+ write_register(counter, data[0], NITIO_Gi_LoadA_Reg(counter->counter_index));
break;
case 2:
counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = data[0];
- counter_dev->write_register(counter, data[0], NITIO_Gi_LoadB_Reg(counter->counter_index));
+ write_register(counter, data[0], NITIO_Gi_LoadB_Reg(counter->counter_index));
break;
default:
return -EINVAL;
{
counter_dev->regs[input_select_reg] &= ~(Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq);
}
- counter_dev->write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
+ write_register(counter, counter_dev->regs[input_select_reg], input_select_reg);
}
break;
case ni_gpct_variant_m_series:
{
counter_dev->regs[gi_dma_config_reg] |= Gi_DMA_Write_Bit;
}
- counter_dev->write_register(counter, counter_dev->regs[gi_dma_config_reg], gi_dma_config_reg);
+ write_register(counter, counter_dev->regs[gi_dma_config_reg], gi_dma_config_reg);
}
break;
}
break;
}
counter_dev->regs[command_reg] &= ~Gi_Save_Trace_Bit;
- counter_dev->write_register(counter, counter_dev->regs[command_reg], command_reg);
+ write_register(counter, counter_dev->regs[command_reg], command_reg);
ni_tio_configure_dma(counter, 1, 1);
mite_dma_arm(counter->mite_chan);
return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
return retval;
}
-static unsigned acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, int *tc_error)
+static void acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, int *tc_error)
{
- const unsigned short gxx_status = counter->counter_dev->read_register(counter, NITIO_Gxx_Status_Reg(counter->counter_index));
- const unsigned short gi_status = counter->counter_dev->read_register(counter, NITIO_Gi_Status_Reg(counter->counter_index));
+ const unsigned short gxx_status = read_register(counter, NITIO_Gxx_Status_Reg(counter->counter_index));
+ const unsigned short gi_status = read_register(counter, NITIO_Gi_Status_Reg(counter->counter_index));
unsigned ack = 0;
if(gate_error) *gate_error = 0;
if(should_ack_gate(counter))
ack |= Gi_Gate_Interrupt_Ack_Bit;
}
- if(ack) counter->counter_dev->write_register(counter, ack, NITIO_Gi_Interrupt_Acknowledge_Reg(counter->counter_index));
- return gxx_status;
+ if(ack) write_register(counter, ack, NITIO_Gi_Interrupt_Acknowledge_Reg(counter->counter_index));
+ if(gxx_status & Gi_Stale_Data_Bit(counter->counter_index))
+ {
+ //XXX
+// rt_printk("%s: Gi_Stale_Data detected.\n", __FUNCTION__);
+ }
+ if(read_register(counter, NITIO_Gxx_Joint_Status2_Reg(counter->counter_index)) & Gi_Permanent_Stale_Bit(counter->counter_index))
+ {
+ //XXX
+// rt_printk("%s: Gi_Permanent_Stale_Data detected.\n", __FUNCTION__);
+ }
}
void ni_tio_handle_interrupt(struct ni_gpct *counter, comedi_subdevice *s)
acknowledge_and_confirm(counter, &gate_error, &tc_error);
if(gate_error)
+ {
+// rt_printk("%s: Gi_Gate_Error detected.\n", __FUNCTION__);
s->async->events |= COMEDI_CB_OVERFLOW;
+ }
switch(counter->counter_dev->variant)
{
case ni_gpct_variant_m_series:
case ni_gpct_variant_660x:
- if(counter->counter_dev->read_register(counter, NITIO_Gi_DMA_Status_Reg(counter->counter_index)) &
+ if(read_register(counter, NITIO_Gi_DMA_Status_Reg(counter->counter_index)) &
Gi_DRQ_Error_Bit)
+ {
+// rt_printk("%s: Gi_DRQ_Error detected.\n", __FUNCTION__);
s->async->events |= COMEDI_CB_OVERFLOW;
+ }
break;
case ni_gpct_variant_e_series:
break;