Examples

Here is a list of API usage examples.


HDCP example

An example of working with a HDCP module.

#
# Import UniTAP module.
#
import time
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.

role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

# Print HDCP 1.4 and 2.3 statuses
# print(role.dptx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
print(role.dptx.hdcp.status.get(UniTAP.HdcpStatus.StatusTx2x))
# print(role.dprx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
print(role.dprx.hdcp.status.get(UniTAP.HdcpStatus.StatusRx2x))

# Set config HDCP 1.4 TX
# config = UniTAP.HdcpTxConfig.Config1x()
# config.encryption = True
# config.authenticate = True
# config.keys = UniTAP.HdcpSource1XKeys.Production
# role.dptx.hdcp.config.set(config)
# time.sleep(2)

# Set config HDCP 1.4 RX
# config = UniTAP.HdcpRxConfig.Config1x()
# config.keys = UniTAP.HdcpSink1XKeys.Production
# config.capable = True

# print(role.dptx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
# print(role.dptx.hdcp.status.get(UniTAP.HdcpStatus.StatusTx2x))
# print(role.dprx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
# print(role.dprx.hdcp.status.get(UniTAP.HdcpStatus.StatusRx2x))

# Set config HDCP 2.3
config = UniTAP.HdcpTxConfig.Config2x()
config.encryption = True
config.authenticate = True
config.keys = UniTAP.HdcpSource2XKeys.Production
config.store_km = True
config.content_level = 1
role.dptx.hdcp.config.set(config)
time.sleep(2)

# Set config HDCP 2.3 RX
config = UniTAP.HdcpRxConfig.Config2x()
config.keys = UniTAP.HdcpSink2XKeys.Production
config.capable = True

# print(role.dptx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
print(role.dptx.hdcp.status.get(UniTAP.HdcpStatus.StatusTx2x))
# print(role.dprx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
print(role.dprx.hdcp.status.get(UniTAP.HdcpStatus.StatusRx2x))

# Get config HDCP 1.4
# config_14 = role.dptx.hdcp.config.get(UniTAP.HdcpTxConfig.Config1x)

# Get config HDCP 2.3
config_23 = role.dptx.hdcp.config.get(UniTAP.HdcpTxConfig.Config2x)


# For UCD-323 -> UCD-301
# role_rx = dev_rx.select_role(UniTAP.dev.UCD301.HDMISink)
# role_tx = dev_tx.select_role(UniTAP.dev.UCD323.HDMISource)

# Print HDCP 1.4 and 2.3 statuses
# print(role_rx.hdrx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
# print(role_tx.hdtx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))

# Set config HDCP 1.4
# config = UniTAP.HdcpTxConfig.Config1x()
# config.encryption = True
# config.authenticate = True
# config.keys = UniTAP.HdcpSource1XKeys.Production
# role_tx.hdtx.hdcp.config.set(config)
# time.sleep(2)

# print(role_rx.hdrx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))
# print(role_tx.hdtx.hdcp.status.get(UniTAP.HdcpStatus.Status1x))

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

EDID example

An example of working with a EDID module.

#
# Import UniTAP module.
#

import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.

# role = dev.select_role(UniTAP.dev.UCD323.DPSource)
# role = dev.select_role(UniTAP.dev.UCD323.HDMISource)
role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)

timings_from_edid = role.dprx.edid.read_timings()

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

Pattern Generator example

An example of working with a Pattern Generator module.

#
# Import UniTAP module.
#

import UniTAP
import time

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.

role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

timing_manager = role.dptx.pg.timing_manager

color_mode = UniTAP.ColorInfo()
color_mode.color_format = UniTAP.ColorInfo.ColorFormat.CF_RGB
color_mode.bpc = 8
color_mode.colorimetry = UniTAP.ColorInfo.Colorimetry.CM_sRGB

timings = [timing_manager.get_cta(16),
           timing_manager.get_cta(12),
           timing_manager.get_cta(1),
           timing_manager.get_cta(19)]

# Also, possible to select timing with using functions: 'get_dmt', 'get_cvt', 'get_by_list_index', 'get_all'

# Print all available timings
print(timing_manager.print_all())

#
# If you want to select pattern, you need to use enum 'VideoPattern' from UniTAP.
# Like this: UniTAP.VideoPattern.ColorRamp
#

# Iterate for each available streams
for i in range(role.dptx.pg.max_stream_count):
    video_mode = UniTAP.VideoMode(timing=timings[i], color_info=color_mode)
    role.dptx.pg[i].set_vm(vm=video_mode)
    role.dptx.pg[i].set_pattern(pattern=UniTAP.VideoPattern.ColorRamp if i == 0 else UniTAP.VideoPattern.SolidGreen)
    role.dptx.pg[i].apply()
    res_app = role.dptx.pg[i].status().error
    print(f"Stream {i} - Apply {res_app.__str__()}")

#
# After configure Pattern Generators, MST should be enabled in link module as well as selected
# stream count
#

cfg = role.dptx.link.config.get()
cfg.mst = True
cfg.mst_stream_count = 4
role.dptx.link.config.set(cfg)
role.dptx.link.start_link_training()

cfg = role.dprx.link.capabilities.link_caps_status()
cfg.mst = True
cfg.dp_128_132_bitrates = None
cfg.override_10g = None
role.dprx.link.capabilities.set(cfg)
role.dprx.link.hpd_pulse()
#
# Just random sleep, to be sure that Sink get video
#
time.sleep(2)

for i in range(role.dptx.pg.max_stream_count):
    res = role.dprx.link.status.stream(i).video_mode.timing == timings[i]
    print(f'Stream {i}
'
          f'Reference timing: {timings[i]}. '
          f'Received timing RX: {role.dprx.link.status.stream(i).video_mode.timing}.
'
          f'Result: {res}')

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

Audio Generator example

An example of working with a Audio Generator module.

#
# Import UniTAP module.
#

import UniTAP
import time

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev_tx = lUniTAP.open("NNNNNNNN")
# dev_rx = lUniTAP.open("MMMMMMMM")
# dev = lUniTAP.open("NNNNNNNN")

# dev_tx = lUniTAP.open(0)
# dev_rx = lUniTAP.open(1)
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
# role_tx = dev_tx.select_role(UniTAP.dev.UCD323.DPSource)
# role_rx = dev_rx.select_role(UniTAP.dev.UCD323.DPSink)
roles = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
role_tx = roles.dptx
role_rx = roles.dprx

# For HDMI uncomment following lines, and comment previous lines.
# role_tx = dev_tx.select_role(UniTAP.dev.UCD323.HDMISource)
# role_rx = dev_rx.select_role(UniTAP.dev.UCD323.HDMISink)
# roles = dev.select_role(UniTAP.dev.UCD422.HDMISourceHDMISink)
# role_tx = roles.hdtx
# role_rx = roles.hdrx

# For configure Pattern Generator, you should call function 'setup' with parameters:
#     number of stream(for UCD 323 DP TX and HDMI will be 0)
#     Video mode - describe selected Timing and ColorMode
#         Timing contain info about all resolutions (like H and V Total, H and V Active and so on), frame rate,
#         timing standard (CVT, DMT, CTA)
#         ColorMode contain info about colorimetry, color_format(RGB, YCbCr444, YCbCr422 and so on),
#         dynamic_range(VESA or CTA) and bits per color (like 8, 10, 12, 16)
#     content_type - one of the value from enum PGPatternID
#     content_data - path to image or bytearray of image (if selected PGPatternID.ImageFile)


# For using our predefined device specific timings, you can use 'timing manager' with which you can get them.
# Timing manager available in dptx and hdtx roles.

# timing_manager = role_tx.dptx.pg.timing_manager

# For HDMI uncomment following lines, and comment previous lines.
# timing_manager = role_tx.hdtx.pg.timing_manager

timing_manager = role_tx.pg.timing_manager

# timing_manager allow to get full timing information from device. For example method get_cta(id) will return Timing
# if there any available CTA timing with VIC=id

timing = timing_manager.get_cta(16)

color_mode = UniTAP.ColorInfo()
color_mode.color_format = UniTAP.ColorInfo.ColorFormat.CF_RGB
color_mode.bpc = 8
color_mode.colorimetry = UniTAP.ColorInfo.Colorimetry.CM_sRGB

video_mode = UniTAP.VideoMode(timing=timing, color_info=color_mode)


#
# Start generate video.
#

# If you want to select pattern, you need to use enum 'VideoPattern' from UniTAP. 
# Like this: UniTAP.VideoPattern.ColorRamp

# role_tx.dptx.pg.set_vm(vm=video_mode)
# role_tx.dptx.pg.set_pattern(pattern=UniTAP.VideoPattern.ColorRamp)
# res = role_tx.dptx.pg.apply()

# For HDMI uncomment following lines, and comment previous lines.

# role_tx.hdtx.pg.set_vm(vm=video_mode)
# role_tx.hdtx.pg.set_pattern(pattern=UniTAP.VideoPattern.ColorRamp)
# res = role_tx.hdtx.pg.apply()

role_tx.pg.set_vm(vm=video_mode)
role_tx.pg.set_pattern(pattern=UniTAP.VideoPattern.ColorRamp)
res = role_tx.pg.apply()

if res:
    print("Pattern generator configure success")

# HPD Control. For DP Possible to control HPD (assert/deassert) and generate HPD pulse with required length,
# for HDMI only HPD (assert/deassert)

# role_rx.dprx.link.set_assert_state(True)
# role_rx.dprx.link.hpd_pulse()

# For HDMI uncomment following lines, and comment previous lines.

# role_rx.hdrx.link.status.set_assert_state(True)

role_rx.link.set_assert_state(True)
role_rx.link.hpd_pulse()

#
# Start generate audio
#

# For starting generate audio, need to config audio generator with following parameters:
#     AudioMode - contain info about sample rate, bits count and channel count
#     audio pattern - value from enum AudioPattern (like UniTAP.AudioPattern.SignalSine)

audio_mode = UniTAP.AudioMode()
audio_mode.channel_count = 2
audio_mode.bits = 16
audio_mode.sample_rate = 44100

# role_tx.dptx.ag.setup(audio_mode=audio_mode, audio_pattern=UniTAP.AudioPattern.SignalSine,
#                       signal_frequency=1000, amplitude=60)
# res = role_tx.dptx.ag.apply()

# For HDMI uncomment following lines, and comment previous lines.

# role_tx.hdtx.ag.setup(audio_mode=audio_mode, audio_pattern='Sine', signal_frequency=1000, amplitude=60)
# res = role_tx.hdtx.ag.apply()

role_tx.ag.setup(audio_mode=audio_mode, audio_pattern=UniTAP.AudioPattern.SignalSine, signal_frequency=1000, amplitude=60)
res = role_tx.ag.apply()

if res:
    print("Audio generator configure success")

# time.sleep(5)
# role.dptx.ag.stop_generate()
# role.hdtx.ag.stop_generate()

#
# Read current video mode and crc
#
time.sleep(1)

# Sometimes RX need some time to start getting video (will be improved in the future versions).


# Get current stream status (VM, CRC, DSC CRC)
# stream = role_rx.dprx.link.status.stream(0)
# print(stream)

# For HDMI uncomment following lines, and comment previous lines.

# stream = role_rx.hdrx.link.status.stream(0)
# print(stream)

stream = role_rx.link.status.stream(0)
print(stream)

#
# Check and capture audio
#
# role_rx.dprx.audio_capturer.start(m_sec=5000)
# audio_capture_result = role_rx.dprx.audio_capturer.capture_result

# For HDMI uncomment following lines, and comment previous lines.

# role_rx.hdrx.audio_capturer.start(m_sec=5000)
# audio_capture_result = role_rx.hdrx.audio_capturer.capture_result

role_rx.audio_capturer.start(m_sec=5000)
audio_capture_result = role_rx.audio_capturer.capture_result

#
# Save captured audio to wav file
#
print(audio_capture_result.audio_mode.__str__())
audio_capture_result.save_to_file(file_format=UniTAP.AudioFileFormat.WAV, path="example")

#
# Run Audio test 'Validate audio signal frequency and glitch-free audio reproduction'
#
# params = role_rx.dut_tests.default_params_of_group(UniTAP.TestGroupId.AUDIO_TEST)

group_test = UniTAP.TestGroupId.AUDIO_TEST

# params = role_rx.dut_tests.get_default_parameters(UniTAP.AudioTestParam)
params = roles.dut_tests.get_default_parameters(UniTAP.AudioTestParam)
params.sample_rate = 44100
params.audio_frequency = 1000
params.frequency_tolerance = 1
params.save_conditions = 'All'
params.storage_folder = "./"

# role_rx.dut_tests.run(group_test, 3, params)
# results = role_rx.dut_tests.get_all_tests_results()

roles.dut_tests.run(group_test, 3, params)
results = roles.dut_tests.get_all_tests_results()

print(results.all_test_results()[0].test_result)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup()

Adaptive-Sync and Scrolling pattern example

An example of working with a Adaptive-Sync and Scrolling pattern.

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.

role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)


timing_manager = role.dptx.pg.timing_manager
timings = timing_manager.get_all()

color_mode = UniTAP.ColorInfo()
color_mode.color_format = UniTAP.ColorInfo.ColorFormat.CF_RGB
color_mode.bpc = 8
color_mode.colorimetry = UniTAP.ColorInfo.Colorimetry.CM_sRGB

video_mode = UniTAP.VideoMode(timing=timings[0], color_info=color_mode)
role.dptx.pg.set_vm(vm=video_mode)
role.dptx.pg.set_pattern(pattern=UniTAP.VideoPattern.ColorRamp)

# I case: configure ConstantASParams
role.dptx.pg.set_as_config(as_config=UniTAP.ConstantASParams(lines=20))

# II case: configure SquareASParams
role.dptx.pg.set_as_config(as_config=UniTAP.SquareASParams(min_lanes=0, max_lanes=1000, period_frames=10))

# III case: configure ZigzagASParams
role.dptx.pg.set_as_config(as_config=UniTAP.ZigzagASParams(min_lanes=0, max_lanes=1000, increase_lines=100,
                                                        decrease_lines=100))

# IV case: configure FixedASParams
role.dptx.pg.set_as_config(as_config=UniTAP.FixedASParams(refresh_rate=60, divide_by_1_001=False, increase_lines=100,
                                                       decrease_lines=100))

# Configure Scrolling Pattern Params
role.dptx.pg.set_scrolling_params(UniTAP.StepsScrollingParams(horizontally=20, vertically=20, frames=10))

role.dptx.pg.apply()
res_app = role.dptx.pg.status().error
print(f"Stream 0 - Apply {res_app.__str__()}")

print(role.dptx.pg[0].adaptive_sync_status())

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

Bulk Capturer example

An example of working with a Bulk Capturer module.

import UniTAP
import time
import threading


def link_training(dev_role):
    time.sleep(1)
    dev_role.dptx.link.start_link_training()


lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# Need to select type of device: UCD-400 or UCD-500
role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

# bulk_size - size of data in megabytes
# trigger_position - available position of trigger. Variants: TP_Start, TP_25, TP_50, TP_75, TP_End
# trigger_config - one of the variant of active trigger.
# assume_scrambler - just flag of assume scrambler

bulk_size = 100

# Case without trigger
# role.dprx.bulk_capturer.start(bulk_size=bulk_size, trigger_position=UniTAP.bulk.TriggerPosition.TP_Start,
#                               assume_scrambler=False, gpio=False)

# Case with trigger
# In loopback mode we need to use special function for calling 'trigger'.
# In current case we need to call 'link training'.
thread = threading.Thread(target=link_training, args=(role,))
trigger_config = UniTAP.bulk.TriggerType.U13()
trigger_config.position = UniTAP.bulk.TriggerTypeEnum.SourceTypePosition.InitialLT

thread.start()
role.dprx.bulk_capturer.start(bulk_size=bulk_size, trigger_position=UniTAP.bulk.TriggerPosition.TP_Start,
                              trigger_config=trigger_config,
                              assume_scrambler=False, gpio=False)
role.dprx.bulk_capturer.stop()
thread.join()
thread.stop_thread = False

# If you want to get captured data, please, use 'capture_result'. It is the object of class 'ResultBulkObject'.
# For saving data in file, please, use 'save_to_bin_file'. You need to set 'directory_name' - name of directory,
# where you want to save files. If directory have already existed, is will be clean up.
# If directory does not exist, it will be created.
result = role.dprx.bulk_capturer.capture_result

directory_name = "./BulkData"
result.save_to_bin_file(directory_name=directory_name)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

An example of working with a DP Link Sink module.

#
# Import UniTAP module.
#

import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.

# role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

#
# Read current Link Status
#
print(role.dprx.link.status.cable_state)
# Read status of lane 0
lane_status = role.dprx.link.status.lane(0)
print(lane_status)

# Read status of VCP (stream 0)
vcp_table_status = role.dprx.link.status.vcp(0)
print(vcp_table_status)

# Get current stream status (VM, CRC, DSC CRC)
stream = role.dprx.link.status.stream(0)
print(stream)

# Also, you can print all status
print(role.dprx.link.status)

# role.dprx.link.hpd_pulse()

# # Assert/Deassert
# print(role.dprx.link.status.hpd_asserted)
# role.dprx.link.set_assert_state(False)
# print(role.dprx.link.status.hpd_asserted)
# role.dprx.link.set_assert_state(True)
# print(role.dprx.link.status.hpd_asserted)

# Scrambler Seed
print(role.dprx.link.scrambler_seed)
role.dprx.link.scrambler_seed = 0xfffe
print(role.dprx.link.scrambler_seed)


caps = UniTAP.LinkCapabilities()
caps.max_lane = 4
caps.bit_rate = 8.1
caps.dp_128_132_bitrates = None
caps.override_10g = None
caps.force_cable_status_to_plugged = False
caps.old_dp_2_0_lt = False
caps.dsc = False
caps.ss_sbm = False
caps.fec = False
caps.tps3 = False
caps.tps4 = False
caps.mst = True

print(role.dprx.link.capabilities.link_caps_status())
role.dprx.link.capabilities.set(caps)
print(role.dprx.link.capabilities.link_caps_status())

print(role.dprx.link.status.stream(0).sdp_crc16)
role.dprx.link.status.reset_sdp_crc16_errors()

#
# Get eDP caps
#
edp_caps = role.dprx.link.capabilities.link_caps_status(UniTAP.LinkEDPCapabilities)
print(edp_caps)
edp_caps.max_lane = 2
edp_caps.eDp_cur_rate = [1.62, 2.16, 2.43]

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

An example of working with a DP Link Source module.

#
# Import UniTAP module.
#

import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.

role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

#
# Read current Link Status
#

# Read status of lane 0
lane_status = role.dptx.link.status.lane(0)
print(lane_status)

# Read status of VCP (stream 0)
vcp_table_status = role.dptx.link.status.vcp(0)
print(vcp_table_status)

# Read current status of link configuration
link_config = role.dptx.link.config.get()
print(link_config)

# Get current stream status (VM, CRC, DSC CRC)
stream = role.dptx.link.status.stream(0)
print(stream)

# Also, you can print all status
print(role.dptx.link.status)

# Configure Link 8b/10b
config = UniTAP.LinkConfig.DP8b10b()

# Set new lane count and bit rate
config.lane_count = 2
config.bit_rate = 6.75

# Configure Link 128b/132b
# config = UniTAP.LinkConfig.DP128b132b()

# Set new lane count and bit rate
# config.lane_count = 2
# config.bit_rate = 5

# config.force_dp_128_132 = True
# config.try_dp_128_132 = True
# config.enhanced_framing_mode = True

# Enable MST mode and configure mst stream count
config.mst = True
config.mst_stream_count = 2

# Enable/Disable Enhanced framing mode
config.enhanced_framing_mode = True

# Configure SSC
ssc_config = UniTAP.SSCConfig()
ssc_config.enabled = True
ssc_config.amplitude = 34
ssc_config.frequency = 59000
config.ssc = ssc_config

# Configure Scrambler Seed
# If you do not want to setting scrambler seed value, you can activate 'auto seed'
# config.auto_seed = True
# role.dptx.link.scrambler_seed = 0xFFFF

role.dptx.link.config.set(config)
role.dptx.link.start_link_training()

edp_conf = role.dptx.link.config.get(UniTAP.LinkConfig.eDP)
print(edp_conf)
edp_conf.force_edp = True
edp_conf.lane_count = 2
edp_conf.eDp_cur_rate = 2.43

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup()

DUT Test example

An example of working with a DUT Test module [manual setting].

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)
dev.opf_handler = UniTAP.OpfHandlerInternal(port_tx=role.dptx, port_rx=role.dprx)

group_test = UniTAP.TestGroupId.DP_TX_LL_CTS

# You can make a copy of the object, configure it and reassign it or can configure it directly

# Copy
params = role.dut_tests.get_default_parameters(UniTAP.Dp14SinkTestParam)

# Configure supported timings for DP DUT Sink tests
params.timings.T_3840_x_2160_60.set_all()
params.timings.T_5120_x_2160_60.set_all()

# Configure Event Filter from Source side
event_filter_tx = role.dptx.event_capturer.event_filter(UniTAP.EventFilterDpTx)  # Get filter object
event_filter_tx.config_hpd_events(True)  # Enable capturing HPD events
event_filter_tx.config_aux_events(True)  # Enable capturing AUX events
role.dptx.event_capturer.configure_capturer(event_filter_tx)  # Transfer updated filter object

event_filter_rx = role.dprx.event_capturer.event_filter(UniTAP.EventFilterDpRx)  # Get filter object
event_filter_rx.config_hpd_events(True)  # Enable capturing HPD events
event_filter_rx.config_aux_events(True)  # Enable capturing AUX events
event_filter_rx.config_sdp_events(True, UniTAP.EventSDP.CG2)  # Enable capturing SDP (CG2) events
role.dprx.event_capturer.configure_capturer(event_filter_rx)  # Transfer updated filter object

role.dptx.event_capturer.start()  # Start event capturing

role.dut_tests.run(group_id=group_test, test_id=0, params=params)  # Run selected test

results = role.dut_tests.get_all_tests_results()  # Get results after testing

role.dptx.event_capturer.stop()  # Stop event capturing

capture_result = role.dptx.event_capturer.pop_all_elements_as_result_object()  # Get all captured events

event_log_file_path = "EventData"
event_log_html_file_path = "EventDataReport"
if len(capture_result.buffer) > 0:
    # Save captured events to BIN file and save HTML report
    capture_result.save_to_file_all_events(file_format=UniTAP.EventFileFormat.BIN, path=event_log_file_path)
    capture_result.save_to_file_all_events(file_format=UniTAP.EventFileFormat.HTML, path=event_log_html_file_path)
else:
    print("Buffer is empty.")

# Save test result to HTML report
role.dut_tests.make_report('./report',
                           tested_by="Example",
                           remarks="Remarks for test report.")
#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup()

DUT Test example

An example of working with a DUT Test module [settings from file].

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)
dev.opf_handler = UniTAP.OpfHandlerInternal(port_tx=role.dptx, port_rx=role.dprx)

file_name = "./config.json"
group_id, test_id, params = role.dut_tests.get_params_from_file(file_name)

role.dut_tests.run(group_id=group_id, test_id=test_id, params=params)  # Run selected test

results = role.dut_tests.get_all_tests_results()  # Get results after testing

role.dptx.event_capturer.stop()  # Stop event capturing

# Save test result to HTML report
role.dut_tests.make_report('./report',
                           tested_by="Example",
                           remarks="Remarks for test report.")

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

Event capturer example

An example of working with a Event capturer.

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
# role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)
dev.opf_handler = UniTAP.OpfHandlerInternal(port_tx=role.dptx, port_rx=role.dprx)

# For getting object of EventFilter, set type of required filter. If filter type is not supported
# will be print list of available types.
event_filter = role.dprx.event_capturer.event_filter(UniTAP.EventFilterDpRx)
event_filter.config_hpd_events(True)
event_filter.config_aux_events(True)
event_filter.config_sdp_events(True, UniTAP.EventSDP.CG2)
event_filter.config_vb_id_events(True, UniTAP.EventVBID.AnyFieldID)

# For configuration EventLogger, set object of EventFilter to function 'configure_capturer'
role.dprx.event_capturer.configure_capturer(event_filter)
role.dprx.link.hpd_pulse()
role.dprx.event_capturer.start(sec=1)
role.dprx.event_capturer.stop()
capture_result = role.dprx.event_capturer.capture_result

file_name = "./EventData"
if len(capture_result.buffer) > 0:
    capture_result.save_to_file_all_events(file_format=UniTAP.EventFileFormat.HTML, path=file_name)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

PDC Capabilities example

An example of working with a PDC Capabilities.

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
role = dev.select_role(UniTAP.dev.UCD424.USBCSourceUSBCSink)
# role = dev.select_role(UniTAP.dev.UCD500.USBCSourceUSBCSink)
dev.opf_handler = UniTAP.OpfHandlerInternal(port_tx=role.dptx, port_rx=role.dprx)

# Print current Capabilities status
print(role.pdcrx.capabilities.status)

# Set Initial role for device
role.pdcrx.capabilities.set_initial_role(UniTAP.pdc.PdcDeviceRole.DFP)

# Set cable control pull up value (current)
role.pdcrx.capabilities.cc_pull_up(UniTAP.pdc.CCPullUp.Current_3A)

# Enable PR Swap
role.pdcrx.capabilities.enable_pr_swap(False)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

PDC Controls example

An example of working with a PDC Controls.

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
# role = dev.select_role(UniTAP.dev.UCD424.USBCSourceUSBCSink)
role = dev.select_role(UniTAP.dev.UCD500.USBCSourceUSBCSink)
dev.opf_handler = UniTAP.OpfHandlerInternal(port_tx=role.dptx, port_rx=role.dprx)

# Send PR Swap (Also available FR swap, DR swap and Vconn swap)
role.pdcrx.controls.send_pr_swap()

# Do Reconnect
role.pdcrx.controls.reconnect()

# Do Attach(True)/DeAttach(False)
role.pdcrx.controls.attach(True)

# Change cable control orientation
role.pdcrx.controls.orientation(UniTAP.pdc.CableControlOrientation.CC2)

# Capable communication as PD Source (also available for Sink)
role.pdcrx.controls.communication_capable_as_pd_source(capable=True)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

PDC DP Alt mode example

An example of working with a PDC DP Alt mode.

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
# role = dev.select_role(UniTAP.dev.UCD424.USBCSourceUSBCSink)
role = dev.select_role(UniTAP.dev.UCD500.USBCSourceUSBCSink)
dev.opf_handler = UniTAP.OpfHandlerInternal(port_tx=role.dptx, port_rx=role.dprx)

# Get and print current DP Alt Mode status
print(role.pdcrx.dp_alt_mode.status)

# Enter to 4 lane (C and E) DP Alt Mode
role.pdcrx.dp_alt_mode.enter_4_lane()

# Enable flag DP to Type-C adapter mode
# role.pdcrx.dp_alt_mode.dp_to_type_c_cable_adapter_mode(enable=True)

# Get and Set UFP Pin Assignment
ufp_pin_assignment = role.pdcrx.dp_alt_mode.ufp_caps
dfp_caps = role.pdcrx.dp_alt_mode.dfp_caps
ufp_pin_assignment.c_4_lanes = True
ufp_pin_assignment.d_2_lanes = False
role.pdcrx.dp_alt_mode.ufp_caps = ufp_pin_assignment
print("UFP:
", ufp_pin_assignment)
print("DFP:
", dfp_caps)

# If was selected UCD-500, may use DP 2.1 DPAM
# role.pdcrx.dp_alt_mode.enable_dp21(True)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

PDC PDO example

An example of working with a PDC PDO.

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
role = dev.select_role(UniTAP.dev.UCD424.USBCSourceUSBCSink)
# role = dev.select_role(UniTAP.dev.UCD500.USBCSourceUSBCSink)
dev.opf_handler = UniTAP.OpfHandlerInternal(port_tx=role.dptx, port_rx=role.dprx)


# Get Source PDO from RX side.
# If read_from_device = True, PDO will be read directly from device, not from internal buffer
source_pdo_list = role.pdcrx.power_source.get_pdo_list(read_from_device=True)

for item in source_pdo_list:
    print(item)

# Get current Power Role
power_role = role.pdcrx.capabilities.status.power_role()
print(power_role.name)

if power_role == UniTAP.pdc.PowerRole.Sink:
    # If needed to change power role, use reconnect
    role.pdcrx.controls.reconnect()
if power_role == UniTAP.pdc.PowerRole.Source:
    for index, item in enumerate(source_pdo_list):
        if index > 0:
            item.interpret_pdo_as_selected_type(UniTAP.pdc.BatteryPdo)
    role.pdcrx.power_source.set_pdo_list(source_pdo_list)
    role.pdcrx.power_source.send_pdo()
    role.pdcrx.controls.reconnect()

source_pdo_list = role.pdcrx.power_source.get_pdo_list(read_from_device=True)
for item in source_pdo_list:
    print(item)

# For Sink PDO the same algorythm, but it is also possible to control `Power Contract`
role.pdcrx.power_contract_control.pdo_type_priority = UniTAP.pdc.ContractTypePriority.HigherCurrent

# Control Internal resistance (only for UCD-340)
# print(role.pdcrx.power_contract_control.internal_resistance)
# role.pdcrx.power_contract_control.internal_resistance = UniTAP.pdc.InternalResistance.Resistance_3_5_Ohm
# print(role.pdcrx.power_contract_control.internal_resistance)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

Video Capturer

An example of working with a Video Capturer.

#
# Import UniTAP module.
#
import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
# For UCD-500 available following roles:
# UniTAP.dev.UCD500.DPSourceDPSink, USBCSourceUSBCSink, DPSourceUSBCSink and USBCSourceDPSink
role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

# First variant of capturing = set frame count number
role.dprx.video_capturer.start(frames_count=1, stream_number=1)
role.dprx.video_capturer.stop()
result = role.dprx.video_capturer.capture_result

# Second variant of capturing = set number of second
# role.dprx.video_capturer.start(sec=1)
# role.dprx.video_capturer.stop()
# result = role.dprx.video_capturer.capture_result

# Third variant of capturing = capturing with user's stop command (without predefined number of frames or second)
# role.dprx.video_capturer.start()
# result = role.dprx.video_capturer.pop_element_as_result_object()
# role.dprx.video_capturer.stop()

# Save captured frames
# file_format - BIN, PPM and BMP
# path - full path to save the image
# index - index of captured image
result.save_image_to_file(file_format=UniTAP.PictureFileFormat.BMP,
                          path="image.bmp",
                          index=0)
#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup()

Panel Replay

An example of working with a Panel Replay.

#
# Import UniTAP module.
#
import time

import UniTAP

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

# Select PR'Active mode'
role.dptx.pg.panel_replay.active_mode()
time.sleep(3)

# Get current panel replay configuration of PR regions
pr_conf = role.dptx.pg.panel_replay.config.get()

# Set new values for PR Region
pr_conf.regions[0].x = 10
pr_conf.regions[0].y = 20
pr_conf.regions[0].width = 30
pr_conf.regions[0].height = 40

# PanelReplay config
pr_conf.flags.mode = UniTAP.PRMode.PR
pr_conf.flags.y_granularity = UniTAP.YGranularity.Value_14
pr_conf.flags.early_transport = True
pr_conf.flags.main_link_remain_on = True
pr_conf.flags.hpd_irq_vsc_sdp = True

# Apply config
role.dptx.pg.panel_replay.config.set(pr_conf)

time.sleep(3)

# Read status, command and error
print(role.dptx.pg.panel_replay.status.status().name)
print(role.dptx.pg.panel_replay.status.command().name)
print(role.dptx.pg.panel_replay.status.error().name)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

DSC Generator

An example of working with a DSC generator.

#
# Import UniTAP module.
#

import UniTAP
from UniTAP.utils import encode_video_frame, calculate_dsc_slice_size
from UniTAP.common import get_vf_from_image, CompressionInfo

#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)
# role = dev.select_role(UniTAP.dev.UCD500.DPSourceDPSink)

#
# For using our predefined device specific timings, you can use 'timing manager' with which you can get them.
#
timing_manager = role.dptx.pg.timing_manager

color_mode = UniTAP.ColorInfo()
color_mode.color_format = UniTAP.ColorInfo.ColorFormat.CF_RGB
color_mode.bpc = 8
color_mode.colorimetry = UniTAP.ColorInfo.Colorimetry.CM_sRGB

target_width = 1920
target_height = 1080
path_custom_image = "Your_Path_To_Image.jpg"

vf = get_vf_from_image(path_custom_image, target_width, target_height)

params = CompressionInfo()
params.color_format = CompressionInfo.DscColorFormat.CF_RGB
params.bpp = 128
params.version = (1, 2)
params.v_slice_size = calculate_dsc_slice_size(target_width, 4)
params.h_slice_size = calculate_dsc_slice_size(target_height, 4)
params.buffer_bit_depth = vf.color_info.bpc + 1

dsc_vf = encode_video_frame(vf, params)

video_mode = UniTAP.VideoMode(timing=timing_manager.get_cta(76), color_info=color_mode)

caps = role.dprx.link.capabilities.link_caps_status()
caps.dsc = True
caps.fec = True
role.dprx.link.capabilities.set(caps)

role.dptx.link.start_link_training()

role.dptx.pg.set_vm(video_mode)

# Also you can put image path (dsc image path also) to function 'set_pattern' as argument.
# path_custom_image = "Your_Path_To_Image.jpg"
# role.dptx.pg.set_pattern(path_custom_image)
role.dptx.pg.set_pattern(dsc_vf)
role.dptx.pg.apply()
res_app = role.dptx.pg.status().error
print(f"Stream {0} - Apply {res_app.__str__()}")

role.dprx.video_capturer.start()
dsc_captured_frame = role.dprx.video_capturer.pop_element()
role.dprx.video_capturer.stop()

print(dsc_captured_frame.is_compressed())
print(dsc_captured_frame)

role.dptx.pg.set_pattern(UniTAP.VideoPattern.ColorSquares)
role.dptx.pg.apply()
res_app = role.dptx.pg.status().error
print(f"Stream {0} - Apply {res_app.__str__()}")

role.dprx.video_capturer.start()
captured_frame = role.dprx.video_capturer.pop_element()
role.dprx.video_capturer.stop()
print(captured_frame.is_compressed())
print(captured_frame)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup(

DSC Images

An example of working with a DSC images.

#
# Import UniTAP module.
#
import UniTAP
from UniTAP.utils import encode_video_frame, decode_video_frame, video_frame_save_to_file, ImageFileFormat
#
# To initialize UniTAP library wrapper user should create UniTAP.TsiLib() object.
#
lUniTAP = UniTAP.TsiLib()

#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# dev = lUniTAP.open("NNNNNNNN")
dev = lUniTAP.open(0)

# After opening device as in UCD Console device role should be selected.
# For UCD-500 available following roles:
# UniTAP.dev.UCD500.DPSourceDPSink, USBCSourceUSBCSink, DPSourceUSBCSink and USBCSourceDPSink
role = dev.select_role(UniTAP.dev.UCD400.DPSourceDPSink)

# First variant of capturing = set frame count number
role.dprx.video_capturer.start(stream_number=0)
frame = role.dprx.video_capturer.pop_element()
role.dprx.video_capturer.stop()

# Decode DSC Video frame and save
image_path = "image.bmp"
decoded_vf = decode_video_frame(frame)
video_frame_save_to_file(video_frame=decoded_vf, path=image_path, file_type=ImageFileFormat.IFF_BMP)

# Save raw DSC Video frame
image_path = "image.dsc"
video_frame_save_to_file(video_frame=frame, path=image_path, file_type=ImageFileFormat.IFF_DSC)

#
# Since the 3.5 version, TsiLib and TSIDevice objects have the option to be closed earlier.
# TSIDevice can be closed with the TsiLib method close(). TsiLib can be closed with cleanup().
# Clean up will close all opened devices and block ability to open any devices
# with same TsiLib object.
#
lUniTAP.close(dev)

lUniTAP.cleanup()