更新UCD-API库及文档

This commit is contained in:
xinzhu.yin
2026-07-02 17:16:18 +08:00
parent a500751d85
commit 9fa811a9eb
290 changed files with 9558 additions and 2306 deletions

View File

@@ -2,6 +2,7 @@ from .dptx5xx import DPTX, DPTX4xx, DPTX5xx
from .dprx5xx import DPRX, DPRX4xx, DPRX5xx
from .hdrx4xx import HDRX, HDRX4xx
from .hdtx4xx import HDTX, HDTX4xx
from .hdrx_earc import HDRX_eARC
from .pdc_port import PDC340, PDC424, PDC500
from .modules import *
import UniTAP.dev.ports.modules.capturer.bulk as bulk

View File

@@ -5,9 +5,7 @@ from .modules.edid.edid import EdidSink
from .modules.hdcp import HdcpSink
from .modules.capturer.event.event_capturer import EventCapturer, EventFilterDpRx, EventFilterUsbc
from .modules.link.dp.private_link_rx_types import DPRXHWCaps
from UniTAP.libs.lib_tsi.tsi_types import TSI_DPRX_HDCP_CAPS_R, TSI_DPRX_HDCP_STATUS_R
from UniTAP.libs.lib_tsi.tsi_types import TSI_DPRX_DPCD_BASE_W, TSI_DPRX_DPCD_DATA
from UniTAP.libs.lib_tsi.tsi_types import TSI_PDC_LOG_CONTROL, TSI_DPRX_HW_CAPS_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.libs.lib_tsi.tsi_io import PortProtocol
@@ -34,11 +32,11 @@ class DPRX(RX):
def __init__(self, port_io: PortIO, memory_manager: MemoryManager, capturer: Capturer):
super().__init__(port_io, memory_manager, capturer)
hw_caps = port_io.get(TSI_DPRX_HW_CAPS_R, DPRXHWCaps)[1]
self.__dpcd = DPCDRegisters(port_io, TSI_DPRX_DPCD_BASE_W, TSI_DPRX_DPCD_DATA)
hw_caps = port_io.get(ci.TSI_DPRX_HW_CAPS_R, DPRXHWCaps)[1]
self.__dpcd = DPCDRegisters(port_io, ci.TSI_DPRX_DPCD_BASE_W, ci.TSI_DPRX_DPCD_DATA)
self.__link = LinkDisplayPortRx(port_io, hw_caps, self.__dpcd)
self.__edid = EdidSink(port_io, self.__link.status.mst_stream_count)
self.__hdcp = HdcpSink(port_io, TSI_DPRX_HDCP_CAPS_R, TSI_DPRX_HDCP_STATUS_R)
self.__hdcp = HdcpSink(port_io, ci.TSI_DPRX_HDCP_CAPS_R, ci.TSI_DPRX_HDCP_STATUS_R)
self.__video_capturer = VideoCapturerDP(capturer, hw_caps.mst_stream_count)
event_filters = []

View File

@@ -4,6 +4,7 @@ from .modules.capturer.bulk.bulk_capturer import BulkCapturer
from .modules.edid.edid import DisplayIdSink
from .modules.panel_replay import SinkPanelReplay, SinkPanelSelfRefresh
from typing import Optional
import UniTAP.libs.lib_tsi.tsi_types as ci
class DPRX4xx(DPRX):
@@ -26,7 +27,7 @@ class DPRX4xx(DPRX):
def __init__(self, port_io: PortIO, memory_manager: MemoryManager, capturer: Capturer):
super().__init__(port_io, memory_manager, capturer)
hw_caps = port_io.get(TSI_DPRX_HW_CAPS_R, DPRXHWCaps)[1]
hw_caps = port_io.get(ci.TSI_DPRX_HW_CAPS_R, DPRXHWCaps)[1]
self.__fec = FecRx(port_io, self.dpcd)
self.__bulk_capturer = BulkCapturer(capturer, memory_manager)
self.__display_id = DisplayIdSink(port_io, hw_caps.mst_stream_count)

View File

@@ -5,9 +5,7 @@ from .modules.vtg.pg import DpPatternGenerator
from .modules.hdcp import HdcpSource
from .modules.capturer.event.event_capturer import EventCapturer, EventFilterDpTx, EventFilterUsbc
from .modules.link.dp.private_link_tx_types import DPTXHWCaps
from UniTAP.libs.lib_tsi.tsi_types import TSI_DPTX_DPCD_BASE_W, TSI_DPTX_DPCD_DATA
from UniTAP.libs.lib_tsi.tsi_types import TSI_DPTX_HDCP_CAPS_R, TSI_DPTX_HDCP_STATUS_R
from UniTAP.libs.lib_tsi.tsi_types import TSI_DPTX_HW_CAPS_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.libs.lib_tsi.tsi_io import PortProtocol
@@ -34,12 +32,12 @@ class DPTX(TX):
def __init__(self, port_io: PortIO, memory_manager: MemoryManager, capturer: Capturer):
super().__init__(port_io, memory_manager, capturer)
hw_caps = port_io.get(TSI_DPTX_HW_CAPS_R, DPTXHWCaps)[1]
self.__dpcd = DPCDRegisters(port_io, TSI_DPTX_DPCD_BASE_W, TSI_DPTX_DPCD_DATA)
hw_caps = port_io.get(ci.TSI_DPTX_HW_CAPS_R, DPTXHWCaps)[1]
self.__dpcd = DPCDRegisters(port_io, ci.TSI_DPTX_DPCD_BASE_W, ci.TSI_DPTX_DPCD_DATA)
self.__link = LinkDisplayPortTx(port_io, self.__dpcd, hw_caps)
self.__pg = DpPatternGenerator(port_io, memory_manager, 0)
self.__edid = EdidSource(port_io, self.__link.max_stream_count)
self.__hdcp = HdcpSource(port_io, TSI_DPTX_HDCP_CAPS_R, TSI_DPTX_HDCP_STATUS_R)
self.__hdcp = HdcpSource(port_io, ci.TSI_DPTX_HDCP_CAPS_R, ci.TSI_DPTX_HDCP_STATUS_R)
# event_filters = [e(hw_caps) for e in self.__CHECK_EVENT_FILTER.get(port_io.protocol())]
event_filters = []

View File

@@ -2,6 +2,8 @@ from .dptx import *
from .modules.fec import FecTx, FECCounters, FECErrorType8b10b
from .modules.vtg.pg import DpMstPatternGenerator
from .modules.edid.edid import DisplayIdSource
import UniTAP.libs.lib_tsi.tsi_types as ci
class DPTX4xx(DPTX):
@@ -21,7 +23,7 @@ class DPTX4xx(DPTX):
def __init__(self, port_io: PortIO, memory_manager: MemoryManager, capturer: Capturer):
super().__init__(port_io, memory_manager, capturer)
hw_caps = port_io.get(TSI_DPTX_HW_CAPS_R, DPTXHWCaps)[1]
hw_caps = port_io.get(ci.TSI_DPTX_HW_CAPS_R, DPTXHWCaps)[1]
self.__fec = FecTx(port_io, self.dpcd)
self.__pg = DpMstPatternGenerator(port_io, memory_manager, hw_caps.mst_stream_count)
self.__display_id = DisplayIdSource(port_io, hw_caps.mst_stream_count)

View File

@@ -4,8 +4,7 @@ from .modules.link.hdmi.link import HdmiLinkRx
from .modules.hdcp import HdcpSink
from .modules.cec.cec_rx import CecRx
from .modules.capturer.event.event_capturer import EventCapturer, EventFilterHdRx
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDRX_HDCP_CAPS_R, TSI_HDRX_HDCP_STATUS_R
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDRX_LOG_CONTROL
import UniTAP.libs.lib_tsi.tsi_types as ci
class HDRX(RX):
@@ -30,7 +29,7 @@ class HDRX(RX):
self.__link = HdmiLinkRx(port_io)
self.__edid = EdidSink(port_io, 1)
self.__hdcp = HdcpSink(port_io, TSI_HDRX_HDCP_CAPS_R, TSI_HDRX_HDCP_STATUS_R)
self.__hdcp = HdcpSink(port_io, ci.TSI_HDRX_HDCP_CAPS_R, ci.TSI_HDRX_HDCP_STATUS_R)
self.__event_capturer = EventCapturer(capturer, port_io.index(), [EventFilterHdRx(0)])
self.__video_capturer = VideoCapturerHDMI(capturer, 1)
self.__cec = CecRx(port_io)

View File

@@ -0,0 +1,30 @@
from UniTAP.dev.ports.modules.earc.earc_tx import EarcTx
from .hdrx import HDRX, PortIO, MemoryManager, Capturer
class HDRX_eARC(HDRX):
"""
Main class of `HDRX` object.
Inherited from class `RX`.
Class describes capabilities of 300th (3XX) series of HDMI devices in Sink (RX - receiver) role with eARC support.
Attributes:
__earc (EarcTx): object of `EarcTx`.
"""
def __init__(self, port_io: PortIO, memory_manager: MemoryManager, capturer: Capturer):
super().__init__(port_io, memory_manager, capturer)
self.__earc = EarcTx(port_io, memory_manager)
@property
def earc(self) -> EarcTx:
"""
Should be used to control link capabilities on Sink (RX - receiver) role.
Returns:
object of `EarcTx` type.
"""
return self.__earc

View File

@@ -5,8 +5,8 @@ from .modules.vtg.pg import HdmiPatternGenerator
from .modules.hdcp import HdcpSource
from .modules.capturer.event.event_capturer import EventCapturer, EventFilterHdTx
from .modules.cec.cec_tx import CecTx
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDTX_HDCP_CAPS_R, TSI_HDTX_HDCP_STATUS_R
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDTX_LOG_CONTROL
import UniTAP.libs.lib_tsi.tsi_types as ci
class HDTX(TX):
@@ -32,7 +32,7 @@ class HDTX(TX):
self.__link = HdmiLinkTx(port_io)
self.__edid = EdidSource(port_io, 1)
self.__pg = HdmiPatternGenerator(port_io, memory_manager)
self.__hdcp = HdcpSource(port_io, TSI_HDTX_HDCP_CAPS_R, TSI_HDTX_HDCP_STATUS_R)
self.__hdcp = HdcpSource(port_io, ci.TSI_HDTX_HDCP_CAPS_R, ci.TSI_HDTX_HDCP_STATUS_R)
self.__event_capturer = EventCapturer(capturer, port_io.index(), [EventFilterHdTx(0)])
self.__cec = CecTx(port_io)

View File

@@ -7,5 +7,7 @@ from .hdcp import *
from .capturer import *
from .edid import *
from .panel_replay import *
from .earc import *
from .packet_generator import *
import UniTAP.dev.ports.modules.cec as cec
import UniTAP.dev.ports.modules.pdc as pdc

View File

@@ -1,4 +1,6 @@
from UniTAP.libs.lib_tsi.tsi_types import *
from ctypes import c_uint8, c_int, c_int32
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.utils import function_scheduler
from .ag_utils import *
from UniTAP.libs.lib_tsi.tsi_io import PortIO, PortProtocol
@@ -43,16 +45,16 @@ class AudioGenerator:
self.__memory_manager.make_default()
self.__memory_manager.set_memory_block_index(MemoryManager.MemoryOwner.MO_AudioGenerator)
self.__io.set(TSI_AUDGEN_SIGNAL_BLOCK, MemoryManager.MemoryOwner.MO_AudioGenerator.value)
self.__io.set(ci.TSI_AUDGEN_SIGNAL_BLOCK, MemoryManager.MemoryOwner.MO_AudioGenerator.value)
self.__memory_manager.memory_write(data, size)
self.__io.set(TSI_AUDGEN_AUDIO_SIZE, size)
self.__io.set(ci.TSI_AUDGEN_AUDIO_SIZE, size)
ag_struct = self.__io.get(TSI_AUDGEN_CONFIG, AudioConfigStructure)[1]
ag_struct = self.__io.get(ci.TSI_AUDGEN_CONFIG, AudioConfigStructure)[1]
ag_struct.non_lpcm = 0
ag_struct.loop = 1
audio_sts = create_audio_sts(audio_mode=audio_mode)
self.__io.set(TSI_AUDGEN_CHANNELS_STS, audio_sts, data_type=c_uint8, data_count=len(audio_sts))
self.__io.set(ci.TSI_AUDGEN_CHANNELS_STS, audio_sts, data_type=c_uint8, data_count=len(audio_sts))
if self.__io.protocol() == PortProtocol.HDMI:
tp = 0
@@ -63,16 +65,16 @@ class AudioGenerator:
ag_struct.n_selector = 1
ag_struct.cts_selector = 1
self.__io.set(TSI_AUDGEN_CONFIG, ag_struct.value())
self.__io.set(ci.TSI_AUDGEN_CONFIG, ag_struct.value())
self.__io.set(TSI_AUDGEN_PACKET_TYPE, tp)
self.__io.set(ci.TSI_AUDGEN_PACKET_TYPE, tp)
else:
self.__io.set(TSI_AUDGEN_CONFIG, ag_struct.value())
self.__io.set(ci.TSI_AUDGEN_CONFIG, ag_struct.value())
self.__io.set(TSI_AUDGEN_SIGNAL_TYPE, AudioPattern.CustomAudio.value)
self.__io.set(TSI_AUDGEN_CHANNEL_COUNT, audio_mode.channel_count)
self.__io.set(TSI_AUDGEN_SAMPLE_RATE, audio_mode.sample_rate)
self.__io.set(TSI_AUDGEN_SAMPLE_SIZE, audio_mode.bits)
self.__io.set(ci.TSI_AUDGEN_SIGNAL_TYPE, AudioPattern.CustomAudio.value)
self.__io.set(ci.TSI_AUDGEN_CHANNEL_COUNT, audio_mode.channel_count)
self.__io.set(ci.TSI_AUDGEN_SAMPLE_RATE, audio_mode.sample_rate)
self.__io.set(ci.TSI_AUDGEN_SAMPLE_SIZE, audio_mode.bits)
elif isinstance(audio_pattern, AudioPattern):
list_sample_rate = [22050, 44100, 88200, 176400, 24000, 48000, 96000, 192000, 32000, 768000]
list_bits = [16, 20, 24]
@@ -93,16 +95,16 @@ class AudioGenerator:
if amplitude not in [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]:
raise ValueError(f"'Amplitude' must be more than 0")
memory_block_no = 2
memory_block_no = 1
self.__memory_manager.make_default()
self.__io.set(TSI_AUDGEN_SIGNAL_BLOCK, memory_block_no)
self.__io.set(TSI_AUDGEN_SIGNAL_TYPE, audio_pattern.value)
self.__io.set(TSI_AUDGEN_CHANNEL_COUNT, audio_mode.channel_count)
self.__io.set(TSI_AUDGEN_SAMPLE_RATE, audio_mode.sample_rate)
self.__io.set(TSI_AUDGEN_SAMPLE_SIZE, audio_mode.bits)
self.__io.set(TSI_AUDGEN_SIGNAL_FREQ, signal_frequency)
self.__io.set(TSI_AUDGEN_SIGNAL_VOLUME, amplitude)
self.__io.set(ci.TSI_AUDGEN_SIGNAL_BLOCK, memory_block_no)
self.__io.set(ci.TSI_AUDGEN_SIGNAL_TYPE, audio_pattern.value)
self.__io.set(ci.TSI_AUDGEN_CHANNEL_COUNT, audio_mode.channel_count)
self.__io.set(ci.TSI_AUDGEN_SAMPLE_RATE, audio_mode.sample_rate)
self.__io.set(ci.TSI_AUDGEN_SAMPLE_SIZE, audio_mode.bits)
self.__io.set(ci.TSI_AUDGEN_SIGNAL_FREQ, signal_frequency)
self.__io.set(ci.TSI_AUDGEN_SIGNAL_VOLUME, amplitude)
else:
available_variants = '\n'.join([e.name for e in AudioPattern])
raise ValueError(f"Incorrect value of audio pattern - {audio_pattern}\n"
@@ -115,7 +117,7 @@ class AudioGenerator:
Returns:
object of `bool` type - generation was enabled successfully or not.
"""
self.__io.set(TSI_W_AUDGEN_CONTROL, 1)
self.__io.set(ci.TSI_W_AUDGEN_CONTROL, 1)
def is_apply_ag_success(ag: AudioGenerator):
return ag.status == AGStatus.Running
@@ -129,7 +131,7 @@ class AudioGenerator:
Returns:
object of `bool` type - generation was disabled successfully or not.
"""
return True if self.__io.set(TSI_W_AUDGEN_CONTROL, 0) >= TSI_SUCCESS else False
return True if self.__io.set(ci.TSI_W_AUDGEN_CONTROL, 0) >= ci.TSI_SUCCESS else False
@property
def status(self) -> AGStatus:
@@ -139,7 +141,7 @@ class AudioGenerator:
Returns:
object of `AGStatus` type
"""
self.__status = AGStatus(self.__io.get(TSI_AUDGEN_STATUS_R, c_int)[1] & 0x1)
self.__status = AGStatus(self.__io.get(ci.TSI_AUDGEN_STATUS_R, c_int)[1] & 0x1)
return self.__status
@property
@@ -150,7 +152,7 @@ class AudioGenerator:
Returns:
object of `AudioMode` type
"""
self.__audio_mode.sample_rate = self.__io.get(TSI_AUDGEN_SAMPLE_RATE, c_int32)[1]
self.__audio_mode.bits = self.__io.get(TSI_AUDGEN_SAMPLE_SIZE, c_int32)[1]
self.__audio_mode.channel_count = self.__io.get(TSI_AUDGEN_CHANNEL_COUNT, c_int32)[1]
self.__audio_mode.sample_rate = self.__io.get(ci.TSI_AUDGEN_SAMPLE_RATE, c_int32)[1]
self.__audio_mode.bits = self.__io.get(ci.TSI_AUDGEN_SAMPLE_SIZE, c_int32)[1]
self.__audio_mode.channel_count = self.__io.get(ci.TSI_AUDGEN_CHANNEL_COUNT, c_int32)[1]
return self.__audio_mode

View File

@@ -1,10 +1,12 @@
import os.path
import warnings
import wave
import pickle
from collections import deque
from ctypes import c_uint32
from _ctypes import sizeof
from UniTAP.common.audio_mode import AudioMode, AudioFileFormat
from UniTAP.libs.lib_tsi.tsi import sizeof, c_uint32
def save_to_wave_file(path: str, audio_mode: AudioMode, data: bytearray):

View File

@@ -0,0 +1,158 @@
from ctypes import c_uint8, c_int, c_int32
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.utils import function_scheduler
from .ag_utils import *
from UniTAP.libs.lib_tsi.tsi_io import PortIO, PortProtocol
from UniTAP.dev.modules import MemoryManager
from .types import *
from .private_types import *
from typing import Union
class AudioGeneratorEARC:
"""
Class `AudioGenerator` allows working with generating audio from Source (TX - transmitter). You can configure
audio generator `setup`, apply settings and start generate audio `apply`, stop generate audio `stop_generate`,
read audio generator `status` and get current `audio_mode`.
"""
def __init__(self, port_io: PortIO, memory_manager: MemoryManager):
self.__io = port_io
self.__memory_manager = memory_manager
self.__status = AGStatus.Unknown
self.__audio_mode = AudioMode()
def setup(self, audio_mode: AudioMode = AudioMode(),
audio_pattern: Union[AudioPattern, str] = AudioPattern.SignalSine,
signal_frequency: int = 1000, amplitude: int = 60):
"""
Configure audio generator. Possible two variants of configuration:
- From 'wav' or 'bin' file.
- From `AudioPattern` parameters.
Args:
audio_mode (AudioMode) - object of `AudioMode`
audio_pattern (Union[AudioPattern, str]) - object of `AudioPattern` or path to audio file ('bin' or 'wave')
signal_frequency (int)
amplitude (int)
"""
self.stop_generate()
if isinstance(audio_pattern, str) and check_file_format(audio_pattern) != AudioFileFormat.UNKNOWN:
if check_file_format(audio_pattern) == AudioFileFormat.BIN:
data, _, size = load_from_bin_file(path=audio_pattern)
else:
data, audio_mode, size = load_from_wave_file(path=audio_pattern)
self.__memory_manager.make_default()
self.__memory_manager.set_memory_block_index(MemoryManager.MemoryOwner.MO_AudioGenerator)
self.__io.set(ci.TSI_EARC_AUDGEN_SIGNAL_BLOCK, MemoryManager.MemoryOwner.MO_AudioGenerator.value)
self.__memory_manager.memory_write(data, size)
self.__io.set(ci.TSI_EARC_AUDGEN_AUDIO_SIZE, size)
ag_struct = self.__io.get(ci.TSI_EARC_AUDGEN_CONFIG, AudioConfigStructure)[1]
ag_struct.non_lpcm = 0
ag_struct.loop = 1
audio_sts = create_audio_sts(audio_mode=audio_mode)
self.__io.set(ci.TSI_EARC_AUDGEN_CHANNELS_STS, audio_sts, data_type=c_uint8, data_count=len(audio_sts))
if self.__io.protocol() == PortProtocol.HDMI:
tp = 0
if audio_mode.channel_count == 8 and audio_mode.sample_rate >= 64000:
tp = 3
ag_struct.n_selector = 1
ag_struct.cts_selector = 1
self.__io.set(ci.TSI_EARC_AUDGEN_CONFIG, ag_struct.value())
self.__io.set(ci.TSI_EARC_AUDGEN_PACKET_TYPE, tp)
else:
self.__io.set(ci.TSI_EARC_AUDGEN_CONFIG, ag_struct.value())
self.__io.set(ci.TSI_EARC_AUDGEN_SIGNAL_TYPE, AudioPattern.CustomAudio.value)
self.__io.set(ci.TSI_EARC_AUDGEN_CHANNEL_COUNT, audio_mode.channel_count)
self.__io.set(ci.TSI_EARC_AUDGEN_SAMPLE_RATE, audio_mode.sample_rate)
self.__io.set(ci.TSI_EARC_AUDGEN_SAMPLE_SIZE, audio_mode.bits)
elif isinstance(audio_pattern, AudioPattern):
list_sample_rate = [22050, 44100, 88200, 176400, 24000, 48000, 96000, 192000, 32000, 768000]
list_bits = [16, 20, 24]
audio_pattern = AudioPattern(audio_pattern.value)
if not (1 <= audio_mode.channel_count <= 8):
raise ValueError(f"'Channel count' must be in range: 1 - 8")
if audio_mode.sample_rate not in list_sample_rate:
raise ValueError(f"'Sample rate' must be in list {list_sample_rate}")
if audio_mode.bits not in list_bits:
raise ValueError(f"'Bits' must be in list {list_bits}")
if signal_frequency <= 0:
raise ValueError(f"'Signal frequency' must be more than 0")
if amplitude not in [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]:
raise ValueError(f"'Amplitude' must be more than 0")
memory_block_no = 1
self.__memory_manager.make_default()
self.__io.set(ci.TSI_EARC_AUDGEN_SIGNAL_BLOCK, memory_block_no)
self.__io.set(ci.TSI_EARC_AUDGEN_SIGNAL_TYPE, audio_pattern.value)
self.__io.set(ci.TSI_EARC_AUDGEN_CHANNEL_COUNT, audio_mode.channel_count)
self.__io.set(ci.TSI_EARC_AUDGEN_SAMPLE_RATE, audio_mode.sample_rate)
self.__io.set(ci.TSI_EARC_AUDGEN_SAMPLE_SIZE, audio_mode.bits)
self.__io.set(ci.TSI_EARC_AUDGEN_SIGNAL_FREQ, signal_frequency)
self.__io.set(ci.TSI_EARC_AUDGEN_SIGNAL_VOLUME, amplitude)
else:
available_variants = '\n'.join([e.name for e in AudioPattern])
raise ValueError(f"Incorrect value of audio pattern - {audio_pattern}\n"
f"Available audio patterns: {available_variants}")
def apply(self) -> bool:
"""
Apply settings and start generate audio.
Returns:
object of `bool` type - generation was enabled successfully or not.
"""
self.__io.set(ci.TSI_EARC_AUDGEN_CONTROL_W, 1)
def is_apply_ag_success(ag: AudioGeneratorEARC) -> bool:
return ag.status == AGStatus.Running
return function_scheduler(is_apply_ag_success, self, interval=1, timeout=10)
def stop_generate(self) -> bool:
"""
Stop generate audio.
Returns:
object of `bool` type - generation was disabled successfully or not.
"""
return True if self.__io.set(ci.TSI_EARC_AUDGEN_CONTROL_W, 0) >= ci.TSI_SUCCESS else False
@property
def status(self) -> AGStatus:
"""
Return audio generator status.
Returns:
object of `AGStatus` type
"""
self.__status = AGStatus(self.__io.get(ci.TSI_EARC_AUDGEN_STATUS_R, c_int)[1] & 0x1)
return self.__status
@property
def audio_mode(self) -> AudioMode:
"""
Return current audio mode.
Returns:
object of `AudioMode` type
"""
self.__audio_mode.sample_rate = self.__io.get(ci.TSI_EARC_AUDGEN_SAMPLE_RATE, c_int32)[1]
self.__audio_mode.bits = self.__io.get(ci.TSI_EARC_AUDGEN_SAMPLE_SIZE, c_int32)[1]
self.__audio_mode.channel_count = self.__io.get(ci.TSI_EARC_AUDGEN_CHANNEL_COUNT, c_int32)[1]
return self.__audio_mode

View File

@@ -17,3 +17,12 @@ class AudioConfigStructure(Structure):
def value(self) -> int:
return self.auto_ch_sts | self.use_raw_data << 1 | self.non_lpcm << 2 | self.loop << 3 | \
self.auto_info_frame << 4 | self.n_selector << 8 | self.cts_selector << 12
class AudioSignalStruct(Structure):
_fields_ = [
('freq', c_uint32, 32),
('volume', c_uint32, 32),
('shift', c_uint32, 32),
('type', c_uint32, 32),
]

View File

@@ -10,7 +10,8 @@ class AudioPattern(IntEnum):
SignalSquare = 2
CustomAudio = 3
SignalIncremental = 4
Unknown = 5
SignalPing = 5
Unknown = 6
class AGStatus(IntEnum):

View File

@@ -4,7 +4,7 @@ import copy
from typing import Union, TypeVar, Type, List
from UniTAP.libs.lib_tsi.tsi import TSIX_TS_SetPortConfigItem
import UniTAP.libs.lib_tsi.tsi as tsi
from UniTAP.dev.modules.capturer.capture import Capturer, CaptureConfig
from UniTAP.dev.modules.capturer.statuses import EventCaptureStatus
from .result_event import ResultEventObject
@@ -98,11 +98,11 @@ class EventCapturer:
self.__event_filter[i] = event_filter
for item in event_filter.additional_filter:
TSIX_TS_SetPortConfigItem(self.__device.device_handle, self.__port_id, item.ci_control, item.value,
data_count=len(item.value) if isinstance(item.value, list) else 1)
tsi.TSIX_TS_SetPortConfigItem(self.__device.device_handle, self.__port_id, item.ci_control, item.value,
data_count=len(item.value) if isinstance(item.value, list) else 1)
TSIX_TS_SetPortConfigItem(self.__device.device_handle, self.__port_id, event_filter._control_ci,
event_filter.config)
tsi.TSIX_TS_SetPortConfigItem(self.__device.device_handle, self.__port_id, event_filter._control_ci,
event_filter.config)
def clear_capturer_config(self):
"""
@@ -110,7 +110,7 @@ class EventCapturer:
"""
for item in self.__event_filter:
item.clear()
TSIX_TS_SetPortConfigItem(self.__device.device_handle, self.__port_id, item._control_ci, 0)
tsi.TSIX_TS_SetPortConfigItem(self.__device.device_handle, self.__port_id, item._control_ci, 0)
def start(self, sec=0, n_elements=0):
"""

View File

@@ -1,7 +1,9 @@
from enum import IntEnum
from .event_utils import set_bit_in_vector, search_in_list
from .private_event_types import AdditionalSDPEventFilter, AdditionalLinkPatternEventFilter, \
AdditionalInfoFrameEventFilter, AdditionalVBIDEventFilter, AdditionalMSAEventFilter, AdditionalLSEEventFilter
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
import warnings
@@ -405,7 +407,7 @@ class EventFilterDpRx(EventFilter):
def __init__(self, hw_caps):
super().__init__(hw_caps)
self._control_ci = TSI_DPRX_LOG_CONTROL
self._control_ci = ci.TSI_DPRX_LOG_CONTROL
self.additional_filter = [AdditionalSDPEventFilter()]
if hw_caps.link_pat_log:
self.additional_filter.append(AdditionalLinkPatternEventFilter())
@@ -422,9 +424,9 @@ class EventFilterDpRx(EventFilter):
enable (bool) - enable/disable HDP events
"""
if enable:
self.config |= TSI_DPRX_LOG_CTRL_VALUE_HPD
self.config |= ci.TSI_DPRX_LOG_CTRL_VALUE_HPD
else:
self.config &= ~TSI_DPRX_LOG_CTRL_VALUE_HPD
self.config &= ~ci.TSI_DPRX_LOG_CTRL_VALUE_HPD
def config_aux_events(self, enable: bool):
"""
@@ -434,9 +436,9 @@ class EventFilterDpRx(EventFilter):
enable (bool) - enable/disable AUX events
"""
if enable:
self.config |= TSI_DPRX_LOG_CTRL_VALUE_AUX
self.config |= ci.TSI_DPRX_LOG_CTRL_VALUE_AUX
else:
self.config &= ~TSI_DPRX_LOG_CTRL_VALUE_AUX
self.config &= ~ci.TSI_DPRX_LOG_CTRL_VALUE_AUX
def config_sdp_events(self, enable: bool, *args: EventSDP):
"""
@@ -447,9 +449,9 @@ class EventFilterDpRx(EventFilter):
*args (`EventSDP`) - SDP packet types
"""
if enable:
self.config |= TSI_DPRX_LOG_CTRL_VALUE_SDP
self.config |= ci.TSI_DPRX_LOG_CTRL_VALUE_SDP
else:
self.config &= ~TSI_DPRX_LOG_CTRL_VALUE_SDP
self.config &= ~ci.TSI_DPRX_LOG_CTRL_VALUE_SDP
if len(args) > 0:
for item in args:
@@ -466,9 +468,9 @@ class EventFilterDpRx(EventFilter):
"""
if self._hw_caps is not None and self._hw_caps.link_pat_log:
if enable:
self.config |= TSI_DPRX_LOG_CTRL_VALUE_LINK_PAT
self.config |= ci.TSI_DPRX_LOG_CTRL_VALUE_LINK_PAT
else:
self.config &= ~TSI_DPRX_LOG_CTRL_VALUE_LINK_PAT
self.config &= ~ci.TSI_DPRX_LOG_CTRL_VALUE_LINK_PAT
if len(args) > 0:
for item in args:
@@ -490,9 +492,9 @@ class EventFilterDpRx(EventFilter):
"""
if self._hw_caps is not None and self._hw_caps.vbid_hw_log:
if enable:
self.config |= TSI_DPRX_LOG_CTRL_VALUE_VBID_HW
self.config |= ci.TSI_DPRX_LOG_CTRL_VALUE_VBID_HW
else:
self.config &= ~TSI_DPRX_LOG_CTRL_VALUE_VBID_HW
self.config &= ~ci.TSI_DPRX_LOG_CTRL_VALUE_VBID_HW
if len(args) > 0:
for item in args:
@@ -516,9 +518,9 @@ class EventFilterDpRx(EventFilter):
"""
if self._hw_caps is not None and self._hw_caps.msa_hw_log:
if enable:
self.config |= TSI_DPRX_LOG_CTRL_VALUE_MSA_HW
self.config |= ci.TSI_DPRX_LOG_CTRL_VALUE_MSA_HW
else:
self.config &= ~TSI_DPRX_LOG_CTRL_VALUE_MSA_HW
self.config &= ~ci.TSI_DPRX_LOG_CTRL_VALUE_MSA_HW
if len(args) > 0:
for item in args:
@@ -541,9 +543,9 @@ class EventFilterDpRx(EventFilter):
"""
if self._hw_caps is not None and self._hw_caps.aux_bw_log:
if enable:
self.config |= TSI_DPRX_LOG_CTRL_VALUE_AUX_BW
self.config |= ci.TSI_DPRX_LOG_CTRL_VALUE_AUX_BW
else:
self.config &= ~TSI_DPRX_LOG_CTRL_VALUE_AUX_BW
self.config &= ~ci.TSI_DPRX_LOG_CTRL_VALUE_AUX_BW
else:
warnings.warn("HW does not support Aux Bw Logger")
@@ -556,7 +558,7 @@ class EventFilterDpTx(EventFilter):
def __init__(self, hw_caps):
super().__init__(hw_caps)
self._control_ci = TSI_DPTX_LOG_CONTROL
self._control_ci = ci.TSI_DPTX_LOG_CONTROL
def config_hpd_events(self, enable: bool):
"""
@@ -566,9 +568,9 @@ class EventFilterDpTx(EventFilter):
enable (bool) - enable/disable HDP events
"""
if enable:
self.config |= TSI_DPTX_LOG_CONTROL_VALUE_HPD
self.config |= ci.TSI_DPTX_LOG_CONTROL_VALUE_HPD
else:
self.config &= ~TSI_DPTX_LOG_CONTROL_VALUE_HPD
self.config &= ~ci.TSI_DPTX_LOG_CONTROL_VALUE_HPD
def config_aux_events(self, enable: bool):
"""
@@ -578,9 +580,9 @@ class EventFilterDpTx(EventFilter):
enable (bool) - enable/disable AUX events
"""
if enable:
self.config |= TSI_DPTX_LOG_CONTROL_VALUE_AUX
self.config |= ci.TSI_DPTX_LOG_CONTROL_VALUE_AUX
else:
self.config &= ~TSI_DPTX_LOG_CONTROL_VALUE_AUX
self.config &= ~ci.TSI_DPTX_LOG_CONTROL_VALUE_AUX
class EventFilterHdRx(EventFilter):
@@ -593,7 +595,7 @@ class EventFilterHdRx(EventFilter):
def __init__(self, hw_caps):
super().__init__(hw_caps)
self.additional_filter = [AdditionalInfoFrameEventFilter()]
self._control_ci = TSI_HDRX_LOG_CONTROL
self._control_ci = ci.TSI_HDRX_LOG_CONTROL
def config_hpd_events(self, enable: bool):
"""
@@ -603,9 +605,9 @@ class EventFilterHdRx(EventFilter):
enable (bool) - enable/disable HPD events
"""
if enable:
self.config |= TSI_HDRX_LOG_CTRL_VALUE_HPD
self.config |= ci.TSI_HDRX_LOG_CTRL_VALUE_HPD
else:
self.config &= ~TSI_HDRX_LOG_CTRL_VALUE_HPD
self.config &= ~ci.TSI_HDRX_LOG_CTRL_VALUE_HPD
def config_packets_events(self, enable: bool, *args: EventInfoFrame):
"""
@@ -616,9 +618,9 @@ class EventFilterHdRx(EventFilter):
*args (`EventInfoFrame`) - InfoFrame packet types
"""
if enable:
self.config |= TSI_HDRX_LOG_CTRL_VALUE_INFO
self.config |= ci.TSI_HDRX_LOG_CTRL_VALUE_INFO
else:
self.config &= ~TSI_HDRX_LOG_CTRL_VALUE_INFO
self.config &= ~ci.TSI_HDRX_LOG_CTRL_VALUE_INFO
if len(args) > 0:
for item in args:
@@ -633,9 +635,9 @@ class EventFilterHdRx(EventFilter):
enable (bool) - enable/disable I2C events
"""
if enable:
self.config |= TSI_HDRX_LOG_CTRL_VALUE_I2C
self.config |= ci.TSI_HDRX_LOG_CTRL_VALUE_I2C
else:
self.config &= ~TSI_HDRX_LOG_CTRL_VALUE_I2C
self.config &= ~ci.TSI_HDRX_LOG_CTRL_VALUE_I2C
def config_cec_events(self, enable: bool):
"""
@@ -645,9 +647,9 @@ class EventFilterHdRx(EventFilter):
enable (bool) - enable/disable CEC events
"""
if enable:
self.config |= TSI_HDRX_LOG_CTRL_VALUE_CEC
self.config |= ci.TSI_HDRX_LOG_CTRL_VALUE_CEC
else:
self.config &= ~TSI_HDRX_LOG_CTRL_VALUE_CEC
self.config &= ~ci.TSI_HDRX_LOG_CTRL_VALUE_CEC
class EventFilterHdTx(EventFilter):
@@ -659,7 +661,7 @@ class EventFilterHdTx(EventFilter):
def __init__(self, hw_caps):
super().__init__(hw_caps)
self._control_ci = TSI_HDTX_LOG_CONTROL
self._control_ci = ci.TSI_HDTX_LOG_CONTROL
def config_hpd_events(self, enable: bool):
"""
@@ -669,9 +671,9 @@ class EventFilterHdTx(EventFilter):
enable (bool) - enable/disable HPD events
"""
if enable:
self.config |= TSI_HDTX_LOG_CTRL_VALUE_HPD
self.config |= ci.TSI_HDTX_LOG_CTRL_VALUE_HPD
else:
self.config &= ~TSI_HDTX_LOG_CTRL_VALUE_HPD
self.config &= ~ci.TSI_HDTX_LOG_CTRL_VALUE_HPD
def config_i2c_events(self, enable: bool):
"""
@@ -681,9 +683,9 @@ class EventFilterHdTx(EventFilter):
enable (bool) - enable/disable I2C events
"""
if enable:
self.config |= TSI_HDTX_LOG_CTRL_VALUE_I2C
self.config |= ci.TSI_HDTX_LOG_CTRL_VALUE_I2C
else:
self.config &= ~TSI_HDTX_LOG_CTRL_VALUE_I2C
self.config &= ~ci.TSI_HDTX_LOG_CTRL_VALUE_I2C
def config_cec_events(self, enable: bool):
"""
@@ -693,9 +695,9 @@ class EventFilterHdTx(EventFilter):
enable (bool) - enable/disable CEC events
"""
if enable:
self.config |= TSI_HDTX_LOG_CTRL_VALUE_CEC
self.config |= ci.TSI_HDTX_LOG_CTRL_VALUE_CEC
else:
self.config &= ~TSI_HDTX_LOG_CTRL_VALUE_CEC
self.config &= ~ci.TSI_HDTX_LOG_CTRL_VALUE_CEC
class EventFilterUsbc(EventFilter):
@@ -707,7 +709,7 @@ class EventFilterUsbc(EventFilter):
def __init__(self, hw_caps):
super().__init__(hw_caps)
self._control_ci = TSI_PDC_LOG_CONTROL
self._control_ci = ci.TSI_PDC_LOG_CONTROL
if hw_caps is not None and hw_caps.voltage:
self.additional_filter.append(AdditionalLSEEventFilter())
@@ -719,9 +721,9 @@ class EventFilterUsbc(EventFilter):
enable (bool) - enable/disable PD events
"""
if enable:
self.config |= TSI_PDC_LOG_CTRL_VALUE_PD
self.config |= ci.TSI_PDC_LOG_CTRL_VALUE_PD
else:
self.config &= ~TSI_PDC_LOG_CTRL_VALUE_PD
self.config &= ~ci.TSI_PDC_LOG_CTRL_VALUE_PD
def config_voltage_events(self, enable: bool, value: EventLCE):
"""
@@ -733,9 +735,9 @@ class EventFilterUsbc(EventFilter):
"""
if self._hw_caps is not None and self._hw_caps.voltage:
if enable:
self.config |= TSI_PDC_LOG_CTRL_VALUE_USBC_VOLTAGE
self.config |= ci.TSI_PDC_LOG_CTRL_VALUE_USBC_VOLTAGE
else:
self.config &= ~TSI_PDC_LOG_CTRL_VALUE_USBC_VOLTAGE
self.config &= ~ci.TSI_PDC_LOG_CTRL_VALUE_USBC_VOLTAGE
for i in enumerate(value.values()):
self.additional_filter[search_in_list(AdditionalLSEEventFilter,
@@ -752,9 +754,9 @@ class EventFilterUsbc(EventFilter):
"""
if self._hw_caps is not None and self._hw_caps.events:
if enable:
self.config |= TSI_PDC_LOG_CTRL_VALUE_USBC_EVENT
self.config |= ci.TSI_PDC_LOG_CTRL_VALUE_USBC_EVENT
else:
self.config &= ~TSI_PDC_LOG_CTRL_VALUE_USBC_EVENT
self.config &= ~ci.TSI_PDC_LOG_CTRL_VALUE_USBC_EVENT
else:
warnings.warn("HW does not support 'USB-C' events")
@@ -767,8 +769,8 @@ class EventFilterUsbc(EventFilter):
"""
if self._hw_caps is not None and self._hw_caps.states:
if enable:
self.config |= TSI_PDC_LOG_CTRL_VALUE_USBC_STATE
self.config |= ci.TSI_PDC_LOG_CTRL_VALUE_USBC_STATE
else:
self.config &= ~TSI_PDC_LOG_CTRL_VALUE_USBC_STATE
self.config &= ~ci.TSI_PDC_LOG_CTRL_VALUE_USBC_STATE
else:
warnings.warn("HW does not support 'USB-C Port State' events")

View File

@@ -113,7 +113,7 @@ def save_to_bin_file(path: str, events: list, index=None):
def save_to_csv_file(path: str, events: list):
with (open(path, 'w', newline='') as file):
with open(path, 'w', newline='') as file:
writer = csv.writer(file, delimiter=';')
writer.writerow(["Source", "Type", "Start", "Brief info", "Full info"])
for data in events:

View File

@@ -1,5 +1,4 @@
from UniTAP.libs.lib_tsi.tsi_types import TSI_DPRX_LOG_IF_SEL, TSI_HDRX_LOG_IF_SEL, TSI_DPRX_LOG_CTRL_VALUE_LINK_PAT, \
TSI_DPRX_VBID_LOG_SEL, TSI_DPRX_MSA_LOG_SEL, TSI_PDC_USBC_LOG_THRESH
import UniTAP.libs.lib_tsi.tsi_types as ci
class AdditionalEventFilter:
@@ -31,7 +30,7 @@ class AdditionalSDPEventFilter(AdditionalEventFilter):
def __init__(self):
super().__init__()
self.ci_control = TSI_DPRX_LOG_IF_SEL
self.ci_control = ci.TSI_DPRX_LOG_IF_SEL
self.value = [0] * 8
@@ -39,7 +38,7 @@ class AdditionalInfoFrameEventFilter(AdditionalEventFilter):
def __init__(self):
super().__init__()
self.ci_control = TSI_HDRX_LOG_IF_SEL
self.ci_control = ci.TSI_HDRX_LOG_IF_SEL
self.value = [0] * 8
@@ -47,7 +46,7 @@ class AdditionalLinkPatternEventFilter(AdditionalEventFilter):
def __init__(self):
super().__init__()
self.ci_control = TSI_DPRX_LOG_CTRL_VALUE_LINK_PAT
self.ci_control = ci.TSI_DPRX_LOG_CTRL_VALUE_LINK_PAT
self.value = [0] * 3
@@ -55,7 +54,7 @@ class AdditionalVBIDEventFilter(AdditionalEventFilter):
def __init__(self):
super().__init__()
self.ci_control = TSI_DPRX_VBID_LOG_SEL
self.ci_control = ci.TSI_DPRX_VBID_LOG_SEL
self.value = 0
@@ -63,7 +62,7 @@ class AdditionalMSAEventFilter(AdditionalEventFilter):
def __init__(self):
super().__init__()
self.ci_control = TSI_DPRX_MSA_LOG_SEL
self.ci_control = ci.TSI_DPRX_MSA_LOG_SEL
self.value = 0
@@ -71,5 +70,5 @@ class AdditionalLSEEventFilter(AdditionalEventFilter):
def __init__(self):
super().__init__()
self.ci_control = TSI_PDC_USBC_LOG_THRESH
self.ci_control = ci.TSI_PDC_USBC_LOG_THRESH
self.value = [0] * 5

View File

@@ -1,7 +1,7 @@
import warnings
from UniTAP.dev.modules.capturer.result_object import ResultObject
from UniTAP.libs.lib_tsi.tsi import TSIEventParser
import UniTAP.libs.lib_tsi.tsi as tsi
from .event_utils import save_to_bin_file, save_to_csv_file, save_to_txt_file, save_to_html_file
from .event_types import EventFileFormat
@@ -96,7 +96,7 @@ class ResultEventObject(ResultObject):
warnings.warn("Buffer size is equal 0.")
def __parse_buffer(self):
with TSIEventParser() as parser:
with tsi.TSIEventParser() as parser:
for index, item in enumerate(self.buffer):
if len(item.data) > 12:
res = parser.parse(item.data, to_dict=True)

View File

@@ -52,6 +52,36 @@ class VideoCapturer:
"""
return self.__max_stream_number
def start(self, frames_count: int = 0, sec: int = 0, capture_type: CaptureConfig.Type = CaptureConfig.Type.LIVE):
"""
Start capturing. Possible some variants of capturing:
- Capture with fixed frames count (will be captured fixed frames count and capturing will be stopped).
- Capture with fixed time (capturing will be continued fixed seconds and capturing will be stopped).
- Capture without parameters - Live capturing (for getting frames you need to use functions `pop_element` and
`pop_all_elements`)
All results can be obtained using the function `capture_result`.
Args:
frames_count (int)
sec (int)
type (CaptureConfig.Type)
"""
config = CaptureConfig()
config.video = True
config.type = capture_type
self.__capturer.start_capture(config)
self.capture_result.clear()
self.capture_result.start_capture_time = time.time()
if frames_count > 0:
self.capture_result.buffer.extend(self.__capturer.capture_video_by_n_frames(frames_count, capture_type))
elif sec > 0:
self.capture_result.buffer.extend(self.__capturer.capture_video_by_n_sec(sec))
def stop(self):
"""
Stop capture video.
@@ -127,8 +157,8 @@ class VideoCapturerDP(VideoCapturer):
super().__init__(capturer, max_stream_number)
self.__capturer = capturer
def start(self, frames_count: int = 0, sec: int = 0, stream_number: int = 0,
capture_type: CaptureConfig.Type = CaptureConfig.Type.LIVE):
def start(self, frames_count: int = 0, sec: int = 0, capture_type: CaptureConfig.Type = CaptureConfig.Type.LIVE,
stream_number: int = 0):
"""
Start capturing. Possible some variants of capturing:
- Capture with fixed frames count (will be captured fixed frames count and capturing will be stopped).
@@ -150,21 +180,7 @@ class VideoCapturerDP(VideoCapturer):
f"{', '.join([str(i) for i in range(self.max_stream_number)])}")
self.__capturer.set_video_stream_number(stream_number)
config = CaptureConfig()
config.video = True
config.type = capture_type
self.__capturer.start_capture(config)
self.capture_result.clear()
self.capture_result.start_capture_time = time.time()
if frames_count > 0:
self.capture_result.buffer.extend(self.__capturer.capture_video_by_n_frames(frames_count, capture_type))
elif sec > 0:
self.capture_result.buffer.extend(self.__capturer.capture_video_by_n_sec(sec))
super().start(frames_count, sec, capture_type)
def get_buffer_capacity(self, stream_number: int = 0):
return self.__capturer.get_buffer_capacity(stream_number)
@@ -182,43 +198,5 @@ class VideoCapturerHDMI(VideoCapturer):
super().__init__(capturer, max_stream_number)
self.__capturer = capturer
def start(self, frames_count: int = 0, sec: int = 0, stream_number: int = 0):
"""
Start capturing. Possible some variants of capturing:
- Capture with fixed frames count (will be captured fixed frames count and capturing will be stopped).
- Capture with fixed time (capturing will be continued fixed seconds and capturing will be stopped).
- Capture without parameters - Live capturing (for getting frames you need to use functions `pop_element` and
`pop_all_elements`)
All results can be obtained using the function `capture_result`.
Args:
frames_count (int)
sec (int)
stream_number (int)
"""
if stream_number >= self.max_stream_number:
assert ValueError(f"Incorrect index of stream. Value must be from available options: "
f"{', '.join([str(i) for i in range(self.max_stream_number)])}")
config = CaptureConfig()
config.video = True
config.type = CaptureConfig.Type.LIVE
self.__capturer.start_capture(config)
self.capture_result.clear()
self.capture_result.start_capture_time = time.time()
if frames_count > 0:
if frames_count > 1:
self.capture_result.buffer.extend(self.__capturer.capture_video_by_n_frames(frames_count))
else:
self.capture_result.buffer.extend(self.__capturer.capture_video_by_n_frames(frames_count))
elif sec > 0:
self.capture_result.buffer.extend(self.__capturer.capture_video_by_n_sec(sec))
def get_buffer_capacity(self):
return self.__capturer.get_buffer_capacity()

View File

@@ -1,5 +1,5 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.libs.lib_tsi.tsi import *
import UniTAP.libs.lib_tsi.tsi_types as ci
from .cec_types import *
from .cec_private_types import *
from typing import Union
@@ -29,7 +29,7 @@ class CecRx:
Args:
state (`bool`)
"""
self.__io.set(TSI_HDRX_CEC_CONTROL, state, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_CONTROL, state, c_uint32)
def is_enabled(self) -> bool:
"""
@@ -38,7 +38,7 @@ class CecRx:
Returns:
object of `bool` type
"""
return self.__io.get(TSI_HDRX_CEC_CONTROL, c_uint32)[1] & 0x1 == 1
return self.__io.get(ci.TSI_HDRX_CEC_CONTROL, c_uint32)[1] & 0x1 == 1
@property
def logical_address(self) -> LogicalAddressEnum:
@@ -48,11 +48,11 @@ class CecRx:
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(TSI_HDRX_CEC_LOGICAL_ADDRESS, c_uint32)[1])
return LogicalAddressEnum(self.__io.get(ci.TSI_HDRX_CEC_LOGICAL_ADDRESS, c_uint32)[1])
@logical_address.setter
def logical_address(self, address: LogicalAddressEnum):
self.__io.set(TSI_HDRX_CEC_LOGICAL_ADDRESS, address.value, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_LOGICAL_ADDRESS, address.value, c_uint32)
@property
def destination(self) -> LogicalAddressEnum:
@@ -62,11 +62,11 @@ class CecRx:
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(TSI_HDRX_CEC_DESTINATION, c_uint32)[1])
return LogicalAddressEnum(self.__io.get(ci.TSI_HDRX_CEC_DESTINATION, c_uint32)[1])
@destination.setter
def destination(self, address: LogicalAddressEnum):
self.__io.set(TSI_HDRX_CEC_DESTINATION, address.value, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_DESTINATION, address.value, c_uint32)
@property
def phy_address(self) -> int:
@@ -76,11 +76,11 @@ class CecRx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDRX_CEC_PHYSICAL_ADDRESS, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_CEC_PHYSICAL_ADDRESS, c_uint32)[1]
@phy_address.setter
def phy_address(self, address: int):
self.__io.set(TSI_HDRX_CEC_PHYSICAL_ADDRESS, address, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_PHYSICAL_ADDRESS, address, c_uint32)
@property
def op_code(self) -> int:
@@ -90,11 +90,11 @@ class CecRx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDRX_CEC_OP_CODE, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_CEC_OP_CODE, c_uint32)[1]
@op_code.setter
def op_code(self, code: int):
self.__io.set(TSI_HDRX_CEC_OP_CODE, code, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_OP_CODE, code, c_uint32)
@property
def op_code_param(self) -> Union[int, list]:
@@ -104,12 +104,12 @@ class CecRx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDRX_CEC_OP_CODE_PARAM, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_CEC_OP_CODE_PARAM, c_uint32)[1]
@op_code_param.setter
def op_code_param(self, code_param: Union[int, list]):
data_count = len(code_param) if isinstance(code_param, list) else 1
self.__io.set(TSI_HDRX_CEC_OP_CODE_PARAM, code_param, c_uint32, data_count=data_count)
self.__io.set(ci.TSI_HDRX_CEC_OP_CODE_PARAM, code_param, c_uint32, data_count=data_count)
@property
def device_type(self) -> DeviceType:
@@ -119,7 +119,7 @@ class CecRx:
Returns:
object of `DeviceType` type
"""
data = self.__io.get(TSI_HDRX_CEC_DEVICE_TYPE, DeviceTypePrivate)[1]
data = self.__io.get(ci.TSI_HDRX_CEC_DEVICE_TYPE, DeviceTypePrivate)[1]
return DeviceType(data.cecSwitch, data.audioSystem, data.pbDevice, data.tuner, data.recDev, data.tv)
@device_type.setter
@@ -134,7 +134,7 @@ class CecRx:
value = dev_type & 0xFF
else:
raise TypeError(f"Unsupported type: {type(dev_type)}")
self.__io.set(TSI_HDRX_CEC_DEVICE_TYPE, value, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_DEVICE_TYPE, value, c_uint32)
@property
def status(self) -> CECStatus:
@@ -144,7 +144,7 @@ class CecRx:
Returns:
object of `CECStatus` type
"""
data = self.__io.get(TSI_HDRX_CEC_STATUS_R, CECStatusPrivate)[1]
data = self.__io.get(ci.TSI_HDRX_CEC_STATUS_R, CECStatusPrivate)[1]
return CECStatus(data.bufferOverflowed)
@property
@@ -155,7 +155,7 @@ class CecRx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDRX_CEC_RECEIVED_CNT_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_CEC_RECEIVED_CNT_R, c_uint32)[1]
@property
def data(self) -> list:
@@ -165,8 +165,8 @@ class CecRx:
Returns:
object of `list` type
"""
data_size = self.__io.get(TSI_HDRX_CEC_DATA_SIZE_R, c_uint32)[1]
return self.__io.get(TSI_HDRX_CEC_DATA_RECIEVED, c_uint32, data_size)[1]
data_size = self.__io.get(ci.TSI_HDRX_CEC_DATA_SIZE_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_CEC_DATA_RECIEVED, c_uint32, data_size)[1]
def reset_data(self, command: CecResetDataCommand):
"""
@@ -175,10 +175,10 @@ class CecRx:
Returns:
object of `CecResetDataCommand` type
"""
self.__io.set(TSI_HDRX_CEC_DATA_RESET_W, command.value, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_DATA_RESET_W, command.value, c_uint32)
def __read_version(self) -> (int, int):
version = self.__io.get(TSI_HDRX_CEC_VERSION_R, CECVersion)[1]
version = self.__io.get(ci.TSI_HDRX_CEC_VERSION_R, CECVersion)[1]
return version.minor, version.major
def add_command(self, command: CECCommand = CECCommand()):
@@ -250,7 +250,7 @@ class CecRx:
self.__send_cec_command()
def __send_cec_command(self):
self.__io.set(TSI_HDRX_CEC_COMMAND, 1, c_uint32)
self.__io.set(ci.TSI_HDRX_CEC_COMMAND, 1, c_uint32)
@property
def commands(self) -> list:

View File

@@ -1,5 +1,5 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.libs.lib_tsi.tsi import *
import UniTAP.libs.lib_tsi.tsi_types as ci
from .cec_types import *
from .cec_private_types import *
from typing import Union
@@ -29,7 +29,7 @@ class CecTx:
Args:
state (`bool`)
"""
self.__io.set(TSI_HDTX_CEC_CONTROL, state, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_CONTROL, state, c_uint32)
def is_enabled(self) -> bool:
"""
@@ -38,7 +38,7 @@ class CecTx:
Returns:
object of `bool` type
"""
return self.__io.get(TSI_HDTX_CEC_CONTROL, c_uint32)[1] & 0x1 == 1
return self.__io.get(ci.TSI_HDTX_CEC_CONTROL, c_uint32)[1] & 0x1 == 1
@property
def logical_address(self) -> LogicalAddressEnum:
@@ -48,11 +48,11 @@ class CecTx:
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(TSI_HDTX_CEC_LOGICAL_ADDRESS, c_uint32)[1])
return LogicalAddressEnum(self.__io.get(ci.TSI_HDTX_CEC_LOGICAL_ADDRESS, c_uint32)[1])
@logical_address.setter
def logical_address(self, address: LogicalAddressEnum):
self.__io.set(TSI_HDTX_CEC_LOGICAL_ADDRESS, address.value, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_LOGICAL_ADDRESS, address.value, c_uint32)
@property
def destination(self) -> LogicalAddressEnum:
@@ -62,11 +62,11 @@ class CecTx:
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(TSI_HDTX_CEC_DESTINATION, c_uint32)[1])
return LogicalAddressEnum(self.__io.get(ci.TSI_HDTX_CEC_DESTINATION, c_uint32)[1])
@destination.setter
def destination(self, address: LogicalAddressEnum):
self.__io.set(TSI_HDTX_CEC_DESTINATION, address.value, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_DESTINATION, address.value, c_uint32)
@property
def phy_address(self) -> int:
@@ -76,11 +76,11 @@ class CecTx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDTX_CEC_PHYSICAL_ADDRESS, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_CEC_PHYSICAL_ADDRESS, c_uint32)[1]
@phy_address.setter
def phy_address(self, address: int):
self.__io.set(TSI_HDTX_CEC_PHYSICAL_ADDRESS, address, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_PHYSICAL_ADDRESS, address, c_uint32)
@property
def op_code(self) -> int:
@@ -90,11 +90,11 @@ class CecTx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDTX_CEC_OP_CODE, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_CEC_OP_CODE, c_uint32)[1]
@op_code.setter
def op_code(self, code: int):
self.__io.set(TSI_HDTX_CEC_OP_CODE, code, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_OP_CODE, code, c_uint32)
@property
def op_code_param(self) -> Union[int, list]:
@@ -104,12 +104,12 @@ class CecTx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDTX_CEC_OP_CODE_PARAM, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_CEC_OP_CODE_PARAM, c_uint32)[1]
@op_code_param.setter
def op_code_param(self, code_param: Union[int, list]):
data_count = len(code_param) if isinstance(code_param, list) else 1
self.__io.set(TSI_HDTX_CEC_OP_CODE_PARAM, code_param, c_uint32, data_count=data_count)
self.__io.set(ci.TSI_HDTX_CEC_OP_CODE_PARAM, code_param, c_uint32, data_count=data_count)
@property
def device_type(self) -> DeviceType:
@@ -119,7 +119,7 @@ class CecTx:
Returns:
object of `DeviceType` type
"""
data = self.__io.get(TSI_HDTX_CEC_DEVICE_TYPE, DeviceTypePrivate)[1]
data = self.__io.get(ci.TSI_HDTX_CEC_DEVICE_TYPE, DeviceTypePrivate)[1]
return DeviceType(data.cecSwitch, data.audioSystem, data.pbDevice, data.tuner, data.recDev, data.tv)
@device_type.setter
@@ -134,7 +134,7 @@ class CecTx:
value = dev_type & 0xFF
else:
raise TypeError(f"Unsupported type: {type(dev_type)}")
self.__io.set(TSI_HDTX_CEC_DEVICE_TYPE, value, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_DEVICE_TYPE, value, c_uint32)
@property
def status(self) -> CECStatus:
@@ -144,7 +144,7 @@ class CecTx:
Returns:
object of `CECStatus` type
"""
data = self.__io.get(TSI_HDTX_CEC_STATUS_R, CECStatusPrivate)[1]
data = self.__io.get(ci.TSI_HDTX_CEC_STATUS_R, CECStatusPrivate)[1]
return CECStatus(data.bufferOverflowed)
@property
@@ -155,7 +155,7 @@ class CecTx:
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDTX_CEC_RECEIVED_CNT_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_CEC_RECEIVED_CNT_R, c_uint32)[1]
@property
def data(self) -> list:
@@ -165,8 +165,8 @@ class CecTx:
Returns:
object of `list` type
"""
data_size = self.__io.get(TSI_HDTX_CEC_DATA_SIZE_R, c_uint32)[1]
return self.__io.get(TSI_HDTX_CEC_DATA_RECEIVED_R, c_uint32, data_size)[1]
data_size = self.__io.get(ci.TSI_HDTX_CEC_DATA_SIZE_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_CEC_DATA_RECEIVED_R, c_uint32, data_size)[1]
def reset_data(self, command: CecResetDataCommand):
"""
@@ -175,10 +175,10 @@ class CecTx:
Returns:
object of `CecResetDataCommand` type
"""
self.__io.set(TSI_HDTX_CEC_DATA_RESET_W, command.value, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_DATA_RESET_W, command.value, c_uint32)
def __read_version(self) -> (int, int):
version = self.__io.get(TSI_HDTX_CEC_VERSION_R, CECVersion)[1]
version = self.__io.get(ci.TSI_HDTX_CEC_VERSION_R, CECVersion)[1]
return version.minor, version.major
def add_command(self, command: CECCommand = CECCommand()):
@@ -250,7 +250,7 @@ class CecTx:
self.__send_cec_command()
def __send_cec_command(self):
self.__io.set(TSI_HDTX_CEC_COMMAND, 1, c_uint32)
self.__io.set(ci.TSI_HDTX_CEC_COMMAND, 1, c_uint32)
@property
def commands(self) -> list:

View File

@@ -1,8 +1,9 @@
import os
from ctypes import c_ubyte
from typing import Union, Tuple
from UniTAP.libs.lib_tsi.tsi import *
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_types as ci
class DPCDRegion:
@@ -129,7 +130,7 @@ class DPCDRegisters:
data = bytearray(data)
result = self.__io.set(self.__base_ci, base)
if result < TSI_SUCCESS:
if result < ci.TSI_SUCCESS:
return result
result = self.__io.set(self.__data_ci, data, c_ubyte, len(data))
return result

View File

@@ -0,0 +1,2 @@
from .earc_types import EarcMode
from .earc_tx import EarcTx

View File

@@ -0,0 +1,83 @@
from ctypes import c_ubyte
from UniTAP.dev.ports.modules.ag.earc import AudioGeneratorEARC
from UniTAP.dev.modules.memory_manager import MemoryManager
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .earc_types import EarcControl, EarcMode, EarcStatus, EarcState, EarcHearthbeatState, EarcRxStatus
class EarcTx:
__MAX_EARC_EDID_SIZE = 128
def __init__(self, port_io: PortIO, memory_manager: MemoryManager) -> None:
self.__io = port_io
self.__earc_ag = AudioGeneratorEARC(port_io, memory_manager)
self.__control = self.__io.get(ci.TSI_HDRX_EARC_CTRL, EarcControl)[1]
def configure(self, mode: EarcMode, latency: int, bypass: bool = False) -> None:
self.__control.mode = mode
self.__control.bypass = bypass
self.__apply_control()
self.__set_audio_latency(latency)
def get_status(self) -> EarcStatus:
"""
Get eARC transmitter status.
Returns:
object of `EarcStatus` type.
"""
return self.__io.get(ci.TSI_HDRX_EARC_STS_R, EarcStatus)[1]
def get_latency(self) -> int:
"""
Get current audio latency for eARC transmitter.
Returns:
object of `int` type.
"""
return self.__io.get(ci.TSI_HDRX_EARC_LATENCY, int)[1]
def get_edid(self) -> bytearray:
"""
Get EDID data from eARC receiver.
Returns:
object of `bytearray` type.
"""
result, edid_data, size = self.__io.get(ci.TSI_HDRX_EARC_EDID_DATA, c_ubyte, self.__MAX_EARC_EDID_SIZE)
if result > 0:
return bytearray(edid_data[:result])
else:
return bytearray()
@property
def ag(self) -> AudioGeneratorEARC:
"""
Get audio generator for eARC transmitter.
Returns:
object of `AudioGeneratorEARC` type.
"""
return self.__earc_ag
def __apply_control(self):
"""
Apply eARC control settings.
"""
self.__io.set(ci.TSI_HDRX_EARC_CTRL, self.__control)
def __set_audio_latency(self, latency: int):
"""
Set audio latency request for eARC transmitter.
Args:
latency (int) - latency value to set
"""
self.__io.set(ci.TSI_HDRX_EARC_LATENCY_REQ, latency)

View File

@@ -0,0 +1,112 @@
from enum import IntEnum
from ctypes import c_uint32, Structure
from UniTAP.utils.bit_ops import get_bitfield, set_bitfield
class EarcMode(IntEnum):
"""
Describes possible eArc modes.
"""
Disabled = 0
eArc = 1
Legacy = 2
eArcNone = 3
class EarcState(IntEnum):
"""
Describes possible eArc states.
"""
H14bARC = 0
IDLE1 = 1
IDLE2 = 2
DISC1 = 3
DISC2 = 4
EARC = 5
def __str__(self) -> str:
return self.name
class EarcHearthbeatState(IntEnum):
"""
Describes possible eArc states.
"""
LOST = 0
SUCCESS = 1
FAIL = 2
def __str__(self) -> str:
return self.name
class EarcRxStatus(IntEnum):
"""
Describes possible eArc RX statuses.
"""
INVALID = 0
STAT_CHNG = 1
CAP_CHNG = 2
EARC_HPD = 4
def __str__(self) -> str:
return self.name
class EarcStatus(Structure):
__EARC_STATE_OFFSET = 0
__EARC_STATE_MASK = 0xF << __EARC_STATE_OFFSET
__EARC_HEARTHBEAT_OFFSET = 4
__EARC_HEARTHBEAT_MASK = 0xF << __EARC_HEARTHBEAT_OFFSET
__EARC_RX_STATUS_OFFSET = 8
__EARC_RX_STATUS_MASK = 0xF << __EARC_RX_STATUS_OFFSET
_fields_ = [
('data', c_uint32, 32)
]
def __init__(self, value: int) -> None:
self.data = value
@property
def earc_state(self) -> EarcState:
return EarcState(get_bitfield(self.data, self.__EARC_STATE_MASK, self.__EARC_STATE_OFFSET))
@property
def earc_hearthbeat(self) -> EarcHearthbeatState:
return EarcHearthbeatState(get_bitfield(self.data, self.__EARC_HEARTHBEAT_MASK, self.__EARC_HEARTHBEAT_OFFSET))
@property
def earc_rx_status(self) -> EarcRxStatus:
return EarcRxStatus(get_bitfield(self.data, self.__EARC_RX_STATUS_MASK, self.__EARC_RX_STATUS_OFFSET))
def __str__(self) -> str:
return f"EarcStatus(state={self.earc_state}, heartbeat={self.earc_hearthbeat}, rx_status={self.earc_rx_status})"
class EarcControl(Structure):
__EARC_MODE_OFFSET = 0
__EARC_MODE_MASK = 0x7 << __EARC_MODE_OFFSET
__EARC_BYPASS_OFFSET = 3
__EARC_BYPASS_MASK = 0x1 << __EARC_BYPASS_OFFSET
_fields_ = [
('data', c_uint32, 32)
]
def __init__(self, value: int) -> None:
self.data = value
@property
def mode(self) -> EarcMode:
return EarcMode(get_bitfield(self.data, self.__EARC_MODE_MASK, self.__EARC_MODE_OFFSET))
@mode.setter
def mode(self, value: EarcMode):
self.data = set_bitfield(self.data, self.__EARC_MODE_MASK, self.__EARC_MODE_OFFSET, value.value)
@property
def bypass(self) -> bool:
return bool(get_bitfield(self.data, self.__EARC_BYPASS_MASK, self.__EARC_BYPASS_OFFSET))
@bypass.setter
def bypass(self, value: bool):
self.data = set_bitfield(self.data, self.__EARC_BYPASS_MASK, self.__EARC_BYPASS_OFFSET, int(value))

View File

@@ -3,10 +3,7 @@ from typing import List
from UniTAP.common import Timing
from UniTAP.libs.lib_tsi.tsi_types import TSI_EDID_SELECT_STREAM, TSI_EDID_TE_INPUT, TSI_EDID_TE_OUTPUT, \
TSI_EDID_TE_OUTPUT_REMOTE_R, TSI_DID_TE_OUTPUT, TSI_DID_TE_INPUT, TSI_DID_SELECT_STREAM, \
TSI_DID_TE_OUTPUT_REMOTE_R, TSI_DPRX_DISPLAYID_CTRL, TSI_DPTX_DISPLAYID_CTRL, TSI_EDID_DUT_TIMINGS_COUNT, \
TSI_EDID_DUT_TIMINGS_DATA
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.dev.ports.modules.device_constants import MAX_EDID_SIZE
from ctypes import c_ubyte, c_uint32
@@ -67,12 +64,12 @@ class Edid:
"""
"""
timings_count = self._io.get(TSI_EDID_DUT_TIMINGS_COUNT, c_uint32)[1]
timings_count = self._io.get(ci.TSI_EDID_DUT_TIMINGS_COUNT, c_uint32)[1]
if timings_count == 0:
return []
timings = self._io.get(TSI_EDID_DUT_TIMINGS_DATA, ParsedTimingStruct, timings_count)[1]
timings = self._io.get(ci.TSI_EDID_DUT_TIMINGS_DATA, ParsedTimingStruct, timings_count)[1]
parsed_timings = []
for i in range(timings_count):
@@ -123,7 +120,7 @@ class EdidSource(Edid):
"""
def __init__(self, port_io: PortIO, max_stream_count: int):
super().__init__(port_io, TSI_EDID_TE_OUTPUT, max_stream_count, TSI_EDID_SELECT_STREAM)
super().__init__(port_io, ci.TSI_EDID_TE_OUTPUT, max_stream_count, ci.TSI_EDID_SELECT_STREAM)
def read_sbm(self, stream: int):
"""
@@ -137,7 +134,7 @@ class EdidSource(Edid):
"""
self._select_stream(stream)
result, edid_data, size = self._io.get(TSI_EDID_TE_OUTPUT_REMOTE_R, c_ubyte, MAX_EDID_SIZE)
result, edid_data, size = self._io.get(ci.TSI_EDID_TE_OUTPUT_REMOTE_R, c_ubyte, MAX_EDID_SIZE)
if result > 0:
return bytearray(edid_data[:result])
else:
@@ -153,7 +150,7 @@ class EdidSink(Edid):
"""
def __init__(self, port_io: PortIO, max_stream_count: int):
super().__init__(port_io, TSI_EDID_TE_INPUT, max_stream_count, TSI_EDID_SELECT_STREAM)
super().__init__(port_io, ci.TSI_EDID_TE_INPUT, max_stream_count, ci.TSI_EDID_SELECT_STREAM)
def write_edid(self, data: bytearray, stream: int = 0):
"""
@@ -216,7 +213,7 @@ class DisplayIdSource(Edid):
"""
def __init__(self, port_io: PortIO, max_stream_count: int):
super().__init__(port_io, TSI_DID_TE_OUTPUT, max_stream_count, TSI_DID_SELECT_STREAM)
super().__init__(port_io, ci.TSI_DID_TE_OUTPUT, max_stream_count, ci.TSI_DID_SELECT_STREAM)
def read_sbm(self, stream: int):
"""
@@ -230,7 +227,7 @@ class DisplayIdSource(Edid):
"""
self._select_stream(stream)
result, data, size = self._io.get(TSI_DID_TE_OUTPUT_REMOTE_R, c_ubyte, MAX_EDID_SIZE)
result, data, size = self._io.get(ci.TSI_DID_TE_OUTPUT_REMOTE_R, c_ubyte, MAX_EDID_SIZE)
if result > 0:
return bytearray(data[:result])
else:
@@ -243,7 +240,7 @@ class DisplayIdSource(Edid):
Args:
mode (`DisplayIDReadMode`)
"""
self._io.set(TSI_DPTX_DISPLAYID_CTRL, mode.value, c_uint32)
self._io.set(ci.TSI_DPTX_DISPLAYID_CTRL, mode.value, c_uint32)
def get_display_id_mode(self) -> DisplayIDReadMode:
"""
@@ -252,7 +249,7 @@ class DisplayIdSource(Edid):
Returns:
object of `DisplayIDReadMode` type.
"""
result = self._io.get(TSI_DPTX_DISPLAYID_CTRL, c_uint32)[1]
result = self._io.get(ci.TSI_DPTX_DISPLAYID_CTRL, c_uint32)[1]
return DisplayIDReadMode(result)
@@ -265,7 +262,7 @@ class DisplayIdSink(Edid):
"""
def __init__(self, port_io: PortIO, max_stream_count: int):
super().__init__(port_io, TSI_DID_TE_INPUT, max_stream_count, TSI_DID_SELECT_STREAM)
super().__init__(port_io, ci.TSI_DID_TE_INPUT, max_stream_count, ci.TSI_DID_SELECT_STREAM)
def is_enabled(self) -> bool:
"""
@@ -274,7 +271,7 @@ class DisplayIdSink(Edid):
Returns:
object of `bool` type.
"""
result = self._io.get(TSI_DPRX_DISPLAYID_CTRL, c_uint32)
result = self._io.get(ci.TSI_DPRX_DISPLAYID_CTRL, c_uint32)
status_display_id = ((result[1] & 0x1) != 0)
return bool(status_display_id)
@@ -286,7 +283,7 @@ class DisplayIdSink(Edid):
enable (bool) - enable (True) or disable (False)
"""
val = 0x1 if enable else 0x0
self._io.set(TSI_DPRX_DISPLAYID_CTRL, val)
self._io.set(ci.TSI_DPRX_DISPLAYID_CTRL, val)
def write_display_id(self, data: bytearray):

View File

@@ -1,4 +1,6 @@
from UniTAP.libs.lib_tsi.tsi import *
from ctypes import c_int
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .fec_shared import FECCounters
@@ -27,7 +29,7 @@ class FecRx:
Returns:
object of `bool` type.
"""
result = self.__io.get(TSI_DPRX_FEC_STATUS_R, c_int)
result = self.__io.get(ci.TSI_DPRX_FEC_STATUS_R, c_int)
status_fec = ((result[1] & 0x1) != 0)
return bool(status_fec)
@@ -38,7 +40,7 @@ class FecRx:
Returns:
object of `bool` type.
"""
result = self.__io.get(TSI_DPRX_FEC_CTRL, c_int)
result = self.__io.get(ci.TSI_DPRX_FEC_CTRL, c_int)
enabled_fec = (result[1] & 0x1) != 0
return enabled_fec
@@ -50,7 +52,7 @@ class FecRx:
enable (bool) - enable (True) or disable (False)
"""
val = 0x1 if enable else 0x0
self.__io.set(TSI_DPRX_FEC_CTRL, val)
self.__io.set(ci.TSI_DPRX_FEC_CTRL, val)
def aggregate_errors(self, enable: bool):
"""
@@ -59,7 +61,7 @@ class FecRx:
Args:
enable (bool) - enable (True) or disable (False)
"""
result = self.__io.get(TSI_DPRX_FEC_CONTROL, c_int)
result = self.__io.get(ci.TSI_DPRX_FEC_CONTROL, c_int)
val = result[1]
if enable:
val |= 0x2
@@ -67,7 +69,7 @@ class FecRx:
else:
val &= ~0x2
self.__aggregate_error = 0
self.__io.set(TSI_DPRX_FEC_CONTROL, val)
self.__io.set(ci.TSI_DPRX_FEC_CONTROL, val)
def get_error_counters(self) -> FECCounters:
"""
@@ -78,7 +80,7 @@ class FecRx:
object of `FECCounters` type
"""
result = FECCounters()
lane_count = self.__io.get(TSI_R_DPRX_LINK_LANE_COUNT, c_int)[1]
lane_count = self.__io.get(ci.TSI_R_DPRX_LINK_LANE_COUNT, c_int)[1]
if lane_count == 4:
lane_count += 1 if self.__aggregate_error else 0

View File

@@ -1,5 +1,8 @@
from UniTAP.libs.lib_tsi.tsi import *
from ctypes import c_int, c_uint32
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .fec_shared import FECCounters, FECErrorType8b10b, FECErrorType128b132b
from UniTAP.dev.ports.modules.dpcd.dpcd import DPCDRegisters
@@ -29,7 +32,7 @@ class FecTx:
Returns:
object of `bool` type.
"""
result = self.__io.get(TSI_DPTX_FEC_STATUS_R, c_int)
result = self.__io.get(ci.TSI_DPTX_FEC_STATUS_R, c_int)
status_fec = ((result[1] & 0x1) != 0)
return bool(status_fec)
@@ -40,7 +43,7 @@ class FecTx:
Returns:
object of `bool` type.
"""
result = self.__io.get(TSI_DPTX_FEC_CTRL, c_int)
result = self.__io.get(ci.TSI_DPTX_FEC_CTRL, c_int)
enabled_fec = (result[1] & 0x2) != 0
return enabled_fec
@@ -51,10 +54,10 @@ class FecTx:
Args:
enable (bool) - enable (True) or disable (False)
"""
result = self.__io.get(TSI_DPTX_FEC_CTRL, c_int)
result = self.__io.get(ci.TSI_DPTX_FEC_CTRL, c_int)
val = result[1]
val |= 0x8 if enable else 0x10
self.__io.set(TSI_DPTX_FEC_CTRL, val)
self.__io.set(ci.TSI_DPTX_FEC_CTRL, val)
def enable_intent(self, enable: bool):
"""
@@ -63,10 +66,10 @@ class FecTx:
Args:
enable (bool) - enable (True) or disable (False)
"""
result = self.__io.get(TSI_DPTX_FEC_CTRL, c_int)
result = self.__io.get(ci.TSI_DPTX_FEC_CTRL, c_int)
val = result[1]
val |= 1 if enable else 4
self.__io.set(TSI_DPTX_FEC_CTRL, val)
self.__io.set(ci.TSI_DPTX_FEC_CTRL, val)
def aggregate_errors(self, enable: bool):
"""
@@ -75,7 +78,7 @@ class FecTx:
Args:
enable (bool) - enable (True) or disable (False)
"""
result = self.__io.get(TSI_DPTX_FEC_CONTROL, c_int)
result = self.__io.get(ci.TSI_DPTX_FEC_CONTROL, c_int)
val = result[1]
if enable:
val |= 0x40
@@ -83,7 +86,7 @@ class FecTx:
else:
val &= ~0x40
self.__aggregate_error = 0
self.__io.set(TSI_DPTX_FEC_CONTROL, val)
self.__io.set(ci.TSI_DPTX_FEC_CONTROL, val)
def generate_errors(self, error_type: Union[FECErrorType8b10b, FECErrorType128b132b], lane: list, ms: int = 100):
"""
@@ -94,8 +97,8 @@ class FecTx:
lane (list)
ms (int) - time in m seconds
"""
result, status = self.__io.get(TSI_DPTX_LINK_MODE_R, c_int)
resut, hw_caps, size = self.__io.get(TSI_DPTX_HW_CAPS_R, c_uint32, 4)
result, status = self.__io.get(ci.TSI_DPTX_LINK_MODE_R, c_int)
resut, hw_caps, size = self.__io.get(ci.TSI_DPTX_HW_CAPS_R, c_uint32, 4)
if status == 0:
if isinstance(error_type, FECErrorType128b132b):
assert False, "This device doesn't support 128b/132b" if (hw_caps[1] & 0x7) == 0 else "Change link mode!"
@@ -109,24 +112,24 @@ class FecTx:
delay = ms * 100
self.__io.set(TSI_MLEG_CONTROL, 0)
nl = self.__io.get(TSI_R_DPTX_LINK_STATUS_LANE_COUNT, c_uint32)[1]
self.__io.set(p_ci.TSI_MLEG_CONTROL, 0)
nl = self.__io.get(ci.TSI_R_DPTX_LINK_STATUS_LANE_COUNT, c_uint32)[1]
self.__io.set(TSI_MLEG_SYMBOL_REPLACE_A, 0x00010000)
self.__io.set(TSI_MLEG_SYMBOL_REPLACE_MASK_A, 0x00010001)
self.__io.set(TSI_MLEG_SYMBOL_REPLACE_B, 0x00000001)
self.__io.set(TSI_MLEG_SYMBOL_REPLACE_MASK_B, 0x00010001)
self.__io.set(p_ci.TSI_MLEG_SYMBOL_REPLACE_A, 0x00010000)
self.__io.set(p_ci.TSI_MLEG_SYMBOL_REPLACE_MASK_A, 0x00010001)
self.__io.set(p_ci.TSI_MLEG_SYMBOL_REPLACE_B, 0x00000001)
self.__io.set(p_ci.TSI_MLEG_SYMBOL_REPLACE_MASK_B, 0x00010001)
self.__io.set(TSI_MLEG_DELAY_COUNTER, delay)
self.__io.set(p_ci.TSI_MLEG_DELAY_COUNTER, delay)
n = lane[0] << 16
self.__io.set(TSI_MLEG_LANE0_REPLACE_COUNTERS, n)
self.__io.set(p_ci.TSI_MLEG_LANE0_REPLACE_COUNTERS, n)
n = lane[1] << 16
self.__io.set(TSI_MLEG_LANE1_REPLACE_COUNTERS, n)
self.__io.set(p_ci.TSI_MLEG_LANE1_REPLACE_COUNTERS, n)
n = lane[2] << 16
self.__io.set(TSI_MLEG_LANE2_REPLACE_COUNTERS, n)
self.__io.set(p_ci.TSI_MLEG_LANE2_REPLACE_COUNTERS, n)
n = lane[3] << 16
self.__io.set(TSI_MLEG_LANE3_REPLACE_COUNTERS, n)
self.__io.set(p_ci.TSI_MLEG_LANE3_REPLACE_COUNTERS, n)
ctrl = 0
ctrl |= (error_type.value << 16)
@@ -144,7 +147,7 @@ class FecTx:
if lane[3]:
ctrl |= (1 << 3)
self.__io.set(TSI_MLEG_CONTROL, ctrl)
self.__io.set(p_ci.TSI_MLEG_CONTROL, ctrl)
def get_error_counters(self) -> FECCounters:
"""
@@ -154,7 +157,7 @@ class FecTx:
object of `FECCounters` type
"""
result = FECCounters()
lane_count = self.__io.get(TSI_R_DPTX_LINK_STATUS_LANE_COUNT, c_uint32)[1]
lane_count = self.__io.get(ci.TSI_R_DPTX_LINK_STATUS_LANE_COUNT, c_uint32)[1]
if lane_count == 4:
lane_count += 1 if self.__aggregate_error else 0

View File

@@ -1,9 +1,10 @@
import warnings
from typing import Optional, Union
from ctypes import c_int
from typing import Optional, Union, Type
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.libs.lib_tsi.tsi_io import PortIO, PortProtocol
from .types import *
from UniTAP.libs.lib_tsi.tsi import c_int
class HdcpSinkStatus:
@@ -77,7 +78,7 @@ class HdcpSinkStatus:
def __read_status(self, mode: HdcpMode) -> int:
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
return self.__io.get(ci.TSI_HDCP_1X_STATUS_R, c_int)[1]
else:
return self.__io.get(self.__ci_status_control, c_int)[1]
@@ -164,7 +165,7 @@ class HdcpSinkConfig:
if keys == HdcpSink2XKeys.Production and not self.__caps_2x.production_keys_available:
warnings.warn("Production keys is not hw supported. Please, select another keys.")
self.__io.set(TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else TSI_HDCP_2X_COMMAND_W, keys.value)
self.__io.set(ci.TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else ci.TSI_HDCP_2X_COMMAND_W, keys.value)
def __set_capable(self, value: Optional[bool], hdcp_mode: HdcpMode):
if value is None:
@@ -172,9 +173,10 @@ class HdcpSinkConfig:
if not self.__full_check(hdcp_mode):
return
self.__io.set(TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else TSI_HDCP_2X_COMMAND_W,
(H1_SINK_SET_CAPABLE if value else H1_SINK_CLEAR_CAPABLE)
if hdcp_mode == HdcpMode.Mode1_4 else (H2_SINK_SET_CAPABLE if value else H2_SINK_CLEAR_CAPABLE))
self.__io.set(ci.TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else ci.TSI_HDCP_2X_COMMAND_W,
(ci.H1_SINK_SET_CAPABLE if value else ci.H1_SINK_CLEAR_CAPABLE)
if hdcp_mode == HdcpMode.Mode1_4 else (
ci.H2_SINK_SET_CAPABLE if value else ci.H2_SINK_CLEAR_CAPABLE))
def __full_check(self, hdcp_mode: HdcpMode) -> bool:
if hdcp_mode == HdcpMode.Unknown:
@@ -239,7 +241,7 @@ class HdcpSink:
def __read_hw_caps(self, mode: HdcpMode, ci_caps_control: int = 0) -> int:
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
return self.__io.get(ci.TSI_HDCP_1X_STATUS_R, c_int)[1]
elif mode == HdcpMode.Mode2_3:
return self.__io.get(ci_caps_control, c_int)[1]
else:

View File

@@ -1,10 +1,11 @@
import warnings
from typing import Optional, Union
from typing import Optional, Union, Type
from UniTAP.libs.lib_tsi.tsi_io import PortIO, PortProtocol
from .types import *
from UniTAP.libs.lib_tsi.tsi_private_types import *
from ctypes import c_int
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from ctypes import c_int, c_uint32
class HdcpSourceStatus:
@@ -52,10 +53,18 @@ class HdcpSourceStatus:
if self.__caps_1x.hw_supported:
status_value = self.__read_status(HdcpMode.Mode1_4)
status = HdcpStatus.Status1x()
if (status_value >> 9) & 1:
status.keys = HdcpSource1XKeys.Test
elif (status_value >> 10) & 1:
status.keys = HdcpSource1XKeys.Production
else:
status.keys = HdcpSource1XKeys.Unload
status.active = (status_value >> 8) & 1
status.keys = HdcpSource1XKeys(((status_value >> 9) & 3) + 0x100)
status.capable = ((status_value >> 11) & 1)
status.authenticated = ((status_value >> 12) & 1)
return status
else:
warnings.warn(f"Not supported 'HDCP 1.4'")
@@ -63,23 +72,21 @@ class HdcpSourceStatus:
if self.__caps_2x.hw_supported:
status_value = self.__read_status(HdcpMode.Mode2_3)
status = HdcpStatus.StatusTx2x()
if self.__io.protocol() == PortProtocol.HDMI:
status.keys = HdcpSource2XKeys.Production if (status_value >> 9) & 1 else HdcpSource2XKeys.Unload
if (status_value >> 14) & 1:
status.keys = HdcpSource2XKeys.TestR1
elif (status_value >> 15) & 1:
status.keys = HdcpSource2XKeys.TestR2
elif (status_value >> 9) & 1:
status.keys = HdcpSource2XKeys.Production
else:
if (status_value >> 14) & 1:
status.keys = HdcpSource2XKeys.TestR1
elif (status_value >> 15) & 1:
status.keys = HdcpSource2XKeys.TestR2
elif (status_value >> 9) & 1:
status.keys = HdcpSource2XKeys.Production
else:
status.keys = HdcpSource2XKeys.Unload
status.km_is_stored = (status_value >> 13) & 1
status.try_authenticate = (status_value >> 18) & 1
status.try_encrypt = (status_value >> 19) & 1
status.content_level = self.__io.get(TSI_HDCP_2X_CFG, c_uint32)[1]
status.keys = HdcpSource2XKeys.Unload
status.km_is_stored = (status_value >> 13) & 1
status.try_authenticate = (status_value >> 18) & 1
status.try_encrypt = (status_value >> 19) & 1
status.content_level = self.__io.get(p_ci.TSI_HDCP_2X_CFG, c_uint32)[1]
status.active = (status_value >> 8) & 1
status.capable = (status_value >> 10) & 1
status.authenticated = (status_value >> 12) & 1
@@ -90,7 +97,7 @@ class HdcpSourceStatus:
def __read_status(self, mode: HdcpMode):
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
return self.__io.get(ci.TSI_HDCP_1X_STATUS_R, c_int)[1]
elif mode == HdcpMode.Mode2_3:
return self.__io.get(self.__ci_status_control, c_int)[1]
else:
@@ -172,17 +179,17 @@ class HdcpSourceConfig:
if value is None:
return
if hdcp_mode == HdcpMode.Mode1_4:
self.__io.set(TSI_HDCP_1X_COMMAND_W, H1_SOURCE_ENABLE_ENCRYPT if value else H1_SOURCE_DISABLE_ENCRYPT)
self.__io.set(ci.TSI_HDCP_1X_COMMAND_W, ci.H1_SOURCE_ENABLE_ENCRYPT if value else ci.H1_SOURCE_DISABLE_ENCRYPT)
elif hdcp_mode == HdcpMode.Mode2_3:
self.__io.set(TSI_HDCP_2X_COMMAND_W, H2_SOURCE_ENABLE_ENCRYPT if value else H2_SOURCE_DISABLE_ENCRYPT)
self.__io.set(ci.TSI_HDCP_2X_COMMAND_W, ci.H2_SOURCE_ENABLE_ENCRYPT if value else ci.H2_SOURCE_DISABLE_ENCRYPT)
def __set_authenticate(self, value: Optional[bool], hdcp_mode: HdcpMode):
if value is None:
return
if hdcp_mode == HdcpMode.Mode1_4:
self.__io.set(TSI_HDCP_1X_COMMAND_W, H1_SOURCE_AUTHENTICATE if value else H1_SOURCE_DE_AUTHENTICATE)
self.__io.set(ci.TSI_HDCP_1X_COMMAND_W, ci.H1_SOURCE_AUTHENTICATE if value else ci.H1_SOURCE_DE_AUTHENTICATE)
elif hdcp_mode == HdcpMode.Mode2_3:
self.__io.set(TSI_HDCP_2X_COMMAND_W, H2_SOURCE_AUTHENTICATE if value else H2_SOURCE_DE_AUTHENTICATE)
self.__io.set(ci.TSI_HDCP_2X_COMMAND_W, ci.H2_SOURCE_AUTHENTICATE if value else ci.H2_SOURCE_DE_AUTHENTICATE)
def __load_keys(self, keys: Optional[Union[HdcpSource1XKeys, HdcpSource2XKeys]], hdcp_mode: HdcpMode):
if keys is None:
@@ -203,7 +210,7 @@ class HdcpSourceConfig:
if keys == HdcpSource2XKeys.Production and not self.__caps_2x.production_keys_available:
warnings.warn("Production keys is not hw supported. Please, select another keys.")
self.__io.set(TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else TSI_HDCP_2X_COMMAND_W, keys.value)
self.__io.set(ci.TSI_HDCP_1X_COMMAND_W if hdcp_mode == HdcpMode.Mode1_4 else ci.TSI_HDCP_2X_COMMAND_W, keys.value)
def __full_check(self, hdcp_mode: HdcpMode) -> bool:
if hdcp_mode == HdcpMode.Unknown:
@@ -231,14 +238,14 @@ class HdcpSourceConfig:
def __set_store_km(self, value: Optional[bool]):
if value is None:
return
self.__io.set(TSI_HDCP_2X_COMMAND_W, H2_SOURCE_AUTHENTICATE_STORE_KM if value else H2_SOURCE_CLEAR_STORE_KM)
self.__io.set(ci.TSI_HDCP_2X_COMMAND_W, ci.H2_SOURCE_AUTHENTICATE_STORE_KM if value else ci.H2_SOURCE_CLEAR_STORE_KM)
def __set_content_level(self, value: Optional[int]):
if value is None:
return
if value not in [0, 1]:
raise ValueError(f"Incorrect input value of 'Content level' - {value}. Must be from range: 0-1")
self.__io.set(TSI_HDCP_2X_CFG, value)
self.__io.set(p_ci.TSI_HDCP_2X_CFG, value)
class HdcpSource:
@@ -280,7 +287,7 @@ class HdcpSource:
def __read_hw_caps(self, mode: HdcpMode, ci_caps_control: int = 0) -> int:
if mode == HdcpMode.Mode1_4:
return self.__io.get(TSI_HDCP_1X_STATUS_R, c_int)[1]
return self.__io.get(ci.TSI_HDCP_1X_STATUS_R, c_int)[1]
elif mode == HdcpMode.Mode2_3:
return self.__io.get(ci_caps_control, c_int)[1]
else:

View File

@@ -1,38 +1,37 @@
from typing import TypeVar
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
from enum import IntEnum
from typing import Type
class HdcpSink1XKeys(IntEnum):
Unknown = -1
Unload = H1_SINK_UNLOAD_KEYS
Test = H1_SINK_LOAD_TEST_KEYS
Production = H1_SINK_LOAD_PROD_KEYS
Unload = ci.H1_SINK_UNLOAD_KEYS
Test = ci.H1_SINK_LOAD_TEST_KEYS
Production = ci.H1_SINK_LOAD_PROD_KEYS
class HdcpSink2XKeys(IntEnum):
Unknown = -1
Unload = H2_SINK_UNLOAD_KEYS
Production = H2_SINK_LOAD_PROD_KEYS
TestR1 = H2_SINK_LOAD_TEST_KEYS_R1
TestR2 = H2_SINK_LOAD_TEST_KEYS_R2
Unload = ci.H2_SINK_UNLOAD_KEYS
Production = ci.H2_SINK_LOAD_PROD_KEYS
TestR1 = ci.H2_SINK_LOAD_TEST_KEYS_R1
TestR2 = ci.H2_SINK_LOAD_TEST_KEYS_R2
class HdcpSource1XKeys(IntEnum):
Unknown = -1
Unload = H1_SOURCE_UNLOAD_KEYS
Test = H1_SOURCE_LOAD_TEST_KEYS
Production = H1_SOURCE_LOAD_PROD_KEYS
Unload = ci.H1_SOURCE_UNLOAD_KEYS
Test = ci.H1_SOURCE_LOAD_TEST_KEYS
Production = ci.H1_SOURCE_LOAD_PROD_KEYS
class HdcpSource2XKeys(IntEnum):
Unknown = -1
Unload = H2_SOURCE_UNLOAD_KEYS
Production = H2_SOURCE_LOAD_PROD_KEYS
TestR1 = H2_SOURCE_LOAD_TEST_KEYS_R1
TestR2 = H2_SOURCE_LOAD_TEST_KEYS_R2
Unload = ci.H2_SOURCE_UNLOAD_KEYS
Production = ci.H2_SOURCE_LOAD_PROD_KEYS
TestR1 = ci.H2_SOURCE_LOAD_TEST_KEYS_R1
TestR2 = ci.H2_SOURCE_LOAD_TEST_KEYS_R2
class HdcpMode(IntEnum):

View File

@@ -1,6 +1,8 @@
from .link_rx_caps import LinkDisplayPortCaps
from .link_rx_status import *
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .dp_cable_info import DpCableInfo, CableCapabilitiesEnum
from .link_rx_aux_controller import DisplayPortAUXController
from UniTAP.dev.ports.modules.dpcd import DPCDRegisters
@@ -20,7 +22,7 @@ class LinkDisplayPortRx:
self.__HW_CAPS = hw_caps
self.__status = LinkDisplayPortStatusSink(port_io, self.__HW_CAPS)
self.__capabilities = LinkDisplayPortCaps(port_io, self.__HW_CAPS)
self.__cable_info = DpCableInfo(port_io, TSI_DPRX_CABLE_ATTRIBUTES_R)
self.__cable_info = DpCableInfo(port_io, p_ci.TSI_DPRX_CABLE_ATTRIBUTES_R)
self.__aux_controller = DisplayPortAUXController(port_io, dpcd)
@property
@@ -60,7 +62,7 @@ class LinkDisplayPortRx:
Args:
duration_us (int)
"""
self.__io.set(TSI_DPRX_HPD_PULSE_W, duration_us, c_int)
self.__io.set(ci.TSI_DPRX_HPD_PULSE_W, duration_us, c_int)
def set_assert_state(self, state: bool):
"""
@@ -70,7 +72,7 @@ class LinkDisplayPortRx:
state (bool)
"""
val = 0x1 if state else 0x0
self.__io.set(TSI_FORCE_HOT_PLUG_STATE_W, val)
self.__io.set(ci.TSI_FORCE_HOT_PLUG_STATE_W, val)
@property
def scrambler_seed(self) -> int:
@@ -84,7 +86,7 @@ class LinkDisplayPortRx:
warnings.warn("Scrambler Seed is not supported.")
return 0
return self.__io.get(TSI_DPRX_SCR_SEED, c_uint32)[1]
return self.__io.get(ci.TSI_DPRX_SCR_SEED, c_uint32)[1]
@scrambler_seed.setter
def scrambler_seed(self, value: int = 0):
@@ -98,7 +100,7 @@ class LinkDisplayPortRx:
raise ValueError(f"Scrambler seed {value} is not available.")
if self.__HW_CAPS.scrambler_seed:
self.__io.set(TSI_DPRX_SCR_SEED, value)
self.__io.set(ci.TSI_DPRX_SCR_SEED, value)
else:
warnings.warn("Scrambler Seed is not supported.")

View File

@@ -1,7 +1,8 @@
from ctypes import c_uint32, c_int
from typing import Optional
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .private_link_rx_types import RoutedLTStatusPrivate
from .link_rx_types import RoutedLTStatus, RoutedLTConfig
from UniTAP.dev.ports.modules.dpcd import DPCDRegisters
@@ -34,7 +35,7 @@ class DisplayPortAUXController:
else:
ctrl &= ~0x01
res = self.__io.set(TSI_DPRX_LT_ROUTE_CONTROL_W, ctrl, c_uint32)
res = self.__io.set(ci.TSI_DPRX_LT_ROUTE_CONTROL_W, ctrl, c_uint32)
if not res:
raise Exception("The feature requires a license key and the required license key is not installed.")
@@ -50,17 +51,18 @@ class DisplayPortAUXController:
max_rate_dp14 = 0
max_rate_dp20 = 0
if config.is128b132b:
if config.link_bw == 1:
max_rate_dp20 = 1
elif config.link_bw == 2:
max_rate_dp20 = 3
elif config.link_bw == 4:
max_rate_dp20 = 5
if not config.is_edp_lt:
if config.is128b132b:
if config.link_bw == 1:
max_rate_dp20 = 1
elif config.link_bw == 2:
max_rate_dp20 = 3
elif config.link_bw == 4:
max_rate_dp20 = 5
max_rate_dp14 = 0x1e
else:
max_rate_dp14 = config.link_bw
max_rate_dp14 = 0x1e
else:
max_rate_dp14 = config.link_bw
res = self.__set_routed_lt_config(config.int_value())
if not res:
@@ -91,12 +93,21 @@ class DisplayPortAUXController:
if config.is128b132b:
self.__dpcd.write(0x21, 0x01)
self.__dpcd.write(0x90, 0xff)
edp_data = [0x00] * 16
self.__dpcd.write(0x10, edp_data)
self.__dpcd.write(0x700, 0x00)
dsc_data = [0x0f, 0x21, 0x03, 0x03, 0xeb, 0x07, 0x01, 0x00, 0x00, 0x1f, 0x0e, 0x11, 0x08, 0x07, 0x00, 0x00]
self.__dpcd.write(0x60, dsc_data)
self.__dpcd.write(0x2217, 0x06)
else:
self.__dpcd.write(0x21, 0x00)
self.__dpcd.write(0x90, 0x00)
edp_data = [0x00] * 16
if config.is_edp_lt:
edp_data[0] = config.link_bw & 0xff
edp_data[1] = (config.link_bw >> 8) & 0xff
self.__dpcd.write(0x10, edp_data)
self.__dpcd.write(0x700, config.is_edp_lt and 0x06 or 0x00)
dsc_data = [0x00] * 16
self.__dpcd.write(0x60, dsc_data)
self.__dpcd.write(0x2217, 0x00)
@@ -200,19 +211,19 @@ class DisplayPortAUXController:
step=routed_lt_status.step)
def __set_routed_lt_config(self, value: int) -> bool:
res = self.__io.set(TSI_DPRX_LT_ROUTE_CREATE, value, c_uint32)
res = self.__io.set(ci.TSI_DPRX_LT_ROUTE_CREATE, value, c_uint32)
return res >= 0
def __set_force_cable_status_to_plugged(self, enable: bool):
val = 0x3C if enable else 0
self.__io.set(TSI_DPRX_HPD_FORCE, val, c_int)
self.__io.set(ci.TSI_DPRX_HPD_FORCE, val, c_int)
def __read_status(self) -> Optional[RoutedLTStatusPrivate]:
res, status = self.__io.get(TSI_DPRX_LT_ROUTE_STATUS_R, RoutedLTStatusPrivate)
res, status = self.__io.get(ci.TSI_DPRX_LT_ROUTE_STATUS_R, RoutedLTStatusPrivate)
if res >= 0:
return status
return None
def __generate_short_hpd_pulse(self, value: int):
self.__io.set(TSI_DPRX_HPD_PULSE_W, value, c_int)
self.__io.set(ci.TSI_DPRX_HPD_PULSE_W, value, c_int)

View File

@@ -1,10 +1,11 @@
import warnings
from ctypes import c_int, c_uint, c_uint32
from typing import List, Optional, Union, Type
from .link_rx_types import LinkCapabilities, LinkEDPCapabilities, DisplayPortLinkCaps
from .private_link_rx_types import DPRXHWCaps, DPRXLinkControl
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
class LinkDisplayPortCaps:
@@ -27,7 +28,8 @@ class LinkDisplayPortCaps:
if isinstance(capabilities, LinkCapabilities):
self.__set_max_lanes(capabilities.max_lane)
self.__set_max_bitrate(capabilities.bit_rate)
self.__set_force_cable_status_to_plugged(capabilities.force_cable_status_to_plugged)
# TODO: Temporarily disabled for writing value
# self.__set_force_cable_status_to_plugged(capabilities.force_cable_status_to_plugged)
self.__set_dp_link_control(old_dp2_lt=capabilities.old_dp_2_0_lt)
self.__set_dp_128_132_bitrates(capabilities.dp_128_132_bitrates)
self.__set_bitrate_override(10.0, capabilities.override_10g)
@@ -86,10 +88,10 @@ class LinkDisplayPortCaps:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DPRX_MAX_LANES, lane_count, c_int)
self.__io.set(ci.TSI_DPRX_MAX_LANES, lane_count, c_int)
def __get_max_lanes(self) -> int:
return self.__io.get(TSI_DPRX_MAX_LANES)[1]
return self.__io.get(ci.TSI_DPRX_MAX_LANES)[1]
def __set_max_bitrate(self, bitrate: Optional[float]):
if bitrate is None:
@@ -97,10 +99,10 @@ class LinkDisplayPortCaps:
bitrate = round(bitrate / 0.27)
if bitrate not in [6, 10, 20, 25, 30]:
raise ValueError(f"Incorrect bit rate number {bitrate}. Must be from list: 1.62, 2.7, 5.4, 6.75, 8.1")
self.__io.set(TSI_DPRX_MAX_LINK_RATE, bitrate, c_int)
self.__io.set(ci.TSI_DPRX_MAX_LINK_RATE, bitrate, c_int)
def __get_max_bitrate(self) -> int:
return round(self.__io.get(TSI_DPRX_MAX_LINK_RATE)[1] * 0.27, 2)
return round(self.__io.get(ci.TSI_DPRX_MAX_LINK_RATE)[1] * 0.27, 2)
def __set_bitrate_override(self, to_override: float, with_override: Optional[float]):
if with_override is None:
@@ -109,19 +111,19 @@ class LinkDisplayPortCaps:
if not isinstance(to_override, float) or not isinstance(with_override, float):
raise TypeError("DP 128b/132b bitrate override settings must float type!")
list_value = self.__io.get(TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
list_value = self.__io.get(ci.TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
if with_override not in [2.5, 2.7, 5.0, 5.4]:
raise ValueError(f"Incorrect bit rate number {with_override}. "
f"Must be from list: 2.5, 2.7, 5.0, 5.4")
list_value[0] = int(with_override * 1000000000 / 200000)
self.__io.set(TSI_DP2RX_CUSTOM_RATE_MAP, list_value, c_uint, 3)
self.__io.set(ci.TSI_DP2RX_CUSTOM_RATE_MAP, list_value, c_uint, 3)
def __get_bitrate_override(self, to_override: float) -> Optional[float]:
if not isinstance(to_override, float):
raise TypeError("DP 128b/132b bitrate override settings must float type!")
override_list = self.__io.get(TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
override_list = self.__io.get(ci.TSI_DP2RX_CUSTOM_RATE_MAP, c_uint, 3)[1]
if override_list.count(0) == len(override_list):
return None
@@ -138,21 +140,21 @@ class LinkDisplayPortCaps:
if edp_aux_preamble is not None:
ctrl.edp_aux_preamble = edp_aux_preamble
self.__io.set(TSI_DPRX_LINK_CONTROL, ctrl.value(), c_uint32)
self.__io.set(ci.TSI_DPRX_LINK_CONTROL, ctrl.value(), c_uint32)
def __get_dp_link_control(self) -> DPRXLinkControl:
return self.__io.get(TSI_DPRX_LINK_CONTROL, DPRXLinkControl)[1]
return self.__io.get(ci.TSI_DPRX_LINK_CONTROL, DPRXLinkControl)[1]
def __set_dp_128_132_bitrates(self, rates: Optional[List[float]]):
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if rates is None:
return
elif isinstance(rates, list) and len(rates) == 0:
flags &= ~(1 << 4)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
else:
flags |= (1 << 4)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
val = 0
if 10.0 in rates:
val |= 0x01
@@ -160,12 +162,12 @@ class LinkDisplayPortCaps:
val |= 0x04
if 20.0 in rates:
val |= 0x02
self.__io.set(TSI_DP2RX_LINK_RATE_CAPS, val, c_int)
self.__io.set(ci.TSI_DP2RX_LINK_RATE_CAPS, val, c_int)
def __get_dp_128_132_bitrates(self) -> Optional[List[float]]:
val = (self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 4) & 0x1
val = (self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 4) & 0x1
if val:
rates = self.__io.get(TSI_DP2RX_LINK_RATE_CAPS)[1]
rates = self.__io.get(ci.TSI_DP2RX_LINK_RATE_CAPS)[1]
list_rates = []
if rates & 0x01:
list_rates.append(10.0)
@@ -181,47 +183,47 @@ class LinkDisplayPortCaps:
if enable is None:
return
val = 0x3C if enable else 0
self.__io.set(TSI_DPRX_HPD_FORCE, val, c_int)
self.__io.set(ci.TSI_DPRX_HPD_FORCE, val, c_int)
def __get_force_cable_status_to_plugged(self) -> bool:
return bool(self.__io.get(TSI_DPRX_HPD_FORCE)[1])
return bool(self.__io.get(ci.TSI_DPRX_HPD_FORCE)[1])
def __set_dsc(self, enable: Optional[bool]):
if enable is None:
return
val = 0x1 if enable else 0x0
if self.__caps.dsc:
self.__io.set(TSI_DPRX_DSC_CONTROL, val, c_int)
self.__io.set(ci.TSI_DPRX_DSC_CONTROL, val, c_int)
def __get_dsc(self) -> Optional[bool]:
if self.__io.get(TSI_DPRX_DSC_STATUS_R)[1] & 0x1:
return bool(self.__io.get(TSI_DPRX_DSC_CONTROL)[1] & 0x1)
if self.__io.get(ci.TSI_DPRX_DSC_STATUS_R)[1] & 0x1:
return bool(self.__io.get(ci.TSI_DPRX_DSC_CONTROL)[1] & 0x1)
def __set_fec(self, enable: Optional[bool]):
if enable is None:
return
val = 0x1 if enable else 0x0
if self.__caps.fec:
self.__io.set(TSI_DPRX_FEC_CONTROL, val, c_int)
self.__io.set(ci.TSI_DPRX_FEC_CONTROL, val, c_int)
def __get_fec(self) -> Optional[bool]:
if self.__caps.fec:
return bool(self.__io.get(TSI_DPRX_FEC_CONTROL)[1] & 0x1)
return bool(self.__io.get(ci.TSI_DPRX_FEC_CONTROL)[1] & 0x1)
def __set_mst(self, enable: Optional[bool]):
if enable is None:
return
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= 1
else:
flags &= ~1
if self.__caps.mst:
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_mst(self) -> Optional[bool]:
if self.__caps.mst:
return bool(self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & 0x1)
return bool(self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & 0x1)
def __set_mst_sink_count(self, count: int):
if count is None:
@@ -230,73 +232,73 @@ class LinkDisplayPortCaps:
if count > self.__caps.mst_stream_count:
warnings.warn(f"Maximum sink count: {self.__caps.mst_stream_count}")
else:
self.__io.set(TSI_DPRX_MST_SINK_COUNT, count, c_uint32)
self.__io.set(ci.TSI_DPRX_MST_SINK_COUNT, count, c_uint32)
else:
warnings.warn("MST or Custom Sink Count are not supported")
def __get_mst_sink_count(self) -> int:
if self.__caps.sink_cnt_config and self.__caps.mst:
return int(self.__io.get(TSI_DPRX_MST_SINK_COUNT)[1])
return int(self.__io.get(ci.TSI_DPRX_MST_SINK_COUNT)[1])
else:
return 0
def __set_tps3(self, enable: Optional[bool]):
if enable is None:
return
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 1)
else:
flags &= ~(1 << 1)
if self.__caps.fec:
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_tps3(self) -> Optional[bool]:
if self.__caps.fec:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 1) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 1) & 0x1)
def __set_tps4(self, enable: Optional[bool]):
if enable is None:
return
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 2)
else:
flags &= ~(1 << 2)
if self.__caps.fec:
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_tps4(self) -> Optional[bool]:
if self.__caps.fec:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 2) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 2) & 0x1)
def __set_ss_sbm(self, enable: bool):
if enable is None:
return
if self.__caps.dp2_support_rates:
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 5)
else:
flags &= ~(1 << 5)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_ss_sbm(self) -> Optional[bool]:
if self.__caps.dp2_support_rates:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 5) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 5) & 0x1)
def __set_edp_support(self, enable: bool):
if self.__caps.edp:
flags = self.__io.get(TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
flags = self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] & ~0xc0
if enable:
flags |= (1 << 3)
else:
flags &= ~(1 << 3)
self.__io.set(TSI_DPRX_LINK_FLAGS, flags, c_int)
self.__io.set(ci.TSI_DPRX_LINK_FLAGS, flags, c_int)
def __get_edp_support(self) -> Optional[bool]:
if self.__caps.edp:
return bool((self.__io.get(TSI_DPRX_LINK_FLAGS)[1] >> 3) & 0x1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_FLAGS)[1] >> 3) & 0x1)
def __set_edp_sel_rates(self, rates: List[float]):
if self.__caps.edp:
@@ -310,11 +312,11 @@ class LinkDisplayPortCaps:
j += 1
rates.sort()
self.__io.set(TSI_DPRX_EDP_SEL_RATES, to_write_list, data_type=c_uint32, data_count=8)
self.__io.set(ci.TSI_DPRX_EDP_SEL_RATES, to_write_list, data_type=c_uint32, data_count=8)
def __get_edp_sel_rates(self) -> List[float]:
if self.__caps.edp:
rates = self.__io.get(TSI_DPRX_EDP_SEL_RATES, data_type=c_uint32, data_count=8)[1]
rates = self.__io.get(ci.TSI_DPRX_EDP_SEL_RATES, data_type=c_uint32, data_count=8)[1]
res_rates = []
for rate in rates:
if rate == 0:
@@ -324,7 +326,7 @@ class LinkDisplayPortCaps:
def __get_edp_caps_rates(self) -> List[float]:
if self.__caps.edp:
rates = self.__io.get(TSI_DPRX_EDP_CAPS_RATES_R, data_type=c_uint32, data_count=32)[1]
rates = self.__io.get(ci.TSI_DPRX_EDP_CAPS_RATES_R, data_type=c_uint32, data_count=32)[1]
new_rates = []
for rate in rates:
if rate > 0:

View File

@@ -1,11 +1,12 @@
import time
import warnings
from ctypes import c_int, c_uint32, c_uint8, c_uint
from typing import Optional
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
from UniTAP.libs.lib_tsi.tsi_types import *
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from UniTAP.utils.function_wrapper import function_scheduler
from .private_link_rx_types import DPRXHWCaps
from .link_status_common import *
@@ -48,7 +49,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of int type
"""
res, value = self.__io.get(TSI_DPRX_MST_STATUS_R, c_uint)
res, value = self.__io.get(p_ci.TSI_DPRX_MST_STATUS_R, c_uint)
return value >> 8
@property
@@ -59,7 +60,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of int type
"""
return self.__io.get(TSI_DPRX_LINK_LANE_COUNT_R, c_int)[1]
return self.__io.get(ci.TSI_DPRX_LINK_LANE_COUNT_R, c_int)[1]
@property
def link_encoding(self) -> DpLinkEncoding:
@@ -69,7 +70,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of `DpLinkEncoding` type
"""
result, value = self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint)
result, value = self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint)
if value >> 20 & 1:
return DpLinkEncoding.LE_128b132b
@@ -84,7 +85,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of float type
"""
current_link_rate = self.__io.get(TSI_DPRX_LINK_BR_R, c_int)[1]
current_link_rate = self.__io.get(ci.TSI_DPRX_LINK_BR_R, c_int)[1]
if self.link_encoding == DpLinkEncoding.LE_8b10b:
return round(current_link_rate * 0.27, 2)
else:
@@ -105,7 +106,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool(self.__io.get(TSI_DPRX_HPD_STATUS_R, c_int)[1] & 1)
return bool(self.__io.get(ci.TSI_DPRX_HPD_STATUS_R, c_int)[1] & 1)
@property
def cable_state(self) -> bool:
@@ -115,7 +116,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool(self.__io.get(TSI_DPRX_HPD_STATUS_R, c_int)[1] & 4)
return bool(self.__io.get(ci.TSI_DPRX_HPD_STATUS_R, c_int)[1] & 4)
@property
def enhanced_framing(self) -> bool:
@@ -125,7 +126,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 17) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 17) & 1)
@property
def scrambling_enabled(self) -> bool:
@@ -135,7 +136,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 18) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 18) & 1)
@property
def dsc_enabled(self) -> Union[bool, None]:
@@ -146,7 +147,7 @@ class LinkDisplayPortStatusSink:
object of bool|None type
"""
if self.__caps.dsc or self.__caps.dsc2:
return bool((self.__io.get(TSI_DPRX_DSC_STATUS_R)[1] >> 1) & 1)
return bool((self.__io.get(ci.TSI_DPRX_DSC_STATUS_R)[1] >> 1) & 1)
else:
return None
@@ -159,7 +160,7 @@ class LinkDisplayPortStatusSink:
object of bool|None type
"""
if self.__caps.fec or self.__caps.fec2:
return bool(self.__io.get(TSI_DPRX_FEC_STATUS_R)[1] & 1)
return bool(self.__io.get(ci.TSI_DPRX_FEC_STATUS_R)[1] & 1)
else:
return None
@@ -172,7 +173,7 @@ class LinkDisplayPortStatusSink:
object of bool|None type
"""
if self.__caps.mst:
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 19) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 19) & 1)
else:
return None
@@ -184,8 +185,8 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool|None type
"""
if (self.__io.get(TSI_DPRX_SSC_STATUS_R, c_int)[1] >> 1) & 1:
return bool(self.__io.get(TSI_DPRX_SSC_STATUS_R, c_int)[1] & 1)
if (self.__io.get(ci.TSI_DPRX_SSC_STATUS_R, c_int)[1] >> 1) & 1:
return bool(self.__io.get(ci.TSI_DPRX_SSC_STATUS_R, c_int)[1] & 1)
else:
return None
@@ -197,7 +198,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 16) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 16) & 1)
@property
def eq_ila(self) -> bool:
@@ -207,7 +208,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 30) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 30) & 1)
@property
def cds_ila(self) -> bool:
@@ -217,7 +218,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 29) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 29) & 1)
@property
def lt_fail(self) -> bool:
@@ -227,7 +228,7 @@ class LinkDisplayPortStatusSink:
Returns:
object of bool type
"""
return bool((self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 28) & 1)
return bool((self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1] >> 28) & 1)
def lane(self, lane_number: int) -> LaneStatus:
"""
@@ -242,10 +243,10 @@ class LinkDisplayPortStatusSink:
if not (0 <= lane_number <= 3):
raise ValueError(f"Incorrect lane number {lane_number}. Available range: 0-{self.lane_count}")
status = self.__io.get(TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1]
voltage_swing = self.__io.get(TSI_DPRX_LINK_VS_R, c_uint32)[1]
pre_emphasis = self.__io.get(TSI_DPRX_LINK_PE_R, c_uint32)[1]
_, error_counters = self.__io.get(TSI_DPRX_GET_ERROR_COUNTS_R, c_uint32 * 4)
status = self.__io.get(ci.TSI_DPRX_LINK_STATUS_FLAGS_R, c_uint32)[1]
voltage_swing = self.__io.get(ci.TSI_DPRX_LINK_VS_R, c_uint32)[1]
pre_emphasis = self.__io.get(ci.TSI_DPRX_LINK_PE_R, c_uint32)[1]
_, error_counters = self.__io.get(ci.TSI_DPRX_GET_ERROR_COUNTS_R, c_uint32 * 4)
lane_status = LaneStatus()
@@ -273,7 +274,7 @@ class LinkDisplayPortStatusSink:
if self.__caps.dp2_support_rates and self.link_encoding == DpLinkEncoding.LE_128b132b:
lane_status.voltage_swing = 0
lane_status.pre_emphasis = 0
_, ffe_preset = self.__io.get(TSI_DP2RX_LINK_FFE_PRESET_R, c_uint32)
_, ffe_preset = self.__io.get(ci.TSI_DP2RX_LINK_FFE_PRESET_R, c_uint32)
lane_status.ffe_preset = (ffe_preset >> (8 * lane_number)) & 0xF
else:
lane_status.voltage_swing = (voltage_swing >> (8 * lane_number)) & 0x3
@@ -297,7 +298,7 @@ class LinkDisplayPortStatusSink:
raise ValueError(f"Selected stream {stream_index} is not available. "
f"Available stream number: {self.mst_stream_count}")
res = self.__io.get(TSI_DPRX_VC_TABLE_R, VCPTable, 4)[1]
res = self.__io.get(ci.TSI_DPRX_VC_TABLE_R, VCPTable, 4)[1]
if self.mst_enabled:
status = VCPStatus()
@@ -316,7 +317,7 @@ class LinkDisplayPortStatusSink:
def __check_video(self) -> bool:
def is_msa_available(io):
result, msa_info, size = io.get(TSI_DPRX_MSA_INFO_R, DpMsa, 4)
result, msa_info, size = io.get(p_ci.TSI_DPRX_MSA_INFO_R, DpMsa, 4)
return size > 0
return function_scheduler(is_msa_available, self.__io, interval=5, timeout=10)
@@ -339,7 +340,7 @@ class LinkDisplayPortStatusSink:
time.sleep(1)
result, msa_info, size = self.__io.get(TSI_DPRX_MSA_INFO_R, DpMsa, 4)
result, msa_info, size = self.__io.get(p_ci.TSI_DPRX_MSA_INFO_R, DpMsa, 4)
if stream_index < size:
msa_info_private = MSAInfo(msa_info[stream_index])
@@ -348,22 +349,22 @@ class LinkDisplayPortStatusSink:
stream_status.mvid = msa_info_private.m_video
stream_status.nvid = msa_info_private.n_video
result = self.__io.get(TSI_DPRX_CRC_LOG_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPRX_CRC_LOG_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and size == 1:
elif result[0] >= ci.TSI_SUCCESS and size == 1:
stream_status.crc = [result[1].r, result[1].g, result[1].b]
result = self.__io.get(TSI_DPRX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPRX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.dsc_crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and size == 1:
elif result[0] >= ci.TSI_SUCCESS and size == 1:
stream_status.dsc_crc = [result[1].r, result[1].g, result[1].b]
if self.__caps.dp2_support_rates:
res = self.__io.get(TSI_DPRX_SDP_CRC16_CTRL, c_uint32)
stream_status.sdp_crc16.state = False if res[0] < TSI_SUCCESS else (res[1] & 0x1 == 1)
stream_status.sdp_crc16.errors = self.__io.get(TSI_DPRX_SDP_CRC16_COUNTERS, c_uint8,
res = self.__io.get(p_ci.TSI_DPRX_SDP_CRC16_CTRL, c_uint32)
stream_status.sdp_crc16.state = False if res[0] < ci.TSI_SUCCESS else (res[1] & 0x1 == 1)
stream_status.sdp_crc16.errors = self.__io.get(p_ci.TSI_DPRX_SDP_CRC16_COUNTERS, c_uint8,
self.__caps.mst_stream_count)[1][stream_index]
else:
raise ValueError(f"Selected stream {stream_index} is not available. "
@@ -378,7 +379,7 @@ class LinkDisplayPortStatusSink:
if not self.__caps.dp2_support_rates:
warnings.warn("SDP CRC16 is not supported. Cannot reset errors.")
return
self.__io.set(TSI_DPRX_SDP_CRC16_COUNTERS, 0)
self.__io.set(p_ci.TSI_DPRX_SDP_CRC16_COUNTERS, 0)
def __str__(self) -> str:
lane_status_str = ""

View File

@@ -78,6 +78,7 @@ class RoutedLTConfig:
def __init__(self):
self.__is128b132b = False
self.__is_old_dp20_lt = False
self.__is_edp_lt = False
self.__vs = 0
self.__pe = 0
self.__ffe = 0
@@ -100,13 +101,21 @@ class RoutedLTConfig:
def is_old_dp20_lt(self, value: bool = False):
self.__is_old_dp20_lt = value
@property
def is_edp_lt(self) -> bool:
return self.__is_edp_lt
@is_edp_lt.setter
def is_edp_lt(self, value: bool = False):
self.__is_edp_lt = value
@property
def vs(self) -> int:
return self.__vs
@vs.setter
def vs(self, value: int):
if not (0 <= value < 3):
if not (0 <= value <= 0x3):
raise ValueError(f"VS cannot be less than 0 and more than 3")
self.__vs = value
@@ -136,8 +145,8 @@ class RoutedLTConfig:
@link_bw.setter
def link_bw(self, value: int):
if not (0 <= value <= 0xFF):
raise ValueError(f"link_bw cannot be less than 0 and more than 0xFF")
if not (0 <= value <= 0xFFFF):
raise ValueError(f"link_bw cannot be less than 0 and more than 0xFFFF")
self.__link_bw = value
@property
@@ -151,8 +160,9 @@ class RoutedLTConfig:
self.__lane_count = value
def int_value(self) -> int:
val = (self.ffe << 8) if self.is128b132b else ((self.vs << 8) | (self.pe << 10))
return self.is128b132b | (self.__is_old_dp20_lt << 1) | val | (self.link_bw << 16) | (self.lane_count << 24)
val = (self.ffe << 4) if self.is128b132b else ((self.vs << 4) | (self.pe << 6))
return self.is128b132b | (self.__is_old_dp20_lt << 1) | (self.__is_edp_lt << 2) | val | \
(self.lane_count << 8) | (self.link_bw << 16)
class RoutedLTStatus:

View File

@@ -1,8 +1,12 @@
import warnings
from ctypes import c_uint, c_uint8
from typing import List
from warnings import warn
from UniTAP.libs.lib_tsi import *
from UniTAP.dev.ports.modules.link.dp.link_status_common import DpLinkTrainingResult
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from UniTAP.utils.function_wrapper import *
from .link_tx_status import LinkDisplayPortStatusSource
from .link_tx_config import LinkDisplayPortConfig
@@ -34,7 +38,7 @@ class LinkDisplayPortTx:
self.__status = LinkDisplayPortStatusSource(self.__io, self.__HW_CAPS, dpcd)
self.__config = LinkDisplayPortConfig(self.__io, self.__HW_CAPS)
self.__force_config = LinkDisplayPortForceConfig(self.__io, self.__HW_CAPS)
self.__cable_info = DpCableInfo(port_io, TSI_DPTX_CABLE_ATTRIBUTES_R)
self.__cable_info = DpCableInfo(port_io, p_ci.TSI_DPTX_CABLE_ATTRIBUTES_R)
@property
def status(self) -> LinkDisplayPortStatusSource:
@@ -86,7 +90,7 @@ class LinkDisplayPortTx:
def is_link_training_success(link: LinkDisplayPortTx):
return link.last_lt_result() == DpLinkTrainingResult.LTR_SUCCESS
self.__io.set(TSI_W_DPTX_COMMAND, 1, c_uint32)
self.__io.set(ci.TSI_W_DPTX_COMMAND, 1, c_uint32)
return function_scheduler(is_link_training_success, self, interval=0.1, timeout=5)
@@ -97,7 +101,7 @@ class LinkDisplayPortTx:
Returns:
object of `DpLinkTrainingResult` type
"""
_, value = self.__io.get(TSI_DPTX_LT_RESULT_R, c_uint)
_, value = self.__io.get(ci.TSI_DPTX_LT_RESULT_R, c_uint)
return DpLinkTrainingResult(value)
@property
@@ -112,7 +116,7 @@ class LinkDisplayPortTx:
warnings.warn("Scrambler Seed is not supported.")
return 0
return self.__io.get(TSI_DPTX_SCR_SEED, c_uint32)[1]
return self.__io.get(ci.TSI_DPTX_SCR_SEED, c_uint32)[1]
@scrambler_seed.setter
def scrambler_seed(self, value: int = 0):
@@ -126,7 +130,7 @@ class LinkDisplayPortTx:
warnings.warn("Scrambler Seed is not supported.")
return
if self.config._read_lt_features().auto_seed is not None and not self.config._read_lt_features().auto_seed:
self.__io.set(TSI_DPTX_SCR_SEED, value, c_uint32)
self.__io.set(ci.TSI_DPTX_SCR_SEED, value, c_uint32)
else:
warnings.warn("AutoSeed has already enabled. Transferred value will not be written")
@@ -160,7 +164,7 @@ class LinkDisplayPortTx:
old_value = self.__get_override_voltage()
old_value &= ~(3 << (stream_index * 8))
old_value |= (value << (stream_index * 8))
self.__io.set(TSI_DPTX_OVERRIDE_VOLTAGE_SWING, old_value, c_uint32)
self.__io.set(ci.TSI_DPTX_OVERRIDE_VOLTAGE_SWING, old_value, c_uint32)
def get_override_pre_emp(self, stream_index: int) -> int:
"""
@@ -192,7 +196,7 @@ class LinkDisplayPortTx:
old_value = self.__get_override_pre_emp()
old_value &= ~(3 << (stream_index * 8))
old_value |= (value << (stream_index * 8))
self.__io.set(TSI_DPTX_OVERRIDE_PRE_EMPHASIS, old_value, c_uint32)
self.__io.set(ci.TSI_DPTX_OVERRIDE_PRE_EMPHASIS, old_value, c_uint32)
@property
def override_ffe_presets(self) -> list:
@@ -205,7 +209,7 @@ class LinkDisplayPortTx:
if not self.__HW_CAPS.dp2_custom_rates:
warnings.warn("FFE presets does not support.")
return []
return self.__io.get(TSI_DP2TX_OUT_FFE, c_uint8, 4)[1]
return self.__io.get(ci.TSI_DP2TX_OUT_FFE, c_uint8, 4)[1]
@override_ffe_presets.setter
def override_ffe_presets(self, value: List[int]):
@@ -219,13 +223,13 @@ class LinkDisplayPortTx:
warnings.warn("FFE presets does not support.")
return
new_value = value[0] | (value[0] << 8) | (value[0] << 16) | (value[0] << 32)
self.__io.set(TSI_DP2TX_OUT_FFE, new_value)
self.__io.set(ci.TSI_DP2TX_OUT_FFE, new_value)
def __get_override_voltage(self) -> int:
return self.__io.get(TSI_DPTX_OVERRIDE_VOLTAGE_SWING, c_uint32)[1]
return self.__io.get(ci.TSI_DPTX_OVERRIDE_VOLTAGE_SWING, c_uint32)[1]
def __get_override_pre_emp(self) -> int:
return self.__io.get(TSI_DPTX_OVERRIDE_PRE_EMPHASIS, c_uint32)[1]
return self.__io.get(ci.TSI_DPTX_OVERRIDE_PRE_EMPHASIS, c_uint32)[1]
@property
def link_pattern(self) -> DPLinkPattern:
@@ -235,7 +239,7 @@ class LinkDisplayPortTx:
Returns:
object of `DPLinkPattern` type
"""
return DPLinkPattern(self.__io.get(TSI_DPTX_OUTPUT_PATTERN, c_uint32)[1])
return DPLinkPattern(self.__io.get(ci.TSI_DPTX_OUTPUT_PATTERN, c_uint32)[1])
def set_link_pattern(self, pattern: DPLinkPattern, additional_param: int = 1):
"""
@@ -247,16 +251,16 @@ class LinkDisplayPortTx:
"""
if not self.__HW_CAPS.dp2_custom_rates and pattern not in [e.value for e in DPLinkPattern]:
raise ValueError(f"Current pattern {pattern.name} is not supported")
self.__io.set(TSI_DPTX_OUTPUT_PATTERN, pattern.value, c_uint32)
self.__io.set(ci.TSI_DPTX_OUTPUT_PATTERN, pattern.value, c_uint32)
if pattern == DPLinkPattern.LinkSquarePattern:
self.__io.set(TSI_DPTX_SQUARE_PATTERN_NUMBER, additional_param, c_uint32)
self.__io.set(ci.TSI_DPTX_SQUARE_PATTERN_NUMBER, additional_param, c_uint32)
def set_force_link_mode(self, link_mode: DPOutLinkMode):
self.__io.set(TSI_DPTX_OUT_LINK_MODE, link_mode.value, c_uint32)
self.__io.set(p_ci.TSI_DPTX_OUT_LINK_MODE, link_mode.value, c_uint32)
def get_force_link_mode(self) -> DPOutLinkMode:
return DPOutLinkMode(self.__io.get(TSI_DPTX_OUT_LINK_MODE, c_uint32)[1])
return DPOutLinkMode(self.__io.get(p_ci.TSI_DPTX_OUT_LINK_MODE, c_uint32)[1])
def cable_rx_type(self) -> CableCapabilitiesEnum:
"""

View File

@@ -1,6 +1,9 @@
from typing import Optional, Union, Type
from ctypes import c_uint, c_int
from typing import Optional, Union, Type, List
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from .link_tx_types import *
from .private_link_tx_types import *
from .link_status_common import *
@@ -123,10 +126,10 @@ class LinkDisplayPortConfig:
return link_status
def _read_lt_features(self) -> LTFeatures:
return self.__io.get(TSI_DPTX_LT_FEATURES, LTFeatures)[1]
return self.__io.get(ci.TSI_DPTX_LT_FEATURES, LTFeatures)[1]
def __get_post_lt_features(self) -> PostLtFeatures:
return self.__io.get(TSI_DPTX_POST_LT_FEATURES, PostLtFeatures)[1]
return self.__io.get(p_ci.TSI_DPTX_POST_LT_FEATURES, PostLtFeatures)[1]
def __set_post_lt_features(self, config: DisplayPortLinkConfig):
post_lt_features = self.__get_post_lt_features()
@@ -134,10 +137,10 @@ class LinkDisplayPortConfig:
post_lt_features.force_edid_timings = config.force_edid_timings_after_lt
if config.adaptive_sync_auto_enable is not None and self.__caps.adaptive_sync:
post_lt_features.as_auto_enable = config.adaptive_sync_auto_enable
self.__io.set(TSI_DPTX_POST_LT_FEATURES, post_lt_features.value(), c_uint32)
self.__io.set(p_ci.TSI_DPTX_POST_LT_FEATURES, post_lt_features.value(), c_uint32)
def __get_dp2_custom_rates(self) -> list:
rates = self.__io.get(TSI_DP2TX_CUSTOM_RATE_CAPS_R, c_uint32, 32)[1]
rates = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_CAPS_R, c_uint32, 32)[1]
custom_rates = []
for i in range(len(rates)):
custom_rates.append(float(rates[i]) * 200000 / 1000000000)
@@ -149,20 +152,20 @@ class LinkDisplayPortConfig:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DPTX_LINK_CFG_LANES, lane_count, c_uint32)
self.__io.set(ci.TSI_DPTX_LINK_CFG_LANES, lane_count, c_uint32)
def __get_lane_count_dp14(self) -> int:
return self.__io.get(TSI_DPTX_LINK_CFG_LANES)[1]
return self.__io.get(ci.TSI_DPTX_LINK_CFG_LANES)[1]
def __set_lane_count_dp21(self, lane_count: Optional[int]):
if lane_count is None:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DP2TX_LT_SLC, lane_count, c_uint32)
self.__io.set(ci.TSI_DP2TX_LT_SLC, lane_count, c_uint32)
def __get_lane_count_dp21(self) -> int:
return self.__io.get(TSI_DP2TX_LT_SLC)[1]
return self.__io.get(ci.TSI_DP2TX_LT_SLC)[1]
def __set_bit_rate_14(self, bit_rate: Optional[float]):
if bit_rate is None:
@@ -170,10 +173,10 @@ class LinkDisplayPortConfig:
if int(round(bit_rate / 0.27)) > self.__caps.max_link_rate:
raise ValueError(f"Following 8b/10b bit rate {bit_rate} is not supported on device. "
f"Max supported link rate {round(self.__caps.max_link_rate * 0.27, 2)}")
self.__io.set(TSI_DPTX_LINK_CFG_BIT_RATE, int(round(bit_rate / 0.27)), c_uint32)
self.__io.set(ci.TSI_DPTX_LINK_CFG_BIT_RATE, int(round(bit_rate / 0.27)), c_uint32)
def __get_bit_rate_14(self) -> float:
return round(self.__io.get(TSI_DPTX_LINK_CFG_BIT_RATE)[1] * 0.27, 2)
return round(self.__io.get(ci.TSI_DPTX_LINK_CFG_BIT_RATE)[1] * 0.27, 2)
def __set_bit_rate_21(self, bit_rate: Optional[Union[float, int]]):
if bit_rate is None:
@@ -182,42 +185,42 @@ class LinkDisplayPortConfig:
if not self.__caps.support_10gbps:
raise ValueError(f"Following bit rate {bit_rate} is not supported on device.")
else:
res = self.__io.get(TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
self.__io.set(TSI_DP2TX_CUSTOM_RATE_MAP, (int(bit_rate * 1000000000 / 200000), res[1], res[2]),
res = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
self.__io.set(ci.TSI_DP2TX_CUSTOM_RATE_MAP, (int(bit_rate * 1000000000 / 200000), res[1], res[2]),
c_uint32, 3)
elif (bit_rate == 10.0 and not self.__caps.support_10gbps) or \
(bit_rate == 13.5 and not self.__caps.support_13_5gbps) or \
(bit_rate == 20.0 and not self.__caps.support_20gbps):
raise ValueError(f"Following bit rate {bit_rate} is not supported on device.")
self.__io.set(TSI_DP2TX_LT_SBR, DP21_LinkRateRev.get(bit_rate), c_uint32)
self.__io.set(ci.TSI_DP2TX_LT_SBR, DP21_LinkRateRev.get(bit_rate), c_uint32)
def __get_bit_rate_21(self) -> float:
return DP21_LinkRate.get(self.__io.get(TSI_DP2TX_LT_SBR)[1])
return DP21_LinkRate.get(self.__io.get(ci.TSI_DP2TX_LT_SBR)[1])
def __support_ssc(self) -> bool:
return (self.__io.get(TSI_DPTX_DOWNSPREAD_STATUS_R, c_uint32)[1] >> 1) & 1 != 0
return (self.__io.get(ci.TSI_DPTX_DOWNSPREAD_STATUS_R, c_uint32)[1] >> 1) & 1 != 0
def __set_config_ssc(self, ssc_conf: Optional[SSCConfig]):
if ssc_conf is None:
return
if not self.__support_ssc():
raise ValueError(f"SSC is not supported on the device.")
self.__io.set(TSI_DPTX_DOWNSPREAD_CONTROL, int(ssc_conf.enabled), c_uint32)
self.__io.set(ci.TSI_DPTX_DOWNSPREAD_CONTROL, int(ssc_conf.enabled), c_uint32)
if ssc_conf.enabled:
if not (1 <= ssc_conf.amplitude <= 50):
raise ValueError(f"Incorrect amplitude value {ssc_conf.amplitude}. Must be from range: 0.1 - 0.5")
self.__io.set(TSI_DPTX_DOWNSPREAD_AMP, ssc_conf.amplitude, c_uint32)
self.__io.set(ci.TSI_DPTX_DOWNSPREAD_AMP, ssc_conf.amplitude, c_uint32)
if not (30000 <= ssc_conf.frequency <= 63000):
raise ValueError(f"Incorrect frequency value {ssc_conf.frequency}. Must be from range: 30000 - 63000")
self.__io.set(TSI_DPTX_DOWNSPREAD_FREQ, ssc_conf.frequency, c_uint32)
self.__io.set(ci.TSI_DPTX_DOWNSPREAD_FREQ, ssc_conf.frequency, c_uint32)
def __get_config_ssc(self) -> SSCConfig:
if not self.__support_ssc():
return None
ssc_conf = SSCConfig()
ssc_conf.enabled = (self.__io.get(TSI_DPTX_DOWNSPREAD_STATUS_R)[1] & 1) != 0
ssc_conf.frequency = self.__io.get(TSI_DPTX_DOWNSPREAD_FREQ)[1]
ssc_conf.amplitude = self.__io.get(TSI_DPTX_DOWNSPREAD_AMP)[1]
ssc_conf.enabled = (self.__io.get(ci.TSI_DPTX_DOWNSPREAD_STATUS_R)[1] & 1) != 0
ssc_conf.frequency = self.__io.get(ci.TSI_DPTX_DOWNSPREAD_FREQ)[1]
ssc_conf.amplitude = self.__io.get(ci.TSI_DPTX_DOWNSPREAD_AMP)[1]
return ssc_conf
def __dp2_support_rates(self) -> bool:
@@ -228,7 +231,7 @@ class LinkDisplayPortConfig:
return
if not self.__dp2_support_rates():
raise ValueError(f"LTTPR is not supported on the device.")
self.__io.set(TSI_DPTX_LTTPR_CONTROL, int(enable))
self.__io.set(ci.TSI_DPTX_LTTPR_CONTROL, int(enable))
def __set_lt_features(self, config: Optional[DisplayPortLinkConfig]):
if config is None:
@@ -270,22 +273,22 @@ class LinkDisplayPortConfig:
else:
raise TypeError("Incorrect DisplayPortLinkConfig format!")
self.__io.set(TSI_DPTX_LT_FEATURES, res.value(), c_uint32)
self.__io.set(ci.TSI_DPTX_LT_FEATURES, res.value(), c_uint32)
def __enable_mst(self, enable: Optional[bool]):
if enable is None:
return
self.__io.set(TSI_DPTX_COMMAND_W, 3 if enable else 4, c_uint32)
self.__io.set(ci.TSI_DPTX_COMMAND_W, 3 if enable else 4, c_uint32)
def __set_mst_channel_count(self, count: Optional[int]):
if count is None:
return
if not (0 <= count <= self.__caps.mst_stream_count):
raise ValueError(f"Incorrect stream count {count}. Available stream count {self.__caps.mst_stream_count}")
self.__io.set(TSI_PG_ENABLED_STREAM_COUNT, count, c_uint32)
self.__io.set(ci.TSI_PG_ENABLED_STREAM_COUNT, count, c_uint32)
def __link_encoding(self) -> DpLinkEncoding:
result, value = self.__io.get(TSI_DPTX_LINK_MODE_R, c_uint)
result, value = self.__io.get(ci.TSI_DPTX_LINK_MODE_R, c_uint)
if value == 0:
return DpLinkEncoding.LE_8b10b
@@ -293,36 +296,36 @@ class LinkDisplayPortConfig:
return DpLinkEncoding.LE_128b132b
def __mst_enabled(self) -> bool:
return (self.__io.get(TSI_DPTX_LINK_STATUS_BITS_R)[1] & (1 << 30)) != 0
return (self.__io.get(ci.TSI_DPTX_LINK_STATUS_BITS_R)[1] & (1 << 30)) != 0
def __mst_stream_count(self) -> int:
result, mst_status = self.__io.get(TSI_DPTX_MST_STATUS_R, c_uint)
result, mst_status = self.__io.get(ci.TSI_DPTX_MST_STATUS_R, c_uint)
return (mst_status >> 8) & 0xFF
def __lttpr_active(self) -> Optional[bool]:
if self.__link_encoding == DpLinkEncoding.LE_128b132b:
return (self.__io.get(TSI_DPTX_LTTPR_CONTROL, c_uint32)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_LTTPR_CONTROL, c_uint32)[1] & 1) != 0
else:
return None
def __check_custom_bit_rate(self) -> float:
res = self.__io.get(TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
res = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
for i in range(3):
if res[i] != 0:
return res[i] * 200000 / 1000000000
return 0
def __try_fec_after_lt(self, enable: bool):
result = self.__io.get(TSI_DPTX_FEC_CTRL, c_int)
result = self.__io.get(ci.TSI_DPTX_FEC_CTRL, c_int)
val = result[1]
if enable:
val |= 0x2
else:
val &= ~0x2
self.__io.set(TSI_DPTX_FEC_CTRL, val)
self.__io.set(ci.TSI_DPTX_FEC_CTRL, val)
def __fec_after_lt_state(self) -> bool:
return (self.__io.get(TSI_DPTX_FEC_CTRL, c_int)[1] & 0x2) != 0
return (self.__io.get(ci.TSI_DPTX_FEC_CTRL, c_int)[1] & 0x2) != 0
def __sdp_control(self, config: Optional[DisplayPortLinkConfig]):
if config is None:
@@ -335,24 +338,24 @@ class LinkDisplayPortConfig:
self.__write_sdp_control(sdp_control)
def __write_sdp_control(self, sdp_control: SdpControl):
self.__io.set(TSI_DPTX_SDP_CTRL, sdp_control.value())
self.__io.set(p_ci.TSI_DPTX_SDP_CTRL, sdp_control.value())
def __read_sdp_control(self) -> SdpControl:
return self.__io.get(TSI_DPTX_SDP_CTRL, SdpControl)[1]
return self.__io.get(p_ci.TSI_DPTX_SDP_CTRL, SdpControl)[1]
def __set_edp_sel_rate(self, rate: float):
if self.__caps.edp and rate in self.__get_edp_caps_rates():
self.__io.set(TSI_DPTX_EDP_LT_SBR, int(rate / 0.0002), c_uint32)
self.__io.set(ci.TSI_DPTX_EDP_LT_SBR, int(rate / 0.0002), c_uint32)
elif not self.__caps.edp:
raise ValueError("EDP is not supported.")
def __get_edp_sel_rate(self) -> int:
if self.__caps.edp:
return self.__io.get(TSI_DPTX_EDP_LT_SBR)[1] * 0.0002
return self.__io.get(ci.TSI_DPTX_EDP_LT_SBR)[1] * 0.0002
def __get_edp_caps_rates(self) -> List[float]:
if self.__caps.edp:
rates = self.__io.get(TSI_DPTX_EXTRA_DP14_RATES, data_type=c_uint32, data_count=8)[1]
rates = self.__io.get(ci.TSI_DPTX_EXTRA_DP14_RATES, data_type=c_uint32, data_count=8)[1]
new_rates = []
for rate in rates:
if rate > 0:

View File

@@ -1,6 +1,6 @@
from typing import Optional, Union, Type
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from .link_tx_types import *
from .private_link_tx_types import *
from .link_status_common import *
@@ -62,25 +62,25 @@ class LinkDisplayPortForceConfig:
(bit_rate == 13.5 and not self.__caps.support_13_5gbps) or \
(bit_rate == 20.0 and not self.__caps.support_20gbps):
raise ValueError(f"Following bit rate {bit_rate} is not supported on device.")
self.__io.set(TSI_DP2TX_OUT_BR, DP21_LinkRateRev.get(bit_rate), c_uint32)
self.__io.set(p_ci.TSI_DP2TX_OUT_BR, DP21_LinkRateRev.get(bit_rate), c_uint32)
def __force_get_bit_rate(self) -> float:
return DP21_LinkRate.get(self.__io.get(TSI_DP2TX_OUT_BR)[1])
return DP21_LinkRate.get(self.__io.get(p_ci.TSI_DP2TX_OUT_BR)[1])
def __force_set_lane_count(self, lane_count: Optional[int]):
if lane_count is None:
return
if lane_count not in [1, 2, 4]:
raise ValueError(f"Incorrect lane count number {lane_count}. Must be from list: 1, 2, 4")
self.__io.set(TSI_DP2TX_OUT_LC, lane_count, c_uint32)
self.__io.set(p_ci.TSI_DP2TX_OUT_LC, lane_count, c_uint32)
def __force_get_lane_count(self) -> int:
return self.__io.get(TSI_DP2TX_OUT_LC)[1]
return self.__io.get(p_ci.TSI_DP2TX_OUT_LC)[1]
def __force_set_pattern(self, pattern: Optional[DP128b132bLinkPattern]):
if pattern is None:
return
self.__io.set(TSI_DP2TX_OUT_TEST_PATTERN, pattern.value, c_uint32)
self.__io.set(p_ci.TSI_DP2TX_OUT_TEST_PATTERN, pattern.value, c_uint32)
def __force_get_pattern(self) -> DP128b132bLinkPattern:
return DP128b132bLinkPattern(self.__io.get(TSI_DP2TX_OUT_TEST_PATTERN, c_uint32)[1])
return DP128b132bLinkPattern(self.__io.get(p_ci.TSI_DP2TX_OUT_TEST_PATTERN, c_uint32)[1])

View File

@@ -2,8 +2,7 @@ import warnings
from typing import Optional
from UniTAP.libs.lib_tsi import PortIO
from UniTAP.libs.lib_tsi.tsi_types import *
from .link_tx_types import *
import UniTAP.libs.lib_tsi.tsi_types as ci
from .private_link_tx_types import *
from .link_status_common import *
from .private_link_status_common import *
@@ -47,7 +46,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of int type
"""
result, mst_status = self.__io.get(TSI_DPTX_MST_STATUS_R, c_uint)
result, mst_status = self.__io.get(ci.TSI_DPTX_MST_STATUS_R, c_uint)
return (mst_status >> 8) & 0xFF
@property
@@ -58,7 +57,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of DpLinkEncoding type
"""
result, value = self.__io.get(TSI_DPTX_LINK_MODE_R, c_uint)
result, value = self.__io.get(ci.TSI_DPTX_LINK_MODE_R, c_uint)
if value == 0:
return DpLinkEncoding.LE_8b10b
@@ -77,9 +76,9 @@ class LinkDisplayPortStatusSource:
if self.__check_custom_bit_rate() != 0:
return self.__check_custom_bit_rate()
else:
return DP21_LinkRate.get(self.__io.get(TSI_DP2TX_LT_RATE_R, c_uint)[1])
return DP21_LinkRate.get(self.__io.get(ci.TSI_DP2TX_LT_RATE_R, c_uint)[1])
else:
return round(self.__io.get(TSI_DPTX_LINK_RATE_R, c_uint)[1] * 0.27, 2)
return round(self.__io.get(ci.TSI_DPTX_LINK_RATE_R, c_uint)[1] * 0.27, 2)
@property
def lane_count(self) -> int:
@@ -89,7 +88,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of int type
"""
return self.__io.get(TSI_DPTX_LINK_LANE_COUNT_R, c_int)[1]
return self.__io.get(ci.TSI_DPTX_LINK_LANE_COUNT_R, c_int)[1]
@property
def hpd_asserted(self) -> bool:
@@ -99,7 +98,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of bool type
"""
return (self.__io.get(TSI_DPTX_HPD_STATUS_R, c_int)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_HPD_STATUS_R, c_int)[1] & 1) != 0
@property
def available_link_rate(self) -> float:
@@ -142,8 +141,8 @@ class LinkDisplayPortStatusSource:
raise ValueError(f"Incorrect lane number {lane_number}. Available range: 0-{self.lane_count}")
status = self.__read_link_status()
voltage_swing = self.__io.get(TSI_DPTX_LINK_VOLTAGE_SWING_R, LinkVoltageSwing)[1]
pre_emphasis = self.__io.get(TSI_DPTX_LINK_PRE_EMPHASIS_R, LinkPreEmphasis)[1]
voltage_swing = self.__io.get(ci.TSI_DPTX_LINK_VOLTAGE_SWING_R, LinkVoltageSwing)[1]
pre_emphasis = self.__io.get(ci.TSI_DPTX_LINK_PRE_EMPHASIS_R, LinkPreEmphasis)[1]
error_counters = self.__dpcd.read(0x210, 8).data
lane_status = LaneStatus()
@@ -178,7 +177,7 @@ class LinkDisplayPortStatusSource:
lane_status.error_count = error_counters[6] | ((error_counters[7] & 0x7F) << 8)
if self.link_encoding == DpLinkEncoding.LE_128b132b:
ffe_preset = self.__io.get(TSI_DP2TX_LT_FFE_PRESET_R, c_uint32)[1]
ffe_preset = self.__io.get(ci.TSI_DP2TX_LT_FFE_PRESET_R, c_uint32)[1]
lane_status.ffe_preset = (ffe_preset >> (8 * lane_number)) & 0xFF
else:
lane_status.ffe_preset = 0
@@ -195,7 +194,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.__caps.dsc or self.__caps.dsc2:
return (self.__io.get(TSI_DPTX_DSC_STATUS_R)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_DSC_STATUS_R)[1] & 1) != 0
else:
return None
@@ -209,7 +208,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.__caps.mst:
return (self.__io.get(TSI_DPTX_MST_STATUS_R, c_uint32)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_MST_STATUS_R, c_uint32)[1] & 1) != 0
else:
return None
@@ -222,7 +221,7 @@ class LinkDisplayPortStatusSource:
Returns:
object of bool or None type
"""
res = self.__io.get(TSI_DPTX_DOWNSPREAD_STATUS_R)[1]
res = self.__io.get(ci.TSI_DPTX_DOWNSPREAD_STATUS_R)[1]
if ((res >> 1) & 1) != 0:
return (res & 1) != 0
else:
@@ -238,7 +237,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.__caps.fec or self.__caps.fec2:
return (self.__io.get(TSI_DPTX_FEC_STATUS_R)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_FEC_STATUS_R)[1] & 1) != 0
else:
return None
@@ -272,7 +271,7 @@ class LinkDisplayPortStatusSource:
object of bool or None type
"""
if self.link_encoding == DpLinkEncoding.LE_128b132b:
return (self.__io.get(TSI_DPTX_LTTPR_STATUS_R, c_uint32)[1] & 1) != 0
return (self.__io.get(ci.TSI_DPTX_LTTPR_STATUS_R, c_uint32)[1] & 1) != 0
else:
return None
@@ -327,7 +326,7 @@ class LinkDisplayPortStatusSource:
object of `StreamStatusDP` type
"""
stream_status = StreamStatusDP()
result, msa_info, size = self.__io.get(TSI_DPTX_MSA_INFO_R, DpMsa, 4)
result, msa_info, size = self.__io.get(ci.TSI_DPTX_MSA_INFO_R, DpMsa, 4)
if stream_index < size:
msa_info_private = MSAInfo(msa_info[stream_index])
@@ -336,16 +335,16 @@ class LinkDisplayPortStatusSource:
stream_status.mvid = msa_info_private.m_video
stream_status.nvid = msa_info_private.n_video
result = self.__io.get(TSI_DPTX_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPTX_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and self.mst_stream_count == 1:
elif result[0] >= ci.TSI_SUCCESS and self.mst_stream_count == 1:
stream_status.crc = [result[1].r, result[1].g, result[1].b]
result = self.__io.get(TSI_DPTX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= TSI_SUCCESS and self.mst_stream_count > 1:
result = self.__io.get(ci.TSI_DPTX_DSC_CRC_R, DpCrc, self.mst_stream_count)
if result[0] >= ci.TSI_SUCCESS and self.mst_stream_count > 1:
stream_status.dsc_crc = [result[1][stream_index].r, result[1][stream_index].g, result[1][stream_index].b]
elif result[0] >= TSI_SUCCESS and self.mst_stream_count == 1:
elif result[0] >= ci.TSI_SUCCESS and self.mst_stream_count == 1:
stream_status.dsc_crc = [result[1].r, result[1].g, result[1].b]
else:
raise ValueError(f"Selected stream {stream_index} is not available. "
@@ -368,7 +367,7 @@ class LinkDisplayPortStatusSource:
raise ValueError(f"Selected stream {stream_index} is not available. "
f"Available stream number: {self.mst_stream_count}")
res = self.__io.get(TSI_DPTX_VCP_TABLE_R, VCPTable, 4)[1]
res = self.__io.get(ci.TSI_DPTX_VCP_TABLE_R, VCPTable, 4)[1]
if self.mst_enabled:
status = VCPStatus()
@@ -389,16 +388,16 @@ class LinkDisplayPortStatusSource:
"""
Send ACT command.
"""
self.__io.set(TSI_DPTX_MST_COMMAND_W, 1, c_uint32)
self.__io.set(ci.TSI_DPTX_MST_COMMAND_W, 1, c_uint32)
def __read_lt_features(self) -> LTFeatures:
return self.__io.get(TSI_DPTX_LT_FEATURES, LTFeatures)[1]
return self.__io.get(ci.TSI_DPTX_LT_FEATURES, LTFeatures)[1]
def __read_link_status(self) -> LinkTxStatus:
return self.__io.get(TSI_DPTX_LINK_STATUS_R, LinkTxStatus)[1]
return self.__io.get(ci.TSI_DPTX_LINK_STATUS_R, LinkTxStatus)[1]
def __check_custom_bit_rate(self) -> float:
res = self.__io.get(TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
res = self.__io.get(ci.TSI_DP2TX_CUSTOM_RATE_MAP, c_uint32, 3)[1]
for i in range(3):
if res[i] != 0:
return res[i] * 200000 / 1000000000

View File

@@ -1,6 +1,6 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from enum import IntEnum
from UniTAP.libs.lib_tsi.tsi_types import TSI_ARC_CONTROL_W, TSI_HDRX_ARC_STATUS_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from ctypes import c_uint32
@@ -44,10 +44,10 @@ class ArcRx:
self.__single_mode = True
def __read_arc_status(self) -> int:
return self.__io.get(TSI_HDRX_ARC_STATUS_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_ARC_STATUS_R, c_uint32)[1]
def __write_arc(self, value: int):
self.__io.set(TSI_ARC_CONTROL_W, value, c_uint32)
self.__io.set(ci.TSI_ARC_CONTROL_W, value, c_uint32)
@property
def supported(self) -> bool:

View File

@@ -1,6 +1,6 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .types import FrlMode, LtpLanesPattern, FrlCaps, LtpPattern, _update_frl_values, _update_ltp_pattern_values
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDRX_FRL_CAPABILITY, TSI_HDRX_FRL_PATTERN, TSI_HDRX_LINK_STATUS_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from ctypes import c_uint32
@@ -19,16 +19,16 @@ class FrlControlRx:
self.__ltp_additional = LtpLanesPattern()
def __read_caps(self) -> int:
return self.__io.get(TSI_HDRX_FRL_CAPABILITY, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_FRL_CAPABILITY, c_uint32)[1]
def __write_caps(self, value: int):
self.__io.set(TSI_HDRX_FRL_CAPABILITY, value, c_uint32)
self.__io.set(ci.TSI_HDRX_FRL_CAPABILITY, value, c_uint32)
def __read_frl_pattern(self) -> int:
return self.__io.get(TSI_HDRX_FRL_PATTERN, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_FRL_PATTERN, c_uint32)[1]
def __write_frl_pattern(self, value: int):
self.__io.set(TSI_HDRX_FRL_PATTERN, value, c_uint32)
self.__io.set(ci.TSI_HDRX_FRL_PATTERN, value, c_uint32)
@property
def frl_mode(self) -> FrlMode:
@@ -130,7 +130,7 @@ class FrlControlRx:
"""
DO re train.
"""
self.__io.set(TSI_HDRX_LINK_STATUS_R, 0x1c0000, c_uint32)
self.__io.set(ci.TSI_HDRX_LINK_STATUS_R, 0x1c0000, c_uint32)
def __str__(self):
return f"FRL Mode: {self.frl_mode.name}\n" \

View File

@@ -1,7 +1,6 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .types import FrlMode, LtpLanesPattern, FrlCaps, _update_frl_values, _update_ltp_pattern_values
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDTX_FRL_CAPABILITY, TSI_HDTX_FRL_PATTERN_R, TSI_HDTX_FRL_TIMERS, \
TSI_HDTX_SINK_FEATURE_W, TSI_HDTX_FRL_STATUS_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from ctypes import c_uint32
@@ -197,19 +196,19 @@ class FrlControlTx:
self.__ltp_additional = LtpLanesPattern()
def __read_caps(self) -> int:
return self.__io.get(TSI_HDTX_FRL_CAPABILITY, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_FRL_CAPABILITY, c_uint32)[1]
def __write_caps(self, value: int):
self.__io.set(TSI_HDTX_FRL_CAPABILITY, value, c_uint32)
self.__io.set(ci.TSI_HDTX_FRL_CAPABILITY, value, c_uint32)
def __read_frl_timers(self) -> int:
return self.__io.get(TSI_HDTX_FRL_TIMERS, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_FRL_TIMERS, c_uint32)[1]
def __write_frl_timers(self, value: int):
self.__io.set(TSI_HDTX_FRL_TIMERS, value, c_uint32)
self.__io.set(ci.TSI_HDTX_FRL_TIMERS, value, c_uint32)
def __read_frl_patterns(self) -> int:
return self.__io.get(TSI_HDTX_FRL_PATTERN_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_FRL_PATTERN_R, c_uint32)[1]
@property
def ltp_pattern(self) -> LtpLanesPattern:
@@ -243,7 +242,7 @@ class FrlControlTx:
Returns:
object of `FrlCaps` type
"""
_update_frl_values(self.__frl_caps, self.__io.get(TSI_HDTX_FRL_STATUS_R, c_uint32)[1])
_update_frl_values(self.__frl_caps, self.__io.get(ci.TSI_HDTX_FRL_STATUS_R, c_uint32)[1])
return self.__frl_caps
@property
@@ -345,7 +344,7 @@ class FrlControlTx:
"""
Do link training.
"""
self.__io.set(TSI_HDTX_SINK_FEATURE_W, 5, c_uint32)
self.__io.set(ci.TSI_HDTX_SINK_FEATURE_W, 5, c_uint32)
@staticmethod
def __update_values(ffe_max: FfeMax, value: int):

View File

@@ -9,7 +9,7 @@ from .status_tx import StatusTx, HdmiModeTx
from .capabilities import HdmiCapabilities
from .frl_control_tx import FrlControlTx
from .frl_caps_rx import FrlControlRx
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDTX_CAPABILITY_R, TSI_HDRX_CAPABILITY_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from typing import Optional
@@ -25,7 +25,7 @@ class HdmiLinkTx:
self.__tmds = TmdsTx(self.__io)
self.__status = StatusTx(self.__io)
self.__frl = FrlControlTx(self.__io)
self.__caps = HdmiCapabilities(TSI_HDTX_CAPABILITY_R, self.__io)
self.__caps = HdmiCapabilities(ci.TSI_HDTX_CAPABILITY_R, self.__io)
@property
def tmds(self) -> Optional[TmdsTx]:
@@ -96,7 +96,7 @@ class HdmiLinkRx:
self.__status = StatusRx(self.__io)
self.__frl = FrlControlRx(self.__io)
self.__arc = ArcRx(self.__io)
self.__caps = HdmiCapabilities(TSI_HDRX_CAPABILITY_R, self.__io)
self.__caps = HdmiCapabilities(ci.TSI_HDRX_CAPABILITY_R, self.__io)
@property
def tmds(self) -> Optional[TmdsRx]:

View File

@@ -2,9 +2,7 @@ import time
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .types import HdmiModeRx, FrlMode, _update_error_counters_rx
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDRX_BEHAVIOR, TSI_HDRX_LANES_ERR_COUNTERS_R, TSI_HDRX_HPD_STATUS_R,\
TSI_HDRX_FRL_CAPABILITY, TSI_HDRX_LINK_STATUS_R, TSI_HDRX_HPD_CONTROL_W, TSI_HDRX_VIDEO_MODE_R, \
TSI_VIDCAP_SIGNAL_CRC_R, TSI_SUCCESS
import UniTAP.libs.lib_tsi.tsi_types as ci
from ctypes import c_uint8, c_uint32, c_uint64
from UniTAP.utils.function_wrapper import function_scheduler
from .types import _hdmi_vm_info_to_video_mode, HdmiVideoModeInfo
@@ -25,7 +23,7 @@ class StatusRx:
self.__io = port_io
def __frl_status(self) -> FrlMode:
return FrlMode(self.__io.get(TSI_HDRX_FRL_CAPABILITY, c_uint32)[1] & 0xF)
return FrlMode(self.__io.get(ci.TSI_HDRX_FRL_CAPABILITY, c_uint32)[1] & 0xF)
@property
def hdmi_mode(self) -> HdmiModeRx:
@@ -35,7 +33,7 @@ class StatusRx:
Returns:
object of `HdmiModeRx` type
"""
return HdmiModeRx(self.__io.get(TSI_HDRX_BEHAVIOR, c_uint32)[1])
return HdmiModeRx(self.__io.get(ci.TSI_HDRX_BEHAVIOR, c_uint32)[1])
@hdmi_mode.setter
def hdmi_mode(self, hdmi_mode: HdmiModeRx):
@@ -45,7 +43,7 @@ class StatusRx:
Args:
hdmi_mode (HdmiModeRx)
"""
self.__io.set(TSI_HDRX_BEHAVIOR, hdmi_mode.value, c_uint32)
self.__io.set(ci.TSI_HDRX_BEHAVIOR, hdmi_mode.value, c_uint32)
@property
def error_counters(self) -> list:
@@ -55,7 +53,7 @@ class StatusRx:
Returns:
object of list type
"""
return _update_error_counters_rx(self.__io.get(TSI_HDRX_LANES_ERR_COUNTERS_R, c_uint64)[1])
return _update_error_counters_rx(self.__io.get(ci.TSI_HDRX_LANES_ERR_COUNTERS_R, c_uint64)[1])
def set_assert_state(self, asserted: bool = True):
"""
@@ -64,7 +62,7 @@ class StatusRx:
Args:
asserted (bool)
"""
self.__io.set(TSI_HDRX_HPD_CONTROL_W, int(asserted), c_uint32)
self.__io.set(ci.TSI_HDRX_HPD_CONTROL_W, int(asserted), c_uint32)
@property
def channel_lock(self) -> list:
@@ -74,7 +72,7 @@ class StatusRx:
Returns:
object of list type
"""
return self.__update_channel_lock(self.__io.get(TSI_HDRX_LINK_STATUS_R, c_uint32)[1], self.hdmi_mode)
return self.__update_channel_lock(self.__io.get(ci.TSI_HDRX_LINK_STATUS_R, c_uint32)[1], self.hdmi_mode)
@staticmethod
def __update_channel_lock(value: int, mode: HdmiModeRx) -> list:
@@ -99,11 +97,11 @@ class StatusRx:
Returns:
object of bool type
"""
return (self.__io.get(TSI_HDRX_HPD_STATUS_R, c_uint32)[1] & 0x1) != 0
return (self.__io.get(ci.TSI_HDRX_HPD_STATUS_R, c_uint32)[1] & 0x1) != 0
def __check_video(self) -> bool:
def is_msa_available(io):
result, msa_info, size = io.get(TSI_HDRX_VIDEO_MODE_R, HdmiVideoMode, 4)
result, msa_info, size = io.get(ci.TSI_HDRX_VIDEO_MODE_R, HdmiVideoMode, 4)
return result > 0
return function_scheduler(is_msa_available, self.__io, interval=5, timeout=10)
@@ -125,7 +123,7 @@ class StatusRx:
time.sleep(1)
result, hdmi_video_mode_info, size = self.__io.get(TSI_HDRX_VIDEO_MODE_R, HdmiVideoMode, 4)
result, hdmi_video_mode_info, size = self.__io.get(ci.TSI_HDRX_VIDEO_MODE_R, HdmiVideoMode, 4)
# TODO - Size temporary will be equal 1
size = 1
@@ -133,8 +131,8 @@ class StatusRx:
if 0 <= stream_index < size:
stream_status.video_mode = _hdmi_vm_info_to_video_mode(HdmiVideoModeInfo(hdmi_video_mode_info
[stream_index]))
result = self.__io.get(TSI_VIDCAP_SIGNAL_CRC_R, data_type=c_uint8, data_count=6)
if result[0] >= TSI_SUCCESS:
result = self.__io.get(ci.TSI_VIDCAP_SIGNAL_CRC_R, data_type=c_uint8, data_count=6)
if result[0] >= ci.TSI_SUCCESS:
hdmi_crc = HdmiCrc.from_buffer(bytearray(result[1]))
stream_status.crc = [hdmi_crc.r, hdmi_crc.g, hdmi_crc.b]

View File

@@ -1,7 +1,6 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .types import HdmiModeTx, FrlMode, _update_error_counters_tx
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDTX_FRL_STATUS_R, TSI_HDTX_CONTROL_W, TSI_HDTX_STATUS_R, \
TSI_HDTX_SINK_STATUS_R, TSI_HDTX_LANES_ERR_COUNTERS_R, TSI_HDTX_HPD_STATUS_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from ctypes import c_uint32, c_uint64
@@ -19,10 +18,10 @@ class StatusTx:
self.__io = port_io
def __read_status(self) -> int:
return self.__io.get(TSI_HDTX_STATUS_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_STATUS_R, c_uint32)[1]
def __frl_status(self) -> FrlMode:
return FrlMode(self.__io.get(TSI_HDTX_FRL_STATUS_R, c_uint32)[1] & 0xF)
return FrlMode(self.__io.get(ci.TSI_HDTX_FRL_STATUS_R, c_uint32)[1] & 0xF)
@property
def video_status(self) -> bool:
@@ -42,7 +41,7 @@ class StatusTx:
Returns:
object of list type
"""
return _update_error_counters_tx(self.__io.get(TSI_HDTX_LANES_ERR_COUNTERS_R, c_uint64)[1])
return _update_error_counters_tx(self.__io.get(ci.TSI_HDTX_LANES_ERR_COUNTERS_R, c_uint64)[1])
@property
def channel_lock(self) -> list:
@@ -53,9 +52,9 @@ class StatusTx:
object of list type
"""
if self.__frl_status().Mode_Disable or self.hdmi_mode in [HdmiModeTx.HDMI_1_4, HdmiModeTx.HDMI_2_0]:
return self.__update_channel_lock(self.__io.get(TSI_HDTX_SINK_STATUS_R, c_uint32)[1], self.hdmi_mode)
return self.__update_channel_lock(self.__io.get(ci.TSI_HDTX_SINK_STATUS_R, c_uint32)[1], self.hdmi_mode)
else:
return self.__update_channel_lock(self.__io.get(TSI_HDTX_FRL_STATUS_R, c_uint32)[1], self.hdmi_mode)
return self.__update_channel_lock(self.__io.get(ci.TSI_HDTX_FRL_STATUS_R, c_uint32)[1], self.hdmi_mode)
@property
def hpd_status(self) -> bool:
@@ -65,7 +64,7 @@ class StatusTx:
Returns:
object of bool type
"""
return (self.__io.get(TSI_HDTX_HPD_STATUS_R, c_uint32)[1] & 0x1) != 0
return (self.__io.get(ci.TSI_HDTX_HPD_STATUS_R, c_uint32)[1] & 0x1) != 0
@property
def hdmi_mode(self) -> HdmiModeTx:
@@ -85,7 +84,7 @@ class StatusTx:
Args:
hdmi_mode (HdmiModeTx)
"""
self.__io.set(TSI_HDTX_CONTROL_W, hdmi_mode.value << 2, c_uint32)
self.__io.set(ci.TSI_HDTX_CONTROL_W, hdmi_mode.value << 2, c_uint32)
@property
def available_link_rate(self) -> float:

View File

@@ -1,6 +1,6 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .types import LinkMode
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDRX_LINK_STATUS_R
import UniTAP.libs.lib_tsi.tsi_types as ci
from ctypes import c_uint32
@@ -17,7 +17,7 @@ class TmdsRx:
self.__input_stream_lock = False
def __read_link_status(self) -> int:
return self.__io.get(TSI_HDRX_LINK_STATUS_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDRX_LINK_STATUS_R, c_uint32)[1]
@property
def clock_rate(self) -> int:
@@ -27,7 +27,7 @@ class TmdsRx:
Returns:
object of int type
"""
return 6 if self.__read_link_status() & 0x2 else 3
return 6 if self.__read_link_status() >> 1 & 0x1 else 3
@property
def link_mode(self) -> LinkMode:
@@ -37,7 +37,7 @@ class TmdsRx:
Returns:
object of `LinkMode` type
"""
self.__link_mode = LinkMode(self.__read_link_status() & 0x8)
self.__link_mode = LinkMode(self.__read_link_status() >> 3 & 0x1)
return self.__link_mode
@property
@@ -48,7 +48,7 @@ class TmdsRx:
Returns:
object of bool type
"""
self.__input_stream_lock = (self.__read_link_status() & 0x4) != 0
self.__input_stream_lock = (self.__read_link_status() >> 2 & 0x1) != 0
return self.__input_stream_lock
def __str__(self):

View File

@@ -2,8 +2,7 @@ import warnings
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .types import ClockRate, LinkMode, ScramblerState
from UniTAP.libs.lib_tsi.tsi_types import TSI_HDTX_SINK_FEATURE_W, TSI_HDTX_STATUS_R, TSI_HDTX_SINK_STATUS_R, \
TSI_HDTX_CONTROL_W
import UniTAP.libs.lib_tsi.tsi_types as ci
from ctypes import c_uint32
@@ -21,13 +20,13 @@ class TmdsTx:
self.__scrambler = ScramblerState.Unknown
def __read_sink_status(self) -> int:
return self.__io.get(TSI_HDTX_SINK_STATUS_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_SINK_STATUS_R, c_uint32)[1]
def __read_hdtx_status(self) -> int:
return self.__io.get(TSI_HDTX_STATUS_R, c_uint32)[1]
return self.__io.get(ci.TSI_HDTX_STATUS_R, c_uint32)[1]
def __write_sink_feature(self, value: int):
self.__io.set(TSI_HDTX_SINK_FEATURE_W, value, c_uint32)
self.__io.set(ci.TSI_HDTX_SINK_FEATURE_W, value, c_uint32)
@property
def clock_rate(self) -> int:
@@ -71,7 +70,7 @@ class TmdsTx:
Args:
link_mode (LinkMode)
"""
self.__io.set(TSI_HDTX_CONTROL_W, link_mode.value, c_uint32)
self.__io.set(ci.TSI_HDTX_CONTROL_W, link_mode.value, c_uint32)
@property
def scrambler(self) -> bool:

View File

@@ -0,0 +1 @@
from .packet_generator import PacketGenerator

View File

@@ -0,0 +1,92 @@
from ctypes import c_byte
from typing import Union, List, Optional
from UniTAP.libs.lib_tsi import ci, p_ci
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.dev.modules import MemoryManager
class PacketGenerator:
class Status:
def __init__(self, value: int):
self.enabled = bool(value & 0x1)
self.active = bool(value & 0x2)
self.error = bool(value & 0x4)
self.overflow = bool(value & 0x8)
def __str__(self):
return f"Packet Generator Status: Enabled: {self.enabled}; Active: {self.active}; Error: {self.error}; Overflow: {self.overflow};"
"""
Main class `PacketGenerator` allows working with PG functionality on the device: set different types of pattern
`set_pattern`, set different video modes `set_vm`, set additional parameters for some patterns `set_pattern_params`,
get information about current video mode on stream `get_stream_video_mode`, `apply` all transferred setting,
`reset` settings and read pattern generator `status`.
"""
def __init__(self, port_io: PortIO, memory_manager: MemoryManager):
self.__io = port_io
self.__memory_manager = memory_manager
self.__packets = []
def reset(self):
"""
Reset static packet generator settings to default values.
"""
self.stop()
self.__packets = []
def start(self):
"""
Start packet generator with current settings.
"""
self.stop()
self.__upload_data()
if self.__io.set(ci.TSI_PACKETGEN_CONTROL_W, 1) < ci.TSI_SUCCESS:
raise Exception("Failed to start packet generator")
def stop(self):
"""
Stop packet generator.
"""
self.__io.set(ci.TSI_PACKETGEN_CONTROL_W, 2)
def status(self) -> Status:
"""
Get current status of packet generator.
Returns:
Status - current status of packet generator
"""
return PacketGenerator.Status(self.__io.get(ci.TSI_PACKETGEN_STATUS_R)[1])
def add_packet(self, raw_packet_data: bytearray):
self.__packets.append(raw_packet_data)
def load_packet(self, file_path: str):
with open(file_path, "rb") as f:
packet_data = f.read()
self.__packets.append(bytearray(packet_data))
def __upload_data(self):
mem_layout = self.__memory_manager.get_memory_layout()
if len(mem_layout) <= MemoryManager.MemoryOwner.MO_Events.value or mem_layout[MemoryManager.MemoryOwner.MO_Events.value] == 0:
self.__memory_manager.make_default()
if self.__io.set(ci.TSI_PACKETGEN_PACKETS_NUMBER, len(self.__packets)) < ci.TSI_SUCCESS:
raise Exception("Failed to set packets number for packet generator")
for index, packet in enumerate(self.__packets):
if self.__io.set(ci.TSI_PACKETGEN_PACKET_DATA, packet, data_type=c_byte, data_count=len(packet)) < ci.TSI_SUCCESS:
raise Exception(f"Failed to set packet data for packet {index} in packet generator")
if self.__io.set(ci.TSI_PACKETGEN_MEM_BLOCK, int(MemoryManager.MemoryOwner.MO_Events)) < ci.TSI_SUCCESS:
raise Exception("Failed to set memory block for packet generator")

View File

@@ -1,5 +1,6 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.libs.lib_tsi.tsi import *
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from .pr_private_types import *
from .pr_status import PanelReplayStatus
from .pr_config import PanelReplayConfig
@@ -68,6 +69,6 @@ class PanelReplay:
self.__write_pr_control(PrControl.EnableSelectiveUpdate)
def __write_pr_control(self, command: PrControl):
self.__io.set(TSI_PG_STREAM_SELECT, 0)
self.__io.set(TSI_PG_PR_CTRL_W, command.value)
self.__io.set(ci.TSI_PG_STREAM_SELECT, 0)
self.__io.set(p_ci.TSI_PG_PR_CTRL_W, command.value)

View File

@@ -1,5 +1,7 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.libs.lib_tsi.tsi import *
import UniTAP.libs.lib_tsi.tsi as tsi
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from .pr_types import *
from .pr_private_types import *
@@ -35,7 +37,7 @@ class PanelReplayConfig:
"""
caps = self.pr_caps
self.__io.set(TSI_PG_STREAM_SELECT, 0)
self.__io.set(ci.TSI_PG_STREAM_SELECT, 0)
pr_config, _ = self.__read_config()
pr_config.early_transport = config.flags.early_transport if caps.pr_flags().early_transport else 0
@@ -60,7 +62,7 @@ class PanelReplayConfig:
region = RegionConfig(0)
region.value = item
data.extend(region.value)
self.__io.set(TSI_PG_PR_CFG, data, data_count=len(data))
self.__io.set(p_ci.TSI_PG_PR_CFG, data, data_count=len(data))
def get(self) -> PrSettings:
"""
@@ -114,8 +116,8 @@ class PanelReplayConfig:
def __read_config(self):
caps = self.pr_caps
self.__io.set(TSI_PG_STREAM_SELECT, 0)
result = self.__io.get(TSI_PG_PR_CFG, c_uint32, caps.calculate_size())[1]
self.__io.set(ci.TSI_PG_STREAM_SELECT, 0)
result = self.__io.get(p_ci.TSI_PG_PR_CFG, c_uint32, caps.calculate_size())[1]
if not isinstance(result, list):
result = [0]
pr_config = PrConfig(result[0])
@@ -128,5 +130,5 @@ class PanelReplayConfig:
return pr_config, pr_regions
def __read_caps(self) -> PRCaps:
self.__io.set(TSI_PG_STREAM_SELECT, 0)
return self.__io.get(TSI_PG_PR_CAPS_R, PRCaps)[1]
self.__io.set(ci.TSI_PG_STREAM_SELECT, 0)
return self.__io.get(p_ci.TSI_PG_PR_CAPS_R, PRCaps)[1]

View File

@@ -1,7 +1,9 @@
from ctypes import c_int, c_uint32
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from .pr_sink_private_types import SinkPanelReplayCapsStruct, SinkPanelSelfRefreshCapsStruct
from .pr_sink_types import PRCapsFlags, PrGranularityCaps, SuYGranularity, PSRCapsFlags, PSRCaps, PSRSetupTime
from UniTAP.libs.lib_tsi.tsi import *
import UniTAP.libs.lib_tsi.tsi_types as ci
from typing import Tuple
@@ -27,7 +29,7 @@ class SinkPanelReplayCaps:
(flags.y_gran_extended_supported << 14) | (flags.link_off_supported << 15))
self.__write([flags_value, x_granularity.value, y_granularity.value, granularity.combined_value()])
self.__io.set(TSI_DPRX_HPD_PULSE_W, 500000, c_int)
self.__io.set(ci.TSI_DPRX_HPD_PULSE_W, 500000, c_int)
def get(self) -> Tuple[PRCapsFlags, PrGranularityCaps, PrGranularityCaps, SuYGranularity]:
caps = self.__read()
@@ -65,10 +67,10 @@ class SinkPanelReplayCaps:
return flags, x_granularity, y_granularity, granularity
def __read(self) -> SinkPanelReplayCapsStruct:
return self.__io.get(TSI_DPRX_PR_CAPS, SinkPanelReplayCapsStruct)[1]
return self.__io.get(ci.TSI_DPRX_PR_CAPS, SinkPanelReplayCapsStruct)[1]
def __write(self, data: list):
self.__io.set(TSI_DPRX_PR_CAPS, data, data_type=c_uint32, data_count=len(data))
self.__io.set(ci.TSI_DPRX_PR_CAPS, data, data_type=c_uint32, data_count=len(data))
class SinkPanelSelfRefreshCaps:
@@ -105,7 +107,7 @@ class SinkPanelSelfRefreshCaps:
return flags, x_granularity, y_granularity
def __read(self) -> SinkPanelSelfRefreshCapsStruct:
return self.__io.get(TSI_DPRX_PSR_CAPS, SinkPanelSelfRefreshCapsStruct)[1]
return self.__io.get(ci.TSI_DPRX_PSR_CAPS, SinkPanelSelfRefreshCapsStruct)[1]
def __write(self, data: list):
self.__io.set(TSI_DPRX_PSR_CAPS, data, data_type=c_uint32, data_count=len(data))
self.__io.set(ci.TSI_DPRX_PSR_CAPS, data, data_type=c_uint32, data_count=len(data))

View File

@@ -1,7 +1,8 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_types as ci
from .pr_sink_private_types import SinkPanelSelfRefreshStatusStruct, SinkPanelReplayStatusStruct
from .pr_sink_types import (SinkPRStatusFlags, SelfStatus, FrameStatus, SinkPSRStatusFlags, PRSSelfRefreshStatus)
from UniTAP.libs.lib_tsi.tsi import *
import UniTAP.libs.lib_tsi.tsi as tsi
class SinkPanelReplayStatus:
@@ -31,7 +32,7 @@ class SinkPanelReplayStatus:
def __read(self) -> SinkPanelReplayStatusStruct:
return self.__io.get(TSI_DPRX_PR_STATUS, SinkPanelReplayStatusStruct)[1]
return self.__io.get(ci.TSI_DPRX_PR_STATUS, SinkPanelReplayStatusStruct)[1]
class SinkPanelSelfRefreshStatus:
@@ -59,4 +60,4 @@ class SinkPanelSelfRefreshStatus:
self_refresh=PRSSelfRefreshStatus(pr_flags.self_refresh))
def __read(self) -> SinkPanelSelfRefreshStatusStruct:
return self.__io.get(TSI_DPRX_PSR_STATUS, SinkPanelSelfRefreshStatusStruct)[1]
return self.__io.get(ci.TSI_DPRX_PSR_STATUS, SinkPanelSelfRefreshStatusStruct)[1]

View File

@@ -1,6 +1,7 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .pr_private_types import *
from UniTAP.libs.lib_tsi.tsi import *
from .pr_types import *
@@ -43,6 +44,6 @@ class PanelReplayStatus:
return PRError(self.__read().error)
def __read(self) -> PrStatus:
self.__io.set(TSI_PG_STREAM_SELECT, 0)
return self.__io.get(TSI_PG_PR_STATUS_R, PrStatus)[1]
self.__io.set(ci.TSI_PG_STREAM_SELECT, 0)
return self.__io.get(p_ci.TSI_PG_PR_STATUS_R, PrStatus)[1]

View File

@@ -237,6 +237,12 @@ class PdcControls500(PdcControlsBase):
super().__init__(pdc_io)
self.__io = pdc_io
def reset(self):
"""
Reset device.
"""
self.__io.write_hw_command(HWControlCommand.ResetPDController)
def reconnect(self) -> bool:
"""
Reconnect device.

View File

@@ -1,5 +1,8 @@
from ctypes import c_uint32
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.libs.lib_tsi.tsi_private_types import *
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
import UniTAP.libs.lib_tsi.tsi_types as ci
from .pdc_private_dpam_types import DPAMCaps, DPAMState, DPAMCommand, DPAMConfig, DPAMDiscModes, DPAMRecv
from .pdc_private_types import HWControlCommand, HWStatus, HWCaps, PDCStatus, PDCControlCommand, PDCState, PDCCaps, \
PDCContractInfo
@@ -13,103 +16,103 @@ class PDCPortIO:
self.write_adc_control()
def write_dpam_caps(self, caps: DPAMCaps):
self.__io.set(TSI_PDC_DPAM_CAPS, caps.value(), c_uint32)
self.__io.set(ci.TSI_PDC_DPAM_CAPS, caps.value(), c_uint32)
def read_dpam_caps(self) -> DPAMCaps:
return self.__io.get(TSI_PDC_DPAM_CAPS, DPAMCaps)[1]
return self.__io.get(ci.TSI_PDC_DPAM_CAPS, DPAMCaps)[1]
def read_dpam_caps2(self) -> bool:
return (self.__io.get(TSI_PDC_DPAM_CAPS2, c_uint32)[1] & 0x1) != 0
return (self.__io.get(ci.TSI_PDC_DPAM_CAPS2, c_uint32)[1] & 0x1) != 0
def read_dpam_state(self) -> DPAMState:
return self.__io.get(TSI_PDC_DPAM_STATE_R, DPAMState)[1]
return self.__io.get(ci.TSI_PDC_DPAM_STATE_R, DPAMState)[1]
def write_dpam_control(self, command: DPAMCommand):
self.__io.set(TSI_PDC_DPAM_CONTROL_W, command.value, c_uint32)
self.__io.set(ci.TSI_PDC_DPAM_CONTROL_W, command.value, c_uint32)
def read_dpam_config(self) -> DPAMConfig:
return self.__io.get(TSI_PDC_DPAM_CONFIG_R, DPAMConfig)[1]
return self.__io.get(p_ci.TSI_PDC_DPAM_CONFIG_R, DPAMConfig)[1]
def read_dpam_disc_modes(self) -> DPAMDiscModes:
return self.__io.get(TSI_PDC_DPAM_DISC_MODES_R, DPAMDiscModes)[1]
return self.__io.get(ci.TSI_PDC_DPAM_DISC_MODES_R, DPAMDiscModes)[1]
def read_dpam_recv(self) -> DPAMRecv:
return self.__io.get(TSI_PDC_DPAM_RECV_STS_R, DPAMRecv)[1]
return self.__io.get(ci.TSI_PDC_DPAM_RECV_STS_R, DPAMRecv)[1]
def write_hw_command(self, command: HWControlCommand):
self.__io.set(TSI_PDC_HW_CONTROL_W, command.value, c_uint32)
self.__io.set(ci.TSI_PDC_HW_CONTROL_W, command.value, c_uint32)
def read_hw_status(self) -> HWStatus:
return self.__io.get(TSI_PDC_HW_STATUS_R, HWStatus)[1]
return self.__io.get(ci.TSI_PDC_HW_STATUS_R, HWStatus)[1]
def read_hw_caps(self) -> HWCaps:
return self.__io.get(TSI_PDC_HW_CAPS_R, HWCaps)[1]
return self.__io.get(p_ci.TSI_PDC_HW_CAPS_R, HWCaps)[1]
def read_pdc_status(self) -> PDCStatus:
return self.__io.get(TSI_PDC_STATUS_R, PDCStatus)[1]
return self.__io.get(ci.TSI_PDC_STATUS_R, PDCStatus)[1]
def write_pdc_command(self, command: PDCControlCommand):
self.__io.set(TSI_PDC_CONTROL, command.value, c_uint32)
self.__io.set(ci.TSI_PDC_CONTROL, command.value, c_uint32)
def read_pdc_state(self) -> PDCState:
return self.__io.get(TSI_PDC_STATE, PDCState)[1]
return self.__io.get(ci.TSI_PDC_STATE, PDCState)[1]
def read_pdc_caps(self) -> PDCCaps:
return self.__io.get(TSI_PDC_CAPS, PDCCaps)[1]
return self.__io.get(ci.TSI_PDC_CAPS, PDCCaps)[1]
def write_pdc_contract_control(self, caps: PDCContractInfo):
self.__io.set(TSI_USBC_PWR_CONTRACT_CONTROL, caps.value(), c_uint32)
self.__io.set(ci.TSI_USBC_PWR_CONTRACT_CONTROL, caps.value(), c_uint32)
def read_pdc_contract_control(self) -> PDCContractInfo:
return self.__io.get(TSI_USBC_PWR_CONTRACT_CONTROL, PDCContractInfo)[1]
return self.__io.get(ci.TSI_USBC_PWR_CONTRACT_CONTROL, PDCContractInfo)[1]
def read_local_spr_source_pdo(self) -> list:
return self.__io.get(TSI_USBC_PWR_LOCAL_SOURCE_PDO, PdoUnion, self.read_hw_caps().pdo_count)[1]
return self.__io.get(ci.TSI_USBC_PWR_LOCAL_SOURCE_PDO, PdoUnion, self.read_hw_caps().pdo_count)[1]
def write_local_spr_source_pdo(self, data: list):
self.__io.set(TSI_USBC_PWR_LOCAL_SOURCE_PDO, data, c_uint32, len(data))
self.__io.set(ci.TSI_USBC_PWR_LOCAL_SOURCE_PDO, data, c_uint32, len(data))
def read_local_spr_sink_pdo(self) -> list:
return self.__io.get(TSI_USBC_PWR_LOCAL_SINK_PDO, PdoUnion, self.read_hw_caps().pdo_count)[1]
return self.__io.get(ci.TSI_USBC_PWR_LOCAL_SINK_PDO, PdoUnion, self.read_hw_caps().pdo_count)[1]
def write_local_spr_sink_pdo(self, data: list):
self.__io.set(TSI_USBC_PWR_LOCAL_SINK_PDO, data, c_uint32, len(data))
self.__io.set(ci.TSI_USBC_PWR_LOCAL_SINK_PDO, data, c_uint32, len(data))
def read_tx_id_vdo_count(self) -> int:
return self.__io.get(TSI_PDC_TX_ID_VDO_CNT, c_uint32)[1]
return self.__io.get(p_ci.TSI_PDC_TX_ID_VDO_CNT, c_uint32)[1]
def read_tx_id_vdo(self) -> list:
return self.__io.get(TSI_PDC_TX_ID_VDO, c_uint32, self.read_tx_id_vdo_count())[1]
return self.__io.get(p_ci.TSI_PDC_TX_ID_VDO, c_uint32, self.read_tx_id_vdo_count())[1]
def write_tx_id_vdo(self, data: list):
self.__io.set(TSI_PDC_TX_ID_VDO, data, c_uint32, len(data))
self.__io.set(p_ci.TSI_PDC_TX_ID_VDO, data, c_uint32, len(data))
def read_contract_data(self) -> list:
return self.__io.get(TSI_PDC_CONTRACT_DATA, c_uint32, 4)[1]
return self.__io.get(p_ci.TSI_PDC_CONTRACT_DATA, c_uint32, 4)[1]
def write_contract_data(self, data: list):
self.__io.set(TSI_PDC_CONTRACT_DATA, data, c_uint32, len(data))
self.__io.set(p_ci.TSI_PDC_CONTRACT_DATA, data, c_uint32, len(data))
def read_power_contract_select(self) -> int:
return self.__io.get(TSI_USBC_PWR_CONTRACT_SELECT, c_uint32)[1]
return self.__io.get(ci.TSI_USBC_PWR_CONTRACT_SELECT, c_uint32)[1]
def write_power_contract_select(self, index: int):
self.__io.set(TSI_USBC_PWR_CONTRACT_SELECT, index, c_uint32)
self.__io.set(ci.TSI_USBC_PWR_CONTRACT_SELECT, index, c_uint32)
def read_resistance(self) -> int:
return self.__io.get(TSI_USBC_RESISTANCE_CONTROL, c_uint32)[1]
return self.__io.get(ci.TSI_USBC_RESISTANCE_CONTROL, c_uint32)[1]
def write_resistance(self, resistance: int):
self.__io.set(TSI_USBC_RESISTANCE_CONTROL, resistance, c_uint32)
self.__io.set(ci.TSI_USBC_RESISTANCE_CONTROL, resistance, c_uint32)
def read_adc_vbus_status(self) -> list:
return self.__io.get(TSI_ADC_VBUS_VOLTAGE_R, c_uint32, TSI_ADC_BLOCK_SIZE_WORDS)[1]
return self.__io.get(ci.TSI_ADC_VBUS_VOLTAGE_R, c_uint32, ci.TSI_ADC_BLOCK_SIZE_WORDS)[1]
def read_internal_resistance(self) -> int:
return self.__io.get(TSI_USBC_INT_RESISTANCE_STATUS_R, c_uint32)[1]
return self.__io.get(ci.TSI_USBC_INT_RESISTANCE_STATUS_R, c_uint32)[1]
def read_external_resistance(self) -> int:
return self.__io.get(TSI_USBC_EXT_RESISTANCE_STATUS_R, c_uint32)[1]
return self.__io.get(ci.TSI_USBC_EXT_RESISTANCE_STATUS_R, c_uint32)[1]
def write_adc_control(self):
self.__io.set(TSI_W_USBC_ADC_CTRL, 1, c_uint32)
self.__io.set(ci.TSI_W_USBC_ADC_CTRL, 1, c_uint32)

View File

@@ -1,10 +1,12 @@
import copy
import os.path
from ctypes import c_uint8, c_uint, c_uint32
from typing import Union, List, Optional
from PIL import Image
from UniTAP.utils import function_scheduler
from UniTAP.libs.lib_tsi.tsi import *
import UniTAP.libs.lib_tsi.tsi_types as ci
import UniTAP.libs.lib_tsi.tsi_private_types as p_ci
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.dev.modules import MemoryManager
from UniTAP.dev.ports.modules.internal_utils.math import aligned
@@ -26,29 +28,29 @@ Image.MAX_IMAGE_PIXELS = None
def _read_predefined_timings(io: PortIO) -> List[Timing]:
count = io.get(TSI_R_PG_PREDEF_TIMING_COUNT)[1]
count = io.get(ci.TSI_R_PG_PREDEF_TIMING_COUNT)[1]
predefined_list = []
for i in range(count):
io.set(TSI_W_PG_PREDEF_TIMING_SELECT, i)
io.set(ci.TSI_W_PG_PREDEF_TIMING_SELECT, i)
timing = Timing()
timing.htotal = io.get(TSI_PG_CUSTOM_TIMING_HTOTAL)[1]
timing.vtotal = io.get(TSI_PG_CUSTOM_TIMING_VTOTAL)[1]
timing.hactive = io.get(TSI_PG_CUSTOM_TIMING_HACTIVE)[1]
timing.vactive = io.get(TSI_PG_CUSTOM_TIMING_VACTIVE)[1]
timing.hstart = io.get(TSI_PG_CUSTOM_TIMING_HSTART)[1]
timing.vstart = io.get(TSI_PG_CUSTOM_TIMING_VSTART)[1]
timing.hswidth = io.get(TSI_PG_CUSTOM_TIMING_HSYNCW)[1]
timing.vswidth = io.get(TSI_PG_CUSTOM_TIMING_VSYNCW)[1]
timing.id = io.get(TSI_PG_CUSTOM_TIMING_ID)[1]
timing.htotal = io.get(ci.TSI_PG_CUSTOM_TIMING_HTOTAL)[1]
timing.vtotal = io.get(ci.TSI_PG_CUSTOM_TIMING_VTOTAL)[1]
timing.hactive = io.get(ci.TSI_PG_CUSTOM_TIMING_HACTIVE)[1]
timing.vactive = io.get(ci.TSI_PG_CUSTOM_TIMING_VACTIVE)[1]
timing.hstart = io.get(ci.TSI_PG_CUSTOM_TIMING_HSTART)[1]
timing.vstart = io.get(ci.TSI_PG_CUSTOM_TIMING_VSTART)[1]
timing.hswidth = io.get(ci.TSI_PG_CUSTOM_TIMING_HSYNCW)[1]
timing.vswidth = io.get(ci.TSI_PG_CUSTOM_TIMING_VSYNCW)[1]
timing.id = io.get(ci.TSI_PG_CUSTOM_TIMING_ID)[1]
# TODO: add conversion from pg AR to Timing AR
timing.aspect_ratio = io.get(TSI_PG_CUSTOM_TIMING_ASPECT_RATIO)[1]
timing.frame_rate = io.get(TSI_PG_CUSTOM_TIMING_FIELD_RATE)[1]
timing.standard = Timing.Standard(io.get(TSI_PG_CUSTOM_TIMING_STANDARD)[1])
timing.aspect_ratio = io.get(ci.TSI_PG_CUSTOM_TIMING_ASPECT_RATIO)[1]
timing.frame_rate = io.get(ci.TSI_PG_CUSTOM_TIMING_FIELD_RATE)[1]
timing.standard = Timing.Standard(io.get(ci.TSI_PG_CUSTOM_TIMING_STANDARD)[1])
timing_flags = io.get(TSI_PG_CUSTOM_TIMING_FLAGS)[1]
timing_flags = io.get(ci.TSI_PG_CUSTOM_TIMING_FLAGS)[1]
timing.hswidth *= (-1 if timing_flags >> 9 & 1 else 1)
timing.vswidth *= (-1 if timing_flags >> 10 & 1 else 1)
timing.reduce_blanking = Timing.ReduceBlanking((timing_flags >> 24) & 0x3)
@@ -191,7 +193,7 @@ class PatternGenerator:
def __read_caps(self):
self._become_active()
return self.__io.get(TSI_PG_CAPS_R, PgCaps)[1]
return self.__io.get(p_ci.TSI_PG_CAPS_R, PgCaps)[1]
def _caps(self) -> PgCaps:
return self.__caps
@@ -242,11 +244,11 @@ class PatternGenerator:
self.__memory_manager.set_memory_layout([block_sizes])
self.__memory_manager.set_memory_block_index(MemoryManager.MemoryOwner.MO_PatternGenerator)
self.__io.set(TSI_PG_CUSTOM_PATTERN_MEMORY_BLOCK_INDEX, 0)
self.__io.set(TSI_PG_CUSTOM_PATTERN_WIDTH, video_mode.timing.hactive)
self.__io.set(TSI_PG_CUSTOM_PATTERN_HEIGHT, video_mode.timing.vactive)
self.__io.set(TSI_PG_CUSTOM_PATTERN_PIXEL_FORMAT, pg_pixel_format_from_vm(video_mode))
self.__io.set(TSI_PG_CUSTOM_PATTERN_DATA, data, c_uint8, data_count=len(data))
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_MEMORY_BLOCK_INDEX, 0)
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_WIDTH, video_mode.timing.hactive)
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_HEIGHT, video_mode.timing.vactive)
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_PIXEL_FORMAT, pg_pixel_format_from_vm(video_mode))
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_DATA, data, c_uint8, data_count=len(data))
def __load_dsc_image(self, video_mode: VideoMode, content_data: Union[str, bytearray, VideoFrameDSC]):
if isinstance(content_data, str):
@@ -259,8 +261,8 @@ class PatternGenerator:
block_sizes = len(data)
self.__memory_manager.set_memory_layout([block_sizes])
self.__memory_manager.set_memory_block_index(MemoryManager.MemoryOwner.MO_PatternGenerator)
self.__io.set(TSI_PG_CUSTOM_PATTERN_MEMORY_BLOCK_INDEX, 0)
self.__io.set(TSI_PG_CUSTOM_PATTERN_DATA, data, c_uint8, data_count=len(data))
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_MEMORY_BLOCK_INDEX, 0)
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_DATA, data, c_uint8, data_count=len(data))
@staticmethod
def __calculate_frame_size(width: int, height: int) -> int:
@@ -331,7 +333,7 @@ class PatternGenerator:
raise TypeError(f"Incorrect input value: {self._pattern}.\n"
f"If you want to select pattern, see following list of available patterns:\n"
f"{self.__available_patterns}")
self.__io.set(TSI_PG_PREDEF_PATTERN_SELECT, self._pattern_id.value)
self.__io.set(ci.TSI_PG_PREDEF_PATTERN_SELECT, self._pattern_id.value)
return True
return False
@@ -362,17 +364,17 @@ class PatternGenerator:
self.__caps.max_h_total >= self._vm.timing.htotal and \
self.__caps.max_v_total >= self._vm.timing.vtotal and \
self.__caps.max_frame >= int(self._vm.timing.frame_rate / 1000):
self.__io.set(TSI_PG_CUSTOM_TIMING_FLAGS, pg_timingflags_from_vm(self._vm))
self.__io.set(TSI_PG_CUSTOM_TIMING_HTOTAL, self._vm.timing.htotal, c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_VTOTAL, self._vm.timing.vtotal, c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_HACTIVE, self._vm.timing.hactive, c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_VACTIVE, self._vm.timing.vactive, c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_HSTART, self._vm.timing.hstart, c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_VSTART, self._vm.timing.vstart, c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_HSYNCW, abs(self._vm.timing.hswidth), c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_VSYNCW, abs(self._vm.timing.vswidth), c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_FIELD_RATE, self._vm.timing.frame_rate, c_uint)
self.__io.set(TSI_PG_CUSTOM_TIMING_STANDARD, self._vm.timing.standard.value, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_FLAGS, pg_timingflags_from_vm(self._vm))
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_HTOTAL, self._vm.timing.htotal, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_VTOTAL, self._vm.timing.vtotal, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_HACTIVE, self._vm.timing.hactive, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_VACTIVE, self._vm.timing.vactive, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_HSTART, self._vm.timing.hstart, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_VSTART, self._vm.timing.vstart, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_HSYNCW, abs(self._vm.timing.hswidth), c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_VSYNCW, abs(self._vm.timing.vswidth), c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_FIELD_RATE, self._vm.timing.frame_rate, c_uint)
self.__io.set(ci.TSI_PG_CUSTOM_TIMING_STANDARD, self._vm.timing.standard.value, c_uint)
return True
else:
raise ValueError(f"Incorrect Video Mode (incorrect resolution and(or) frame rate")
@@ -384,29 +386,40 @@ class PatternGenerator:
See available `PGPatternParams` types: `SolidColorParams`, `WhiteVStripsParams`, `GradientStripsParams`,
`MotionParams`,`SquareWindowParams` (see in pg pattern params).
These parameters can be applied without calling apply() method, if active pattern matches pattern params.
Args:
pattern_params (PGPatternParams)
"""
self._pattern_params = pattern_params
self._setup_pattern_params()
def _setup_pattern_params(self):
if self._pattern_params is not None and isinstance(self._pattern, VideoPattern):
if self._MAP_PATTERN_PARAMETER.get(PGPatternID(self._pattern_id.value)) is not None:
if isinstance(self._pattern_params,
self._MAP_PATTERN_PARAMETER.get(PGPatternID(self._pattern_id.value))):
self.__io.set(TSI_PG_PREDEF_PATTERN_PARAMS, get_pattern_params_value(self._pattern_params,
self._vm.color_info.bpc),
data_count=len(get_pattern_params_value(self._pattern_params)))
return True
else:
warnings.warn(f"Incorrect pattern name {self._pattern} and "
f"pattern params {type(self._pattern_params)}.\n"
f"For {self._pattern} you need to use "
f"{self._MAP_PATTERN_PARAMETER.get(self._pattern_id)}")
return False
if self._pattern_params is None or not isinstance(self._pattern, VideoPattern):
return False
if self._MAP_PATTERN_PARAMETER.get(self._pattern_id) is None:
return False
if not isinstance(self._pattern_params, self._MAP_PATTERN_PARAMETER.get(self._pattern_id)):
warnings.warn(f"Incorrect pattern name {self._pattern} and "
f"pattern params {type(self._pattern_params)}.\n"
f"For {self._pattern} you need to use "
f"{self._MAP_PATTERN_PARAMETER.get(self._pattern_id)}")
return False
solid_color_shifter = 16 - self._vm.color_info.bpc if self._vm is not None else 0
params = get_pattern_params_value(self._pattern_params, solid_color_shifter)
self._become_active()
self.__io.set(ci.TSI_PG_PREDEF_PATTERN_PARAM_1, params[0])
self.__io.set(ci.TSI_PG_PREDEF_PATTERN_PARAM_2, params[1])
return True
def __get_custom_timing_flags_to_video_mode(self) -> (ColorInfo, bool, bool):
timing_flags = self.__io.get(TSI_PG_CUSTOM_TIMING_FLAGS, CustomTimingFlags)[1]
timing_flags = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_FLAGS, CustomTimingFlags)[1]
vm_color_format = pg_colorformat_to_ci_colorformat(PGColorInfo(timing_flags.color_space))
@@ -440,28 +453,28 @@ class PatternGenerator:
video_mode = VideoMode()
video_mode.timing.hactive = self.__io.get(TSI_PG_CUSTOM_TIMING_HACTIVE, c_uint32)[1]
video_mode.timing.vactive = self.__io.get(TSI_PG_CUSTOM_TIMING_VACTIVE, c_uint32)[1]
video_mode.timing.htotal = self.__io.get(TSI_PG_CUSTOM_TIMING_HTOTAL, c_uint32)[1]
video_mode.timing.vtotal = self.__io.get(TSI_PG_CUSTOM_TIMING_VTOTAL, c_uint32)[1]
video_mode.timing.hstart = self.__io.get(TSI_PG_CUSTOM_TIMING_HSTART, c_uint32)[1]
video_mode.timing.vstart = self.__io.get(TSI_PG_CUSTOM_TIMING_VSTART, c_uint32)[1]
video_mode.timing.hactive = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_HACTIVE, c_uint32)[1]
video_mode.timing.vactive = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_VACTIVE, c_uint32)[1]
video_mode.timing.htotal = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_HTOTAL, c_uint32)[1]
video_mode.timing.vtotal = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_VTOTAL, c_uint32)[1]
video_mode.timing.hstart = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_HSTART, c_uint32)[1]
video_mode.timing.vstart = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_VSTART, c_uint32)[1]
video_mode.color_info, h_sync_polarity, v_sync_polarity = self.__get_custom_timing_flags_to_video_mode()
video_mode.timing.hswidth = self.__io.get(TSI_PG_CUSTOM_TIMING_HSYNCW, c_uint32)[1] * (
video_mode.timing.hswidth = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_HSYNCW, c_uint32)[1] * (
-1 if h_sync_polarity else 1)
video_mode.timing.vswidth = self.__io.get(TSI_PG_CUSTOM_TIMING_VSYNCW, c_uint32)[1] * (
video_mode.timing.vswidth = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_VSYNCW, c_uint32)[1] * (
-1 if v_sync_polarity else 1)
video_mode.timing.frame_rate = self.__io.get(TSI_PG_CUSTOM_TIMING_FIELD_RATE, c_uint32)[1]
video_mode.timing.frame_rate = self.__io.get(ci.TSI_PG_CUSTOM_TIMING_FIELD_RATE, c_uint32)[1]
return video_mode
def _become_active(self):
self.__io.set(TSI_PG_STREAM_SELECT, self.__stream)
self.__io.set(ci.TSI_PG_STREAM_SELECT, self.__stream)
def __read_pg_settings(self):
self.__io.set(TSI_PG_COMMAND_W, 2)
self.__io.set(ci.TSI_PG_COMMAND_W, 2)
def apply(self) -> bool:
"""
@@ -471,7 +484,7 @@ class PatternGenerator:
Returns:
object of bool type - settings were set successfully or not
"""
self.__io.set(TSI_PG_COMMAND_W, 3)
self.__io.set(ci.TSI_PG_COMMAND_W, 3)
def is_apply_pg_success(pg: PatternGenerator):
return pg.status().error == PGStatus.PGError.OK
@@ -487,7 +500,7 @@ class PatternGenerator:
object of PGStatus type.
"""
self._become_active()
return PGStatus(self.__io.get(TSI_PG_STATUS_R, c_uint32)[1])
return PGStatus(self.__io.get(ci.TSI_PG_STATUS_R, c_uint32)[1])
def reset(self):
"""
@@ -631,7 +644,7 @@ class DpPatternGenerator(PatternGenerator):
self.__as_config = None
return False
self.__io.set(TSI_PG_ADAPTIVE_SYNC_CTRL,
self.__io.set(p_ci.TSI_PG_ADAPTIVE_SYNC_CTRL,
get_as_params_value(self.__as_config),
data_count=len(get_as_params_value(self.__as_config)))
return True
@@ -659,8 +672,8 @@ class DpPatternGenerator(PatternGenerator):
return False
value = 1
value |= (1 << 31)
self.__io.set(TSI_PG_CUSTOM_PATTERN_SCROLLING_CONTROL, value, c_uint32)
self.__io.set(TSI_PG_CUSTOM_PATTERN_SCROLLING_CONFIG, get_pattern_params_value(self.__scrolling_params),
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_SCROLLING_CONTROL, value, c_uint32)
self.__io.set(ci.TSI_PG_CUSTOM_PATTERN_SCROLLING_CONFIG, get_pattern_params_value(self.__scrolling_params),
data_count=len(get_pattern_params_value(self.__scrolling_params)))
return True
return False
@@ -675,9 +688,9 @@ class DpPatternGenerator(PatternGenerator):
"""
self._become_active()
res = self.__io.get(TSI_PG_ADAPTIVE_SYNC_STS, c_uint32)
res = self.__io.get(p_ci.TSI_PG_ADAPTIVE_SYNC_STS, c_uint32)
if res[0] < TSI_SUCCESS:
if res[0] < ci.TSI_SUCCESS:
return False
return res[1] & 1 != 0
@@ -894,5 +907,5 @@ class DpMstPatternGenerator:
return self.__pg_list[0].panel_replay()
def __read_max_stream_count(self) -> int:
result = self.__io.get(TSI_PG_MAX_STREAM_COUNT_R, c_uint32)
result = self.__io.get(ci.TSI_PG_MAX_STREAM_COUNT_R, c_uint32)
return result[1]

View File

@@ -10,18 +10,18 @@ class SolidColorParams:
"""
def __init__(self, first: int = 0, second: int = 0, third: int = 0):
if not (0 <= first <= 255):
warnings.warn("Incorrect value. Must use value from range: 0 - 255. Will be used default value = 0")
if not (0 <= first < (1 << 16)):
warnings.warn("Incorrect value. Must use value from range: 0 - 65535. Will be used default value = 0")
first = 0
self.first = first
if not (0 <= second <= 255):
warnings.warn("Incorrect value. Must use value from range: 0 - 255. Will be used default value = 0")
if not (0 <= second < (1 << 16)):
warnings.warn("Incorrect value. Must use value from range: 0 - 65535. Will be used default value = 0")
second = 0
self.second = second
if not (0 <= third <= 255):
warnings.warn("Incorrect value. Must use value from range: 0 - 255. Will be used default value = 0")
if not (0 <= third < (1 << 16)):
warnings.warn("Incorrect value. Must use value from range: 0 - 65535. Will be used default value = 0")
third = 0
self.third = third

View File

@@ -1,8 +1,5 @@
from UniTAP.common import ColorInfo, VideoMode
from UniTAP.libs.lib_tsi.tsi_types import TSI_IMF_PK444_RGB_W8_C8, TSI_IMF_PK444_RGB_W16_C12, \
TSI_IMF_PK444_RGB_W16_C16, TSI_IMF_PK444_YCbCr_W8_C8, TSI_IMF_PK444_YCbCr_W16_C16, \
TSI_IMF_PK422_CbYCrY_W16_C8, TSI_IMF_PK422_CbYCrY_W16_C16, TSI_IMF_PK420_CxYY0_W8_C8, \
TSI_IMF_PK420_CxYY0_W8_C10, TSI_IMF_PK420_CxYY_W16_C12, TSI_IMF_PK420_CxYY_W16_C16
import UniTAP.libs.lib_tsi.tsi_types as ci
from .types import PGColorInfo, PGColorDepth, PGColorimetry, PGDynamicRange
@@ -106,30 +103,30 @@ def pg_pixel_format_from_vm(vm: VideoMode) -> int:
if color_format == ColorInfo.ColorFormat.CF_RGB:
if bpc == 8:
return TSI_IMF_PK444_RGB_W8_C8
return ci.TSI_IMF_PK444_RGB_W8_C8
elif bpc in [10, 12]:
return TSI_IMF_PK444_RGB_W16_C12
return ci.TSI_IMF_PK444_RGB_W16_C12
elif bpc == 16:
return TSI_IMF_PK444_RGB_W16_C16
return ci.TSI_IMF_PK444_RGB_W16_C16
elif color_format == ColorInfo.ColorFormat.CF_YCbCr_444:
if bpc == 8:
return TSI_IMF_PK444_YCbCr_W8_C8
return ci.TSI_IMF_PK444_YCbCr_W8_C8
elif bpc in [10, 12, 16]:
return TSI_IMF_PK444_YCbCr_W16_C16
return ci.TSI_IMF_PK444_YCbCr_W16_C16
elif color_format == ColorInfo.ColorFormat.CF_YCbCr_422:
if bpc == 8:
return TSI_IMF_PK422_CbYCrY_W16_C8
return ci.TSI_IMF_PK422_CbYCrY_W16_C8
elif bpc in [10, 12, 16]:
return TSI_IMF_PK422_CbYCrY_W16_C16
return ci.TSI_IMF_PK422_CbYCrY_W16_C16
elif color_format == ColorInfo.ColorFormat.CF_YCbCr_420:
if bpc == 8:
return TSI_IMF_PK420_CxYY0_W8_C8
return ci.TSI_IMF_PK420_CxYY0_W8_C8
elif bpc == 10:
return TSI_IMF_PK420_CxYY0_W8_C10
return ci.TSI_IMF_PK420_CxYY0_W8_C10
elif bpc == 12:
return TSI_IMF_PK420_CxYY_W16_C12
return ci.TSI_IMF_PK420_CxYY_W16_C12
elif bpc == 16:
return TSI_IMF_PK420_CxYY_W16_C16
return ci.TSI_IMF_PK420_CxYY_W16_C16
return 0xffffffff

View File

@@ -93,10 +93,9 @@ def get_as_params_value(params: ASParams) -> list:
params.increase_lines, params.decrease_lines]
def get_pattern_params_value(params: Union[PGPatternParams, PGScrollingParams], bpc: int = 8) -> list:
def get_pattern_params_value(params: Union[PGPatternParams, PGScrollingParams], solid_color_shifter = 8) -> list:
if isinstance(params, SolidColorParams):
up_shift = 16 - bpc
return [(((params.first << up_shift) << 16) | (params.second << up_shift)), (params.third << up_shift)]
return [(params.first << solid_color_shifter << 16) | (params.second << solid_color_shifter), params.third << solid_color_shifter]
elif isinstance(params, WhiteVStripsParams):
return [params.white_stripes_width, params.black_stripes_width]
elif isinstance(params, GradientStripsParams):
@@ -107,3 +106,5 @@ def get_pattern_params_value(params: Union[PGPatternParams, PGScrollingParams],
return [params.white_square]
elif isinstance(params, StepsScrollingParams):
return [params.frames, params.horizontally, params.frames, params.vertically]
else:
raise ValueError("Unsupported pattern params type")

View File

@@ -1,5 +1,6 @@
from .port import TSIPort, MemoryManager, PortIO, Capturer
from .modules.ag.ag import AudioGenerator
from .modules.packet_generator.packet_generator import PacketGenerator
class TX(TSIPort):
@@ -12,6 +13,7 @@ class TX(TSIPort):
super().__init__(port_io, memory_manager, capturer)
self.__ag = AudioGenerator(port_io, memory_manager)
self.__sdpg = PacketGenerator(port_io, memory_manager)
@property
def ag(self) -> AudioGenerator:
@@ -23,3 +25,14 @@ class TX(TSIPort):
object of `AudioGenerator` type.
"""
return self.__ag
@property
def sdpg(self) -> PacketGenerator:
"""
Should be used to control `PacketGenerator` on Source (TX - transmitter) role.
Returns:
object of `PacketGenerator` type.
"""
return self.__sdpg