Exemple #1
0
static int ni_tio_set_clock_src(struct ni_gpct *counter,
				unsigned int clock_source,
				unsigned int period_ns)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned input_select_bits = 0;
	static const uint64_t pico_per_nano = 1000;

/*FIXME: validate clock source */
	switch (counter_dev->variant) {
	case ni_gpct_variant_660x:
		input_select_bits |= ni_660x_source_select_bits(clock_source);
		break;
	case ni_gpct_variant_e_series:
	case ni_gpct_variant_m_series:
		input_select_bits |=
		    ni_m_series_source_select_bits(clock_source);
		break;
	default:
		BUG();
		break;
	}
	if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
		input_select_bits |= Gi_Source_Polarity_Bit;
	ni_tio_set_bits(counter,
			NITIO_Gi_Input_Select_Reg(counter->counter_index),
			Gi_Source_Select_Mask | Gi_Source_Polarity_Bit,
			input_select_bits);
	ni_tio_set_source_subselect(counter, clock_source);
	if (ni_tio_counting_mode_registers_present(counter_dev)) {
		const unsigned prescaling_mode =
		    clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
		unsigned counting_mode_bits = 0;

		switch (prescaling_mode) {
		case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
			break;
		case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
			counting_mode_bits |=
			    Gi_Prescale_X2_Bit(counter_dev->variant);
			break;
		case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
			counting_mode_bits |=
			    Gi_Prescale_X8_Bit(counter_dev->variant);
			break;
		default:
			return -EINVAL;
			break;
		}
		ni_tio_set_bits(counter,
				NITIO_Gi_Counting_Mode_Reg(counter->
							   counter_index),
				Gi_Prescale_X2_Bit(counter_dev->variant) |
				Gi_Prescale_X8_Bit(counter_dev->variant),
				counting_mode_bits);
	}
	counter->clock_period_ps = pico_per_nano * period_ns;
	ni_tio_set_sync_mode(counter, 0);
	return 0;
}
Exemple #2
0
int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;

	unsigned command_transient_bits = 0;

	if (arm) {
		switch (start_trigger) {
		case NI_GPCT_ARM_IMMEDIATE:
			command_transient_bits |= Gi_Arm_Bit;
			break;
		case NI_GPCT_ARM_PAIRED_IMMEDIATE:
			command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit;
			break;
		default:
			break;
		}
		if (ni_tio_counting_mode_registers_present(counter_dev)) {
			unsigned counting_mode_bits = 0;

			switch (start_trigger) {
			case NI_GPCT_ARM_IMMEDIATE:
			case NI_GPCT_ARM_PAIRED_IMMEDIATE:
				break;
			default:
				if (start_trigger & NI_GPCT_ARM_UNKNOWN) {
					/* pass-through the least significant bits so we can figure out what select later */
					unsigned hw_arm_select_bits =
					    (start_trigger <<
					     Gi_HW_Arm_Select_Shift) &
					    Gi_HW_Arm_Select_Mask
					    (counter_dev->variant);

					counting_mode_bits |=
					    Gi_HW_Arm_Enable_Bit |
					    hw_arm_select_bits;
				} else {
					return -EINVAL;
				}
				break;
			}
			ni_tio_set_bits(counter,
					NITIO_Gi_Counting_Mode_Reg
					(counter->counter_index),
					Gi_HW_Arm_Select_Mask
					(counter_dev->variant) |
					Gi_HW_Arm_Enable_Bit,
					counting_mode_bits);
		}
	} else {
		command_transient_bits |= Gi_Disarm_Bit;
	}
	ni_tio_set_bits_transient(counter,
				  NITIO_Gi_Command_Reg(counter->counter_index),
				  0, 0, command_transient_bits);
	return 0;
}
Exemple #3
0
void ni_tio_init_counter(struct ni_gpct *counter)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;

	ni_tio_reset_count_and_disarm(counter);
	/* initialize counter registers */
	counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] =
	    0x0;
	write_register(counter,
		       counter_dev->
		       regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)],
		       NITIO_Gi_Autoincrement_Reg(counter->counter_index));
	ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
			~0, Gi_Synchronize_Gate_Bit);
	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), ~0,
			0);
	counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = 0x0;
	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;
	write_register(counter,
		       counter_dev->
		       regs[NITIO_Gi_LoadB_Reg(counter->counter_index)],
		       NITIO_Gi_LoadB_Reg(counter->counter_index));
	ni_tio_set_bits(counter,
			NITIO_Gi_Input_Select_Reg(counter->counter_index), ~0,
			0);
	if (ni_tio_counting_mode_registers_present(counter_dev)) {
		ni_tio_set_bits(counter,
				NITIO_Gi_Counting_Mode_Reg(counter->
							   counter_index), ~0,
				0);
	}
	if (ni_tio_second_gate_registers_present(counter_dev)) {
		counter_dev->
		    regs[NITIO_Gi_Second_Gate_Reg(counter->counter_index)] =
		    0x0;
		write_register(counter,
			       counter_dev->
			       regs[NITIO_Gi_Second_Gate_Reg
				    (counter->counter_index)],
			       NITIO_Gi_Second_Gate_Reg(counter->
							counter_index));
	}
	ni_tio_set_bits(counter,
			NITIO_Gi_DMA_Config_Reg(counter->counter_index), ~0,
			0x0);
	ni_tio_set_bits(counter,
			NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
			~0, 0x0);
}
Exemple #4
0
static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	const unsigned counting_mode_bits = ni_tio_get_soft_copy(counter,
		NITIO_Gi_Counting_Mode_Reg(counter->counter_index));
	unsigned bits = 0;

	if (ni_tio_get_soft_copy(counter,
			NITIO_Gi_Input_Select_Reg(counter->
				counter_index)) & Gi_Source_Polarity_Bit)
		bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
	if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant))
		bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
	if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant))
		bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
	return bits;
}
Exemple #5
0
static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	const unsigned counting_mode_reg =
		NITIO_Gi_Counting_Mode_Reg(counter->counter_index);
	static const uint64_t min_normal_sync_period_ps = 25000;
	const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter,
		ni_tio_generic_clock_src_select(counter));

	if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
		return;

	switch (ni_tio_get_soft_copy(counter,
			counting_mode_reg) & Gi_Counting_Mode_Mask) {
	case Gi_Counting_Mode_QuadratureX1_Bits:
	case Gi_Counting_Mode_QuadratureX2_Bits:
	case Gi_Counting_Mode_QuadratureX4_Bits:
	case Gi_Counting_Mode_Sync_Source_Bits:
		force_alt_sync = 1;
		break;
	default:
		break;
	}
	/* It's not clear what we should do if clock_period is unknown, so we are not
	   using the alt sync bit in that case, but allow the caller to decide by using the
	   force_alt_sync parameter. */
	if (force_alt_sync ||
		(clock_period_ps
			&& clock_period_ps < min_normal_sync_period_ps)) {
		ni_tio_set_bits(counter, counting_mode_reg,
			Gi_Alternate_Sync_Bit(counter_dev->variant),
			Gi_Alternate_Sync_Bit(counter_dev->variant));
	} else {
		ni_tio_set_bits(counter, counting_mode_reg,
			Gi_Alternate_Sync_Bit(counter_dev->variant), 0x0);
	}
}
Exemple #6
0
static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	const unsigned counting_mode_reg =
	    NITIO_Gi_Counting_Mode_Reg(counter->counter_index);
	static const uint64_t min_normal_sync_period_ps = 25000;
	const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter,
								ni_tio_generic_clock_src_select
								(counter));

	if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
		return;

	switch (ni_tio_get_soft_copy(counter,
				     counting_mode_reg) & Gi_Counting_Mode_Mask)
	{
	case Gi_Counting_Mode_QuadratureX1_Bits:
	case Gi_Counting_Mode_QuadratureX2_Bits:
	case Gi_Counting_Mode_QuadratureX4_Bits:
	case Gi_Counting_Mode_Sync_Source_Bits:
		force_alt_sync = 1;
		break;
	default:
		break;
	}
	
	if (force_alt_sync ||
	    (clock_period_ps && clock_period_ps < min_normal_sync_period_ps)) {
		ni_tio_set_bits(counter, counting_mode_reg,
				Gi_Alternate_Sync_Bit(counter_dev->variant),
				Gi_Alternate_Sync_Bit(counter_dev->variant));
	} else {
		ni_tio_set_bits(counter, counting_mode_reg,
				Gi_Alternate_Sync_Bit(counter_dev->variant),
				0x0);
	}
}
Exemple #7
0
static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned mode_reg_mask;
	unsigned mode_reg_values;
	unsigned input_select_bits = 0;
	/* these bits map directly on to the mode register */
	static const unsigned mode_reg_direct_mask =
		NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK |
		NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK |
		NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
		NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;

	mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit;
	mode_reg_values = mode & mode_reg_direct_mask;
	switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
	case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
		break;
	case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
		mode_reg_values |= Gi_Reload_Source_Switching_Bit;
		break;
	case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
		input_select_bits |= Gi_Gate_Select_Load_Source_Bit;
		mode_reg_mask |= Gi_Gating_Mode_Mask;
		mode_reg_values |= Gi_Level_Gating_Bits;
		break;
	default:
		break;
	}
	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
		mode_reg_mask, mode_reg_values);

	if (ni_tio_counting_mode_registers_present(counter_dev)) {
		unsigned counting_mode_bits = 0;
		counting_mode_bits |=
			(mode >> NI_GPCT_COUNTING_MODE_SHIFT) &
			Gi_Counting_Mode_Mask;
		counting_mode_bits |=
			((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) <<
			Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask;
		if (mode & NI_GPCT_INDEX_ENABLE_BIT) {
			counting_mode_bits |= Gi_Index_Mode_Bit;
		}
		ni_tio_set_bits(counter,
			NITIO_Gi_Counting_Mode_Reg(counter->counter_index),
			Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask |
			Gi_Index_Mode_Bit, counting_mode_bits);
		ni_tio_set_sync_mode(counter, 0);
	}

	ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
		Gi_Up_Down_Mask,
		(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << Gi_Up_Down_Shift);

	if (mode & NI_GPCT_OR_GATE_BIT) {
		input_select_bits |= Gi_Or_Gate_Bit;
	}
	if (mode & NI_GPCT_INVERT_OUTPUT_BIT) {
		input_select_bits |= Gi_Output_Polarity_Bit;
	}
	ni_tio_set_bits(counter,
		NITIO_Gi_Input_Select_Reg(counter->counter_index),
		Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit |
		Gi_Output_Polarity_Bit, input_select_bits);

	return 0;
}