From 67ec63f5479ee869e948cea7a9ef80473e1fd2be Mon Sep 17 00:00:00 2001 From: sbethur <48041236+sbethur@users.noreply.github.com> Date: Mon, 2 Mar 2020 10:06:01 -0600 Subject: [PATCH 1/3] Added pins rep cap for just methods --- docs/nidigital/class.rst | 24 ++-- generated/nidigital/nidigital/session.py | 104 ++++++++++-------- src/nidigital/metadata/functions.py | 4 + .../system_tests/test_system_nidigital.py | 10 ++ 4 files changed, 86 insertions(+), 56 deletions(-) diff --git a/docs/nidigital/class.rst b/docs/nidigital/class.rst index 89e91a918..3cb9a35b2 100644 --- a/docs/nidigital/class.rst +++ b/docs/nidigital/class.rst @@ -645,21 +645,23 @@ configure_time_set_drive_format .. py:currentmodule:: nidigital.Session - .. py:method:: configure_time_set_drive_format(pin_list, time_set, drive_format) + .. py:method:: configure_time_set_drive_format(time_set, drive_format) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].configure_time_set_drive_format(time_set, drive_format) - :type pin_list: str :param time_set: @@ -1650,21 +1652,23 @@ get_time_set_drive_format .. py:currentmodule:: nidigital.Session - .. py:method:: get_time_set_drive_format(pin, time_set) + .. py:method:: get_time_set_drive_format(time_set) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin: - + .. code:: python - + session.pins[0,1].get_time_set_drive_format(time_set) - :type pin: str :param time_set: diff --git a/generated/nidigital/nidigital/session.py b/generated/nidigital/nidigital/session.py index 294f5606e..5213504a0 100644 --- a/generated/nidigital/nidigital/session.py +++ b/generated/nidigital/nidigital/session.py @@ -767,6 +767,34 @@ def configure_active_load_levels(self, iol, ioh, vcom): errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return + @ivi_synchronized + def configure_time_set_drive_format(self, time_set, drive_format): + r'''configure_time_set_drive_format + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].configure_time_set_drive_format(time_set, drive_format) + + Args: + time_set (str): + + drive_format (int): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + drive_format_ctype = _visatype.ViInt32(drive_format) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetDriveFormat(vi_ctype, pin_list_ctype, time_set_ctype, drive_format_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + @ivi_synchronized def configure_voltage_levels(self, vil, vih, vol, voh, vterm): r'''configure_voltage_levels @@ -1183,6 +1211,36 @@ def _get_pin_results_pin_information(self): errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return [int(pin_indexes_ctype[i]) for i in range(buffer_size_ctype.value)], [int(site_numbers_ctype[i]) for i in range(buffer_size_ctype.value)], [int(channel_indexes_ctype[i]) for i in range(buffer_size_ctype.value)] + @ivi_synchronized + def get_time_set_drive_format(self, time_set): + r'''get_time_set_drive_format + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].get_time_set_drive_format(time_set) + + Args: + time_set (str): + + + Returns: + format (int): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + format_ctype = _visatype.ViInt32() # case S220 + error_code = self._library.niDigital_GetTimeSetDriveFormat(vi_ctype, pin_ctype, time_set_ctype, None if format_ctype is None else (ctypes.pointer(format_ctype))) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return int(format_ctype.value) + def lock(self): '''lock @@ -1925,28 +1983,6 @@ def configure_time_set_drive_edges2x(self, pin_list, time_set, format, drive_on_ errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return - @ivi_synchronized - def configure_time_set_drive_format(self, pin_list, time_set, drive_format): - r'''configure_time_set_drive_format - - TBD - - Args: - pin_list (str): - - time_set (str): - - drive_format (int): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - drive_format_ctype = _visatype.ViInt32(drive_format) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetDriveFormat(vi_ctype, pin_list_ctype, time_set_ctype, drive_format_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - @ivi_synchronized def configure_time_set_edge(self, pin_list, time_set, edge, time): r'''configure_time_set_edge @@ -2746,30 +2782,6 @@ def get_site_results_site_numbers(self, site_list, site_result_type): errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return [int(site_numbers_ctype[i]) for i in range(site_numbers_buffer_size_ctype.value)] - @ivi_synchronized - def get_time_set_drive_format(self, pin, time_set): - r'''get_time_set_drive_format - - TBD - - Args: - pin (str): - - time_set (str): - - - Returns: - format (int): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_ctype = ctypes.create_string_buffer(pin.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - format_ctype = _visatype.ViInt32() # case S220 - error_code = self._library.niDigital_GetTimeSetDriveFormat(vi_ctype, pin_ctype, time_set_ctype, None if format_ctype is None else (ctypes.pointer(format_ctype))) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return int(format_ctype.value) - @ivi_synchronized def get_time_set_edge(self, pin, time_set, edge): r'''get_time_set_edge diff --git a/src/nidigital/metadata/functions.py b/src/nidigital/metadata/functions.py index e804b374f..ecf45fc96 100644 --- a/src/nidigital/metadata/functions.py +++ b/src/nidigital/metadata/functions.py @@ -463,6 +463,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -1723,6 +1725,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pin', 'type': 'ViConstString' }, diff --git a/src/nidigital/system_tests/test_system_nidigital.py b/src/nidigital/system_tests/test_system_nidigital.py index c5e970fe6..4c85c76ec 100644 --- a/src/nidigital/system_tests/test_system_nidigital.py +++ b/src/nidigital/system_tests/test_system_nidigital.py @@ -22,11 +22,21 @@ def multi_instrument_session(): def test_pins_rep_cap(multi_instrument_session): multi_instrument_session.load_pin_map(os.path.join(test_files_base_dir, "pin_map.pinmap")) + # Channel-based properties multi_instrument_session.vil = 1 multi_instrument_session.pins['PinA', 'PinB', 'PinC'].vil = 2 assert multi_instrument_session.pins['DutPins'].vil == pytest.approx(2, abs=1e-3) assert multi_instrument_session.pins['SysPins'].vil == pytest.approx(1, abs=1e-3) + # Methods that accept channel_list parameter + states = multi_instrument_session.pins['PinA', 'PinB'].read_static() + assert len(states) == 4 # 2 sites per pin + + # Methods that accept pin_list parameter + multi_instrument_session.create_time_set('t0') + multi_instrument_session.pins['PinA', 'PinB'].configure_time_set_drive_format('t0', 1501) + drive_format = multi_instrument_session.pins['PinA', 'PinB'].get_time_set_drive_format('t0') + assert drive_format == 1501 def test_property_boolean(multi_instrument_session): channel = multi_instrument_session.get_channel_name(index=42) From 48db1734dd842398dde62032147f101d624e24d5 Mon Sep 17 00:00:00 2001 From: sbethur <48041236+sbethur@users.noreply.github.com> Date: Tue, 3 Mar 2020 16:53:42 -0600 Subject: [PATCH 2/3] Update methods to use pins repeated capability --- docs/nidigital/class.rst | 170 +-- generated/nidigital/nidigital/session.py | 1150 +++++++++-------- src/nidigital/metadata/functions.py | 26 + src/nidigital/metadata/functions_addon.py | 13 +- .../system_tests/test_system_nidigital.py | 33 +- ...etch_history_ram_cycle_information.py.mako | 2 +- 6 files changed, 762 insertions(+), 632 deletions(-) diff --git a/docs/nidigital/class.rst b/docs/nidigital/class.rst index 3cb9a35b2..55fdea4b9 100644 --- a/docs/nidigital/class.rst +++ b/docs/nidigital/class.rst @@ -428,21 +428,23 @@ configure_time_set_compare_edges_strobe .. py:currentmodule:: nidigital.Session - .. py:method:: configure_time_set_compare_edges_strobe(pin_list, time_set, strobe_edge) + .. py:method:: configure_time_set_compare_edges_strobe(time_set, strobe_edge) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].configure_time_set_compare_edges_strobe(time_set, strobe_edge) - :type pin_list: str :param time_set: @@ -463,21 +465,23 @@ configure_time_set_compare_edges_strobe2x .. py:currentmodule:: nidigital.Session - .. py:method:: configure_time_set_compare_edges_strobe2x(pin_list, time_set, strobe_edge, strobe2_edge) + .. py:method:: configure_time_set_compare_edges_strobe2x(time_set, strobe_edge, strobe2_edge) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: + .. code:: python + session.pins[0,1].configure_time_set_compare_edges_strobe2x(time_set, strobe_edge, strobe2_edge) - - - :type pin_list: str :param time_set: @@ -505,21 +509,23 @@ configure_time_set_drive_edges .. py:currentmodule:: nidigital.Session - .. py:method:: configure_time_set_drive_edges(pin_list, time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge) + .. py:method:: configure_time_set_drive_edges(time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].configure_time_set_drive_edges(time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge) - :type pin_list: str :param time_set: @@ -568,21 +574,23 @@ configure_time_set_drive_edges2x .. py:currentmodule:: nidigital.Session - .. py:method:: configure_time_set_drive_edges2x(pin_list, time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge, drive_data2_edge, drive_return2_edge) + .. py:method:: configure_time_set_drive_edges2x(time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge, drive_data2_edge, drive_return2_edge) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].configure_time_set_drive_edges2x(time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge, drive_data2_edge, drive_return2_edge) - :type pin_list: str :param time_set: @@ -682,21 +690,23 @@ configure_time_set_edge .. py:currentmodule:: nidigital.Session - .. py:method:: configure_time_set_edge(pin_list, time_set, edge, time) + .. py:method:: configure_time_set_edge(time_set, edge, time) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].configure_time_set_edge(time_set, edge, time) - :type pin_list: str :param time_set: @@ -724,21 +734,23 @@ configure_time_set_edge_multiplier .. py:currentmodule:: nidigital.Session - .. py:method:: configure_time_set_edge_multiplier(pin_list, time_set, edge_multiplier) + .. py:method:: configure_time_set_edge_multiplier(time_set, edge_multiplier) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].configure_time_set_edge_multiplier(time_set, edge_multiplier) - :type pin_list: str :param time_set: @@ -873,21 +885,23 @@ create_capture_waveform_parallel .. py:currentmodule:: nidigital.Session - .. py:method:: create_capture_waveform_parallel(pin_list, waveform_name) + .. py:method:: create_capture_waveform_parallel(waveform_name) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].create_capture_waveform_parallel(waveform_name) - :type pin_list: str :param waveform_name: @@ -901,21 +915,23 @@ create_capture_waveform_serial .. py:currentmodule:: nidigital.Session - .. py:method:: create_capture_waveform_serial(pin_list, waveform_name, sample_width, bit_order) + .. py:method:: create_capture_waveform_serial(waveform_name, sample_width, bit_order) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].create_capture_waveform_serial(waveform_name, sample_width, bit_order) - :type pin_list: str :param waveform_name: @@ -978,21 +994,23 @@ create_source_waveform_parallel .. py:currentmodule:: nidigital.Session - .. py:method:: create_source_waveform_parallel(pin_list, waveform_name, data_mapping) + .. py:method:: create_source_waveform_parallel(waveform_name, data_mapping) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].create_source_waveform_parallel(waveform_name, data_mapping) - :type pin_list: str :param waveform_name: @@ -1013,21 +1031,23 @@ create_source_waveform_serial .. py:currentmodule:: nidigital.Session - .. py:method:: create_source_waveform_serial(pin_list, waveform_name, data_mapping, sample_width, bit_order) + .. py:method:: create_source_waveform_serial(waveform_name, data_mapping, sample_width, bit_order) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin_list: - + .. code:: python - + session.pins[0,1].create_source_waveform_serial(waveform_name, data_mapping, sample_width, bit_order) - :type pin_list: str :param waveform_name: @@ -1190,7 +1210,7 @@ fetch_history_ram_cycle_information .. py:currentmodule:: nidigital.Session - .. py:method:: fetch_history_ram_cycle_information(site, pin_list, position, samples_to_read) + .. py:method:: fetch_history_ram_cycle_information(site, position, samples_to_read) Returns the pattern information acquired for the specified cycles. @@ -1198,9 +1218,22 @@ fetch_history_ram_cycle_information consist of multiple DUT cycles. When using pins with mixed edge multipliers, pins may return :py:data:`~nidigital.DigitalState.PIN_STATE_NOT_ACQUIRED` for DUT cycles where those pins do not have edges defined. + If pins are not specified, pin list from the pattern containing the start label is used. Call + :py:meth:`nidigital.Session.get_pattern_pin_list` or :py:meth:`nidigital.Session.get_pattern_pin_indexes` with the start label to retrieve the pins + associated with the pattern burst. + + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + .. code:: python + + session.pins[0,1].fetch_history_ram_cycle_information(site, position, samples_to_read) + :param site: @@ -1212,17 +1245,6 @@ fetch_history_ram_cycle_information :type site: str - :param pin_list: - - - Pins for which to retrieve History RAM data. If empty, the pin list from the pattern - containing the start label is used. Call :py:meth:`nidigital.Session.get_pattern_pin_list` or :py:meth:`nidigital.Session.get_pattern_pin_indexes` with the start - label to retrieve the pins associated with the pattern burst. - - - - - :type pin_list: str :param position: @@ -1690,21 +1712,23 @@ get_time_set_edge .. py:currentmodule:: nidigital.Session - .. py:method:: get_time_set_edge(pin, time_set, edge) + .. py:method:: get_time_set_edge(time_set, edge) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin: - + .. code:: python - + session.pins[0,1].get_time_set_edge(time_set, edge) - :type pin: str :param time_set: @@ -1733,21 +1757,23 @@ get_time_set_edge_multiplier .. py:currentmodule:: nidigital.Session - .. py:method:: get_time_set_edge_multiplier(pin, time_set) + .. py:method:: get_time_set_edge_multiplier(time_set) TBD + .. tip:: This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: - :param pin: - + .. code:: python - + session.pins[0,1].get_time_set_edge_multiplier(time_set) - :type pin: str :param time_set: diff --git a/generated/nidigital/nidigital/session.py b/generated/nidigital/nidigital/session.py index 5213504a0..34b3bdcce 100644 --- a/generated/nidigital/nidigital/session.py +++ b/generated/nidigital/nidigital/session.py @@ -767,6 +767,151 @@ def configure_active_load_levels(self, iol, ioh, vcom): errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return + @ivi_synchronized + def configure_time_set_compare_edges_strobe(self, time_set, strobe_edge): + r'''configure_time_set_compare_edges_strobe + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].configure_time_set_compare_edges_strobe(time_set, strobe_edge) + + Args: + time_set (str): + + strobe_edge (float): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + strobe_edge_ctype = _visatype.ViReal64(strobe_edge) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetCompareEdgesStrobe(vi_ctype, pin_list_ctype, time_set_ctype, strobe_edge_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def configure_time_set_compare_edges_strobe2x(self, time_set, strobe_edge, strobe2_edge): + r'''configure_time_set_compare_edges_strobe2x + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].configure_time_set_compare_edges_strobe2x(time_set, strobe_edge, strobe2_edge) + + Args: + time_set (str): + + strobe_edge (float): + + strobe2_edge (float): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + strobe_edge_ctype = _visatype.ViReal64(strobe_edge) # case S150 + strobe2_edge_ctype = _visatype.ViReal64(strobe2_edge) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetCompareEdgesStrobe2x(vi_ctype, pin_list_ctype, time_set_ctype, strobe_edge_ctype, strobe2_edge_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def configure_time_set_drive_edges(self, time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge): + r'''configure_time_set_drive_edges + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].configure_time_set_drive_edges(time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge) + + Args: + time_set (str): + + format (int): + + drive_on_edge (float): + + drive_data_edge (float): + + drive_return_edge (float): + + drive_off_edge (float): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + format_ctype = _visatype.ViInt32(format) # case S150 + drive_on_edge_ctype = _visatype.ViReal64(drive_on_edge) # case S150 + drive_data_edge_ctype = _visatype.ViReal64(drive_data_edge) # case S150 + drive_return_edge_ctype = _visatype.ViReal64(drive_return_edge) # case S150 + drive_off_edge_ctype = _visatype.ViReal64(drive_off_edge) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetDriveEdges(vi_ctype, pin_list_ctype, time_set_ctype, format_ctype, drive_on_edge_ctype, drive_data_edge_ctype, drive_return_edge_ctype, drive_off_edge_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def configure_time_set_drive_edges2x(self, time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge, drive_data2_edge, drive_return2_edge): + r'''configure_time_set_drive_edges2x + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].configure_time_set_drive_edges2x(time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge, drive_data2_edge, drive_return2_edge) + + Args: + time_set (str): + + format (int): + + drive_on_edge (float): + + drive_data_edge (float): + + drive_return_edge (float): + + drive_off_edge (float): + + drive_data2_edge (float): + + drive_return2_edge (float): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + format_ctype = _visatype.ViInt32(format) # case S150 + drive_on_edge_ctype = _visatype.ViReal64(drive_on_edge) # case S150 + drive_data_edge_ctype = _visatype.ViReal64(drive_data_edge) # case S150 + drive_return_edge_ctype = _visatype.ViReal64(drive_return_edge) # case S150 + drive_off_edge_ctype = _visatype.ViReal64(drive_off_edge) # case S150 + drive_data2_edge_ctype = _visatype.ViReal64(drive_data2_edge) # case S150 + drive_return2_edge_ctype = _visatype.ViReal64(drive_return2_edge) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetDriveEdges2x(vi_ctype, pin_list_ctype, time_set_ctype, format_ctype, drive_on_edge_ctype, drive_data_edge_ctype, drive_return_edge_ctype, drive_off_edge_ctype, drive_data2_edge_ctype, drive_return2_edge_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + @ivi_synchronized def configure_time_set_drive_format(self, time_set, drive_format): r'''configure_time_set_drive_format @@ -779,58 +924,356 @@ def configure_time_set_drive_format(self, time_set, drive_format): You can specify a subset of repeated capabilities using the Python index notation on an nidigital.Session repeated capabilities container, and calling this method on the result.: - session.pins[0,1].configure_time_set_drive_format(time_set, drive_format) + session.pins[0,1].configure_time_set_drive_format(time_set, drive_format) + + Args: + time_set (str): + + drive_format (int): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + drive_format_ctype = _visatype.ViInt32(drive_format) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetDriveFormat(vi_ctype, pin_list_ctype, time_set_ctype, drive_format_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def configure_time_set_edge(self, time_set, edge, time): + r'''configure_time_set_edge + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].configure_time_set_edge(time_set, edge, time) + + Args: + time_set (str): + + edge (int): + + time (float): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + edge_ctype = _visatype.ViInt32(edge) # case S150 + time_ctype = _visatype.ViReal64(time) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetEdge(vi_ctype, pin_list_ctype, time_set_ctype, edge_ctype, time_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def configure_time_set_edge_multiplier(self, time_set, edge_multiplier): + r'''configure_time_set_edge_multiplier + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].configure_time_set_edge_multiplier(time_set, edge_multiplier) + + Args: + time_set (str): + + edge_multiplier (int): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + edge_multiplier_ctype = _visatype.ViInt32(edge_multiplier) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetEdgeMultiplier(vi_ctype, pin_list_ctype, time_set_ctype, edge_multiplier_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def configure_voltage_levels(self, vil, vih, vol, voh, vterm): + r'''configure_voltage_levels + + TBD + + Tip: + This method requires repeated capabilities (channels). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.channels[0,1].configure_voltage_levels(vil, vih, vol, voh, vterm) + + Args: + vil (float): + + vih (float): + + vol (float): + + voh (float): + + vterm (float): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + channel_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + vil_ctype = _visatype.ViReal64(vil) # case S150 + vih_ctype = _visatype.ViReal64(vih) # case S150 + vol_ctype = _visatype.ViReal64(vol) # case S150 + voh_ctype = _visatype.ViReal64(voh) # case S150 + vterm_ctype = _visatype.ViReal64(vterm) # case S150 + error_code = self._library.niDigital_ConfigureVoltageLevels(vi_ctype, channel_list_ctype, vil_ctype, vih_ctype, vol_ctype, voh_ctype, vterm_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def create_capture_waveform_parallel(self, waveform_name): + r'''create_capture_waveform_parallel + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].create_capture_waveform_parallel(waveform_name) + + Args: + waveform_name (str): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 + error_code = self._library.niDigital_CreateCaptureWaveformParallel(vi_ctype, pin_list_ctype, waveform_name_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def create_capture_waveform_serial(self, waveform_name, sample_width, bit_order): + r'''create_capture_waveform_serial + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].create_capture_waveform_serial(waveform_name, sample_width, bit_order) + + Args: + waveform_name (str): + + sample_width (int): + + bit_order (int): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 + sample_width_ctype = _visatype.ViUInt32(sample_width) # case S150 + bit_order_ctype = _visatype.ViInt32(bit_order) # case S150 + error_code = self._library.niDigital_CreateCaptureWaveformSerial(vi_ctype, pin_list_ctype, waveform_name_ctype, sample_width_ctype, bit_order_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def create_source_waveform_parallel(self, waveform_name, data_mapping): + r'''create_source_waveform_parallel + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].create_source_waveform_parallel(waveform_name, data_mapping) + + Args: + waveform_name (str): + + data_mapping (int): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 + data_mapping_ctype = _visatype.ViInt32(data_mapping) # case S150 + error_code = self._library.niDigital_CreateSourceWaveformParallel(vi_ctype, pin_list_ctype, waveform_name_ctype, data_mapping_ctype) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return + + @ivi_synchronized + def create_source_waveform_serial(self, waveform_name, data_mapping, sample_width, bit_order): + r'''create_source_waveform_serial + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].create_source_waveform_serial(waveform_name, data_mapping, sample_width, bit_order) Args: - time_set (str): + waveform_name (str): - drive_format (int): + data_mapping (int): + + sample_width (int): + + bit_order (int): ''' vi_ctype = _visatype.ViSession(self._vi) # case S110 pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - drive_format_ctype = _visatype.ViInt32(drive_format) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetDriveFormat(vi_ctype, pin_list_ctype, time_set_ctype, drive_format_ctype) + waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 + data_mapping_ctype = _visatype.ViInt32(data_mapping) # case S150 + sample_width_ctype = _visatype.ViUInt32(sample_width) # case S150 + bit_order_ctype = _visatype.ViInt32(bit_order) # case S150 + error_code = self._library.niDigital_CreateSourceWaveformSerial(vi_ctype, pin_list_ctype, waveform_name_ctype, data_mapping_ctype, sample_width_ctype, bit_order_ctype) errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return @ivi_synchronized - def configure_voltage_levels(self, vil, vih, vol, voh, vterm): - r'''configure_voltage_levels + def fetch_history_ram_cycle_information(self, site, position, samples_to_read): + '''fetch_history_ram_cycle_information - TBD + Returns the pattern information acquired for the specified cycles. + + If the pattern is using the edge multiplier feature, cycle numbers represent tester cycles, each of which may + consist of multiple DUT cycles. When using pins with mixed edge multipliers, pins may return + DigitalState.PIN_STATE_NOT_ACQUIRED for DUT cycles where those pins do not have edges defined. + + If pins are not specified, pin list from the pattern containing the start label is used. Call + get_pattern_pin_list or get_pattern_pin_indexes with the start label to retrieve the pins + associated with the pattern burst. Tip: - This method requires repeated capabilities (channels). If called directly on the + This method requires repeated capabilities (pins). If called directly on the nidigital.Session object, then the method will use all repeated capabilities in the session. You can specify a subset of repeated capabilities using the Python index notation on an nidigital.Session repeated capabilities container, and calling this method on the result.: - session.channels[0,1].configure_voltage_levels(vil, vih, vol, voh, vterm) + session.pins[0,1].fetch_history_ram_cycle_information(site, position, samples_to_read) Args: - vil (float): + site (str): Site on which to retrieve History RAM data. Specify site as a string in the form of siteN, + where N is the site number. The VI returns an error if more than one site is specified. - vih (float): + position (int): Sample index from which to start fetching pattern information. - vol (float): + samples_to_read (int): Number of samples to fetch. A value of -1 specifies to fetch all available samples. - voh (float): - vterm (float): + Returns: + history_ram_cycle_information (list of HistoryRAMCycleInformation): Returns a list of class instances with + the following information about each pattern cycle: + + - **pattern_name** (str) Name of the pattern for the acquired cycle. + - **time_set_name** (str) Time set for the acquired cycle. + - **vector_number** (int) Vector number within the pattern for the acquired cycle. Vector numbers start + at 0 from the beginning of the pattern. + - **cycle_number** (int) Cycle number acquired by this History RAM sample. Cycle numbers start at 0 + from the beginning of the pattern burst. + - **scan_cycle_number** (int) Scan cycle number acquired by this History RAM sample. Scan cycle numbers + start at 0 from the first cycle of the scan vector. Scan cycle numbers are -1 for cycles that do not + have a scan opcode. + - **expected_pin_states** (list of list of enums.DigitalState) Pin states as expected by the loaded + pattern in the order specified in the pin list. Pins without defined edges in the specified DUT cycle + will have a value of DigitalState.PIN_STATE_NOT_ACQUIRED. + Length of the outer list will be equal to the value of edge multiplier for the given vector. + Length of the inner list will be equal to the number of pins requested. + - **actual_pin_states** (list of list of enums.DigitalState) Pin states acquired by History RAM in the + order specified in the pin list. Pins without defined edges in the specified DUT cycle will have a + value of DigitalState.PIN_STATE_NOT_ACQUIRED. + Length of the outer list will be equal to the value of edge multiplier for the given vector. + Length of the inner list will be equal to the number of pins requested. + - **per_pin_pass_fail** (list of list of bool) Pass fail information for pins in the order specified in + the pin list. Pins without defined edges in the specified DUT cycle will have a value of pass (True). + Length of the outer list will be equal to the value of edge multiplier for the given vector. + Length of the inner list will be equal to the number of pins requested. ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - channel_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 - vil_ctype = _visatype.ViReal64(vil) # case S150 - vih_ctype = _visatype.ViReal64(vih) # case S150 - vol_ctype = _visatype.ViReal64(vol) # case S150 - voh_ctype = _visatype.ViReal64(voh) # case S150 - vterm_ctype = _visatype.ViReal64(vterm) # case S150 - error_code = self._library.niDigital_ConfigureVoltageLevels(vi_ctype, channel_list_ctype, vil_ctype, vih_ctype, vol_ctype, voh_ctype, vterm_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return + if position < 0: + raise ValueError('position should be greater than or equal to 0.') + + if samples_to_read < -1: + raise ValueError('samples_to_read should be greater than or equal to -1.') + + samples_available = self.get_history_ram_sample_count(site) + if position >= samples_available: + raise ValueError('position: Specified value = {0}, Maximum value = {1}.'.format(position, samples_available - 1)) + + if samples_to_read == -1: + if not self.history_ram_number_of_samples_is_finite: + raise RuntimeError( + 'Specifying -1 to fetch all History RAM samples is not supported when the digital pattern instrument is ' + 'configured for continuous History RAM acquisition. You must specify an exact number of samples to fetch.') + samples_to_read = samples_available - position + + if position + samples_to_read > samples_available: + raise ValueError( + 'position: Specified value = {0}, samples_to_read: Specified value = {1}; Samples available = {2}.' + .format(position, samples_to_read, samples_available - position)) + + pattern_names = {} + time_set_names = {} + cycle_infos = [] + for _ in range(samples_to_read): + + pattern_index, time_set_index, vector_number, cycle_number, num_dut_cycles = self._fetch_history_ram_cycle_information(site, position) + + if pattern_index not in pattern_names: + pattern_names[pattern_index] = self.get_pattern_name(pattern_index) + pattern_name = pattern_names[pattern_index] + + if time_set_index not in time_set_names: + time_set_names[time_set_index] = self.get_time_set_name(time_set_index) + time_set_name = time_set_names[time_set_index] + + scan_cycle_number = self._fetch_history_ram_scan_cycle_number(site, position) + + vector_expected_pin_states = [] + vector_actual_pin_states = [] + vector_per_pin_pass_fail = [] + for dut_cycle_index in range(num_dut_cycles): + cycle_expected_pin_states, cycle_actual_pin_states, cycle_per_pin_pass_fail = self._fetch_history_ram_cycle_pin_data(site, position, dut_cycle_index) + vector_expected_pin_states.append(cycle_expected_pin_states) + vector_actual_pin_states.append(cycle_actual_pin_states) + vector_per_pin_pass_fail.append(cycle_per_pin_pass_fail) + + cycle_infos.append(history_ram_cycle_information.HistoryRAMCycleInformation( + pattern_name=pattern_name, + time_set_name=time_set_name, + vector_number=vector_number, + cycle_number=cycle_number, + scan_cycle_number=scan_cycle_number, + expected_pin_states=vector_expected_pin_states, + actual_pin_states=vector_actual_pin_states, + per_pin_pass_fail=vector_per_pin_pass_fail)) + position += 1 + + return cycle_infos @ivi_synchronized def get_pin_results_pin_information(self): @@ -875,6 +1318,59 @@ def get_pin_results_pin_information(self): return pin_infos + @ivi_synchronized + def _fetch_history_ram_cycle_pin_data(self, site, sample_index, dut_cycle_index): + r'''_fetch_history_ram_cycle_pin_data + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1]._fetch_history_ram_cycle_pin_data(site, sample_index, dut_cycle_index) + + Args: + site (str): + + sample_index (int): + + dut_cycle_index (int): + + + Returns: + expected_pin_states (list of enums.DigitalState): + + actual_pin_states (list of enums.DigitalState): + + per_pin_pass_fail (list of bool): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + site_ctype = ctypes.create_string_buffer(site.encode(self._encoding)) # case C020 + pin_list_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + sample_index_ctype = _visatype.ViInt64(sample_index) # case S150 + dut_cycle_index_ctype = _visatype.ViInt32(dut_cycle_index) # case S150 + pin_data_buffer_size_ctype = _visatype.ViInt32(0) # case S190 + expected_pin_states_ctype = None # case B610 + actual_pin_states_ctype = None # case B610 + per_pin_pass_fail_ctype = None # case B610 + actual_num_pin_data_ctype = _visatype.ViInt32() # case S220 + error_code = self._library.niDigital_FetchHistoryRAMCyclePinData(vi_ctype, site_ctype, pin_list_ctype, sample_index_ctype, dut_cycle_index_ctype, pin_data_buffer_size_ctype, expected_pin_states_ctype, actual_pin_states_ctype, per_pin_pass_fail_ctype, None if actual_num_pin_data_ctype is None else (ctypes.pointer(actual_num_pin_data_ctype))) + errors.handle_error(self, error_code, ignore_warnings=True, is_error_handling=False) + pin_data_buffer_size_ctype = _visatype.ViInt32(actual_num_pin_data_ctype.value) # case S200 + expected_pin_states_size = actual_num_pin_data_ctype.value # case B620 + expected_pin_states_ctype = get_ctypes_pointer_for_buffer(library_type=_visatype.ViUInt8, size=expected_pin_states_size) # case B620 + actual_pin_states_size = actual_num_pin_data_ctype.value # case B620 + actual_pin_states_ctype = get_ctypes_pointer_for_buffer(library_type=_visatype.ViUInt8, size=actual_pin_states_size) # case B620 + per_pin_pass_fail_size = actual_num_pin_data_ctype.value # case B620 + per_pin_pass_fail_ctype = get_ctypes_pointer_for_buffer(library_type=_visatype.ViBoolean, size=per_pin_pass_fail_size) # case B620 + error_code = self._library.niDigital_FetchHistoryRAMCyclePinData(vi_ctype, site_ctype, pin_list_ctype, sample_index_ctype, dut_cycle_index_ctype, pin_data_buffer_size_ctype, expected_pin_states_ctype, actual_pin_states_ctype, per_pin_pass_fail_ctype, None if actual_num_pin_data_ctype is None else (ctypes.pointer(actual_num_pin_data_ctype))) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return [enums.DigitalState(expected_pin_states_ctype[i]) for i in range(pin_data_buffer_size_ctype.value)], [enums.DigitalState(actual_pin_states_ctype[i]) for i in range(pin_data_buffer_size_ctype.value)], [bool(per_pin_pass_fail_ctype[i]) for i in range(pin_data_buffer_size_ctype.value)] + @ivi_synchronized def frequency_counter_measure_frequency(self): r'''frequency_counter_measure_frequency @@ -1209,11 +1705,74 @@ def _get_pin_results_pin_information(self): channel_indexes_ctype = get_ctypes_pointer_for_buffer(library_type=_visatype.ViInt32, size=channel_indexes_size) # case B620 error_code = self._library.niDigital_GetPinResultsPinInformation(vi_ctype, channel_list_ctype, buffer_size_ctype, pin_indexes_ctype, site_numbers_ctype, channel_indexes_ctype, None if actual_num_values_ctype is None else (ctypes.pointer(actual_num_values_ctype))) errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return [int(pin_indexes_ctype[i]) for i in range(buffer_size_ctype.value)], [int(site_numbers_ctype[i]) for i in range(buffer_size_ctype.value)], [int(channel_indexes_ctype[i]) for i in range(buffer_size_ctype.value)] + return [int(pin_indexes_ctype[i]) for i in range(buffer_size_ctype.value)], [int(site_numbers_ctype[i]) for i in range(buffer_size_ctype.value)], [int(channel_indexes_ctype[i]) for i in range(buffer_size_ctype.value)] + + @ivi_synchronized + def get_time_set_drive_format(self, time_set): + r'''get_time_set_drive_format + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].get_time_set_drive_format(time_set) + + Args: + time_set (str): + + + Returns: + format (int): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + format_ctype = _visatype.ViInt32() # case S220 + error_code = self._library.niDigital_GetTimeSetDriveFormat(vi_ctype, pin_ctype, time_set_ctype, None if format_ctype is None else (ctypes.pointer(format_ctype))) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return int(format_ctype.value) + + @ivi_synchronized + def get_time_set_edge(self, time_set, edge): + r'''get_time_set_edge + + TBD + + Tip: + This method requires repeated capabilities (pins). If called directly on the + nidigital.Session object, then the method will use all repeated capabilities in the session. + You can specify a subset of repeated capabilities using the Python index notation on an + nidigital.Session repeated capabilities container, and calling this method on the result.: + + session.pins[0,1].get_time_set_edge(time_set, edge) + + Args: + time_set (str): + + edge (int): + + + Returns: + time (float): + + ''' + vi_ctype = _visatype.ViSession(self._vi) # case S110 + pin_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + edge_ctype = _visatype.ViInt32(edge) # case S150 + time_ctype = _visatype.ViReal64() # case S220 + error_code = self._library.niDigital_GetTimeSetEdge(vi_ctype, pin_ctype, time_set_ctype, edge_ctype, None if time_ctype is None else (ctypes.pointer(time_ctype))) + errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) + return float(time_ctype.value) @ivi_synchronized - def get_time_set_drive_format(self, time_set): - r'''get_time_set_drive_format + def get_time_set_edge_multiplier(self, time_set): + r'''get_time_set_edge_multiplier TBD @@ -1223,23 +1782,23 @@ def get_time_set_drive_format(self, time_set): You can specify a subset of repeated capabilities using the Python index notation on an nidigital.Session repeated capabilities container, and calling this method on the result.: - session.pins[0,1].get_time_set_drive_format(time_set) + session.pins[0,1].get_time_set_edge_multiplier(time_set) Args: time_set (str): Returns: - format (int): + edge_multiplier (int): ''' vi_ctype = _visatype.ViSession(self._vi) # case S110 pin_ctype = ctypes.create_string_buffer(self._repeated_capability.encode(self._encoding)) # case C010 time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - format_ctype = _visatype.ViInt32() # case S220 - error_code = self._library.niDigital_GetTimeSetDriveFormat(vi_ctype, pin_ctype, time_set_ctype, None if format_ctype is None else (ctypes.pointer(format_ctype))) + edge_multiplier_ctype = _visatype.ViInt32() # case S220 + error_code = self._library.niDigital_GetTimeSetEdgeMultiplier(vi_ctype, pin_ctype, time_set_ctype, None if edge_multiplier_ctype is None else (ctypes.pointer(edge_multiplier_ctype))) errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return int(format_ctype.value) + return int(edge_multiplier_ctype.value) def lock(self): '''lock @@ -1848,339 +2407,77 @@ def commit(self): @ivi_synchronized def configure_pattern_burst_sites(self, site_list): - r'''configure_pattern_burst_sites - - TBD - - Args: - site_list (str): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - site_list_ctype = ctypes.create_string_buffer(site_list.encode(self._encoding)) # case C020 - error_code = self._library.niDigital_ConfigurePatternBurstSites(vi_ctype, site_list_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def configure_time_set_compare_edges_strobe(self, pin_list, time_set, strobe_edge): - r'''configure_time_set_compare_edges_strobe - - TBD - - Args: - pin_list (str): - - time_set (str): - - strobe_edge (float): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - strobe_edge_ctype = _visatype.ViReal64(strobe_edge) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetCompareEdgesStrobe(vi_ctype, pin_list_ctype, time_set_ctype, strobe_edge_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def configure_time_set_compare_edges_strobe2x(self, pin_list, time_set, strobe_edge, strobe2_edge): - r'''configure_time_set_compare_edges_strobe2x - - TBD - - Args: - pin_list (str): - - time_set (str): - - strobe_edge (float): - - strobe2_edge (float): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - strobe_edge_ctype = _visatype.ViReal64(strobe_edge) # case S150 - strobe2_edge_ctype = _visatype.ViReal64(strobe2_edge) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetCompareEdgesStrobe2x(vi_ctype, pin_list_ctype, time_set_ctype, strobe_edge_ctype, strobe2_edge_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def configure_time_set_drive_edges(self, pin_list, time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge): - r'''configure_time_set_drive_edges - - TBD - - Args: - pin_list (str): - - time_set (str): - - format (int): - - drive_on_edge (float): - - drive_data_edge (float): - - drive_return_edge (float): - - drive_off_edge (float): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - format_ctype = _visatype.ViInt32(format) # case S150 - drive_on_edge_ctype = _visatype.ViReal64(drive_on_edge) # case S150 - drive_data_edge_ctype = _visatype.ViReal64(drive_data_edge) # case S150 - drive_return_edge_ctype = _visatype.ViReal64(drive_return_edge) # case S150 - drive_off_edge_ctype = _visatype.ViReal64(drive_off_edge) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetDriveEdges(vi_ctype, pin_list_ctype, time_set_ctype, format_ctype, drive_on_edge_ctype, drive_data_edge_ctype, drive_return_edge_ctype, drive_off_edge_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def configure_time_set_drive_edges2x(self, pin_list, time_set, format, drive_on_edge, drive_data_edge, drive_return_edge, drive_off_edge, drive_data2_edge, drive_return2_edge): - r'''configure_time_set_drive_edges2x - - TBD - - Args: - pin_list (str): - - time_set (str): - - format (int): - - drive_on_edge (float): - - drive_data_edge (float): - - drive_return_edge (float): - - drive_off_edge (float): - - drive_data2_edge (float): - - drive_return2_edge (float): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - format_ctype = _visatype.ViInt32(format) # case S150 - drive_on_edge_ctype = _visatype.ViReal64(drive_on_edge) # case S150 - drive_data_edge_ctype = _visatype.ViReal64(drive_data_edge) # case S150 - drive_return_edge_ctype = _visatype.ViReal64(drive_return_edge) # case S150 - drive_off_edge_ctype = _visatype.ViReal64(drive_off_edge) # case S150 - drive_data2_edge_ctype = _visatype.ViReal64(drive_data2_edge) # case S150 - drive_return2_edge_ctype = _visatype.ViReal64(drive_return2_edge) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetDriveEdges2x(vi_ctype, pin_list_ctype, time_set_ctype, format_ctype, drive_on_edge_ctype, drive_data_edge_ctype, drive_return_edge_ctype, drive_off_edge_ctype, drive_data2_edge_ctype, drive_return2_edge_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def configure_time_set_edge(self, pin_list, time_set, edge, time): - r'''configure_time_set_edge - - TBD - - Args: - pin_list (str): - - time_set (str): - - edge (int): - - time (float): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - edge_ctype = _visatype.ViInt32(edge) # case S150 - time_ctype = _visatype.ViReal64(time) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetEdge(vi_ctype, pin_list_ctype, time_set_ctype, edge_ctype, time_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def configure_time_set_edge_multiplier(self, pin_list, time_set, edge_multiplier): - r'''configure_time_set_edge_multiplier - - TBD - - Args: - pin_list (str): - - time_set (str): - - edge_multiplier (int): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - edge_multiplier_ctype = _visatype.ViInt32(edge_multiplier) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetEdgeMultiplier(vi_ctype, pin_list_ctype, time_set_ctype, edge_multiplier_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def configure_time_set_period(self, time_set, period): - r'''configure_time_set_period - - TBD - - Args: - time_set (str): - - period (float): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - period_ctype = _visatype.ViReal64(period) # case S150 - error_code = self._library.niDigital_ConfigureTimeSetPeriod(vi_ctype, time_set_ctype, period_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def create_capture_waveform_from_file_digicapture(self, waveform_name, waveform_file_path): - r'''create_capture_waveform_from_file_digicapture - - TBD - - Args: - waveform_name (str): - - waveform_file_path (str): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 - waveform_file_path_ctype = ctypes.create_string_buffer(waveform_file_path.encode(self._encoding)) # case C020 - error_code = self._library.niDigital_CreateCaptureWaveformFromFileDigicapture(vi_ctype, waveform_name_ctype, waveform_file_path_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def create_capture_waveform_parallel(self, pin_list, waveform_name): - r'''create_capture_waveform_parallel - - TBD - - Args: - pin_list (str): - - waveform_name (str): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 - error_code = self._library.niDigital_CreateCaptureWaveformParallel(vi_ctype, pin_list_ctype, waveform_name_ctype) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return - - @ivi_synchronized - def create_capture_waveform_serial(self, pin_list, waveform_name, sample_width, bit_order): - r'''create_capture_waveform_serial - - TBD - - Args: - pin_list (str): - - waveform_name (str): + r'''configure_pattern_burst_sites - sample_width (int): + TBD - bit_order (int): + Args: + site_list (str): ''' vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 - sample_width_ctype = _visatype.ViUInt32(sample_width) # case S150 - bit_order_ctype = _visatype.ViInt32(bit_order) # case S150 - error_code = self._library.niDigital_CreateCaptureWaveformSerial(vi_ctype, pin_list_ctype, waveform_name_ctype, sample_width_ctype, bit_order_ctype) + site_list_ctype = ctypes.create_string_buffer(site_list.encode(self._encoding)) # case C020 + error_code = self._library.niDigital_ConfigurePatternBurstSites(vi_ctype, site_list_ctype) errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return @ivi_synchronized - def create_source_waveform_from_file_tdms(self, waveform_name, waveform_file_path, write_waveform_data): - r'''create_source_waveform_from_file_tdms + def configure_time_set_period(self, time_set, period): + r'''configure_time_set_period TBD Args: - waveform_name (str): - - waveform_file_path (str): + time_set (str): - write_waveform_data (bool): + period (float): ''' vi_ctype = _visatype.ViSession(self._vi) # case S110 - waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 - waveform_file_path_ctype = ctypes.create_string_buffer(waveform_file_path.encode(self._encoding)) # case C020 - write_waveform_data_ctype = _visatype.ViBoolean(write_waveform_data) # case S150 - error_code = self._library.niDigital_CreateSourceWaveformFromFileTDMS(vi_ctype, waveform_name_ctype, waveform_file_path_ctype, write_waveform_data_ctype) + time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 + period_ctype = _visatype.ViReal64(period) # case S150 + error_code = self._library.niDigital_ConfigureTimeSetPeriod(vi_ctype, time_set_ctype, period_ctype) errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return @ivi_synchronized - def create_source_waveform_parallel(self, pin_list, waveform_name, data_mapping): - r'''create_source_waveform_parallel + def create_capture_waveform_from_file_digicapture(self, waveform_name, waveform_file_path): + r'''create_capture_waveform_from_file_digicapture TBD Args: - pin_list (str): - waveform_name (str): - data_mapping (int): + waveform_file_path (str): ''' vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 - data_mapping_ctype = _visatype.ViInt32(data_mapping) # case S150 - error_code = self._library.niDigital_CreateSourceWaveformParallel(vi_ctype, pin_list_ctype, waveform_name_ctype, data_mapping_ctype) + waveform_file_path_ctype = ctypes.create_string_buffer(waveform_file_path.encode(self._encoding)) # case C020 + error_code = self._library.niDigital_CreateCaptureWaveformFromFileDigicapture(vi_ctype, waveform_name_ctype, waveform_file_path_ctype) errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return @ivi_synchronized - def create_source_waveform_serial(self, pin_list, waveform_name, data_mapping, sample_width, bit_order): - r'''create_source_waveform_serial + def create_source_waveform_from_file_tdms(self, waveform_name, waveform_file_path, write_waveform_data): + r'''create_source_waveform_from_file_tdms TBD Args: - pin_list (str): - waveform_name (str): - data_mapping (int): - - sample_width (int): + waveform_file_path (str): - bit_order (int): + write_waveform_data (bool): ''' vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 waveform_name_ctype = ctypes.create_string_buffer(waveform_name.encode(self._encoding)) # case C020 - data_mapping_ctype = _visatype.ViInt32(data_mapping) # case S150 - sample_width_ctype = _visatype.ViUInt32(sample_width) # case S150 - bit_order_ctype = _visatype.ViInt32(bit_order) # case S150 - error_code = self._library.niDigital_CreateSourceWaveformSerial(vi_ctype, pin_list_ctype, waveform_name_ctype, data_mapping_ctype, sample_width_ctype, bit_order_ctype) + waveform_file_path_ctype = ctypes.create_string_buffer(waveform_file_path.encode(self._encoding)) # case C020 + write_waveform_data_ctype = _visatype.ViBoolean(write_waveform_data) # case S150 + error_code = self._library.niDigital_CreateSourceWaveformFromFileTDMS(vi_ctype, waveform_name_ctype, waveform_file_path_ctype, write_waveform_data_ctype) errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return @@ -2305,119 +2602,6 @@ def fetch_capture_waveform(self, site_list, waveform_name, samples_to_read, time return waveforms - @ivi_synchronized - def fetch_history_ram_cycle_information(self, site, pin_list, position, samples_to_read): - '''fetch_history_ram_cycle_information - - Returns the pattern information acquired for the specified cycles. - - If the pattern is using the edge multiplier feature, cycle numbers represent tester cycles, each of which may - consist of multiple DUT cycles. When using pins with mixed edge multipliers, pins may return - DigitalState.PIN_STATE_NOT_ACQUIRED for DUT cycles where those pins do not have edges defined. - - Args: - site (str): Site on which to retrieve History RAM data. Specify site as a string in the form of siteN, - where N is the site number. The VI returns an error if more than one site is specified. - - pin_list (str): Pins for which to retrieve History RAM data. If empty, the pin list from the pattern - containing the start label is used. Call get_pattern_pin_list or get_pattern_pin_indexes with the start - label to retrieve the pins associated with the pattern burst. - - position (int): Sample index from which to start fetching pattern information. - - samples_to_read (int): Number of samples to fetch. A value of -1 specifies to fetch all available samples. - - - Returns: - history_ram_cycle_information (list of HistoryRAMCycleInformation): Returns a list of class instances with - the following information about each pattern cycle: - - - **pattern_name** (str) Name of the pattern for the acquired cycle. - - **time_set_name** (str) Time set for the acquired cycle. - - **vector_number** (int) Vector number within the pattern for the acquired cycle. Vector numbers start - at 0 from the beginning of the pattern. - - **cycle_number** (int) Cycle number acquired by this History RAM sample. Cycle numbers start at 0 - from the beginning of the pattern burst. - - **scan_cycle_number** (int) Scan cycle number acquired by this History RAM sample. Scan cycle numbers - start at 0 from the first cycle of the scan vector. Scan cycle numbers are -1 for cycles that do not - have a scan opcode. - - **expected_pin_states** (list of list of enums.DigitalState) Pin states as expected by the loaded - pattern in the order specified in the pin list. Pins without defined edges in the specified DUT cycle - will have a value of DigitalState.PIN_STATE_NOT_ACQUIRED. - Length of the outer list will be equal to the value of edge multiplier for the given vector. - Length of the inner list will be equal to the number of pins requested. - - **actual_pin_states** (list of list of enums.DigitalState) Pin states acquired by History RAM in the - order specified in the pin list. Pins without defined edges in the specified DUT cycle will have a - value of DigitalState.PIN_STATE_NOT_ACQUIRED. - Length of the outer list will be equal to the value of edge multiplier for the given vector. - Length of the inner list will be equal to the number of pins requested. - - **per_pin_pass_fail** (list of list of bool) Pass fail information for pins in the order specified in - the pin list. Pins without defined edges in the specified DUT cycle will have a value of pass (True). - Length of the outer list will be equal to the value of edge multiplier for the given vector. - Length of the inner list will be equal to the number of pins requested. - - ''' - if position < 0: - raise ValueError('position should be greater than or equal to 0.') - - if samples_to_read < -1: - raise ValueError('samples_to_read should be greater than or equal to -1.') - - samples_available = self.get_history_ram_sample_count(site) - if position >= samples_available: - raise ValueError('position: Specified value = {0}, Maximum value = {1}.'.format(position, samples_available - 1)) - - if samples_to_read == -1: - if not self.history_ram_number_of_samples_is_finite: - raise RuntimeError( - 'Specifying -1 to fetch all History RAM samples is not supported when the digital pattern instrument is ' - 'configured for continuous History RAM acquisition. You must specify an exact number of samples to fetch.') - samples_to_read = samples_available - position - - if position + samples_to_read > samples_available: - raise ValueError( - 'position: Specified value = {0}, samples_to_read: Specified value = {1}; Samples available = {2}.' - .format(position, samples_to_read, samples_available - position)) - - pattern_names = {} - time_set_names = {} - cycle_infos = [] - for _ in range(samples_to_read): - - pattern_index, time_set_index, vector_number, cycle_number, num_dut_cycles = self._fetch_history_ram_cycle_information(site, position) - - if pattern_index not in pattern_names: - pattern_names[pattern_index] = self.get_pattern_name(pattern_index) - pattern_name = pattern_names[pattern_index] - - if time_set_index not in time_set_names: - time_set_names[time_set_index] = self.get_time_set_name(time_set_index) - time_set_name = time_set_names[time_set_index] - - scan_cycle_number = self._fetch_history_ram_scan_cycle_number(site, position) - - vector_expected_pin_states = [] - vector_actual_pin_states = [] - vector_per_pin_pass_fail = [] - for dut_cycle_index in range(num_dut_cycles): - cycle_expected_pin_states, cycle_actual_pin_states, cycle_per_pin_pass_fail = self._fetch_history_ram_cycle_pin_data(site, pin_list, position, dut_cycle_index) - vector_expected_pin_states.append(cycle_expected_pin_states) - vector_actual_pin_states.append(cycle_actual_pin_states) - vector_per_pin_pass_fail.append(cycle_per_pin_pass_fail) - - cycle_infos.append(history_ram_cycle_information.HistoryRAMCycleInformation( - pattern_name=pattern_name, - time_set_name=time_set_name, - vector_number=vector_number, - cycle_number=cycle_number, - scan_cycle_number=scan_cycle_number, - expected_pin_states=vector_expected_pin_states, - actual_pin_states=vector_actual_pin_states, - per_pin_pass_fail=vector_per_pin_pass_fail)) - position += 1 - - return cycle_infos - @ivi_synchronized def self_test(self): '''self_test @@ -2523,53 +2707,6 @@ def _fetch_history_ram_cycle_information(self, site, sample_index): errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return int(pattern_index_ctype.value), int(time_set_index_ctype.value), int(vector_number_ctype.value), int(cycle_number_ctype.value), int(num_dut_cycles_ctype.value) - @ivi_synchronized - def _fetch_history_ram_cycle_pin_data(self, site, pin_list, sample_index, dut_cycle_index): - r'''_fetch_history_ram_cycle_pin_data - - TBD - - Args: - site (str): - - pin_list (str): - - sample_index (int): - - dut_cycle_index (int): - - - Returns: - expected_pin_states (list of enums.DigitalState): - - actual_pin_states (list of enums.DigitalState): - - per_pin_pass_fail (list of bool): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - site_ctype = ctypes.create_string_buffer(site.encode(self._encoding)) # case C020 - pin_list_ctype = ctypes.create_string_buffer(pin_list.encode(self._encoding)) # case C020 - sample_index_ctype = _visatype.ViInt64(sample_index) # case S150 - dut_cycle_index_ctype = _visatype.ViInt32(dut_cycle_index) # case S150 - pin_data_buffer_size_ctype = _visatype.ViInt32(0) # case S190 - expected_pin_states_ctype = None # case B610 - actual_pin_states_ctype = None # case B610 - per_pin_pass_fail_ctype = None # case B610 - actual_num_pin_data_ctype = _visatype.ViInt32() # case S220 - error_code = self._library.niDigital_FetchHistoryRAMCyclePinData(vi_ctype, site_ctype, pin_list_ctype, sample_index_ctype, dut_cycle_index_ctype, pin_data_buffer_size_ctype, expected_pin_states_ctype, actual_pin_states_ctype, per_pin_pass_fail_ctype, None if actual_num_pin_data_ctype is None else (ctypes.pointer(actual_num_pin_data_ctype))) - errors.handle_error(self, error_code, ignore_warnings=True, is_error_handling=False) - pin_data_buffer_size_ctype = _visatype.ViInt32(actual_num_pin_data_ctype.value) # case S200 - expected_pin_states_size = actual_num_pin_data_ctype.value # case B620 - expected_pin_states_ctype = get_ctypes_pointer_for_buffer(library_type=_visatype.ViUInt8, size=expected_pin_states_size) # case B620 - actual_pin_states_size = actual_num_pin_data_ctype.value # case B620 - actual_pin_states_ctype = get_ctypes_pointer_for_buffer(library_type=_visatype.ViUInt8, size=actual_pin_states_size) # case B620 - per_pin_pass_fail_size = actual_num_pin_data_ctype.value # case B620 - per_pin_pass_fail_ctype = get_ctypes_pointer_for_buffer(library_type=_visatype.ViBoolean, size=per_pin_pass_fail_size) # case B620 - error_code = self._library.niDigital_FetchHistoryRAMCyclePinData(vi_ctype, site_ctype, pin_list_ctype, sample_index_ctype, dut_cycle_index_ctype, pin_data_buffer_size_ctype, expected_pin_states_ctype, actual_pin_states_ctype, per_pin_pass_fail_ctype, None if actual_num_pin_data_ctype is None else (ctypes.pointer(actual_num_pin_data_ctype))) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return [enums.DigitalState(expected_pin_states_ctype[i]) for i in range(pin_data_buffer_size_ctype.value)], [enums.DigitalState(actual_pin_states_ctype[i]) for i in range(pin_data_buffer_size_ctype.value)], [bool(per_pin_pass_fail_ctype[i]) for i in range(pin_data_buffer_size_ctype.value)] - @ivi_synchronized def _fetch_history_ram_scan_cycle_number(self, site, sample_index): r'''_fetch_history_ram_scan_cycle_number @@ -2782,57 +2919,6 @@ def get_site_results_site_numbers(self, site_list, site_result_type): errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) return [int(site_numbers_ctype[i]) for i in range(site_numbers_buffer_size_ctype.value)] - @ivi_synchronized - def get_time_set_edge(self, pin, time_set, edge): - r'''get_time_set_edge - - TBD - - Args: - pin (str): - - time_set (str): - - edge (int): - - - Returns: - time (float): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_ctype = ctypes.create_string_buffer(pin.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - edge_ctype = _visatype.ViInt32(edge) # case S150 - time_ctype = _visatype.ViReal64() # case S220 - error_code = self._library.niDigital_GetTimeSetEdge(vi_ctype, pin_ctype, time_set_ctype, edge_ctype, None if time_ctype is None else (ctypes.pointer(time_ctype))) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return float(time_ctype.value) - - @ivi_synchronized - def get_time_set_edge_multiplier(self, pin, time_set): - r'''get_time_set_edge_multiplier - - TBD - - Args: - pin (str): - - time_set (str): - - - Returns: - edge_multiplier (int): - - ''' - vi_ctype = _visatype.ViSession(self._vi) # case S110 - pin_ctype = ctypes.create_string_buffer(pin.encode(self._encoding)) # case C020 - time_set_ctype = ctypes.create_string_buffer(time_set.encode(self._encoding)) # case C020 - edge_multiplier_ctype = _visatype.ViInt32() # case S220 - error_code = self._library.niDigital_GetTimeSetEdgeMultiplier(vi_ctype, pin_ctype, time_set_ctype, None if edge_multiplier_ctype is None else (ctypes.pointer(edge_multiplier_ctype))) - errors.handle_error(self, error_code, ignore_warnings=False, is_error_handling=False) - return int(edge_multiplier_ctype.value) - @ivi_synchronized def get_time_set_name(self, time_set_index): r'''get_time_set_name diff --git a/src/nidigital/metadata/functions.py b/src/nidigital/metadata/functions.py index ecf45fc96..5b4fcb53e 100644 --- a/src/nidigital/metadata/functions.py +++ b/src/nidigital/metadata/functions.py @@ -296,6 +296,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -324,6 +326,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -357,6 +361,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -405,6 +411,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -493,6 +501,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -526,6 +536,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -643,6 +655,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -666,6 +680,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -727,6 +743,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -755,6 +773,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -996,6 +1016,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pinList', 'type': 'ViConstString' }, @@ -1755,6 +1777,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pin', 'type': 'ViConstString' }, @@ -1788,6 +1812,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'name': 'pin', 'type': 'ViConstString' }, diff --git a/src/nidigital/metadata/functions_addon.py b/src/nidigital/metadata/functions_addon.py index df97e49bb..15befb501 100644 --- a/src/nidigital/metadata/functions_addon.py +++ b/src/nidigital/metadata/functions_addon.py @@ -155,7 +155,16 @@ } ], 'documentation': { - 'description': '\nReturns the pattern information acquired for the specified cycles.\n\nIf the pattern is using the edge multiplier feature, cycle numbers represent tester cycles, each of which may\nconsist of multiple DUT cycles. When using pins with mixed edge multipliers, pins may return\nNIDIGITAL_VAL_PIN_STATE_NOT_ACQUIRED for DUT cycles where those pins do not have edges defined.\n' + 'description': """\nReturns the pattern information acquired for the specified cycles. + +If the pattern is using the edge multiplier feature, cycle numbers represent tester cycles, each of which may +consist of multiple DUT cycles. When using pins with mixed edge multipliers, pins may return +NIDIGITAL_VAL_PIN_STATE_NOT_ACQUIRED for DUT cycles where those pins do not have edges defined. + +If pins are not specified, pin list from the pattern containing the start label is used. Call +niDigital_GetPatternPinList or niDigital_GetPatternPinIndexes with the start label to retrieve the pins +associated with the pattern burst. +""" }, 'parameters': [ { @@ -173,6 +182,8 @@ }, { 'direction': 'in', + 'is_repeated_capability': True, + 'repeated_capability_type': 'pins', 'documentation': { 'description': 'Pins for which to retrieve History RAM data. If empty, the pin list from the pattern\ncontaining the start label is used. Call niDigital_GetPatternPinList or niDigital_GetPatternPinIndexes with the start\nlabel to retrieve the pins associated with the pattern burst.' }, diff --git a/src/nidigital/system_tests/test_system_nidigital.py b/src/nidigital/system_tests/test_system_nidigital.py index 4c85c76ec..cee60c2fa 100644 --- a/src/nidigital/system_tests/test_system_nidigital.py +++ b/src/nidigital/system_tests/test_system_nidigital.py @@ -38,6 +38,7 @@ def test_pins_rep_cap(multi_instrument_session): drive_format = multi_instrument_session.pins['PinA', 'PinB'].get_time_set_drive_format('t0') assert drive_format == 1501 + def test_property_boolean(multi_instrument_session): channel = multi_instrument_session.get_channel_name(index=42) multi_instrument_session.channels[channel].ppmu_allow_extended_voltage_range = True @@ -95,10 +96,7 @@ def test_source_waveform_parallel_broadcast(multi_instrument_session): multi_instrument_session.load_pattern(get_test_file_path(test_name, 'pattern.digipat')) - multi_instrument_session.create_source_waveform_parallel( - pin_list='LowPins', - waveform_name='src_wfm', - data_mapping=2600) + multi_instrument_session.pins['LowPins'].create_source_waveform_parallel(waveform_name='src_wfm', data_mapping=2600) multi_instrument_session.write_source_waveform_broadcast( waveform_name='src_wfm', @@ -148,10 +146,7 @@ def test_source_waveform_parallel_site_unique(multi_instrument_session, source_w num_samples = 256 multi_instrument_session.write_sequencer_register(reg='reg0', value=num_samples) - multi_instrument_session.create_source_waveform_parallel( - pin_list='LowPins', - waveform_name='src_wfm', - data_mapping=2601) + multi_instrument_session.pins['LowPins'].create_source_waveform_parallel(waveform_name='src_wfm', data_mapping=2601) if source_waveform_type == array.array: source_waveform = { @@ -172,7 +167,7 @@ def test_source_waveform_parallel_site_unique(multi_instrument_session, source_w waveform_name='src_wfm', waveform_data=source_waveform) - multi_instrument_session.create_capture_waveform_parallel(pin_list='HighPins', waveform_name='capt_wfm') + multi_instrument_session.pins['HighPins'].create_capture_waveform_parallel(waveform_name='capt_wfm') multi_instrument_session.burst_pattern( site_list='', @@ -201,16 +196,11 @@ def test_fetch_capture_waveform(multi_instrument_session): num_samples = 256 multi_instrument_session.write_sequencer_register(reg='reg0', value=num_samples) - multi_instrument_session.create_source_waveform_parallel( - pin_list='LowPins', - waveform_name='src_wfm', - data_mapping=2600) + multi_instrument_session.pins['LowPins'].create_source_waveform_parallel(waveform_name='src_wfm', data_mapping=2600) source_waveform = [i for i in range(num_samples)] - multi_instrument_session.write_source_waveform_broadcast( - waveform_name='src_wfm', - waveform_data=source_waveform) + multi_instrument_session.write_source_waveform_broadcast(waveform_name='src_wfm', waveform_data=source_waveform) - multi_instrument_session.create_capture_waveform_parallel(pin_list='HighPins', waveform_name='capt_wfm') + multi_instrument_session.pins['HighPins'].create_capture_waveform_parallel(waveform_name='capt_wfm') multi_instrument_session.burst_pattern( site_list='', @@ -289,7 +279,6 @@ def test_fetch_history_ram_cycle_information_position_negative(multi_instrument_ with pytest.raises(ValueError, match='position should be greater than or equal to 0.'): multi_instrument_session.fetch_history_ram_cycle_information( site='site1', - pin_list='', position=-1, samples_to_read=-1) @@ -320,7 +309,6 @@ def test_fetch_history_ram_cycle_information_position_out_of_bound(multi_instrum with pytest.raises(ValueError, match='position: Specified value = 7, Maximum value = 6.'): multi_instrument_session.fetch_history_ram_cycle_information( site='site1', - pin_list='', position=7, samples_to_read=-1) @@ -331,7 +319,6 @@ def test_fetch_history_ram_cycle_information_position_last(multi_instrument_sess history_ram_cycle_info = multi_instrument_session.fetch_history_ram_cycle_information( site='site1', - pin_list='', position=6, samples_to_read=-1) @@ -351,7 +338,6 @@ def test_fetch_history_ram_cycle_information_is_finite_invalid(multi_instrument_ with pytest.raises(RuntimeError, match=expected_error_description): multi_instrument_session.fetch_history_ram_cycle_information( site='site1', - pin_list='', position=0, samples_to_read=-1) @@ -365,7 +351,6 @@ def test_fetch_history_ram_cycle_information_samples_to_read_too_much(multi_inst multi_instrument_session.fetch_history_ram_cycle_information( site=site, - pin_list='', position=0, samples_to_read=3) @@ -374,7 +359,6 @@ def test_fetch_history_ram_cycle_information_samples_to_read_too_much(multi_inst with pytest.raises(ValueError, match=expected_error_description): multi_instrument_session.fetch_history_ram_cycle_information( site=site, - pin_list='', position=3, samples_to_read=5) @@ -385,7 +369,6 @@ def test_fetch_history_ram_cycle_information_samples_to_read_negative(multi_inst with pytest.raises(ValueError, match='samples_to_read should be greater than or equal to -1.'): multi_instrument_session.fetch_history_ram_cycle_information( site='site1', - pin_list='', position=0, samples_to_read=-2) @@ -396,7 +379,6 @@ def test_fetch_history_ram_cycle_information_samples_to_read_zero(multi_instrume history_ram_cycle_info = multi_instrument_session.fetch_history_ram_cycle_information( site='site1', - pin_list='', position=0, samples_to_read=0) @@ -409,7 +391,6 @@ def test_fetch_history_ram_cycle_information_samples_to_read_all(multi_instrumen history_ram_cycle_info = multi_instrument_session.fetch_history_ram_cycle_information( site='site1', - pin_list='', position=0, samples_to_read=-1) diff --git a/src/nidigital/templates/session.py/fancy_fetch_history_ram_cycle_information.py.mako b/src/nidigital/templates/session.py/fancy_fetch_history_ram_cycle_information.py.mako index 9e6e29597..d2c6d28be 100644 --- a/src/nidigital/templates/session.py/fancy_fetch_history_ram_cycle_information.py.mako +++ b/src/nidigital/templates/session.py/fancy_fetch_history_ram_cycle_information.py.mako @@ -51,7 +51,7 @@ vector_actual_pin_states = [] vector_per_pin_pass_fail = [] for dut_cycle_index in range(num_dut_cycles): - cycle_expected_pin_states, cycle_actual_pin_states, cycle_per_pin_pass_fail = self._fetch_history_ram_cycle_pin_data(site, pin_list, position, dut_cycle_index) + cycle_expected_pin_states, cycle_actual_pin_states, cycle_per_pin_pass_fail = self._fetch_history_ram_cycle_pin_data(site, position, dut_cycle_index) vector_expected_pin_states.append(cycle_expected_pin_states) vector_actual_pin_states.append(cycle_actual_pin_states) vector_per_pin_pass_fail.append(cycle_per_pin_pass_fail) From 1a6daf5589d3399549aa856226d429ab2c7f24c1 Mon Sep 17 00:00:00 2001 From: sbethur <48041236+sbethur@users.noreply.github.com> Date: Tue, 3 Mar 2020 17:04:41 -0600 Subject: [PATCH 3/3] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5803f2382..b9e16cdb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ All notable changes to this project will be documented in this file. * #### Changed * `write_source_waveform_site_unique()` now supports `numpy.array` and `list` as site waveform types * `fetch_history_ram_cycle_information` method now supports fetching multiple History RAM samples in a single API call - [#1071](https://github.com/ni/nimi-python/issues/1071) + * Update methods that require `pin_list` to be passed in, such that `pin_list` can be passed in via `pins` repeated capability - [#1294](https://github.com/ni/nimi-python/issues/1294) * #### Removed * Removed redundant (redundant because corresponding properties can be used instead) API methods - [#1065](https://github.com/ni/nimi-python/issues/1065) * Removed programmatic pin map creation API - [#1124](https://github.com/ni/nimi-python/issues/1124)