Files
pqAutomationApp/docs/UCD-API文档/examples/work_with_bulk_different_modes.py

259 lines
9.5 KiB
Python
Raw Normal View History

2026-07-02 17:16:18 +08:00
import os
import UniTAP
import time
import math
import threading
#
# Config.
#
BULK_SIZE_MB = 100 # Mb
FOLDER_TO_GENERATE = "./BulkData"
tps3 = True
tps4 = True
fec = True
lanes = [
1,
2,
4
]
# If you want to use UCD-400, please, set 'dp_14_mode = True' and 'enable_dp_21_mode = False'
# If you want to use UCD-500 in DP 1.4 mode, please, set 'dp_14_mode = True' and 'enable_dp_21_mode = False'
# If you want to use UCD-500 in DP 2.1 mode, please, set 'dp_14_mode = False' and 'enable_dp_21_mode = True'
dp_14_mode = False
bit_rates_14 = [
1.62,
2.7,
5.4,
6.75,
8.1
]
enable_dp_21_mode = True
bit_rates_21 = [
10,
13.5,
20
]
mst = True
streams = [
0,
1,
2,
3
]
#
# Trigger config.
#
trigger_positions = [
UniTAP.bulk.TriggerPosition.TP_Start,
UniTAP.bulk.TriggerPosition.TP_25,
UniTAP.bulk.TriggerPosition.TP_50,
UniTAP.bulk.TriggerPosition.TP_75,
UniTAP.bulk.TriggerPosition.TP_End
]
# If you do not want to use trigger config, please, set 'None' to variable
# Use other types of trigger config. Full list located in 'TriggerType'
trigger_config = UniTAP.bulk.TriggerType.U13()
trigger_config.position = UniTAP.bulk.TriggerTypeEnum.SourceTypePosition.InitialLT
lUniTAP = UniTAP.TsiLib()
#
# For opening device, please, put serial number of the device as 8 symbol str or put index of device.
#
# serial_number = "2150C474"
# dev = lUniTAP.open(serial_number)
# If you do not want to write device serial number, you can write index position of device
index_position = 0
dev = lUniTAP.open(index_position)
# 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)
timing_manager = role.dptx.pg.timing_manager
timings = [
timing_manager.get_cta(16),
timing_manager.get_cta(90),
timing_manager.get_cta(97),
timing_manager.get_cta(126),
timing_manager.get_cta(196),
]
color_formats = [
UniTAP.ColorInfo.ColorFormat.CF_RGB,
UniTAP.ColorInfo.ColorFormat.CF_YCbCr_444,
UniTAP.ColorInfo.ColorFormat.CF_YCbCr_422,
UniTAP.ColorInfo.ColorFormat.CF_YCbCr_420,
UniTAP.ColorInfo.ColorFormat.CF_Y_ONLY,
UniTAP.ColorInfo.ColorFormat.CF_RAW
]
colorimetry_list = [
UniTAP.ColorInfo.Colorimetry.CM_sRGB,
UniTAP.ColorInfo.Colorimetry.CM_ITUR_BT601,
UniTAP.ColorInfo.Colorimetry.CM_ITUR_BT709
]
# Note: BPC 7 and 14 will be work only with CF_Y_ONLY and CF_RAW
bpc_list = [
6,
7,
8,
10,
12,
14,
16
]
def link_training(dev_role):
time.sleep(1)
dev_role.dptx.link.start_link_training()
def bool_str_format(value: bool) -> str:
return "ON" if value else "OFF"
def prepare_directory_name(_timing, _color_mode, _lane, _rate, _stream, tr_pos, tr_config=None) -> str:
tr_conf_str = type(tr_config).__name__ if tr_config is not None else "-"
auto_generated_folder = f"cap_[TG_Pos_{tr_pos.name}][TG_Conf-{tr_conf_str}][{'DP1.4' if dp_14_mode else 'DP2.1'}]" \
f"[MST-{bool_str_format(mst)}][FEC-{bool_str_format(fec)}][stream-{_stream}]" \
f"[TPS3-{bool_str_format(tps3)}][TPS4-{bool_str_format(tps4)}]" \
f"[{_timing.hactive}x{_timing.vactive}@" \
f"{math.ceil(_timing.frame_rate / 1000)}_{_color_mode.color_format.name}_{_color_mode.bpc}bpc" \
f"-{_color_mode.colorimetry.name}]"
directory_name = os.path.join(FOLDER_TO_GENERATE, auto_generated_folder)
return directory_name
def do_bulk_capture(dev_role, _timing, _color_mode, _lane, _rate, _stream):
# 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
for tr_pos in trigger_positions:
thread = None
if trigger_config is not None:
thread = threading.Thread(target=link_training, args=(role,))
thread.start()
dev_role.dprx.bulk_capturer.start(bulk_size=BULK_SIZE_MB, trigger_position=tr_pos, trigger_config=trigger_config,
assume_scrambler=False, gpio=False)
dev_role.dprx.bulk_capturer.stop()
if trigger_config is not None and thread is not None:
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 = dev_role.dprx.bulk_capturer.capture_result
directory_name = prepare_directory_name(_timing, _color_mode, _lane, _rate, _stream, tr_pos, trigger_config)
result.save_to_bin_file(directory_name=directory_name)
for lane in lanes:
if dp_14_mode:
rates = bit_rates_14
else:
rates = bit_rates_21
for timing in timings:
for rate in rates:
for stream in streams:
for color_format in color_formats:
for bpc in bpc_list:
for colorimetry in colorimetry_list:
# Configure Sink Link caps
caps = UniTAP.LinkCapabilities()
caps.max_lane = lane
if dp_14_mode:
caps.bit_rate = rate
else:
caps.dp_128_132_bitrates = [rate]
caps.fec = fec
caps.tps3 = tps3
caps.tps4 = tps4
caps.mst = mst
role.dprx.link.capabilities.set(caps)
role.dprx.link.hpd_pulse()
time.sleep(0.5)
# Configure Source Link
if dp_14_mode:
config = UniTAP.LinkConfig.DP8b10b()
config.mst = mst
else:
config = UniTAP.LinkConfig.DP128b132b()
config.lane_count = lane
config.bit_rate = rate
if enable_dp_21_mode:
config.force_dp_128_132 = True
config.try_dp_128_132 = True
else:
config.force_dp_128_132 = False
config.try_dp_128_132 = False
role.dptx.link.config.set(config)
role.dptx.link.start_link_training()
time.sleep(0.5)
color_mode = UniTAP.ColorInfo()
color_mode.color_format = color_format
color_mode.bpc = bpc
color_mode.colorimetry = colorimetry
if color_format in [UniTAP.ColorInfo.ColorFormat.CF_RGB,
UniTAP.ColorInfo.ColorFormat.CF_RAW,
UniTAP.ColorInfo.ColorFormat.CF_Y_ONLY]:
color_mode.dynamic_range = UniTAP.ColorInfo.DynamicRange.DR_VESA
else:
color_mode.dynamic_range = UniTAP.ColorInfo.DynamicRange.DR_CTA
video_mode = UniTAP.VideoMode(timing=timing, color_info=color_mode)
if stream < role.dptx.pg.max_stream_count:
role.dptx.pg[stream].set_vm(vm=video_mode)
role.dptx.pg[stream].set_pattern(pattern=UniTAP.VideoPattern.ColorBars)
role.dptx.pg[stream].apply()
res_app = role.dptx.pg[stream].status().error
print(f"Stream {stream} - Apply {res_app.__str__()}")
if res_app == res_app.OK:
print("Start do bulk capturing")
try:
do_bulk_capture(role, timing, color_mode, lane, rate, stream)
print("Bulk capture completed successfully")
except BaseException as e:
print(f'Error during bulk capturing. Error: {e}')
else:
print('Cannot start to do bulk capturing, because PG does not apply settings.')
#
# 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()