1.1.0版本

This commit is contained in:
xinzhu.yin
2026-04-16 16:51:05 +08:00
commit c157e774e5
333 changed files with 70759 additions and 0 deletions

View File

@@ -0,0 +1 @@
from .bulk_types import TriggerType, TriggerPosition, TriggerTypeEnum

View File

@@ -0,0 +1,132 @@
import warnings
import time
from typing import Optional
from UniTAP.dev.modules.capturer.capture import Capturer, CaptureConfig
from UniTAP.dev.modules.memory_manager import MemoryManager
from UniTAP.dev.ports.modules.capturer.bulk.bulk_types import (TriggerPosition, TriggerVarType, _get_trigger_value,
EncodingTypeEnum, LaneCountEnum)
from UniTAP.dev.ports.modules.capturer.bulk.result_bulk import ResultBulkObject
megabyte = 1024 * 1024
class BulkCapturer:
"""
Class `BulkCapturer` allows working with capturing Bulk data on Sink (RX - receiver) side.
You can `start` capturing in several modes, `stop` capturing, getting current `status` and result of
capturing `capture_result`.
"""
def __init__(self, capturer: Capturer, memory_manager: MemoryManager):
self.__capturer = capturer
self.__memory_manager = memory_manager
self.__trigger_position = TriggerPosition.TP_Start
self.__result = ResultBulkObject()
@property
def status(self):
"""
Returns current bulk capturer status.
Returns:
object of `VideoCaptureStatus` type
"""
return self.__capturer.bulk_capturer_status
@property
def capture_result(self) -> ResultBulkObject:
"""
Returns result of bulk capturing.
Returns:
object of `ResultBulkObject` type
"""
return self.__result
@property
def encoding_type(self) -> EncodingTypeEnum:
"""
Returns current encoding type of capturing.
Returns:
object of `EncodingTypeEnum` type
"""
return self.__capturer.read_encoding_type()
@property
def lane_count(self) -> LaneCountEnum:
"""
Returns current lane count for capturing.
Returns:
object of `LaneCountEnum` type
"""
return self.__capturer.read_lane_count()
def start(self, bulk_size: int = 1, trigger_position: TriggerPosition = TriggerPosition.TP_Start,
trigger_config: Optional[TriggerVarType] = None, assume_scrambler: bool = False, gpio: bool = False,
encoding_type: Optional[EncodingTypeEnum] = None, lane_count: Optional[LaneCountEnum] = None):
"""
Start capturing. All results can be obtained using the function `capture_result`.
Args:
bulk_size (int) - bulk data size in megabytes
trigger_position (`TriggerPosition`)
trigger_config (`TriggerVarType`|None)
assume_scrambler (bool)
gpio (bool)
encoding_type (`EncodingTypeEnum`|None)
lane_count (`LaneCountEnum`|None)
"""
self.__result.clear()
if trigger_config is None:
trigger_position = TriggerPosition.TP_Start
capture_config = CaptureConfig()
capture_config.video = True
capture_config.event = True
capture_config.audio = True
capture_config.type = CaptureConfig.Type.LIVE
self.__capturer.stop_capture(capture_config)
self.__capturer.stop_bulk_capture()
self.__capturer.clear_bulk_buffer()
max_bulk_block_bytes = self.__memory_manager.get_total_memory() - self.__memory_manager.RESERVED_MEMORY_BYTES
bulk_block_bytes = max_bulk_block_bytes if bulk_size * megabyte > max_bulk_block_bytes else bulk_size * megabyte
self.__memory_manager.set_memory_layout([bulk_block_bytes])
self.__capturer.write_bulk_size(bulk_block_bytes)
if encoding_type is None:
encoding_type = EncodingTypeEnum.Encoding_Auto
self.__capturer.write_encoding_type(encoding_type)
if lane_count is None:
lane_count = LaneCountEnum.Auto
self.__capturer.write_lane_count(lane_count)
if self.__capturer.read_bulk_capture_caps().bitGrabWidth:
self.__capturer.write_bulk_gpio(gpio)
self.__capturer.write_bulk_trigger_position(trigger_position.value)
if self.__capturer.read_bulk_capture_caps().triggers:
self.__capturer.write_bulk_trigger_settings(*_get_trigger_value(trigger_config,
self.__capturer.read_bulk_trigger_caps()))
else:
warnings.warn("Triggers are not supported.")
self.__result.assume_scrambler_disabled = assume_scrambler
self.__result.start_capture_time = time.time()
self.__capturer.start_bulk_capture()
self.__result.buffer.extend(self.__capturer.bulk_capture(bulk_block_bytes, trigger_config))
def stop(self):
"""
Stop capture video.
"""
self.__capturer.stop_bulk_capture()
self.__result.end_capture_time = time.time()

View File

@@ -0,0 +1,979 @@
from enum import IntEnum
from typing import TypeVar, Optional
class EncodingTypeEnum(IntEnum):
Encoding_Auto = 0,
Encoding_10Bit = 1,
Encoding_32Bit = 2
class LaneCountEnum(IntEnum):
Auto = 0,
Lane_1 = 1,
Lane_2 = 2,
Lane_4 = 4
class TriggerPosition(IntEnum):
"""
Trigger position relative to the start of capture, in percent of total capture size.
- TP_Start 0%
- TP_25 25%
- TP_50 50%
- TP_75 75%
- TP_End - 100%
"""
TP_Start = 0
TP_25 = 1
TP_50 = 2
TP_75 = 3
TP_End = 4
class TriggerTypeEnum:
"""
Class `TriggerTypeEnum` contains all necessary enum types for describing values.
"""
class SourceType(IntEnum):
TPS1 = 0
TPS2 = 1
TPS3 = 2
TPS4 = 3
class SourceTypePosition(IntEnum):
InitialLT = 0
AfterALPM = 1
InitialLTORAfterALPM = 2
class SourceMLPHY(IntEnum):
Standby = 0
Sleep = 1
class SourceVBIDWithMask(IntEnum):
AnyVB_IDChange = 0
VB_IDMatchWithMask = 1
ChangeAnyBitSetInMask = 2
class SourceVBID(IntEnum):
BS = 0
SR = 1
CPBS = 2
CPSR = 3
class SDPTypeReceived(IntEnum):
MatchHB0 = 1
MatchHB1 = 2
MatchHB0AndHB1 = 3
class MSA(IntEnum):
AnyMSAChange = 0
ChangeMSAAttribute = 1
MatchMSAAttribute = 2
class Error8b_10b(IntEnum):
CodeError = 0
DisparityError = 0
Both = 0
class TypeAUX(IntEnum):
NativeWrite = 0x8
NativeRead = 0x9
class TriggerType:
"""
Main class `TriggerType` defines possible variants of trigger types.
- `U1` - Start of TPS1/TPS2/TPS3/TPS4 - initial LT, after ALPM exit, both.
- `U2` - Exit of TPS1/TPS2/TPS3/TPS4 - initial LT, after ALPM exit, both.
- `U3` - Start of ML_PHY_STANDBY or ML_PHY_SLEEP.
- `U4` - Exit of ML_PHY_STANDBY or ML_PHY_SLEEP.
- `U5` - Start of EIEOS - initial LT, after ALPM exit, both.
- `U6` - Exit of EIEOS - initial LT, after ALPM exit, both.
- `U7` - VB-ID with the MASK - any change, match, selected bit transition.
- `U8` - VB-ID on TYPE - BS/SR/CPBS/CPSR.
- `U9` - Up to 8 control or data symbols, 8b/10b encoded.
- `U10` - SDP Type received HB0 and/or HB1 match.
- `U11` - MSA any change, change by mask, match by mask.
- `U12` - 8b/10b error code error, disparity error, both.
- `U13` - Any AUX transaction - initial LT, after ALPM exit, both.
- `U17` - AUX read or write of specific address.
"""
class U1:
"""
Class `U1` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get source type `source_type` - `TriggerTypeEnum.SourceType`.
- Set and get position `position` - `TriggerTypeEnum.SourceTypePosition.
"""
def __init__(self):
self.__trigger_mask = 1
self.__source_type = TriggerTypeEnum.SourceType.TPS1
self.__position = TriggerTypeEnum.SourceTypePosition.InitialLT
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source_type(self) -> TriggerTypeEnum.SourceType:
"""
Returns source type.
Returns:
object of `TriggerTypeEnum.SourceType` value
"""
return self.__source_type
@property
def position(self) -> TriggerTypeEnum.SourceTypePosition:
"""
Returns position.
Returns:
object of `TriggerTypeEnum.SourceTypePosition` value
"""
return self.__position
@source_type.setter
def source_type(self, value: TriggerTypeEnum.SourceType):
self.__source_type = value
@position.setter
def position(self, value: TriggerTypeEnum.SourceTypePosition):
self.__position = value
class U2:
"""
Class `U2` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get source type `source_type` - `TriggerTypeEnum.SourceType`.
- Set and get position `position` - `TriggerTypeEnum.SourceTypePosition.
"""
def __init__(self):
self.__trigger_mask = 1 << 1
self.__source_type = TriggerTypeEnum.SourceType.TPS1
self.__position = TriggerTypeEnum.SourceTypePosition.InitialLT
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source_type(self) -> TriggerTypeEnum.SourceType:
"""
Returns source type.
Returns:
object of `TriggerTypeEnum.SourceType` value
"""
return self.__source_type
@property
def position(self) -> TriggerTypeEnum.SourceTypePosition:
"""
Returns position.
Returns:
object of `TriggerTypeEnum.SourceTypePosition` value
"""
return self.__position
@source_type.setter
def source_type(self, value: TriggerTypeEnum.SourceType):
self.__source_type = value
@position.setter
def position(self, value: TriggerTypeEnum.SourceTypePosition):
self.__position = value
class U3:
"""
Class `U3` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get source `source` - `TriggerTypeEnum.SourceMLPHY`.
"""
def __init__(self):
self.__trigger_mask = 1 << 2
self.__source = TriggerTypeEnum.SourceMLPHY.Standby
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source(self) -> TriggerTypeEnum.SourceMLPHY:
"""
Returns source.
Returns:
object of `TriggerTypeEnum.SourceMLPHY` value
"""
return self.__source
@source.setter
def source(self, value: TriggerTypeEnum.SourceMLPHY):
self.__source = value
class U4:
"""
Class `U4` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get source `source` - `TriggerTypeEnum.SourceMLPHY`.
"""
def __init__(self):
self.__trigger_mask = 1 << 3
self.__source = TriggerTypeEnum.SourceMLPHY.Standby
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source(self) -> TriggerTypeEnum.SourceMLPHY:
"""
Returns source.
Returns:
object of `TriggerTypeEnum.SourceMLPHY` value
"""
return self.__source
@source.setter
def source(self, value: TriggerTypeEnum.SourceMLPHY):
self.__source = value
class U5:
"""
Class `U5` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get position `position` - `TriggerTypeEnum.SourceTypePosition`.
"""
def __init__(self):
self.__trigger_mask = 1 << 4
self.__position = TriggerTypeEnum.SourceTypePosition.InitialLT
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def position(self) -> TriggerTypeEnum.SourceTypePosition:
"""
Returns position.
Returns:
object of `TriggerTypeEnum.SourceTypePosition` value
"""
return self.__position
@position.setter
def position(self, value: TriggerTypeEnum.SourceTypePosition):
self.__position = value
class U6:
"""
Class `U6` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get position `position` - `TriggerTypeEnum.SourceTypePosition`.
"""
def __init__(self):
self.__trigger_mask = 1 << 5
self.__position = TriggerTypeEnum.SourceTypePosition.InitialLT
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def position(self) -> TriggerTypeEnum.SourceTypePosition:
"""
Returns position.
Returns:
object of `TriggerTypeEnum.SourceTypePosition` value
"""
return self.__position
@position.setter
def position(self, value: TriggerTypeEnum.SourceTypePosition):
self.__position = value
class U7:
"""
Class `U7` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get mask `mask`.
- Set and get source `source` - `TriggerTypeEnum.SourceVBIDWithMask`.
"""
def __init__(self):
self.__trigger_mask = 1 << 6
self.__source = TriggerTypeEnum.SourceVBIDWithMask.AnyVB_IDChange
self.__mask = 0
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source(self) -> TriggerTypeEnum.SourceVBIDWithMask:
"""
Returns source.
Returns:
object of `TriggerTypeEnum.SourceVBIDWithMask` value
"""
return self.__source
@property
def mask(self) -> int:
"""
Returns mask.
Returns:
object of int value
"""
return self.__mask
@source.setter
def source(self, value: TriggerTypeEnum.SourceVBIDWithMask):
self.__source = value
@mask.setter
def mask(self, value: int):
if value < 0:
raise ValueError("Mask must be more than 0.")
self.__mask = value
class U8:
"""
Class `U8` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get source `source` - `TriggerTypeEnum.SourceVBID`.
"""
def __init__(self):
self.__trigger_mask = 1 << 7
self.__source = TriggerTypeEnum.SourceVBID.BS
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source(self) -> TriggerTypeEnum.SourceVBID:
"""
Returns source.
Returns:
object of `TriggerTypeEnum.SourceVBID` value
"""
return self.__source
@source.setter
def source(self, value: TriggerTypeEnum.SourceVBID):
self.__source = value
class U9:
"""
Class `U9` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get value for count of symbols `count`.
- Set and get value for symbol 0 `symbol_0`.
- Set and get value for symbol 1 `symbol_1`.
- Set and get value for symbol 2 `symbol_2`.
- Set and get value for symbol 3 `symbol_3`.
- Set and get value for symbol 4 `symbol_4`.
- Set and get value for symbol 5 `symbol_5`.
- Set and get value for symbol 6 `symbol_6`.
- Set and get value for symbol 7 `symbol_7`.
"""
def __init__(self):
self.__trigger_mask = 1 << 8
self.__symbol_0 = 0
self.__symbol_1 = 0
self.__symbol_2 = 0
self.__symbol_3 = 0
self.__symbol_4 = 0
self.__symbol_5 = 0
self.__symbol_6 = 0
self.__symbol_7 = 0
self.__count = 0
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def count(self) -> int:
"""
Returns count of symbols.
Returns:
object of int value
"""
return self.__count
@count.setter
def count(self, value: int):
if value < 0:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__count = value
@property
def symbol_0(self) -> int:
"""
Returns value of symbol 0.
Returns:
object of int value
"""
return self.__symbol_0
@symbol_0.setter
def symbol_0(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_0 = value
@property
def symbol_1(self) -> int:
"""
Returns value of symbol 1.
Returns:
object of int value
"""
return self.__symbol_1
@symbol_1.setter
def symbol_1(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_1 = value
@property
def symbol_2(self) -> int:
"""
Returns value of symbol 2.
Returns:
object of int value
"""
return self.__symbol_2
@symbol_2.setter
def symbol_2(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_2 = value
@property
def symbol_3(self) -> int:
"""
Returns value of symbol 3.
Returns:
object of int value
"""
return self.__symbol_3
@symbol_3.setter
def symbol_3(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_3 = value
@property
def symbol_4(self) -> int:
"""
Returns value of symbol 4.
Returns:
object of int value
"""
return self.__symbol_4
@symbol_4.setter
def symbol_4(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_4 = value
@property
def symbol_5(self) -> int:
"""
Returns value of symbol 5.
Returns:
object of int value
"""
return self.__symbol_5
@symbol_5.setter
def symbol_5(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_5 = value
@property
def symbol_6(self) -> int:
"""
Returns value of symbol 6.
Returns:
object of int value
"""
return self.__symbol_6
@symbol_6.setter
def symbol_6(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_6 = value
@property
def symbol_7(self) -> int:
"""
Returns value of symbol 7.
Returns:
object of int value
"""
return self.__symbol_7
@symbol_7.setter
def symbol_7(self, value: int):
if value < 0 or len(str(value)) >= 5:
raise ValueError("Mask must be more than 0 and length must be less than 5")
self.__symbol_7 = value
class U10:
"""
Class `U10` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get SDP type `sdp_type` - `TriggerTypeEnum.SDPTypeReceived`.
- Set and get value for HB 0 `hb0`.
- Set and get value for HB 1 `hb1`.
"""
def __init__(self):
self.__trigger_mask = 1 << 9
self.__sdp_type = TriggerTypeEnum.SDPTypeReceived.MatchHB0
self.__hb0 = 0
self.__hb1 = 0
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def sdp_type(self) -> TriggerTypeEnum.SDPTypeReceived:
"""
Returns SDP type.
Returns:
object of `TriggerTypeEnum.SDPTypeReceived` value
"""
return self.__sdp_type
@sdp_type.setter
def sdp_type(self, value: TriggerTypeEnum.SDPTypeReceived):
self.__sdp_type = value
@property
def hb0(self) -> int:
"""
Returns value of HB0.
Returns:
object of int value
"""
return self.__hb0
@hb0.setter
def hb0(self, value: int):
if value < 0:
raise ValueError("Mask must be more than 0.")
self.__hb0 = value
@property
def hb1(self) -> int:
"""
Returns value of HB1.
Returns:
object of int value
"""
return self.__hb1
@hb1.setter
def hb1(self, value: int):
if value < 0:
raise ValueError("Mask must be more than 0.")
self.__hb1 = value
class U11:
"""
Class `U11` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get source `source` - `TriggerTypeEnum.MSA`.
- Set and get MSa attributes (mvid, nvid, hactive, vactive and so on.)
"""
def __init__(self):
self.__trigger_mask = 1 << 10
self.__source = TriggerTypeEnum.MSA.AnyMSAChange
self.mvid_flag = False
self.nvid_flag = False
self.hactive_flag = False
self.vactive_flag = False
self.htotal_flag = False
self.vtotal_flag = False
self.hsyncw_flag = False
self.vsyncw_flag = False
self.hsyncp_flag = False
self.vsyncp_flag = False
self.hsyncs_flag = False
self.vsyncs_flag = False
self.misc0_flag = False
self.misc1_flag = False
self.mvid = 0
self.nvid = 0
self.hactive = 0
self.vactive = 0
self.htotal = 0
self.vtotal = 0
self.hsyncw = 0
self.vsyncw = 0
self.hsyncs = 0
self.vsyncs = 0
self.misc0 = 0
self.misc1 = 0
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source(self) -> TriggerTypeEnum.MSA:
"""
Returns source.
Returns:
object of `TriggerTypeEnum.MSA` value
"""
return self.__source
@source.setter
def source(self, value: TriggerTypeEnum.MSA):
self.__source = value
class U12:
"""
Class `U12` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get source `source` - `TriggerTypeEnum.Error8b_10b`.
"""
def __init__(self):
self.__trigger_mask = 1 << 11
self.__source = TriggerTypeEnum.Error8b_10b.CodeError
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def source(self) -> TriggerTypeEnum.Error8b_10b:
"""
Returns source.
Returns:
object of `TriggerTypeEnum.Error8b_10b` value
"""
return self.__source
@source.setter
def source(self, value: TriggerTypeEnum.Error8b_10b):
self.__source = value
class U13:
"""
Class `U13` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get position `position` - `TriggerTypeEnum.SourceTypePosition`.
"""
def __init__(self):
self.__trigger_mask = 1 << 12
self.__position = TriggerTypeEnum.SourceTypePosition.InitialLT
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def position(self) -> TriggerTypeEnum.SourceTypePosition:
"""
Returns position.
Returns:
object of `TriggerTypeEnum.SourceTypePosition` value
"""
return self.__position
@position.setter
def position(self, value: TriggerTypeEnum.SourceTypePosition):
self.__position = value
class U17:
"""
Class `U17` describes one of the possible trigger type. Allows:
- Get trigger mask `trigger_mask`.
- Set and get address `address`.
- Set and get type `type` - `TriggerTypeEnum.TypeAUX`.
"""
def __init__(self):
self.__trigger_mask = 1 << 16
self.__address = 0
self.__type = TriggerTypeEnum.TypeAUX.NativeWrite
@property
def trigger_mask(self) -> int:
"""
Returns trigger mask.
Returns:
object of int value
"""
return self.__trigger_mask
@property
def address(self) -> int:
"""
Returns address.
Returns:
object of int value
"""
return self.__address
@address.setter
def address(self, value: int):
if value < 0:
raise ValueError("Mask must be more than 0.")
self.__address = value
@property
def type(self) -> TriggerTypeEnum.TypeAUX:
"""
Returns type.
Returns:
object of `TriggerTypeEnum.TypeAUX` value
"""
return self.__type
@type.setter
def type(self, value: TriggerTypeEnum.TypeAUX):
self.__type = value
TriggerVarType = TypeVar("TriggerVarType", TriggerType.U1, TriggerType.U2, TriggerType.U3, TriggerType.U4,
TriggerType.U5, TriggerType.U6, TriggerType.U7, TriggerType.U8, TriggerType.U9,
TriggerType.U10, TriggerType.U11, TriggerType.U12, TriggerType.U13, TriggerType.U17)
def _get_trigger_value(value: Optional[TriggerVarType], caps: int):
trigger_config = [0] * 39
trigger_config_ext = [0] * 35
if value is None:
return 0, trigger_config, trigger_config_ext
if isinstance(value, TriggerType.U1) and caps & 0x1:
trigger_config[0] |= value.source_type.value
trigger_config[0] |= (value.position.value << 4)
if isinstance(value, TriggerType.U2) and (caps >> 1) & 0x1:
trigger_config[1] |= value.source_type.value
trigger_config[1] |= (value.position.value << 4)
if isinstance(value, TriggerType.U3) and (caps >> 2) & 0x1:
trigger_config[2] |= value.source.value
if isinstance(value, TriggerType.U4) and (caps >> 3) & 0x1:
trigger_config[3] |= value.source.value
if isinstance(value, TriggerType.U5) and (caps >> 4) & 0x1:
trigger_config[4] |= value.position.value << 4
if isinstance(value, TriggerType.U6) and (caps >> 5) & 0x1:
trigger_config[5] |= value.position.value << 4
if isinstance(value, TriggerType.U7) and (caps >> 6) & 0x1:
trigger_config[6] |= value.source.value
trigger_config[6] |= value.mask.value << 8
if isinstance(value, TriggerType.U8) and (caps >> 7) & 0x1:
trigger_config[7] |= value.source.value
if isinstance(value, TriggerType.U9) and (caps >> 8) & 0x1:
trigger_config[8] |= value.count
if value.symbol_0:
trigger_config_ext[0] |= value.symbol_0
if value.symbol_1:
trigger_config_ext[0] |= (value.symbol_1 << 16)
if value.symbol_0:
trigger_config_ext[1] |= value.symbol_2
if value.symbol_0:
trigger_config_ext[1] |= (value.symbol_3 << 16)
if value.symbol_0:
trigger_config_ext[2] |= value.symbol_4
if value.symbol_0:
trigger_config_ext[2] |= (value.symbol_5 << 16)
if value.symbol_0:
trigger_config_ext[3] |= value.symbol_6
if value.symbol_0:
trigger_config_ext[3] |= (value.symbol_7 << 16)
if isinstance(value, TriggerType.U10) and (caps >> 10) & 0x1:
trigger_config[9] |= value.sdp_type.value
trigger_config[9] |= (value.hb0 << 8)
trigger_config[9] |= (value.hb1 << 16)
if isinstance(value, TriggerType.U11) and (caps >> 11) & 0x1:
trigger_config[10] |= value.source.value
trigger_config[10] |= value.source
trigger_config[10] |= (1 << 8) if value.mvid_flag else 0
trigger_config[10] |= (1 << 9) if value.nvid_flag else 0
trigger_config[10] |= (1 << 10) if value.htotal_flag else 0
trigger_config[10] |= (1 << 11) if value.vtotal_flag else 0
trigger_config[10] |= (1 << 12) if value.hactive_flag else 0
trigger_config[10] |= (1 << 13) if value.vactive_flag else 0
trigger_config[10] |= (1 << 14) if value.hsyncw_flag else 0
trigger_config[10] |= (1 << 15) if value.vsyncw_flag else 0
trigger_config[10] |= (1 << 16) if value.hsyncp_flag else 0
trigger_config[10] |= (1 << 17) if value.vsyncp_flag else 0
trigger_config[10] |= (1 << 18) if value.hsyncs_flag else 0
trigger_config[10] |= (1 << 19) if value.vsyncs_flag else 0
trigger_config[10] |= (1 << 20) if value.misc0_flag else 0
trigger_config[10] |= (1 << 21) if value.misc1_flag else 0
if value.mvid_flag:
trigger_config_ext[4] |= value.mvid & 0xFFFFFF
if value.nvid_flag:
trigger_config_ext[5] |= value.nvid & 0xFFFFFF
if value.htotal_flag:
trigger_config_ext[6] |= value.htotal & 0xFFFF
if value.vtotal_flag:
trigger_config_ext[6] |= ((value.vtotal & 0xFFFF) << 16)
if value.hactive_flag:
trigger_config_ext[7] |= value.hactive & 0xFFFF
if value.vactive_flag:
trigger_config_ext[7] |= ((value.vactive & 0xFFFF) << 16)
if value.hsyncw_flag:
trigger_config_ext[8] |= value.hsyncw & 0x7FFF
if value.hsyncp_flag:
trigger_config_ext[8] |= (value.hsyncp_flag << 15)
if value.vsyncw_flag:
trigger_config_ext[8] |= ((value.vsyncw & 0x7FFF) << 16)
if value.vsyncp_flag:
trigger_config_ext[8] |= (value.vsyncp_flag << 31)
if value.hsyncs_flag:
trigger_config_ext[9] |= value.hsyncs & 0xFFFF
if value.vsyncs_flag:
trigger_config_ext[9] |= ((value.vsyncs & 0xFFFF) << 16)
if value.misc0_flag:
trigger_config_ext[10] |= value.misc0 & 0xFF
if value.misc1_flag:
trigger_config_ext[10] |= ((value.misc1 & 0xFF) << 8)
if isinstance(value, TriggerType.U12) and (caps >> 11) & 0x1:
trigger_config[11] |= value.position
if isinstance(value, TriggerType.U13) and (caps >> 12) & 0x1:
trigger_config[12] |= (value.position << 4)
if isinstance(value, TriggerType.U17) and (caps >> 16) & 0x1:
trigger_config[16] |= (value.type.value << 24) | value.address
return value.trigger_mask, trigger_config, trigger_config_ext

View File

@@ -0,0 +1,45 @@
from ctypes import Structure, c_uint8, c_uint16, c_uint32, c_uint64
class BulkHeader(Structure):
class Attributes(Structure):
_fields_ = [
('LINK_BW', c_uint8),
('LANE_COUNT', c_uint8, 4),
('Packing1', c_uint8, 1),
('Packing', c_uint8, 2),
('MST', c_uint8, 1),
('n_val', c_uint16),
]
_fields_ = [
('Sync', c_uint32),
('Tns', c_uint32),
('SourcId', c_uint32),
('Length', c_uint32),
('TimeStamp', c_uint64),
('Sync', c_uint32),
('Attribute', Attributes)
]
class CaptureCaps(Structure):
_fields_ = [
('triggers', c_uint32, 1),
('multipleTriggersSelection', c_uint32, 1),
('multipleTriggersAndingSelection', c_uint32, 1),
('alpmTriggers', c_uint32, 1),
('', c_uint32, 4),
('grab128_132', c_uint32, 1),
('', c_uint32, 3),
("bitGrabWidth", c_uint32, 4),
("", c_uint32, 16)
]
class SBlock(Structure):
_fields_ = [
('BLOCK', c_uint32),
('OFFSET', c_uint64),
('SIZE', c_uint64),
]

View File

@@ -0,0 +1,60 @@
import os
import warnings
import shutil
from ctypes import sizeof
from datetime import datetime
from UniTAP.dev.modules.capturer.result_object import ResultObject
from UniTAP.dev.modules.capturer.types import CapturedDataType
from UniTAP.dev.ports.modules.capturer.bulk.private_bulk_types import BulkHeader
class ResultBulkObject(ResultObject):
"""
Class `ResultBulkObject` inherited from class `ResultObject`.
Class `ResultBulkObject` allows saving captured data to file `save_to_bin_file`.
Also has all the `ResultObject` functionality.
"""
def __init__(self, assume_scrambler_disabled: bool = False):
super().__init__()
self.assume_scrambler_disabled = assume_scrambler_disabled
def save_to_bin_file(self, directory_name: str):
"""
Saving captured bulk data to file.
Args:
directory_name (str) - path to save
"""
if len(self.buffer) > 0:
if not os.path.exists(directory_name):
os.makedirs(directory_name)
else:
shutil.rmtree(directory_name)
os.makedirs(directory_name)
main_link_file = f'capture_{datetime.now().strftime("%Y%m%d_%H%M%S")}.mainlink.bin'
events_file = f'capture_{datetime.now().strftime("%Y%m%d_%H%M%S")}.events.bin'
for data in self.buffer:
if data.type == CapturedDataType.Event:
e_file = open(os.path.join(directory_name, events_file), 'a+b')
sync = 0x0B41550B
e_file.write(sync.to_bytes(length=4, byteorder='little'))
e_file.write(0x0.to_bytes(length=4, byteorder='little'))
e_file.write(int(data.data[13] & 0xF).to_bytes(length=4, byteorder='little'))
e_file.write(int((len(data.data) - 12) / 4).to_bytes(length=4, byteorder='little'))
e_file.write(data.data[12:])
elif data.type == CapturedDataType.Bulk:
b_file = open(os.path.join(directory_name, main_link_file), 'a+b')
if len(data.data) > sizeof(BulkHeader):
header = BulkHeader.from_buffer(data.data)
if self.assume_scrambler_disabled:
header.Attribute.Packing |= 0x2
b_file.write(bytearray(header))
b_file.write(data.data[sizeof(BulkHeader):])
else:
warnings.warn("Buffer size is equal 0, without bulk data.")
def __str__(self):
return f"Start capture time: {self.start_capture_time}\n" \
f"End capture time: {self.end_capture_time}\n" \
f"Timestamp: {self.timestamp.__str__()}\n"