diff --git a/CHANGELOG.md b/CHANGELOG.md index 83d1d3267b..7fefe411b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -558,6 +558,7 @@ #### [nidigital] Unreleased - Added - (Common) Added `nitlsconfig[grpc]>=1.0.0a2` to the optional gRPC dependencies. + - Added the `nidigital_source_waveform.py` example. - Changed - Removed diff --git a/docs/nidigital/examples.rst b/docs/nidigital/examples.rst index b8c8cc689a..303dcff661 100644 --- a/docs/nidigital/examples.rst +++ b/docs/nidigital/examples.rst @@ -30,3 +30,12 @@ nidigital_ppmu_source_and_measure.py :encoding: utf8 :caption: `(nidigital_ppmu_source_and_measure.py) `_ +nidigital_source_waveform.py +---------------------------- + +.. literalinclude:: ../../src/nidigital/examples/source_waveform/nidigital_source_waveform.py + :language: python + :linenos: + :encoding: utf8 + :caption: `(nidigital_source_waveform.py) `_ + diff --git a/src/nidigital/examples/source_waveform/Pattern.digipat b/src/nidigital/examples/source_waveform/Pattern.digipat new file mode 100644 index 0000000000..0ee9d4fef9 Binary files /dev/null and b/src/nidigital/examples/source_waveform/Pattern.digipat differ diff --git a/src/nidigital/examples/source_waveform/PinLevels.digilevels b/src/nidigital/examples/source_waveform/PinLevels.digilevels new file mode 100644 index 0000000000..1908b117fa --- /dev/null +++ b/src/nidigital/examples/source_waveform/PinLevels.digilevels @@ -0,0 +1,15 @@ + + + + + + 0 + 3.3 + 0.8 + 2 + 0 + HighZ + + + + \ No newline at end of file diff --git a/src/nidigital/examples/source_waveform/PinMap.pinmap b/src/nidigital/examples/source_waveform/PinMap.pinmap new file mode 100644 index 0000000000..46d985a9f9 --- /dev/null +++ b/src/nidigital/examples/source_waveform/PinMap.pinmap @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/nidigital/examples/source_waveform/SourceWaveform.tdms b/src/nidigital/examples/source_waveform/SourceWaveform.tdms new file mode 100644 index 0000000000..4f85ffcdff Binary files /dev/null and b/src/nidigital/examples/source_waveform/SourceWaveform.tdms differ diff --git a/src/nidigital/examples/source_waveform/Specifications.specs b/src/nidigital/examples/source_waveform/Specifications.specs new file mode 100644 index 0000000000..65c615cfd6 --- /dev/null +++ b/src/nidigital/examples/source_waveform/Specifications.specs @@ -0,0 +1,9 @@ + + +
+ + 1 µs + +
+ +
\ No newline at end of file diff --git a/src/nidigital/examples/source_waveform/Timing.digitiming b/src/nidigital/examples/source_waveform/Timing.digitiming new file mode 100644 index 0000000000..b5908eabfb --- /dev/null +++ b/src/nidigital/examples/source_waveform/Timing.digitiming @@ -0,0 +1,23 @@ + + + + + + timing.period + + + + 0 ns + timing.period / 2 + timing.period + + + (3 * timing.period) / 4 + + Pattern + + + + + + \ No newline at end of file diff --git a/src/nidigital/examples/source_waveform/nidigital_source_waveform.py b/src/nidigital/examples/source_waveform/nidigital_source_waveform.py new file mode 100644 index 0000000000..266d731ca5 --- /dev/null +++ b/src/nidigital/examples/source_waveform/nidigital_source_waveform.py @@ -0,0 +1,100 @@ +#!/usr/bin/python + +import argparse +import nidigital +import os +import sys + + +def example(resource_name, options, source_waveform_type='PARALLEL', data_mapping='BROADCAST', waveform_name='new_waveform', start_label='new_pattern', + parallel_channel_list='PinGroup1', serial_channel_list='DUTPin1', sample_width=32, bit_order='MSB', waveform_file=None, write_waveform_data=True): + + with nidigital.Session(resource_name=resource_name, options=options) as session: + + dir = os.path.join(os.path.dirname(__file__)) + if waveform_file is None: + waveform_file = os.path.join(dir, 'SourceWaveform.tdms') + + session.load_pin_map(os.path.join(dir, 'PinMap.pinmap')) + + spec_filename = os.path.join(dir, 'Specifications.specs') + levels_filename = os.path.join(dir, 'PinLevels.digilevels') + timing_filename = os.path.join(dir, 'Timing.digitiming') + session.load_specifications_levels_and_timing(spec_filename, levels_filename, timing_filename) + + session.apply_levels_and_timing(levels_filename, timing_filename) + + session.load_pattern(os.path.join(dir, 'Pattern.digipat')) + + mapping = nidigital.SourceDataMapping[data_mapping] + + # Configure the source waveform type + if source_waveform_type == 'PARALLEL': + session.pins[parallel_channel_list].create_source_waveform_parallel(waveform_name, mapping) + elif source_waveform_type == 'SERIAL': + session.pins[serial_channel_list].create_source_waveform_serial(waveform_name, mapping, sample_width, nidigital.BitOrder[bit_order]) + elif source_waveform_type == 'TDMS': + # Waveform configuration and data are read from the TDMS file + session.create_source_waveform_from_file_tdms(waveform_name, waveform_file, write_waveform_data) + + # Write the source waveform data + if source_waveform_type != 'TDMS': + # Placeholder ramp data for illustration; replace with your own waveform samples + sample_count = 2 ** min(sample_width, 8) if source_waveform_type == 'SERIAL' else 256 + samples = [i % sample_count for i in range(sample_count)] + if mapping == nidigital.SourceDataMapping.BROADCAST: + session.write_source_waveform_broadcast(waveform_name, samples) + else: + # Site-unique data is a dict of site number to samples; both sites use the same placeholder data here + session.write_source_waveform_site_unique(waveform_name, {0: samples, 1: samples}) + + print('Start bursting pattern') + session.burst_pattern(start_label=start_label) + + session.selected_function = nidigital.SelectedFunction.DISCONNECT + print('Done bursting pattern') + + +def _main(argsv): + parser = argparse.ArgumentParser(description='Demonstrates how to configure, write, and burst a source waveform using NI-Digital source memory.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('-n', '--resource-name', default='PXI1Slot2,PXI1Slot3', help='The specified resource name shown in Measurement & Automation Explorer (MAX) for a digital pattern instrument, for example, PXI1Slot3, where PXI1Slot3 is an instrument resource name.') + parser.add_argument('-s', '--simulate', default='True', choices=['True', 'False'], help='Whether to run on simulated hardware or real hardware') + parser.add_argument('-w', '--waveform-name', default='new_waveform', help='The name to assign to the waveform. Use the waveform_name with source_start opcode in your pattern.') + parser.add_argument('-l', '--start-label', default='new_pattern', help='Pattern name or exported pattern label from which to start bursting the pattern.') + parser.add_argument('-d', '--data-mapping', default='BROADCAST', choices=nidigital.SourceDataMapping.__members__.keys(), type=str.upper, help='Parameter that specifies how to map data on multiple sites.') + parser.add_argument('-t', '--source-waveform-type', default='PARALLEL', choices=['PARALLEL', 'SERIAL', 'TDMS'], type=str.upper, help='Type of source waveform to configure.') + parser.add_argument('--parallel-channel-list', default='PinGroup1', help='Pins that source data for a parallel waveform.') + parser.add_argument('--serial-channel-list', default='DUTPin1', help='Pins that source data for a serial waveform.') + parser.add_argument('--sample-width', default=32, type=int, help='Width in bits of each serial sample. Valid values are between 1 and 32.') + parser.add_argument('--bit-order', default='MSB', choices=nidigital.BitOrder.__members__.keys(), type=str.upper, help='Order in which to shift the bits.') + parser.add_argument('--waveform-file', default=None, help='Absolute file path to the load source waveform file (.tdms). Defaults to SourceWaveform.tdms next to this example.') + parser.add_argument('--write-waveform-data', default='True', choices=['True', 'False'], help='A Boolean that writes waveform data to source memory if True and the waveform data is in the file.') + args = parser.parse_args(argsv) + + example(args.resource_name, + 'Simulate=1, DriverSetup=Model:6571' if args.simulate == 'True' else '', + args.source_waveform_type, args.data_mapping, args.waveform_name, args.start_label, + args.parallel_channel_list, args.serial_channel_list, args.sample_width, args.bit_order, + args.waveform_file, args.write_waveform_data == 'True') + + +def main(): + _main(sys.argv[1:]) + + +def test_main(): + _main([]) + _main(['--source-waveform-type', 'SERIAL', '--data-mapping', 'SITE_UNIQUE']) + _main(['--source-waveform-type', 'TDMS']) + + +def test_example(): + resource_name = 'PXI1Slot2,PXI1Slot3' + options = {'simulate': True, 'driver_setup': {'Model': '6571'}, } + example(resource_name, options) + example(resource_name, options, 'SERIAL', 'SITE_UNIQUE') + example(resource_name, options, 'TDMS') + + +if __name__ == '__main__': + main() diff --git a/src/nidigital/examples/source_waveform/source_waveform.digiproj b/src/nidigital/examples/source_waveform/source_waveform.digiproj new file mode 100644 index 0000000000..971b8ff9b9 --- /dev/null +++ b/src/nidigital/examples/source_waveform/source_waveform.digiproj @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file