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; }
static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter) { unsigned clock_source = 0; unsigned i; const unsigned input_select = (ni_tio_get_soft_copy(counter, NITIO_Gi_Input_Select_Reg (counter->counter_index)) & Gi_Source_Select_Mask) >> Gi_Source_Select_Shift; switch (input_select) { case NI_660x_Timebase_1_Clock: clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; break; case NI_660x_Timebase_2_Clock: clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; break; case NI_660x_Timebase_3_Clock: clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; break; case NI_660x_Logic_Low_Clock: clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; break; case NI_660x_Source_Pin_i_Clock: clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS; break; case NI_660x_Next_Gate_Clock: clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; break; case NI_660x_Next_TC_Clock: clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; break; default: for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { if (input_select == NI_660x_RTSI_Clock(i)) { clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); break; } } if (i <= ni_660x_max_rtsi_channel) break; for (i = 0; i <= ni_660x_max_source_pin; ++i) { if (input_select == NI_660x_Source_Pin_Clock(i)) { clock_source = NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i); break; } } if (i <= ni_660x_max_source_pin) break; BUG(); break; } clock_source |= ni_tio_clock_src_modifiers(counter); return clock_source; }
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); }
static int ni_m_series_set_first_gate(struct ni_gpct *counter, lsampl_t gate_source) { const unsigned selected_gate = CR_CHAN(gate_source); /* bits of selected_gate that may be meaningful to input select register */ const unsigned selected_gate_mask = 0x1f; unsigned ni_m_series_gate_select; unsigned i; switch (selected_gate) { case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT: case NI_GPCT_AI_START2_GATE_SELECT: case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT: case NI_GPCT_NEXT_OUT_GATE_SELECT: case NI_GPCT_AI_START1_GATE_SELECT: case NI_GPCT_NEXT_SOURCE_GATE_SELECT: case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT: case NI_GPCT_LOGIC_LOW_GATE_SELECT: ni_m_series_gate_select = selected_gate & selected_gate_mask; break; default: for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { ni_m_series_gate_select = selected_gate & selected_gate_mask; break; } } if (i <= ni_m_series_max_rtsi_channel) break; for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) { ni_m_series_gate_select = selected_gate & selected_gate_mask; break; } } if (i <= ni_m_series_max_pfi_channel) break; return -EINVAL; break; } ni_tio_set_bits(counter, NITIO_Gi_Input_Select_Reg(counter->counter_index), Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_m_series_gate_select)); return 0; }
static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_source) { const unsigned selected_gate = CR_CHAN(gate_source); /* bits of selected_gate that may be meaningful to input select register */ const unsigned selected_gate_mask = 0x1f; unsigned ni_660x_gate_select; unsigned i; switch (selected_gate) { case NI_GPCT_NEXT_SOURCE_GATE_SELECT: ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select; break; case NI_GPCT_NEXT_OUT_GATE_SELECT: case NI_GPCT_LOGIC_LOW_GATE_SELECT: case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: case NI_GPCT_GATE_PIN_i_GATE_SELECT: ni_660x_gate_select = selected_gate & selected_gate_mask; break; default: for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { ni_660x_gate_select = selected_gate & selected_gate_mask; break; } } if (i <= ni_660x_max_rtsi_channel) break; for (i = 0; i <= ni_660x_max_gate_pin; ++i) { if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) { ni_660x_gate_select = selected_gate & selected_gate_mask; break; } } if (i <= ni_660x_max_gate_pin) break; return -EINVAL; break; } ni_tio_set_bits(counter, NITIO_Gi_Input_Select_Reg(counter->counter_index), Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_660x_gate_select)); return 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; }
static void ni_tio_configure_dma(struct ni_gpct *counter, short enable, short read_not_write) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned input_select_bits = 0; if (enable) { if (read_not_write) { input_select_bits |= Gi_Read_Acknowledges_Irq; } else { input_select_bits |= Gi_Write_Acknowledges_Irq; } } ni_tio_set_bits(counter, NITIO_Gi_Input_Select_Reg(counter->counter_index), Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq, input_select_bits); switch (counter_dev->variant) { case ni_gpct_variant_e_series: break; case ni_gpct_variant_m_series: case ni_gpct_variant_660x: { unsigned gi_dma_config_bits = 0; if (enable) { gi_dma_config_bits |= Gi_DMA_Enable_Bit; gi_dma_config_bits |= Gi_DMA_Int_Bit; } if (read_not_write == 0) { gi_dma_config_bits |= Gi_DMA_Write_Bit; } ni_tio_set_bits(counter, NITIO_Gi_DMA_Config_Reg(counter-> counter_index), Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit | Gi_DMA_Write_Bit, gi_dma_config_bits); } break; } }
static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; const unsigned second_gate_reg = NITIO_Gi_Second_Gate_Reg(counter->counter_index); unsigned clock_source = 0; unsigned i; const unsigned input_select = (ni_tio_get_soft_copy(counter, NITIO_Gi_Input_Select_Reg(counter-> counter_index)) & Gi_Source_Select_Mask) >> Gi_Source_Select_Shift; switch (input_select) { case NI_M_Series_Timebase_1_Clock: clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; break; case NI_M_Series_Timebase_2_Clock: clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; break; case NI_M_Series_Timebase_3_Clock: if (counter_dev-> regs[second_gate_reg] & Gi_Source_Subselect_Bit) clock_source = NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS; else clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; break; case NI_M_Series_Logic_Low_Clock: clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; break; case NI_M_Series_Next_Gate_Clock: if (counter_dev-> regs[second_gate_reg] & Gi_Source_Subselect_Bit) clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS; else clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; break; case NI_M_Series_PXI10_Clock: clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS; break; case NI_M_Series_Next_TC_Clock: clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; break; default: for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { if (input_select == NI_M_Series_RTSI_Clock(i)) { clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); break; } } if (i <= ni_m_series_max_rtsi_channel) break; for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { if (input_select == NI_M_Series_PFI_Clock(i)) { clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i); break; } } if (i <= ni_m_series_max_pfi_channel) break; BUG(); break; } clock_source |= ni_tio_clock_src_modifiers(counter); return clock_source; }
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; }
static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index, lsampl_t * gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; const unsigned mode_bits = ni_tio_get_soft_copy(counter, NITIO_Gi_Mode_Reg(counter->counter_index)); const unsigned second_gate_reg = NITIO_Gi_Second_Gate_Reg(counter->counter_index); unsigned gate_select_bits; switch (gate_index) { case 0: if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits) { *gate_source = NI_GPCT_DISABLED_GATE_SELECT; return 0; } else { gate_select_bits = (ni_tio_get_soft_copy(counter, NITIO_Gi_Input_Select_Reg(counter-> counter_index)) & Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift; } switch (counter_dev->variant) { case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: *gate_source = ni_m_series_first_gate_to_generic_gate_source (gate_select_bits); break; case ni_gpct_variant_660x: *gate_source = ni_660x_first_gate_to_generic_gate_source (gate_select_bits); break; default: BUG(); break; } if (mode_bits & Gi_Gate_Polarity_Bit) { *gate_source |= CR_INVERT; } if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) { *gate_source |= CR_EDGE; } break; case 1: if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits || (counter_dev-> regs[second_gate_reg] & Gi_Second_Gate_Mode_Bit) == 0) { *gate_source = NI_GPCT_DISABLED_GATE_SELECT; return 0; } else { gate_select_bits = (counter_dev-> regs[second_gate_reg] & Gi_Second_Gate_Select_Mask) >> Gi_Second_Gate_Select_Shift; } switch (counter_dev->variant) { case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: *gate_source = ni_m_series_second_gate_to_generic_gate_source (gate_select_bits); break; case ni_gpct_variant_660x: *gate_source = ni_660x_second_gate_to_generic_gate_source (gate_select_bits); break; default: BUG(); break; } if (counter_dev-> regs[second_gate_reg] & Gi_Second_Gate_Polarity_Bit) { *gate_source |= CR_INVERT; } /* second gate can't have edge/level mode set independently */ if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) { *gate_source |= CR_EDGE; } break; default: return -EINVAL; break; } return 0; }