更新UCD-API库及文档
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
30
UniTAP/dev/ports/hdrx_earc.py
Normal file
30
UniTAP/dev/ports/hdrx_earc.py
Normal 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
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
158
UniTAP/dev/ports/modules/ag/earc.py
Normal file
158
UniTAP/dev/ports/modules/ag/earc.py
Normal 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
|
||||
@@ -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),
|
||||
]
|
||||
|
||||
@@ -10,7 +10,8 @@ class AudioPattern(IntEnum):
|
||||
SignalSquare = 2
|
||||
CustomAudio = 3
|
||||
SignalIncremental = 4
|
||||
Unknown = 5
|
||||
SignalPing = 5
|
||||
Unknown = 6
|
||||
|
||||
|
||||
class AGStatus(IntEnum):
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
2
UniTAP/dev/ports/modules/earc/__init__.py
Normal file
2
UniTAP/dev/ports/modules/earc/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .earc_types import EarcMode
|
||||
from .earc_tx import EarcTx
|
||||
83
UniTAP/dev/ports/modules/earc/earc_tx.py
Normal file
83
UniTAP/dev/ports/modules/earc/earc_tx.py
Normal 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)
|
||||
|
||||
|
||||
|
||||
112
UniTAP/dev/ports/modules/earc/earc_types.py
Normal file
112
UniTAP/dev/ports/modules/earc/earc_types.py
Normal 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))
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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.")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 = ""
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
"""
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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" \
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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]:
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
1
UniTAP/dev/ports/modules/packet_generator/__init__.py
Normal file
1
UniTAP/dev/ports/modules/packet_generator/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .packet_generator import PacketGenerator
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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))
|
||||
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user