1.1.0版本
This commit is contained in:
2
UniTAP/dev/modules/dut_tests/report/__init__.py
Normal file
2
UniTAP/dev/modules/dut_tests/report/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .report_maker import generate_html_report, TestAdditionalInfo, TestResult
|
||||
from .report_utils import update_configuration, dp21_source_timing_table, detect_warning_message
|
||||
179
UniTAP/dev/modules/dut_tests/report/report_maker.py
Normal file
179
UniTAP/dev/modules/dut_tests/report/report_maker.py
Normal file
@@ -0,0 +1,179 @@
|
||||
import platform
|
||||
from datetime import datetime
|
||||
from enum import IntEnum
|
||||
|
||||
from .report_template import *
|
||||
|
||||
|
||||
class TestResult(IntEnum):
|
||||
Unknown = -1
|
||||
Passed = 0
|
||||
Failed = 1
|
||||
Skipped = 2
|
||||
Aborted = 3
|
||||
|
||||
|
||||
class TestAdditionalInfo:
|
||||
|
||||
def __init__(self, dut_model_name: str = "", dut_revision: str = "", dut_serial_number: str = "",
|
||||
dut_firmware_version: str = "", dut_driver_version: str = "", tested_by: str = "", remarks: str = ""):
|
||||
self.device_name = str()
|
||||
self.device_serial_number = str()
|
||||
self.device_detailed_data = str()
|
||||
self.device_frontend_version = str()
|
||||
self.memory_size = str()
|
||||
self.python_version = platform.python_version()
|
||||
self.bundle_version = str()
|
||||
self.dut_model_name = dut_model_name
|
||||
self.dut_revision = dut_revision
|
||||
self.dut_serial_number = dut_serial_number
|
||||
self.dut_firmware_version = dut_firmware_version
|
||||
self.dut_driver_version = dut_driver_version
|
||||
self.tested_by = tested_by
|
||||
self.remarks = remarks
|
||||
|
||||
|
||||
def write_to_file(file_name, text: str):
|
||||
with open(file_name, 'w', encoding='UTF-8') as file:
|
||||
file.write(text)
|
||||
|
||||
|
||||
def replace_additional_info(test_additional_info: TestAdditionalInfo):
|
||||
result = DeviceDescription
|
||||
|
||||
result = result.replace("#device_name#", test_additional_info.device_name)
|
||||
result = result.replace("#detailed_vdata#", test_additional_info.device_detailed_data)
|
||||
result = result.replace("#frontend_version#", test_additional_info.device_frontend_version)
|
||||
result = result.replace("#memory_size#", test_additional_info.memory_size)
|
||||
result = result.replace("#console_app_version#", test_additional_info.python_version)
|
||||
result = result.replace("#console_bundle_version#", test_additional_info.bundle_version)
|
||||
result = result.replace("#date_time#", datetime.now().strftime("%d-%m-%Y %H:%M"))
|
||||
result = result.replace("#model_name#", test_additional_info.dut_model_name)
|
||||
result = result.replace("#revision#", test_additional_info.dut_revision)
|
||||
result = result.replace("#serial_number#", test_additional_info.dut_serial_number)
|
||||
result = result.replace("#firmware_version#", test_additional_info.dut_firmware_version)
|
||||
result = result.replace("#driver_version#", test_additional_info.dut_driver_version)
|
||||
result = result.replace("#conducted_by#", test_additional_info.tested_by)
|
||||
result = result.replace("#remarks#", test_additional_info.remarks)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def generate_html_report(path: str, test_additional_info: TestAdditionalInfo, reports: list):
|
||||
result = str()
|
||||
|
||||
head = ReportHead
|
||||
head = head.replace("#count#", str((len(reports) + 2)))
|
||||
|
||||
body = ReportBody
|
||||
body = body.replace("#device_description#", replace_additional_info(test_additional_info))
|
||||
|
||||
runs = 0
|
||||
failed = 0
|
||||
skipped = 0
|
||||
aborted = 0
|
||||
|
||||
dict_result_2 = {TestResult.Failed: "FAILED",
|
||||
TestResult.Skipped: "SKIPPED",
|
||||
TestResult.Aborted: "ABORTED",
|
||||
TestResult.Passed: "PASSED"}
|
||||
|
||||
json_config_info = '[' + ",".join(f'"{report.json_config_info}"' for report in reports) + ']'
|
||||
|
||||
for item in reports:
|
||||
runs += 1
|
||||
if item.test_result == TestResult.Failed:
|
||||
failed += 1
|
||||
elif item.test_result == TestResult.Skipped:
|
||||
skipped += 1
|
||||
elif item.test_result == TestResult.Aborted:
|
||||
aborted += 1
|
||||
|
||||
head = head.replace("#configInfo#", json_config_info)
|
||||
result += head
|
||||
|
||||
passed = runs - failed - skipped - aborted
|
||||
|
||||
body = body.replace("#runs#", str(runs))
|
||||
body = body.replace("#passed#", str(passed))
|
||||
body = body.replace("#failed#", str(failed))
|
||||
body = body.replace("#skipped#", str(skipped))
|
||||
body = body.replace("#aborted#", str(aborted))
|
||||
|
||||
options_list = ""
|
||||
for i in range(len(reports)):
|
||||
line = OptionListLine
|
||||
line = line.replace("#number#", str(i + 2))
|
||||
line = line.replace("#test_name#", f"{reports[i].group_name} / {reports[i].test_name}")
|
||||
line = line.replace("#test_result#", dict_result_2.get(reports[i].test_result))
|
||||
options_list += line + "\n"
|
||||
|
||||
body = body.replace("#optionList#", options_list)
|
||||
|
||||
tables = Tables
|
||||
table_lines = ""
|
||||
for i in range(len(reports)):
|
||||
line = TestDescriptionLine
|
||||
line = line.replace("#handler_number#", str(i + 2))
|
||||
line = line.replace("#test_name#", reports[i].test_name)
|
||||
line = line.replace("#test_group#", reports[i].group_name)
|
||||
line = line.replace("#test_result#", dict_result_2.get(reports[i].test_result))
|
||||
line = line.replace("#error#", f"{reports[i].error_code}" if reports[i].error_code != 0 else "-")
|
||||
line = line.replace("#ending#", "2" if i % 2 else "")
|
||||
test_result = dict_result_2.get(reports[i].test_result)
|
||||
line = line.replace("#SUCCESS#", test_result if test_result is not None else "PASSED")
|
||||
table_lines += line + "\n"
|
||||
|
||||
tables = tables.replace("#test_description_lines#", table_lines)
|
||||
|
||||
def escape_html(log: str) -> str:
|
||||
res = []
|
||||
|
||||
for c in log:
|
||||
if c == '&':
|
||||
res.append("&")
|
||||
elif c == '<':
|
||||
res.append("<")
|
||||
elif c == '>':
|
||||
res.append(">")
|
||||
elif c == '"':
|
||||
res.append(""")
|
||||
elif c == '\'':
|
||||
res.append("'")
|
||||
else:
|
||||
res.append(c)
|
||||
|
||||
return ''.join(res)
|
||||
|
||||
tables_list = ""
|
||||
warnings = ""
|
||||
for i in range(len(reports)):
|
||||
line = TestTable
|
||||
line = line.replace("#number#", f"{i + 2}")
|
||||
line = line.replace("#test_number#", f"{i + 1}")
|
||||
line = line.replace("#test_group#", reports[i].group_name)
|
||||
line = line.replace("#test_name#", reports[i].test_name)
|
||||
line = line.replace("#result#", dict_result_2.get(reports[i].test_result))
|
||||
line = line.replace("#test_delay#", f"{reports[i].test_delay * 1000}")
|
||||
line = line.replace("#test_parameters#", reports[i].config_info)
|
||||
line = line.replace("#warning#", "<b>Debug options enabled!</b><br><br>" if reports[i].debug else "")
|
||||
|
||||
if reports[i].debug:
|
||||
warnings = "<b>Debug options enabled!</b><br><br>"
|
||||
|
||||
line = line.replace("#test_log#", escape_html(reports[i].fw_logs))
|
||||
tables_list += line + "\n"
|
||||
|
||||
body = body.replace("#warning#", warnings)
|
||||
tables = tables.replace("#test_tables_list#", tables_list)
|
||||
tables = tables.replace("#warning#", warnings)
|
||||
|
||||
result += body
|
||||
result += tables
|
||||
|
||||
footer = ReportFooter
|
||||
footer = footer.replace("#result#", "PASSED" if failed == 0 else "FAILED")
|
||||
result += footer
|
||||
|
||||
full_name = path if path.lower().find(".html") != -1 else (path + ".html")
|
||||
write_to_file(full_name, result)
|
||||
153
UniTAP/dev/modules/dut_tests/report/report_template.py
Normal file
153
UniTAP/dev/modules/dut_tests/report/report_template.py
Normal file
@@ -0,0 +1,153 @@
|
||||
ReportHead = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" \
|
||||
"<html><head><title>Unigraf Test Report</title>\n" \
|
||||
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Windows-1252\">\n" \
|
||||
"<style>\n" \
|
||||
"html {scroll-behavior: smooth;}\n" \
|
||||
" TABLE.DOCUMENT{width: 100%;}\n" \
|
||||
" P.CONTENTS{font-weight: bold;font-family: \"Arial\";font-size: 11pt;margin-left: 0.3cm;margin-top: 10;margin-bottom: 0.3cm;color: #000000;}\n" \
|
||||
" P.HEADING{background-color: #BBC3FF;margin-top: 0;margin-bottom: 0.5cm;margin-left: 0cm;font-weight: bold;font-family: \"Arial\";font-size: 16pt;color: #000000;}\n" \
|
||||
" P.SUBHEADING{background-color: #BBC3FF;margin-top: 1.25cm;margin-bottom: 0.5cm;margin-left: 0.5cm;margin-right: 0;font-weight: bold;font-family: \"Arial\";font-size: 12pt;color: #000000;text-transform: uppercase;}\n" \
|
||||
" P.GREENSUBHEADING{background-color: #DCFABC;margin-top: 0.5cm;margin-bottom: 0.5cm;margin-left: 0.6cm; margin-right: 0; font-weight: bold;font-family: \"Arial\";font-size: 12pt;color: #000000;}\n" \
|
||||
" P.BODYTEXT{margin-top: 0;margin-bottom: 0;margin-left: 1.0cm;font-weight: medium;font-family: \"Arial\";font-size: 11pt;color: #000000;}\n" \
|
||||
" P.BODYWARNINGS{margin-top: 0;margin-bottom: 0;margin-left: 1.0cm;font-weight: medium;font-family: \"Arial\";font-size: 14pt;color: #ff0000;}\n" \
|
||||
" P.TESTBODY{margin-top: 0;margin-bottom: 0;margin-left: 1.0cm;font-weight: medium;font-family: \"Courier New\";font-size: 11pt;color: #000000;}\n" \
|
||||
" PRE.TESTBODY{margin-top: 0;margin-bottom: 0;margin-left: 1.0cm;font-weight: medium;font-family: \"Courier New\";font-size: 11pt;color: #000000;}\n" \
|
||||
" P.BODYDETAILTEXT{margin-top: 0;margin-bottom: 0;margin-left: 1.4cm;font-weight: medium;font-family: \"Arial\";font-size: 9pt;color: #000000;}\n" \
|
||||
" P.CONTENTS SELECT{font-weight: normal;font-family: \"Arial\";font-size: 11pt;width: 98%;margin-top: 0;text-align: left;}\n" \
|
||||
"P.TABLE_HEADERS{background-color: #DCFABC;margin-top: 0;margin-bottom: 0;margin-left: 1.0cm;font-weight: " \
|
||||
"medium;font-family: \"Arial\";font-size: 12pt;color: #000000;}\n" \
|
||||
" P.TABLE_LINKS{margin-top: 0;margin-bottom: 0;margin-left: 1.0cm;font-weight: medium;font-family: \"Arial\";font-size: 11pt;}\n" \
|
||||
" P.TABLE_LINKS2{margin-top: 0;margin-bottom: 0;margin-left: 1.0cm;font-weight: medium;font-family: \"Arial\";font-size: 11pt; background-color: #DDDDDD;}\n" \
|
||||
" P.FAILED{margin-top: 0;margin-bottom: 0;background-color: #FFBCBC; font-weight: bold;font-family: \"Arial\";font-size: 11pt;color: #000000;}\n" \
|
||||
" P.PASSED{margin-top: 0;margin-bottom: 0;background-color: #BCFFBC; font-weight: bold;font-family: \"Arial\";font-size: 11pt;color: #000000;}\n" \
|
||||
" P.SKIPPED{margin-top: 0;margin-bottom: 0;background-color: #BCBCBC; font-weight: bold;font-family: \"Arial\";font-size: 11pt;color: #000000;}\n" \
|
||||
" P.ERROR_CODE{margin-top: 0;margin-bottom: 0;background-color: #FFFFFF; font-weight: bold;font-family: \"Arial\";font-size: 11pt;color: #000000;}\n" \
|
||||
" P.ABORTED{margin-top: 0;margin-bottom: 0;background-color: #FFFFFF; font-weight: bold;font-family: \"Arial\";font-size: 11pt;color: #000000;}\n" \
|
||||
" .TOPBUTTON{display: none; position: fixed; bottom: 20px; right: 30px; z-index: 99; font-size: 18px; border: solid black 1px; outline: none; background-color: #DCFABC; cursor: pointer; padding: 15px; border-radius: 5px;}\n" \
|
||||
"</style>\n" \
|
||||
"<script type=\"text/javascript\">\n" \
|
||||
"var base64Content = #configInfo#;\n"\
|
||||
"window.current_index = 2;\n" \
|
||||
"window.min_value = 2;\n" \
|
||||
"window.max_value = #count# - 1;\n" \
|
||||
"window.onscroll = function() {scrollFunction()};\n" \
|
||||
"function Hide(iElementIndex) { document.getElementById(\"ID\"+iElementIndex).style.display = 'none'; }\n" \
|
||||
"function Show(iElementIndex) { document.getElementById(\"ID\"+iElementIndex).style.display = 'inline'; }\n" \
|
||||
"function HideAll(iDivCount) { for(var i=0;i<iDivCount;i++) { Hide(i); }}\n" \
|
||||
"function ShowAll(iDivCount) { for(var i=0;i<iDivCount;i++) { Show(i); }}\n" \
|
||||
"function SetIndex(value) { window.current_index = value; }\n" \
|
||||
"function GetIndex() { return parseInt(window.current_index, 10); }\n" \
|
||||
"function HideButtons() { document.getElementById(\"top_buttons\").style.display = 'none'; document.getElementById(\"bottom_buttons\").style.display = 'none'; }\n" \
|
||||
"function ShowButtons() { document.getElementById(\"top_buttons\").style.display = 'inline'; document.getElementById(\"bottom_buttons\").style.display = 'inline'; }\n" \
|
||||
"function UpdateButtonsState() { GetIndex() >= window.min_value && window.max_value ? ShowButtons() : HideButtons(); }\n" \
|
||||
"function ListHandler (iOptionValue) { if(iOptionValue==-1) { ShowAll(#count#); Hide(1); SetIndex(1); UpdateButtonsState(); return; } HideAll(#count#); Show(iOptionValue); SetIndex(iOptionValue > 1 ? iOptionValue : 1); UpdateButtonsState();}\n" \
|
||||
"function NextTest() { var index = GetIndex(); ListHandler ((index + 1 > window.max_value) ? (window.min_value) : (index + 1)); }\n" \
|
||||
"function PreviousTest() { var index = GetIndex(); ListHandler ((index - 1 < window.min_value) ? (window.max_value) : (index - 1)); }\n" \
|
||||
"function scrollFunction() { let topButton = document.getElementById('topBtn'); if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {topButton.style.display = 'block';} else {topButton.style.display = 'none';} }\n" \
|
||||
"function TopFunction() { document.body.scrollTop = 0; document.documentElement.scrollTop = 0;}\n" \
|
||||
"function SaveConfig() { var jsonData = atob(base64Content[GetIndex()-2]); var blob = new Blob([jsonData], { type: 'application/json' }); var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); var currentPageURL = window.location.href; var decodedURL = decodeURIComponent(currentPageURL); link.download = getText() + \".json\"; document.body.appendChild(link); link.click(); document.body.removeChild(link); }\n"\
|
||||
"function getText() { var index = GetIndex(); let a = document.getElementById(\"testlist\"); let option = a.options[index]; return option.text.replace('/', '').replace('>', '').replace(':', '') }\n"\
|
||||
"</script>\n" \
|
||||
"</head>\n"
|
||||
|
||||
OptionListLine = " <option value=\"#number#\"> #test_name# (#test_result#)</option>\n"
|
||||
|
||||
TestDescriptionLine = ("<tr><td><p class=\"TABLE_LINKS#ending#\"><a href=\"javascript:ListHandler(#handler_number#)\">"
|
||||
"#test_group# / #test_name#</a></p></td><td align=\"center\"><p class=\"#SUCCESS#\">"
|
||||
" #test_result# </p></td><td align=\"center\"><p class=\"ERROR_CODE\"> #error# </p></td></tr>\n")
|
||||
|
||||
Tables = "<div id=\"ID1\">\n" \
|
||||
"<p class=\"BODYTEXT\">\n" \
|
||||
"<p class=\"SUBHEADING\" style=\"margin-left: 0; margin-top: " \
|
||||
"0;\"> Summary of individual test runs</p>\n" \
|
||||
"<p class=\"BODYWARNINGS\">\n#warning#</p>\n" \
|
||||
"<table width=\"80%\"><colgroup><col span=\"1\" style=\"width: 85%;\"><col span=\"1\" style=\"width: 10%;\"><col span=\"1\" style=\"width: 5%;\"></colgroup>\n" \
|
||||
"<tr><th><p class=\"TABLE_HEADERS\">Test name</p></th><th><p class=\"TABLE_HEADERS\" style=\"margin-left: 0;\">Result</p></th><th><p class=\"TABLE_HEADERS\" style=\"margin-left: 0;\">Error</p></th></tr>\n" \
|
||||
"#test_description_lines#\n" \
|
||||
"</table>\n" \
|
||||
"#test_tables_list#\n"
|
||||
|
||||
DeviceDescription = "<p class=\"BODYTEXT\">\n" \
|
||||
"Device: #device_name#\n" \
|
||||
"<br>Firmware Package: #detailed_vdata#\n" \
|
||||
"<br>UniTAP: #console_app_version#\n" \
|
||||
"<br>Software Bundle: #console_bundle_version#\n" \
|
||||
"<br>Frontend Info: #frontend_version#\n" \
|
||||
"<br>Device total memory size: #memory_size#\n" \
|
||||
"<br><br>Report generated: #date_time#<br>\n" \
|
||||
"</p></p><p class=\"GREENSUBHEADING\"> DUT<p class=\"BODYTEXT\">\n" \
|
||||
"Device/Model name: #model_name#\n" \
|
||||
"<br>HW Revision: #revision#\n" \
|
||||
"<br>Serial number: #serial_number#\n" \
|
||||
"<br>Firmware: #firmware_version#\n" \
|
||||
"<br>Driver: #driver_version#\n" \
|
||||
"<br><br>Testing conducted by: #conducted_by#\n" \
|
||||
"<br><br>Remarks: #remarks#\n" \
|
||||
"<p class=\"BODYDETAILTEXT\">\n"
|
||||
|
||||
TestTable = "<br><br></p></div><div id=\"ID#number#\">\n" \
|
||||
"<p class=\"SUBHEADING\" style=\"margin-left: 0; margin-top: 0;\"> Test Details, Test #test_number#</p>\n" \
|
||||
"<p class=\"GREENSUBHEADING\"> #test_name#</p>\n" \
|
||||
"<p class=\"BODYWARNINGS\">\n" \
|
||||
"#warning#</p>\n" \
|
||||
"<p class=\"BODYTEXT\">\n" \
|
||||
"Test Set: <b>#test_group#</b><br>\n" \
|
||||
"Test Result: <b>#result#</b>\n" \
|
||||
"<br><br><b>Test Settings:</b></p>\n" \
|
||||
"<p class=\"BODYTEXT\">\n" \
|
||||
"Delay between tests = #test_delay#ms\n<br>" \
|
||||
"#test_parameters#\n" \
|
||||
"</p><p class=\"GREENSUBHEADING\"> Test Log</p><pre class=\"TESTBODY\">" \
|
||||
"#test_log#" \
|
||||
"\n"
|
||||
|
||||
ReportBody = "<body onload='ListHandler(0);'>\n" \
|
||||
" <button class=\"TOPBUTTON\" onclick=\"TopFunction()\" id=\"topBtn\" title=\"Go to top\">↑</button>\n" \
|
||||
" <div><p class=\"HEADING\" id=\"top\"> Unigraf Test Report</p></div>\n" \
|
||||
" <div>\n" \
|
||||
" <table class=\"DOCUMENT\" cellpadding=\"0\" cellspacing=\"0\">\n" \
|
||||
" <colgroup>\n" \
|
||||
" <col width=\"200\">\n" \
|
||||
" <col width=\"*\">\n" \
|
||||
" </colgroup>\n" \
|
||||
" <td><p class=\"CONTENTS\">Select item to display</p></td> \n" \
|
||||
" <td><select id=\"testlist\" onchange=\"ListHandler (document.getElementById ('testlist').value)\" onkeyup=\"ListHandler (document.getElementById ('testlist').value)\"></span>\n" \
|
||||
" <option value=\"0\">Report Summary</option>\n" \
|
||||
" <option value=\"1\">Test Summary</option>\n" \
|
||||
"#optionList#\n" \
|
||||
" <option value=\"-1\">Show everything</option>\n" \
|
||||
" </select>\n" \
|
||||
" </td>\n" \
|
||||
" </table>\n" \
|
||||
"<div id=\"top_buttons\" style='margin-left: 12'>\n" \
|
||||
"<button type=\"button\" onclick=\"PreviousTest()\">Previous</button>\n" \
|
||||
"<button type=\"button\" onclick=\"ListHandler(1)\">Summary</button>\n" \
|
||||
"<button type=\"button\" onclick=\"SaveConfig()\">Save Test Config</button>\n" \
|
||||
"<button type=\"button\" onclick=\"NextTest()\">Next</button>\n" \
|
||||
"<br>\n" \
|
||||
"</div>\n" \
|
||||
"<br>\n" \
|
||||
"<div id=\"ID0\">\n" \
|
||||
"<p class=\"SUBHEADING\" style=\"margin-left: 0; margin-top: 0;\"> Report summary</p>\n" \
|
||||
"<p class=\"GREENSUBHEADING\"> Unigraf device\n" \
|
||||
"#device_description#\n" \
|
||||
"</p></p></p><p class=\"GREENSUBHEADING\"> Test results summary<p class=\"BODYWARNINGS\">\n#warning#</p>\n<p class=\"BODYTEXT\">\n" \
|
||||
"Total number of test runs: #runs#<br>Passed test runs: #passed#<br>Failed test runs: #failed#<br>Skipped test runs: #skipped#<br>Aborted test runs: #aborted#\n" \
|
||||
"<br></p></p></div>\n"
|
||||
|
||||
ReportFooter = "<br><br></pre></div>\n" \
|
||||
"<div id=\"bottom_buttons\" style='margin-left: 12'>\n" \
|
||||
"<button type=\"button\" onclick=\"PreviousTest()\">Previous</button>\n" \
|
||||
"<button type=\"button\" onclick=\"ListHandler(1)\">Summary</button>\n" \
|
||||
"<button type=\"button\" onclick=\"SaveConfig()\">Save Test Config</button>\n" \
|
||||
"<button type=\"button\" onclick=\"NextTest()\">Next</button>\n" \
|
||||
"</div>\n" \
|
||||
"</div>\n" \
|
||||
" <hr>\n" \
|
||||
" <p class=\"BODYTEXT\" style=\"text-align: center;\">\n" \
|
||||
" Unigraf Oy<span style=\"color:#808080;\"> |</span> Piispantilankuja 4 <span style=\"color:#808080;\">|</span> 02240 Espoo <span style=\"color:#808080;\">|</span> Finland <span style=\"color:#808080;\">|</span> +358-9-859 550<br />\n" \
|
||||
" E-mail: <a href=\"mailto:info@unigraf.fi\">info@unigraf.fi</a><span style=\"color:#808080;\"> " \
|
||||
"|</span> Web site: <a href=\"http://www.unigraf.fi\">www.unigraf.fi</a>\n" \
|
||||
" </p>\n" \
|
||||
"</body>\n" \
|
||||
"</html>\n"
|
||||
780
UniTAP/dev/modules/dut_tests/report/report_utils.py
Normal file
780
UniTAP/dev/modules/dut_tests/report/report_utils.py
Normal file
@@ -0,0 +1,780 @@
|
||||
import re
|
||||
from UniTAP.dev.modules.dut_tests.test_utils import TestReportConfigType, make_cf, CMTFormat, CMTBitDepth
|
||||
|
||||
|
||||
def value_from_enumeration_var(_data, _value):
|
||||
|
||||
if len(_data.str_presentation) > 0:
|
||||
return _data.str_presentation[_data.available_values.index(str(_value))]
|
||||
else:
|
||||
return _value
|
||||
|
||||
|
||||
def copy_data(data):
|
||||
_data = {}
|
||||
for item in data:
|
||||
if item.config_id_name in ["TSI_DP14_SRCCTS_DUT_CAPS", "TSI_DP14_SRCCTS_DUT_TA",
|
||||
"TSI_DP14_SRCCTS_DMT_TIMING", "TSI_DP14_SRCCTS_CTA_TIMING",
|
||||
"TSI_DP14_SRCCTS_CVT_TIMING", "TSI_DP14_SRCCTS_AS_DUT_CAPS",
|
||||
"TSI_DP20_SRCCTS_DUT_CAPS", "TSI_DP20_SRCCTS_DUT_TA",
|
||||
"TSI_DP20_SRCCTS_DMT_TIMING", "TSI_DP20_SRCCTS_CTA_TIMING",
|
||||
"TSI_DP20_SRCCTS_CVT_TIMING", "TSI_DP20_SRCCTS_AS_DUT_CAPS",
|
||||
"TSI_DP20_SRCCTS_DUT_LINK_RATES", "TSI_DP14_SRCCTS_DUT_DEBUG_CONF",
|
||||
"TSI_DP20_SRCCTS_DUT_DEBUG_CONF", "TSI_DP20_SINKCTS_DEBUG_CONF"]:
|
||||
_data.update({item.config_id_name: [item.default_value, item.bit_field_list]})
|
||||
elif item.enumeration_variants is not None:
|
||||
_data.update({item.config_id_name: [item.default_value, item.enumeration_variants]})
|
||||
else:
|
||||
_data.update({item.config_id_name: item.default_value})
|
||||
return _data
|
||||
|
||||
|
||||
def detect_warning_message(type_of_test: TestReportConfigType, data):
|
||||
_data = copy_data(data)
|
||||
_dict = {TestReportConfigType.Dp1_4_Source: "TSI_DP14_SRCCTS_DUT_DEBUG_CONF",
|
||||
TestReportConfigType.Dp2_1_Source: "TSI_DP20_SRCCTS_DUT_DEBUG_CONF",
|
||||
TestReportConfigType.Dp2_1_Sink: "TSI_DP20_SINKCTS_DEBUG_CONF",
|
||||
TestReportConfigType.Dp2_1_Lttpr: "TSI_DP20_LTTPR_DEBUG_CR_ITERATION_DELAY"}
|
||||
key = _dict.get(type_of_test)
|
||||
val = _data.get(key)
|
||||
if val is not None:
|
||||
if key in ["TSI_DP14_SRCCTS_DUT_DEBUG_CONF",
|
||||
"TSI_DP20_SRCCTS_DUT_DEBUG_CONF",
|
||||
"TSI_DP20_SINKCTS_DEBUG_CONF"] and val[0] != 0:
|
||||
return True
|
||||
elif key == "TSI_DP20_LTTPR_DEBUG_CR_ITERATION_DELAY" and int(val[0] != 100):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def update_configuration(type_of_test: TestReportConfigType, data):
|
||||
configuration = ""
|
||||
_data = copy_data(data)
|
||||
if type_of_test == TestReportConfigType.Dp1_4_Source:
|
||||
val = _data.get("TSI_DP14_SRCCTS_DUT_DEBUG_CONF")
|
||||
if val is not None and val[0] != 0:
|
||||
configuration += "<span class=DBG_HIGHLIGHT><br>Debug options:<br>"
|
||||
for _bit in val[1]:
|
||||
if val[0] & _bit.mask:
|
||||
configuration += f" - {_bit.description}<br>"
|
||||
configuration += "<br>"
|
||||
|
||||
configuration += "Test timeout = {}ms<br>".format(_data.get("TSI_DP14_SRCCTS_TIMEOUT"))
|
||||
configuration += "Long HPD Duration = {}ms<br><br>".format(_data.get("TSI_DP14_SRCCTS_LONG_HPD_PULSE"))
|
||||
configuration += "DUT capability settings and flags:<br>"
|
||||
configuration += "- Max lanes = {}<br>".format(_data.get("TSI_DP14_SRCCTS_MAX_LANES")[0])
|
||||
configuration += "- Max link rate = {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_MAX_LINK_RATE")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_MAX_LINK_RATE")[0]))
|
||||
value = _data.get("TSI_DP14_SRCCTS_DUT_CAPS")
|
||||
dut_caps_value = int(value[0])
|
||||
for _bit in _data.get("TSI_DP14_SRCCTS_DUT_CAPS")[1]:
|
||||
if dut_caps_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
configuration += "<br>Test automation flags and settings:<br>"
|
||||
|
||||
ta_flags = ["Always ready", "EDID read", "Link Training end", "Active Video"]
|
||||
ta_flags_value = _data.get("TSI_DP14_SRCCTS_DUT_TA")[0]
|
||||
for bit in _data.get("TSI_DP14_SRCCTS_DUT_TA")[1]:
|
||||
if bit.mask & ta_flags_value or bit.enumeration_variants is not None:
|
||||
if bit.enumeration_variants is not None:
|
||||
configuration += "- Event indicating DUT ready: {}<br>".format(
|
||||
ta_flags[(ta_flags_value >> 3) & 0x3])
|
||||
else:
|
||||
configuration += "- {}<br>".format(bit.description)
|
||||
|
||||
fail_mode = "640 x 480 @ 60Hz 6 BPC"
|
||||
configuration += "<br>Failsafe timing: {}<br>".format(
|
||||
fail_mode if int(_data.get("TSI_DP14_SRCCTS_FAILSAFE_MODE")[0]) else "")
|
||||
configuration += "Max supported timing: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_MAX_RESOLUTION")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_MAX_RESOLUTION")[0]))
|
||||
|
||||
configuration += "<br>Most packed timings, 1 lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_1L_MOST_PACKED")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_1L_MOST_PACKED")[0]))
|
||||
configuration += "Most packed timings, 2 lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_2L_MOST_PACKED")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_2L_MOST_PACKED")[0]))
|
||||
configuration += "Most packed timings, 4 lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_4L_MOST_PACKED")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_4L_MOST_PACKED")[0]))
|
||||
|
||||
configuration += "<br>Time stamp generation timigns:<br>"
|
||||
configuration += "RBR, 1 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_1L_RBB")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_1L_RBB")[0]))
|
||||
configuration += "RBR, 2 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_2L_RBB")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_2L_RBB")[0]))
|
||||
configuration += "RBR, 4 Lane: {}<br><br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_4L_RBB")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_4L_RBB")[0]))
|
||||
|
||||
configuration += "HBR, 1 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_1L_HBR")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_1L_HBR")[0]))
|
||||
configuration += "HBR, 2 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_2L_HBR")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_2L_HBR")[0]))
|
||||
configuration += "HBR, 4 Lane: {}<br><br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_4L_HBR")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_4L_HBR")[0]))
|
||||
|
||||
configuration += "HBR2, 1 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_1L_HBR2")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_1L_HBR2")[0]))
|
||||
configuration += "HBR2, 2 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_2L_HBR2")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_2L_HBR2")[0]))
|
||||
configuration += "HBR2, 4 Lane: {}<br><br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_4L_HBR2")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_4L_HBR2")[0]))
|
||||
|
||||
configuration += "HBR3, 1 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_1L_HBR3")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_1L_HBR3")[0]))
|
||||
configuration += "HBR3, 2 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_2L_HBR3")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_2L_HBR3")[0]))
|
||||
configuration += "HBR3, 4 Lane: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_4L_HBR3")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_4L_HBR3")[0]))
|
||||
|
||||
configuration += "<br>Colorimetry:<br>"
|
||||
configuration += "- RGB 6 bpc VESA<br>"
|
||||
|
||||
for i in range(1, 13):
|
||||
value = int(_data.get(f"TSI_DP14_SRCCTS_COLOR_MODE_{i}"))
|
||||
if value == make_cf(CMTFormat.RGB_LEGACY, CMTBitDepth.BPC_8):
|
||||
configuration += "- RGB 8 bpc VESA<br>"
|
||||
elif value == make_cf(CMTFormat.RGB_LEGACY, CMTBitDepth.BPC_10):
|
||||
configuration += "- RGB 10 bpc VESA<br>"
|
||||
elif value == make_cf(CMTFormat.RGB_CEA, CMTBitDepth.BPC_8):
|
||||
configuration += "- RGB 8 bpc CTA<br>"
|
||||
elif value == make_cf(CMTFormat.RGB_CEA, CMTBitDepth.BPC_10):
|
||||
configuration += "- RGB 10 bpc CTA<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_422_BT601, CMTBitDepth.BPC_8):
|
||||
configuration += "- YCbCr 4:2:2 8 bpc CTA (ITU.601)<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_422_BT601, CMTBitDepth.BPC_10):
|
||||
configuration += "- YCbCr 4:2:2 10 bpc CTA (ITU.601)<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_422_BT709, CMTBitDepth.BPC_8):
|
||||
configuration += "- YCbCr 4:2:2 8 bpc CTA (ITU.709)<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_422_BT709, CMTBitDepth.BPC_10):
|
||||
configuration += "- YCbCr 4:2:2 10 bpc CTA (ITU.709)<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_444_BT601, CMTBitDepth.BPC_8):
|
||||
configuration += "- YCbCr 4:4:4 8 bpc CTA (ITU.601)<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_444_BT601, CMTBitDepth.BPC_10):
|
||||
configuration += "- YCbCr 4:4:4 10 bpc CTA (ITU.601)<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_444_BT709, CMTBitDepth.BPC_8):
|
||||
configuration += "- YCbCr 4:4:4 8 bpc CTA (ITU.709)<br>"
|
||||
elif value == make_cf(CMTFormat.YCBCR_444_BT709, CMTBitDepth.BPC_10):
|
||||
configuration += "- YCbCr 4:4:4 10 bpc CTA (ITU.709)<br>"
|
||||
|
||||
configuration += "<br>Audio format:<br>"
|
||||
configuration += "- Minimum supported sample frequency: {}Hz<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_MIN_SAMPLE_RATE")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_MIN_SAMPLE_RATE")[0]))
|
||||
configuration += "- Maximum supported sample frequency: {}Hz<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_MAX_SAMPLE_RATE")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_MAX_SAMPLE_RATE")[0]))
|
||||
configuration += "- Audio test pattern: {}<br>". \
|
||||
format(value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_AUDIO_TEST_PATTERN")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_AUDIO_TEST_PATTERN")[0]))
|
||||
configuration += "- Audio sample size: {}<br>". \
|
||||
format(value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_EDID_SAMPLE_SIZE")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_EDID_SAMPLE_SIZE")[0]))
|
||||
|
||||
ch_alloc_title = ["Minimum channel configuration / Min. sample rate",
|
||||
"Maximum channel configuration / Min. sample rate",
|
||||
"Minimum channel configuration / Max. sample rate",
|
||||
"Maximum channel configuration / Max. sample rate"]
|
||||
|
||||
ch_alloc_str = [
|
||||
"- Front Left + Front Right (2 Channels)",
|
||||
"- Low Frequency Effect (1 Channel)",
|
||||
"- Front Center (1 Channel)",
|
||||
"- Rear Left + Rear Right (2 Channels)",
|
||||
"- Rear Center (1 Channel)",
|
||||
"- Front Left Center + Front Right Center (2 Channels)",
|
||||
"- Rear Left Center + Rear Right Center (2 Channels)",
|
||||
"- Front Left Wide + Front Right Wide (2 Channels)",
|
||||
"- Front Left High + Front Right High (2 Channels)",
|
||||
"- Top Center (1 Channel)",
|
||||
"- Front Center High (1 Channel)"]
|
||||
|
||||
for i in range(len(ch_alloc_title)):
|
||||
CH_ALLOC_CI = f"TSI_DP14_SRCCTS_CH_ALLOC{i + 1}"
|
||||
CH_ALLOC_VAL = int(_data.get(CH_ALLOC_CI))
|
||||
|
||||
CH_COUNT_CI = f"TSI_DP14_SRCCTS_CHANNELS{i + 1}"
|
||||
CH_COUNT_VAL = int(_data.get(CH_COUNT_CI))
|
||||
|
||||
configuration += "<br>{}:<br>".format(ch_alloc_title[i])
|
||||
configuration += "- Channel count: {}<br>".format(CH_COUNT_VAL)
|
||||
|
||||
for j in range(len(ch_alloc_str)):
|
||||
if CH_ALLOC_VAL >> j & 1:
|
||||
configuration += "{}<br>".format(ch_alloc_str[j])
|
||||
|
||||
configuration += "<br>DSC Info:<br>"
|
||||
dsc_version = int(_data.get("TSI_DP14_SRCCTS_DSC_VERSION")[0])
|
||||
configuration += "- DSC Version: {}.{}<br>".format((dsc_version >> 16) & 0xff, dsc_version & 0xff)
|
||||
configuration += "- DSC Max. Slices: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_DSC_DUT_MAX_SLICE")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_DSC_DUT_MAX_SLICE")[0]))
|
||||
|
||||
configuration += "<br>DSC Colorimetry:<br>"
|
||||
configuration += "- RGB 8 bpc VESA<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_1")):
|
||||
configuration += "- RGB 10 bpc VESA<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_2")):
|
||||
configuration += "- RGB 12 bpc VESA<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_3")):
|
||||
configuration += "- YCbCr 4:4:4 8 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_4")):
|
||||
configuration += "- YCbCr 4:4:4 10 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_5")):
|
||||
configuration += "- YCbCr 4:4:4 12 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_6")):
|
||||
configuration += "- YCbCr 4:2:2 8 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_7")):
|
||||
configuration += "- YCbCr 4:2:2 10 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_8")):
|
||||
configuration += "- YCbCr 4:2:2 12 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_9")):
|
||||
configuration += "- YCbCr 4:2:2 Simple 8 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_10")):
|
||||
configuration += "- YCbCr 4:2:2 Simple 10 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_11")):
|
||||
configuration += "- YCbCr 4:2:2 Simple 12 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_12")):
|
||||
configuration += "- YCbCr 4:2:0 Simple 8 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_13")):
|
||||
configuration += "- YCbCr 4:2:0 Simple 10 bpc CTA (ITU.709)<br>"
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DSC_COLOR_MODE_14")):
|
||||
configuration += "- YCbCr 4:2:0 Simple 12 bpc CTA (ITU.709)<br>"
|
||||
configuration += "<br>DSC resolutions to be tested:<br>"
|
||||
|
||||
dsc_timings = ["1920x1080 @ 30Hz", "1920x1080 @ 60Hz", "1920x1080 @ 120Hz", "3840x2160 @ 30Hz",
|
||||
"3840x2160 @ 60Hz", "3840x2160 @ 120Hz", "5120x2160 @ 30Hz", "5120x2160 @ 60Hz",
|
||||
"5120x2160 @ 120Hz", "7680x4320 @ 30Hz", "7680x4320 @ 60Hz", "7680x4320 @ 100Hz"]
|
||||
|
||||
for item in enumerate(dsc_timings):
|
||||
if int(_data.get(f"TSI_DP14_SRCCTS_DSC_VMT_{item[0]}_TIMINGS")):
|
||||
lane_count_link_rate = _data.get(f"TSI_DP14_SRCCTS_DSC_VMT_{item[0]}_LC_LR")
|
||||
if lane_count_link_rate in [1 << 0, 1 << 1, 1 << 2, 1 << 3]:
|
||||
n_lanes = "1"
|
||||
elif lane_count_link_rate in [1 << 4, 1 << 5, 1 << 6, 1 << 7]:
|
||||
n_lanes = "2"
|
||||
else:
|
||||
n_lanes = "4"
|
||||
if lane_count_link_rate in [1 << 0, 1 << 4, 1 << 8]:
|
||||
bit_rate = "1.62"
|
||||
elif lane_count_link_rate in [1 << 1, 1 << 5, 1 << 9]:
|
||||
bit_rate = "2.7"
|
||||
elif lane_count_link_rate in [1 << 2, 1 << 6, 1 << 10]:
|
||||
bit_rate = '5.4'
|
||||
else:
|
||||
bit_rate = "8.1"
|
||||
configuration += "- {} with {} lanes(s) @ {} Gbps<br>".format(item[1], n_lanes, bit_rate)
|
||||
|
||||
configuration += "<br>DisplayID test configuration:<br>"
|
||||
configuration += "- Max HActive = {}<br>".format(_data.get("TSI_DP14_SRCCTS_MAX_STREAM_HACTIVE"))
|
||||
configuration += "- Max VActive = {}<br>".format(_data.get("TSI_DP14_SRCCTS_MAX_STREAM_VACTIVE"))
|
||||
configuration += "- Max Pixel Clock (kHz) = {} <br>".format(
|
||||
_data.get("TSI_DP14_SRCCTS_MAX_STREAM_PIXEL_CLOCK"))
|
||||
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[1][15].mask) & int(
|
||||
_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[0]):
|
||||
configuration += "<br>DMT Timings:<br>"
|
||||
dmt_timing_value = int(_data.get("TSI_DP14_SRCCTS_DMT_TIMING")[0])
|
||||
for _bit in _data.get("TSI_DP14_SRCCTS_DMT_TIMING")[1]:
|
||||
if dmt_timing_value & int(_bit.mask):
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
if int(_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[1][16].mask) & int(
|
||||
_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[0]):
|
||||
configuration += "<br>CTA Timings:<br>"
|
||||
cta_timing_value = int(_data.get("TSI_DP14_SRCCTS_CTA_TIMING")[0])
|
||||
for _bit in _data.get("TSI_DP14_SRCCTS_CTA_TIMING")[1]:
|
||||
if cta_timing_value & int(_bit.mask):
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
if (int(_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[1][17].mask) & int(
|
||||
_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[0])) or \
|
||||
(int(_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[1][18].mask) &
|
||||
_data.get("TSI_DP14_SRCCTS_DUT_CAPS")[0]):
|
||||
configuration += "<br>CVT Timings:<br>"
|
||||
cvt_timing_value = int(_data.get("TSI_DP14_SRCCTS_CVT_TIMING")[0])
|
||||
for _bit in _data.get("TSI_DP14_SRCCTS_CVT_TIMING")[1]:
|
||||
if cvt_timing_value & int(_bit.mask):
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
configuration += "<br>Audio modes:<br>"
|
||||
|
||||
for i in range(8):
|
||||
audio_mode = int(_data.get(f"TSI_DP14_SRCCTS_TESTED_AUDIO_MODE_{i}"))
|
||||
audio_type = ["Refer to Stream Header", "L-PCM", "AC-3", "MPEG-1", "MP3", "MPEG2", "AAC LC", "DTS",
|
||||
"ATRAC", "One Bit Audio", "Enhanced AC-3", "DTS-HD", "MAT", "DST", "WMA Pro",
|
||||
"Refer to Audio Coding Extension Type (CXT)"]
|
||||
audio_sampling = ["Refer to Stream Header", "32 kHz", "44.1 kHz (CD)", "48 kHz", "88.2 kHz", "96 kHz",
|
||||
"176.4 kHz", "192 kHz"]
|
||||
audio_ch_count = ["Refer to Stream Header", "2 channels", "3 channels", "4 channels", "5 channels",
|
||||
"6 channels", "7 channels", "8 channels"]
|
||||
audio_sample_size = ["Refer to Stream Header", "16 bit", "20 bit", "24 bit"]
|
||||
|
||||
if audio_mode:
|
||||
configuration += "- Audio Mode {}: {}, {}, {} @ {}<br>".format(i, audio_type[
|
||||
audio_mode >> 4 & 0xF],
|
||||
audio_ch_count[
|
||||
audio_mode & 0x7],
|
||||
audio_sample_size[
|
||||
audio_mode >> 8 & 0x3],
|
||||
audio_sampling[
|
||||
audio_mode >> 10 & 0x7])
|
||||
else:
|
||||
configuration += f"- Audio Mode {i}: Disabled<br>"
|
||||
|
||||
configuration += "<br>AdaptiveSync configuration:<br>"
|
||||
as_value = _data.get("TSI_DP14_SRCCTS_AS_DUT_CAPS")[0]
|
||||
for _bit in _data.get("TSI_DP14_SRCCTS_AS_DUT_CAPS")[1]:
|
||||
if as_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
configuration += "- Adaptive-Sync range minimum refresh rate supported by the Source: {}<br>" \
|
||||
.format(value_from_enumeration_var(_data.get("TSI_DP14_SRCCTS_AS_RANGE_MIN_RATE")[1],
|
||||
_data.get("TSI_DP14_SRCCTS_AS_RANGE_MIN_RATE")[0]))
|
||||
|
||||
as_timings = ["1920x1080p", "2560x1080p", "2560x1440p", "3840x2160p", "4096x2160p", "5120x2160p",
|
||||
"7680x4320p", "10240x4320p"]
|
||||
|
||||
for item in enumerate(as_timings):
|
||||
as_value = int(_data.get(f"TSI_DP14_SRCCTS_AS_RANGE_MAX_RATE_{item[0]}"))
|
||||
if as_value:
|
||||
configuration += "- {} maximum refresh rate: {}Hz<br>".format(item[1], as_value)
|
||||
else:
|
||||
configuration += "- {} is not supported<br>".format(item[1])
|
||||
|
||||
elif type_of_test == TestReportConfigType.Dp2_1_Source:
|
||||
|
||||
val = _data.get("TSI_DP20_SRCCTS_DUT_DEBUG_CONF")
|
||||
if val is not None and val[0] != 0:
|
||||
configuration += "<span class=DBG_HIGHLIGHT><br>Debug options:<br>"
|
||||
for _bit in val[1]:
|
||||
if val[0] & _bit.mask:
|
||||
configuration += f" - {_bit.description}<br>"
|
||||
configuration += "<br>"
|
||||
|
||||
configuration += "Test timeout = {}ms<br>".format(_data.get("TSI_DP20_SRCCTS_TIMEOUT"))
|
||||
configuration += "Long HPD Duration = {}ms<br><br>".format(_data.get("TSI_DP20_SRCCTS_LONG_HPD_PULSE"))
|
||||
configuration += "DUT capability settings and flags:<br>"
|
||||
configuration += "- Max lanes = {}<br>".format(_data.get("TSI_DP20_SRCCTS_MAX_LANES")[0])
|
||||
configuration += "- Max link rate = {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_MAX_LINK_RATE")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_MAX_LINK_RATE")[0]))
|
||||
|
||||
dut_caps_value = _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[0]
|
||||
for _bit in _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[1]:
|
||||
if dut_caps_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
dut_link_rates_value = _data.get("TSI_DP20_SRCCTS_DUT_LINK_RATES")[0]
|
||||
for _bit in _data.get("TSI_DP20_SRCCTS_DUT_LINK_RATES")[1]:
|
||||
if dut_link_rates_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
configuration += f"- Number of LTTPR devices: {_data.get('TSI_DP20_SRCCTS_LTTPR_DEVICE_COUNT')}<br>"
|
||||
configuration += "- Number of minimum link bandwidth: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_MAX_LINK_BW_POLICY")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_MAX_LINK_BW_POLICY")[0]))
|
||||
|
||||
configuration += "<br>Settings for Dynamic Refresh Rate with VBlank stretch with MSA_TIMING_PAR_IGNORED:<br>"
|
||||
configuration += f"- HActive: {_data.get('TSI_DP20_SRCCTS_DRR_HACTIVE')} pixels<br>"
|
||||
configuration += f"- VActive: {_data.get('TSI_DP20_SRCCTS_DRR_VACTIVE')} lines<br>"
|
||||
configuration += f"- Pixel Clock: {_data.get('TSI_DP20_SRCCTS_DRR_PIXEL_CLOCK')} kHz<br>"
|
||||
configuration += f"- Minimum Vertical Refresh Rate: {_data.get('TSI_DP20_SRCCTS_DRR_MIN_VRR')} Hz<br>"
|
||||
configuration += f"- Maximum Vertical Refresh Rate: {_data.get('TSI_DP20_SRCCTS_DRR_MAX_VRR')} Hz<br>"
|
||||
|
||||
configuration += "<br>Test automation flags and settings:<br>"
|
||||
|
||||
ta_flags = ["Always ready", "EDID read", "Link Training end", "Active Video"]
|
||||
ta_flags_value = _data.get("TSI_DP20_SRCCTS_DUT_TA")[0]
|
||||
for bit in _data.get("TSI_DP20_SRCCTS_DUT_TA")[1]:
|
||||
if bit.mask & ta_flags_value or bit.enumeration_variants is not None:
|
||||
if bit.enumeration_variants is not None:
|
||||
configuration += "- Event indicating DUT ready: {}<br>".format(ta_flags[(ta_flags_value >> 3) & 0x3])
|
||||
else:
|
||||
configuration += "- {}<br>".format(bit.description)
|
||||
|
||||
configuration += "<br>Audio format:<br>"
|
||||
configuration += "- Minimum supported sample frequency: {}Hz<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_MIN_SAMPLE_RATE")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_MIN_SAMPLE_RATE")[0]))
|
||||
configuration += "- Maximum supported sample frequency: {}Hz<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_MAX_SAMPLE_RATE")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_MAX_SAMPLE_RATE")[0]))
|
||||
configuration += "- Audio test pattern: {}<br>". \
|
||||
format(value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_AUDIO_TEST_PATTERN")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_AUDIO_TEST_PATTERN")[0]))
|
||||
configuration += "- Audio sample size: {}<br>". \
|
||||
format(value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_EDID_SAMPLE_SIZE")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_EDID_SAMPLE_SIZE")[0]))
|
||||
|
||||
ch_alloc_title = ["Minimum channel configuration / Min. sample rate",
|
||||
"Maximum channel configuration / Min. sample rate",
|
||||
"Minimum channel configuration / Max. sample rate",
|
||||
"Maximum channel configuration / Max. sample rate"]
|
||||
|
||||
ch_alloc_str = [
|
||||
"- Front Left + Front Right (2 Channels)",
|
||||
"- Low Frequency Effect (1 Channel)",
|
||||
"- Front Center (1 Channel)",
|
||||
"- Rear Left + Rear Right (2 Channels)",
|
||||
"- Rear Center (1 Channel)",
|
||||
"- Front Left Center + Front Right Center (2 Channels)",
|
||||
"- Rear Left Center + Rear Right Center (2 Channels)",
|
||||
"- Front Left Wide + Front Right Wide (2 Channels)",
|
||||
"- Front Left High + Front Right High (2 Channels)",
|
||||
"- Top Center (1 Channel)",
|
||||
"- Front Center High (1 Channel)"]
|
||||
|
||||
for i in range(len(ch_alloc_title)):
|
||||
CH_ALLOC_CI = f"TSI_DP20_SRCCTS_CH_ALLOC{i + 1}"
|
||||
CH_ALLOC_VAL = int(_data.get(CH_ALLOC_CI))
|
||||
|
||||
CH_COUNT_CI = f"TSI_DP20_SRCCTS_CHANNELS{i + 1}"
|
||||
CH_COUNT_VAL = int(_data.get(CH_COUNT_CI))
|
||||
|
||||
configuration += "<br>{}:<br>".format(ch_alloc_title[i])
|
||||
configuration += "- Channel count: {}<br>".format(CH_COUNT_VAL)
|
||||
|
||||
for j in range(len(ch_alloc_str)):
|
||||
if CH_ALLOC_VAL >> j & 1:
|
||||
configuration += "{}<br>".format(ch_alloc_str[j])
|
||||
|
||||
configuration += "<br>DSC Info:<br>"
|
||||
dsc_version = int(_data.get("TSI_DP20_SRCCTS_DSC_VERSION")[0])
|
||||
configuration += "- DSC Version: {}.{}<br>".format((dsc_version >> 16) & 0xff, dsc_version & 0xff)
|
||||
configuration += "- DSC Max. Slices: {}<br>".format(
|
||||
value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_DSC_DUT_MAX_SLICE")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_DSC_DUT_MAX_SLICE")[0]))
|
||||
|
||||
configuration += "<br>DisplayID test configuration:<br>"
|
||||
configuration += "- Max HActive = {}<br>".format(_data.get("TSI_DP20_SRCCTS_MAX_STREAM_HACTIVE"))
|
||||
configuration += "- Max VActive = {}<br>".format(_data.get("TSI_DP20_SRCCTS_MAX_STREAM_VACTIVE"))
|
||||
configuration += "- Max Pixel Clock (kHz) = {} <br>".format(
|
||||
_data.get("TSI_DP20_SRCCTS_MAX_STREAM_PIXEL_CLOCK"))
|
||||
|
||||
if _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[1][17].mask & _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[0]:
|
||||
configuration += "<br>DMT Timings:<br>"
|
||||
dmt_timing_value = _data.get("TSI_DP20_SRCCTS_DMT_TIMING")[0]
|
||||
for _bit in _data.get("TSI_DP20_SRCCTS_DMT_TIMING")[1]:
|
||||
if dmt_timing_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
if _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[1][18].mask & _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[0]:
|
||||
configuration += "<br>CTA Timings:<br>"
|
||||
cta_timing_value = _data.get("TSI_DP20_SRCCTS_CTA_TIMING")[0]
|
||||
for _bit in _data.get("TSI_DP20_SRCCTS_CTA_TIMING")[1]:
|
||||
if cta_timing_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
if (_data.get("TSI_DP20_SRCCTS_DUT_CAPS")[1][19].mask & _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[0]) or \
|
||||
(_data.get("TSI_DP20_SRCCTS_DUT_CAPS")[1][20].mask & _data.get("TSI_DP20_SRCCTS_DUT_CAPS")[0]):
|
||||
configuration += "<br>CVT Timings:<br>"
|
||||
cvt_timing_value = _data.get("TSI_DP20_SRCCTS_CVT_TIMING")[0]
|
||||
for _bit in _data.get("TSI_DP20_SRCCTS_CVT_TIMING")[1]:
|
||||
if cvt_timing_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
configuration += "<br>Audio modes:<br>"
|
||||
|
||||
for i in range(8):
|
||||
audio_mode = int(_data.get(f"TSI_DP20_SRCCTS_TESTED_AUDIO_MODE_{i}"))
|
||||
audio_type = ["Refer to Stream Header", "L-PCM", "AC-3", "MPEG-1", "MP3", "MPEG2", "AAC LC", "DTS",
|
||||
"ATRAC", "One Bit Audio", "Enhanced AC-3", "DTS-HD", "MAT", "DST", "WMA Pro",
|
||||
"Refer to Audio Coding Extension Type (CXT)"]
|
||||
audio_sampling = ["Refer to Stream Header", "32 kHz", "44.1 kHz (CD)", "48 kHz", "88.2 kHz", "96 kHz",
|
||||
"176.4 kHz", "192 kHz"]
|
||||
audio_ch_count = ["Refer to Stream Header", "2 channels", "3 channels", "4 channels", "5 channels",
|
||||
"6 channels", "7 channels", "8 channels"]
|
||||
audio_sample_size = ["Refer to Stream Header", "16 bit", "20 bit", "24 bit"]
|
||||
|
||||
if audio_mode:
|
||||
configuration += "- Audio Mode {}: {}, {}, {} @ {}<br>".format(i, audio_type[
|
||||
audio_mode >> 4 & 0xF],
|
||||
audio_ch_count[
|
||||
audio_mode & 0x7],
|
||||
audio_sample_size[
|
||||
audio_mode >> 8 & 0x3],
|
||||
audio_sampling[
|
||||
audio_mode >> 10 & 0x7])
|
||||
else:
|
||||
configuration += f"- Audio Mode {i}: Disabled<br>"
|
||||
|
||||
configuration += "<br>AdaptiveSync configuration:<br>"
|
||||
as_value = _data.get("TSI_DP20_SRCCTS_AS_DUT_CAPS")[0]
|
||||
for _bit in _data.get("TSI_DP20_SRCCTS_AS_DUT_CAPS")[1]:
|
||||
if as_value & _bit.mask:
|
||||
configuration += "- {}<br>".format(_bit.description)
|
||||
|
||||
configuration += "- Adaptive-Sync range minimum refresh rate supported by the Source: {}<br>" \
|
||||
.format(value_from_enumeration_var(_data.get("TSI_DP20_SRCCTS_AS_RANGE_MIN_RATE")[1],
|
||||
_data.get("TSI_DP20_SRCCTS_AS_RANGE_MIN_RATE")[0]))
|
||||
|
||||
as_timings = ["1920x1080p", "2560x1080p", "2560x1440p", "3840x2160p", "4096x2160p", "5120x2160p",
|
||||
"7680x4320p", "10240x4320p"]
|
||||
|
||||
for item in enumerate(as_timings):
|
||||
as_value = int(_data.get(f"TSI_DP20_SRCCTS_AS_RANGE_MAX_RATE_{item[0]}"))
|
||||
if as_value:
|
||||
configuration += "- {} maximum refresh rate: {}Hz<br>".format(item[1], as_value)
|
||||
else:
|
||||
configuration += "- {} is not supported<br>".format(item[1])
|
||||
|
||||
colorimetry_map = {0: '-', 1: 8, 3: 10, 7: 12, 15: 16}
|
||||
|
||||
def add_column_title(include_dsc : bool):
|
||||
title = "<tr>"
|
||||
style = 'style="padding: 10px; border: 1px solid black;"'
|
||||
title_list = [f'<th rowspan="2" {style}>Timing</th>\n',
|
||||
f'<th colspan="6" {style}>Timing vendors</th>\n',
|
||||
f'<th colspan="5" {style}>Colorimetry</th>\n']
|
||||
timing_vendors = ['CTA', 'DMT', 'CVT', 'CVT RB1', 'CVT RB2', 'OVT']
|
||||
colorimetry = ["RGB", "YCbCr444", "YCbCr422", "YCbCr422Simple", "YCbCr420"] if include_dsc else [ "RGB", "YCbCr444", "YCbCr422", "YCbCr420" ]
|
||||
|
||||
for title_item in title_list:
|
||||
title += title_item
|
||||
title += "</tr>\n<tr>"
|
||||
|
||||
for timing_vendors_item in timing_vendors:
|
||||
title += f'<th {style}>{timing_vendors_item}</th>'
|
||||
|
||||
for colorimetry_item in colorimetry:
|
||||
title += f'<th {style}>{colorimetry_item}</th>'
|
||||
|
||||
title += "</tr>\n"
|
||||
|
||||
return title
|
||||
|
||||
def add_video_row(timing_info, tim_value):
|
||||
style = 'align="center";'
|
||||
row = f'<tr><td align="left">{timing_info}</td>' \
|
||||
f'<td {style}>{"+" if tim_value & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 1) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 2) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 3) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 4) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 5) & 0x1 else "-"}</td>'
|
||||
row += f'<td {style}>{colorimetry_map.get((tim_value >> 12) & 0xF)}</td>' \
|
||||
f'<td {style}>{colorimetry_map.get((tim_value >> 16) & 0xF)}</td>' \
|
||||
f'<td {style}>{colorimetry_map.get((tim_value >> 20) & 0xF)}</td>' \
|
||||
f'<td {style}>{colorimetry_map.get((tim_value >> 28) & 0xF)}</td>'
|
||||
return row
|
||||
|
||||
def add_dsc_row(timing_info, tim_value):
|
||||
style = 'align="center";'
|
||||
row = f'<tr><td align="left">{timing_info}</td>' \
|
||||
f'<td {style}>{"+" if tim_value & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 1) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 2) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 3) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 4) & 0x1 else "-"}</td>' \
|
||||
f'<td {style}>{"+" if (tim_value >> 5) & 0x1 else "-"}</td>'
|
||||
row += f'<td {style}>{colorimetry_map.get((tim_value >> 12) & 0xF)}</td>' \
|
||||
f'<td {style}>{colorimetry_map.get((tim_value >> 16) & 0xF)}</td>' \
|
||||
f'<td {style}>{colorimetry_map.get((tim_value >> 20) & 0xF)}</td>' \
|
||||
f'<td {style}>{colorimetry_map.get((tim_value >> 24) & 0xF)}</td>' \
|
||||
f'<td {style}>{colorimetry_map.get((tim_value >> 28) & 0xF)}</td>'
|
||||
return row
|
||||
|
||||
configuration += '<br><table border="1">' + add_column_title(False)
|
||||
|
||||
deprecated_video_modes = [ "TSI_DP20_SRCCTS_VMT_1920_1080_144", "TSI_DP20_SRCCTS_VMT_1920_1080_240",
|
||||
"TSI_DP20_SRCCTS_VMT_3840_2160_30", "TSI_DP20_SRCCTS_VMT_3840_2160_240",
|
||||
"TSI_DP20_SRCCTS_VMT_5120_2160_120", "TSI_DP20_SRCCTS_VMT_5120_2160_240",
|
||||
"TSI_DP20_SRCCTS_VMT_7680_4320_120", "TSI_DP20_SRCCTS_VMT_10240_4320_30",
|
||||
"TSI_DP20_SRCCTS_VMT_10240_4320_60"]
|
||||
|
||||
for key in _data.keys():
|
||||
if key in deprecated_video_modes:
|
||||
continue
|
||||
if key.find("TSI_DP20_SRCCTS_VMT_") != -1:
|
||||
value = _data.get(key)
|
||||
_, h_active, w_active, rate = re.findall(r'\d+', key)
|
||||
configuration += add_video_row(f"{h_active}x{w_active} @ {rate}Hz", value)
|
||||
configuration += "</table><br>"
|
||||
|
||||
configuration += '<br><table border="1">' + add_column_title(True)
|
||||
|
||||
for key in _data.keys():
|
||||
if key.find("TSI_DP20_SRCCTS_DSC_VMT_") != -1:
|
||||
value = _data.get(key)
|
||||
_, h_active, w_active, rate = re.findall(r'\d+', key)
|
||||
configuration += add_dsc_row(f"{h_active}x{w_active} @ {rate}Hz", value)
|
||||
configuration += "</table><br>"
|
||||
|
||||
|
||||
elif type_of_test == TestReportConfigType.Dp1_4_Sink:
|
||||
configuration = "Test timeout = {}ms<br>".format(_data.get("TSI_DP14_SINKCTS_TIMEOUT"))
|
||||
if not int(_data.get("TSI_DP14_SINKCTS_DSC_SOURCE")[0]):
|
||||
configuration += "<br>DSC resolutions to be tested:<br>"
|
||||
dsc_timings = ["1920x1080 @ 30Hz", "1920x1080 @ 60Hz", "1920x1080 @ 120Hz", "3840x2160 @ 30Hz",
|
||||
"3840x2160 @ 60Hz", "3840x2160 @ 120Hz", "5120x2160 @ 30Hz", "5120x2160 @ 60Hz",
|
||||
"5120x2160 @ 120Hz", "7680x4320 @ 30Hz", "7680x4320 @ 60Hz", "7680x4320 @ 100Hz"]
|
||||
|
||||
for item in enumerate(dsc_timings):
|
||||
timing_flags = int(str(_data.get(f"TSI_DP14_SINKCTS_DSC_VM_T_{item[0]}")), 16)
|
||||
if timing_flags:
|
||||
configuration += "- {}{}{}{}<br>".format(item[1], " CTA" if timing_flags & 0x1 else "",
|
||||
" RB1" if timing_flags & 0x2 else "",
|
||||
" RB2" if timing_flags & 0x4 else "")
|
||||
else:
|
||||
configuration += "<br>DSC resolutions to be tested are defined by DUT EDID<br>"
|
||||
|
||||
configuration += "<br>Sink DUT supports DSC Simple 422 CRC for {}<br>". \
|
||||
format(value_from_enumeration_var(_data.get("TSI_DP14_SINKCTS_SUPPORT_444CRC")[1],
|
||||
_data.get("TSI_DP14_SINKCTS_SUPPORT_444CRC")[0]))
|
||||
|
||||
if int(_data.get("TSI_DP14_SINKCTS_VISUAL_TEST_CHECK")[0]):
|
||||
configuration += "Never skip Display ID test's visual video checks<br>"
|
||||
else:
|
||||
configuration += "Skip Display ID test's visual video checks if CRC available and matching<br>"
|
||||
|
||||
if not int(_data.get("TSI_DP14_SINKCTS_PACKET_SOURCE")[0]):
|
||||
configuration += "<br>Most packed resolutions to be tested:<br>"
|
||||
video_timings = ["CVT 1280 x 800 @ 60p [RB1] 18bpp 99", "DMT 1280 x 768 @ 60p [RB1] 18bpp 95",
|
||||
"DMT 800 x 600 @ 60.317p 30bpp 93", "DMT 1024 x 768 @ 60p 18bpp 90",
|
||||
"DMT 1280 x 1024 @ 60p 24bpp 100", "DMT 1280 x 960 @ 60p 24bpp 100",
|
||||
"DMT 1360 x 768 @ 60p 30bpp 99", "CVT 1280 x 800 @ 60p 30bpp 97",
|
||||
"DMT 1400 x 1050 @ 60p [RB1] 24bpp 94", "DMT 1280 x 768 @ 60p 30bpp 92",
|
||||
"CVT 1600 x 1200 @ 60p [RB1] 18bpp 90", "CVT 2048 x 1536 @ 60p [RB1] 24bpp 97",
|
||||
"DMT 1792 x 1344 @ 60p 24bpp 95", "DMT 1600 x 1200 @ 60p 30bpp 94",
|
||||
"CTA 1440 x 480 @ 59.94p 24bpp 100", "CTA 1440 x 576 @ 50p 24bpp 100",
|
||||
"CTA 1920 x 1080 @ 60p 30bpp 86"]
|
||||
|
||||
for item in video_timings:
|
||||
configuration += "- {}<br>".format(item)
|
||||
else:
|
||||
configuration += "<br>Most packed resolutions to be tested are defined by DUT EDID<br>"
|
||||
elif type_of_test == TestReportConfigType.Dp2_1_Sink:
|
||||
configuration = ""
|
||||
|
||||
val = _data.get("TSI_DP20_SINKCTS_DEBUG_CONF")
|
||||
if val is not None and val[0] != 0:
|
||||
configuration += "<span class=DBG_HIGHLIGHT><br>Debug options:<br>"
|
||||
for _bit in val[1]:
|
||||
if val[0] & _bit.mask:
|
||||
configuration += f" - {_bit.description}<br>"
|
||||
configuration += "<br>"
|
||||
|
||||
configuration += "Test timeout = {}ms<br>".format(_data.get("TSI_DP20_SINKCTS_TIMEOUT"))
|
||||
if not int(_data.get("TSI_DP20_SINKCTS_DSC_SOURCE")[0]):
|
||||
configuration += "<br>DSC resolutions to be tested:<br>"
|
||||
video_modes_list = [[1920, 1080, 30], [1920, 1080, 60], [1920, 1080, 120], [1920, 1080, 144],
|
||||
[1920, 1080, 240],
|
||||
[3840, 2160, 30], [3840, 2160, 60], [3840, 2160, 120], [3840, 2160, 144],
|
||||
[3840, 2160, 240],
|
||||
[5120, 2160, 30], [5120, 2160, 60], [5120, 2160, 120], [5120, 2160, 144],
|
||||
[5120, 2160, 240],
|
||||
[7680, 4320, 30], [7680, 4320, 60], [7680, 4320, 120], [7680, 4320, 144],
|
||||
[7680, 4320, 240],
|
||||
[10240, 4320, 30], [10240, 4320, 60], [10240, 4320, 120], [10240, 4320, 144],
|
||||
[10240, 4320, 240],
|
||||
[15360, 8640, 30], [15360, 8640, 60], [15360, 8640, 120], [15360, 8640, 144],
|
||||
[15360, 8640, 240]]
|
||||
for vm in video_modes_list:
|
||||
timing_flag = _data.get(f"TSI_DP20_SINKCTS_VMT_{vm[0]}_{vm[1]}")
|
||||
bit_n = 0
|
||||
if vm[2] == 60:
|
||||
bit_n = 4
|
||||
elif vm[2] == 120:
|
||||
bit_n = 8
|
||||
elif vm[2] == 144:
|
||||
bit_n = 13
|
||||
elif vm[2] == 240:
|
||||
bit_n = 17
|
||||
|
||||
if vm[2] in [144, 240]:
|
||||
rb1_value = (timing_flag >> bit_n) & 0x1
|
||||
rb2_value = (timing_flag >> (bit_n + 1)) & 0x1
|
||||
ovt_value = (timing_flag >> (bit_n + 2)) & 0x1
|
||||
if rb1_value or rb2_value or ovt_value:
|
||||
configuration += f"- {vm[0]}x{vm[1]} @ {vm[2]}Hz" \
|
||||
f"{' RB1' if rb1_value else ''}" \
|
||||
f"{' RB2' if rb2_value else ''}" \
|
||||
f"{' OVT' if ovt_value else ''}<br>"
|
||||
else:
|
||||
cta_value = (timing_flag >> bit_n) & 0x1
|
||||
rb1_value = (timing_flag >> (bit_n + 1)) & 0x1
|
||||
rb2_value = (timing_flag >> (bit_n + 2)) & 0x1
|
||||
if rb1_value or rb2_value or cta_value:
|
||||
configuration += f"- {vm[0]}x{vm[1]} @ {vm[2]}Hz" \
|
||||
f"{' CTA' if cta_value else ''}" \
|
||||
f"{' RB1' if rb1_value else ''}" \
|
||||
f"{' RB2' if rb2_value else ''}<br>"
|
||||
else:
|
||||
configuration += "<br>DSC resolutions to be tested are defined by DUT EDID<br>"
|
||||
|
||||
if _data.get("TSI_DP20_SINKCTS_SUPPORT_444CRC")[0] == 0:
|
||||
configuration += "<br>Sink DUT supports YCbCR 422 CRC for Simple 422 bitstream<br>"
|
||||
elif _data.get("TSI_DP20_SINKCTS_SUPPORT_444CRC")[0] == 1:
|
||||
configuration += "<br>Sink DUT supports YCbCR 444 CRC for Simple 422 bitstream<br>"
|
||||
else:
|
||||
configuration += "<br><br>"
|
||||
|
||||
if int(_data.get("TSI_DP20_SINKCTS_VISUAL_TEST_CHECK")[0]):
|
||||
configuration += "<br>Skip Display ID test's visual video checks if CRC available and matching<br>"
|
||||
else:
|
||||
configuration += "<br>Never skip Display ID test's visual video checks<br>"
|
||||
|
||||
return configuration
|
||||
|
||||
|
||||
def dp21_source_timing_table(data) -> str:
|
||||
_data = copy_data(data)
|
||||
colorimetry_map = {0: '-', 1: 8, 3: 10, 7: 12, 15: 16}
|
||||
info = f"Timing {'Timing vendors':>35} {'Colorimetry':>40}\n"
|
||||
info += f"{'CTA DMT CVT CVT-RB1 CVT-RB2 OVT':>50}"
|
||||
info += f"{'RGB YCbCr444 YCbCr422 YCbCr422Simple YCbCr420':>50}\n"
|
||||
|
||||
def shift(str_length) -> int:
|
||||
if str_length == 14:
|
||||
return 7
|
||||
elif str_length == 15:
|
||||
return 6
|
||||
elif str_length == 16:
|
||||
return 5
|
||||
elif str_length == 17:
|
||||
return 4
|
||||
|
||||
def support(flag) -> str:
|
||||
return "+" if flag else "-"
|
||||
|
||||
def add_row(timing_info, tim_value):
|
||||
row = f'{timing_info}' \
|
||||
f'{support(tim_value & 0x1):>{shift(len(timing_info))}}' \
|
||||
f'{support((tim_value >> 1) & 0x1):>4}' \
|
||||
f'{support((tim_value >> 2) & 0x1):>4}' \
|
||||
f'{support((tim_value >> 3) & 0x1):>6}' \
|
||||
f'{support((tim_value >> 4) & 0x1):>8}' \
|
||||
f'{support((tim_value >> 5) & 0x1):>6}'
|
||||
row += f'{colorimetry_map.get((tim_value >> 12) & 0xF):>8}' \
|
||||
f'{colorimetry_map.get((tim_value >> 16) & 0xF):>7}' \
|
||||
f'{colorimetry_map.get((tim_value >> 20) & 0xF):>9}' \
|
||||
f'{colorimetry_map.get((tim_value >> 24) & 0xF):>12}' \
|
||||
f'{colorimetry_map.get((tim_value >> 28) & 0xF):>12}\n'
|
||||
return row
|
||||
|
||||
for key in _data.keys():
|
||||
if key.find("TSI_DP20_SRCCTS_VMT_") != -1:
|
||||
value = _data.get(key)
|
||||
_, h_active, w_active, rate = re.findall(r'\d+', key)
|
||||
info += add_row(f"{h_active}x{w_active} @ {rate}Hz", value)
|
||||
|
||||
return info
|
||||
Reference in New Issue
Block a user