I have some AIODIO code which I've ( finally ) gotten working on M-Series PCIx & PCIe cards, and I'm now trying to down-port it to E-Series PCI cards, but I've run into some problems. Here's a snippet of the working M-Series code:
// Setup the acquisition
-( void )aiSetup {
[ super aiSetup ];
UInt32 i;
UInt32 scanInterval = ( UInt32 )floor( 20000000. / _aiSampleRate );
UInt16 convert = 280;
if( _debug ) NSLog( @"aiScanInterval: %d", scanInterval );
BOOL continuous = FALSE;
[ self initMITE ];
[ self initialize ];
[ self configureTimebase ];
[ self resetPLL ];
[ self resetAnalogTrigger ];
[ self aiReset ];
[ self aiPersonalize:_aiNIConvertOutputSelect ];
[ self aiClearFifo ];
[ self resetADC ];
[ self aiDisarm ];
[ self aiClearConfigurationMemory ];
for( i = _aiFirstChannel; i < ( _aiFirstChannel + _aiChannelsToRecord ); i++ ) {
if( _debug ) NSLog( @"aiChannelConfig: %d, %d, %@, %d, %@", i, _aiGainIndex, ( kBiPolar ) ? @"bi" : @"uni", _aiChannelType, ( i == ( ( _aiFirstChannel + _aiChannelsToRecord ) - 1 ) ) ? @"last" : @"not last" );
[ self aiConfigureChannel:i :_aiGainIndex :kBiPolar :_aiChannelType
😞 i == ( ( _aiFirstChannel + _aiChannelsToRecord ) - 1 ) ) ? TRUE : FALSE ];
}
[ self aiSetFIFORequestMode ];
[ self aiEnvironmentalize ];
[ self aiHardwareGating ];
[ self aiTrigger:kAISTART1SelectPulse :kAISTART1PolarityRisingEdge :kAISTART2SelectPulse :kAISTART2PolarityRisingEdge ];
[ self aiSampleStop:( _aiChannelsToRecord > 1 ) ? TRUE : FALSE ];
[ self aiNumberOfSamples:_aiFramesPerBuffer :0 :continuous ];
[ self aiSampleStart:scanInterval :3 :kAISTARTSelectSITC :kAISTARTPolarityRisingEdge ];
[ self aiConvert:convert :3 :FALSE ];
[ self aiClearFifo ];
}
// Actually read the values
// Raw values
-( UInt32 )aiGetNextValue {
if( _debug ) NSLog( @"[ %@ getNextValue ]", [ self description ] );
UInt32 val = read32( kDAQSTC, kAIFIFOData );
return val;
}
// Normalized Values
-( double )aiGetNormalizedValue {
double scalar = 1 << ( _aiResolution - 1 );
SInt32 val = [ self aiGetNextValue ];
return ( double )( val / scalar );
}
Here's the E-Series code:
// Set up the acquisition
-( void )aiSetup {
UInt32 i;
UInt32 scanInterval = ( UInt32 )floor( 20000000. / _aiSampleRate );
UInt32 convert = 280;
UInt32 delay = 3;
if( _debug ) NSLog( @"aiScanInterval: %d", scanInterval );
BOOL continuous = FALSE;
// From nidaq.h
[ super aiSetup ];
[ self initMITE ];
// Configure_Board
[ self aiClearConfigurationMemory ];
[ self aiClearFifo ];
for( i = _aiFirstChannel; i < ( _aiFirstChannel + _aiChannelsToRecord ); i++ ) {
if( _debug ) NSLog( @"aiChannelConfig: %d, %d, %@, %d, %@", i, _aiGainIndex, ( kBiPolar ) ? @"bi" : @"uni", _aiChannelType, ( i == ( ( _aiFirstChannel + _aiChannelsToRecord ) - 1 ) ) ? @"last" : @"not last" );
[ self aiConfigureChannel:i :_aiGainIndex :kBiPolar :_aiChannelType
😞 i == ( ( _aiFirstChannel + _aiChannelsToRecord ) - 1 ) ) ? TRUE : FALSE ];
}
// Set the timebase
[ self configureTimebase ];
// Clear the FIFO Queue
[ self aiClearFifo ];
// Stop any activities in progress
[ self aiReset ];
// Set the DAQ for the board
[ self aiPersonalize:_aiNIConvertOutputSelect ];
// Access the first vaule in the FIFO
[ self aiInitializeConfigurationMemoryOutput ];
// Setup the external multiplexer (if needed)
[ self aiEnvironmentalize ];
// Set Triggering Options
[ self aiTrigger:kAISTART1SelectPulse :kAISTART1PolarityRisingEdge :kAISTART2SelectPulse :kAISTART2PolarityRisingEdge ];
// Set the number of scans
[ self aiNumberOfSamples:_aiFramesPerBuffer :0 :continuous ];
// Set the scan start event
[ self aiSampleStart:scanInterval :delay :kAISTARTSelectSITC :kAISTARTPolarityRisingEdge ];
// Set the end of scan event
[ self aiSampleStop:( _aiChannelsToRecord > 1 ) ? TRUE : FALSE ];
// Select the convert signal
[ self aiConvert:convert :delay :FALSE ];
// Clear the FIFO Queue
[ self aiClearFifo ];
}
// Raw Values
-( UInt32 )aiGetNextValue {
if( _debug ) NSLog( @"[ %@ aiGetNextValue ]", [ self name ] );
return ( UInt32 )read16( kDAQSTC, ADC_FIFO_Data_Register );
}
// Normalized values
-( double )aiGetNormalizedValue {
double scalar = 1 << ( _aiResolution - 1 );
UInt16 raw = read16( kDAQSTC, ADC_FIFO_Data_Register );
return ( double )( ( SInt16 )raw / scalar );
}
When I read in the normalized E-Series values, something weird happens. According to the daq-stc manual, when a channel is configured in Bi-Polar mode, it should return a signed, twos-complement integer. However, when I debug or log the data coming off of the card directly, the sign bit gets cleared on every other sample, so for a pulse train I get scaled values like:
+.9999997
-.9999997
(repeats)
+.0000032
-.0000032
(repeats)
instead of:
.9999997
(repeats)
.00000032
(repeats)
What could be causing this? Is there some additional bit flipping going on that I should be aware of on the E-Series cards?
----
Rob Dotson
Asst. Research Scientist
Center for Neural Science
New York University