# Examples

Here is a list of API usage examples.

- HDCP example
- EDID example
- Pattern Generator example
- Audio Generator example
- Adaptive-Sync and Scrolling pattern example
- Bulk Capturer example
- DP Link Sink example
- DP Link Source example
- DUT Test example
- DUT Test example
- Event capturer example
- PDC Capabilities example
- PDC Controls example
- PDC DP Alt mode example
- PDC PDO example
- Video Capturer
- Panel Replay
- DSC Generator
- DSC Images

### 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(

### DP Link Sink example

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(

### DP Link Source example

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()