04-06-2012 03:24 PM
hi --
i have buffered event counting mostly ported over to x-series from my m-series driver.
For the counter sample clock, I am using AI_Start, so that the counter values coming in are synchronized with analog input.
This works fine, and i get values like so (assuming we are getting a constant 100 counts between AI_Start signals):
100 200 300 400 500 etc...
Optionally, though, I would like to get non cumulative data, like so:
100 100 100 100 100 etc...
To accomplish this, I am also using AI_Start as the counter Gate, where the Gate function is to reload the counter (reset to zero) on each rising Gate edge. This doesn't seem to work. However if I drive the sample clock and Gate from a slower external signal (e.g. a 1MHz square wave via PFI) , the counter is reloaded correctly, and I get non-cumulative values.
M-series is a little different, but basically uses the same idea, with the Gate being AI_Start_Pulse via RTSI.
If anyone has a suggestion, or an alternate way to accomplish this (basically, a counter reload synchronous with the counter sample clock or AI_Start signal), I'd appreciate some input.
My initial setup code is below, based on gpctex5.cpp:
thanks,
--spg
static void counterSetup(tCounter *counter,
nNISTC3::counterResetHelper *counterResetHelper,
bool enabled,
int cumulative,
int pfi, // pfi, or -1 for internal clock
bool fallingPolarity,
UInt32 *buffer)
{
nMDBG::tStatus2 status;
counterResetHelper->reset( /*initialReset*/ kTrue, status);
if (!enabled)
return;
// -------------------
// Mode
// -------------------
counter->Gi_Mode_Register.setGi_Reload_Source_Switching(nCounter::kUseSameLoadRegister);
counter->Gi_Mode_Register.setGi_Loading_On_Gate(cumulative ? nCounter::kNoCounterReloadOnGate : nCounter::kReloadOnStopGate );// cumulative?
counter->Gi_Mode_Register.setGi_ForceSourceEqualToTimebase(kFalse);
counter->Gi_Mode_Register.setGi_Loading_On_TC(nCounter::kRolloverOnTC);
counter->Gi_Mode_Register.setGi_Counting_Once(nCounter::kNoHardwareDisarm);
counter->Gi_Mode_Register.setGi_Load_Source_Select(nCounter::kLoad_From_Register_A);
counter->Gi_Mode_Register.setGi_Trigger_Mode_For_Edge_Gate(nCounter::kGateLoads);
counter->Gi_Mode_Register.setGi_Gate_On_Both_Edges(nCounter::kDisabled);
counter->Gi_Mode_Register.setGi_Gating_Mode(nCounter::kAssertingEdgeGating);
// Gi_Output_Mode doesn't matter
// Gi_Stop_Mode doesn't matter
// Gi_Gate_On_Both_Edges doesn't matter
counter->Gi_Mode_Register.flush();
// -------------------
// Mode2
// -------------------
counter->Gi_Mode2_Register.setGi_Up_Down(nCounter::kCountUp);
counter->Gi_Mode2_Register.setGi_Bank_Switch_Enable(nCounter::kDisabled_If_Armed_Else_Write_To_X);
counter->Gi_Mode2_Register.setGi_Bank_Switch_Mode(nCounter::kGate);
counter->Gi_Mode2_Register.setGi_StopOnError(kFalse);
// Gi_WriteOnSwitchRequest doesn't matter
// Gi_CtrOutFifoRegenerationEn doesn't matter
// Gi_HwArmSyncMode doesn't matter
counter->Gi_Mode2_Register.flush();
// -------------------
// Counting Mode
// -------------------
counter->Gi_Counting_Mode_Register.setGi_Prescale(kFalse);
counter->Gi_Counting_Mode_Register.setGi_HW_Arm_Enable(kFalse);
counter->Gi_Counting_Mode_Register.setGi_Counting_Mode(nCounter::kNormalCounting);
// Gi_Prescale_Div_2 doesn't matter
// Gi_HW_Arm_Select doesn't matter
// Gi_Index_Phase doesn't matter
// Gi_Index_Mode doesn't matter
// Gi_HW_Arm_Polarity doesn't matter
counter->Gi_Counting_Mode_Register.flush();
// -------------------
// Sample Clock
// -------------------
const nCounter::tGi_SampleClockSelect_t sampClkSource = nCounter::kSampleClk_AI_START;
const nCounter::tGi_Polarity_t sampClkPolarity = nCounter::kActiveHigh;
counter->Gi_SampleClockRegister.setGi_SampleClockGateIndependent(kTrue);
counter->Gi_SampleClockRegister.setGi_SampleClockSampleMode(nCounter::kSC_LastSaved);
counter->Gi_SampleClockRegister.setGi_SampleClockMode(nCounter::kSC_SingleSample);
counter->Gi_SampleClockRegister.setGi_SampleClockPolarity(sampClkPolarity);
counter->Gi_SampleClockRegister.setGi_SampleClockSelect(sampClkSource);
// Gi_SampleClockPulse doesn't matter
// Gi_SampleClockLevelMode doesn't matter
counter->Gi_SampleClockRegister.flush();
// -------------------
// Aux
// -------------------
counter->Gi_AuxCtrRegister.writeGi_AuxCtrMode(nCounter::kAux_Disabled);
// -------------------
// Don't Matter
// -------------------
// Gi_Autoincrement_Register doesn't matter
// Gi_ABZ_Select_Register doesn't matter
// -------------------
// Second Gate
// -------------------
counter->Gi_Second_Gate_Register.setGi_Second_Gate_Mode(nCounter::kDisabledSecondGate);
// Gi_Second_Gate_Polarity doesn't matter
// Gi_Second_Gate_Select doesn't matter
counter->Gi_Second_Gate_Register.flush();
// -------------------
// Input Select
// -------------------
const nCounter::tGi_Source_Select_t source = (pfi==-1) ? nCounter::kSrc_TB1 : (nCounter::tGi_Source_Select_t) (pfi + ((pfi<10) ? 1 : 11));
const nCounter::tGi_Polarity_t sourcePolarity = (fallingPolarity ? nCounter::kActiveLow : nCounter::kActiveHigh);
counter->Gi_Input_Select_Register.setGi_Gate_Select(nCounter::kGate_AI_START1);
counter->Gi_Input_Select_Register.setGi_Source_Polarity(sourcePolarity);
counter->Gi_Input_Select_Register.setGi_Source_Select(source);
// Gi_Output_Polarity doesn't matter
// Gi_Gate_Select_Load_Source doesn't matter
// Gi_Gate_Polarity doesn't matter
counter->Gi_Input_Select_Register.flush();
// -------------------
// Fifo
// -------------------
counter->Gi_DMA_Config_Register.setGi_WrFifoEnable(kFalse);
counter->Gi_DMA_Config_Register.setGi_DMA_Write(kFalse);
counter->Gi_DMA_Config_Register.setGi_DMA_Enable(kTrue);
// Gi_DoneNotificationEnable doesn't matter
// Gi_WaitForFirstEventOnGate doesn't matter
// Gi_DMA_Reset doesn't matter
counter->Gi_DMA_Config_Register.flush();
}
Solved! Go to Solution.
04-07-2012 01:29 PM
blurg!
i just realized what the problem is:
counter->Gi_Input_Select_Register.setGi_Gate_Select(nCounter::kGate_AI_START1);// <------------------ using Start1 instead of Start
So, similar to M-series, I can't get the signal I want directly, so by exporting it to RTSI0:
device.Triggers.RTSI_OutputSelectRegister_i[0].writeRTSI_i_Output_Select(nTriggers::kRTSI_AI_START);
device.Triggers.RTSI_Trig_Direction_Register.writeRTSI0_Pin_Dir(nTriggers::kRTSI_Output);
i can then replace the erroneous line with:
counter->Gi_Input_Select_Register.setGi_Gate_Select(nCounter::kGate_RTSI0);