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,2 @@
from .cec_types import (CECStatus, DeviceType, CecResetDataCommand, LogicalAddressEnum, CECCommand, CECCommand,
DeviceTypeEnum)

View File

@@ -0,0 +1,41 @@
from ctypes import Structure, c_uint32, c_uint16
from .cec_types import DeviceType
class DeviceTypePrivate(Structure):
_fields_ = [
("reserved", c_uint32, 2),
("cecSwitch", c_uint32, 1),
('audioSystem', c_uint32, 1),
('pbDevice', c_uint32, 1),
('tuner', c_uint32, 1),
('recDev', c_uint32, 1),
('tv', c_uint32, 1),
]
@property
def value(self) -> int:
return (self.reserved | self.cecSwitch << 2 | self.audioSystem << 3 | self.pbDevice << 4 | self.tuner << 5
| self.recDev << 6 | self.tv << 7)
@value.setter
def value(self, dev_type: DeviceType):
self.cecSwitch = dev_type.cec_switch
self.audioSystem = dev_type.audio_system
self.pbDevice = dev_type.pb_device
self.tuner = dev_type.tuner
self.recDev = dev_type.rec_dev
self.tv = dev_type.tv
class CECStatusPrivate(Structure):
_fields_ = [
("bufferOverflowed", c_uint32, 1)
]
class CECVersion(Structure):
_fields_ = [
("minor", c_uint16),
("major", c_uint16)
]

View File

@@ -0,0 +1,269 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.libs.lib_tsi.tsi import *
from .cec_types import *
from .cec_private_types import *
from typing import Union
class CecRx:
def __init__(self, port_io: PortIO):
self.__io = port_io
self.__version = self.__read_version()
self.__commands = []
@property
def version(self) -> (int, int):
"""
Read CEC version from the RX side.
Returns:
object of tuple of `int` type
"""
return self.__version
def enable(self, state: bool):
"""
Enable/Disable CEC.
Args:
state (`bool`)
"""
self.__io.set(TSI_HDRX_CEC_CONTROL, state, c_uint32)
def is_enabled(self) -> bool:
"""
Return state of CEC (enabled or not).
Returns:
object of `bool` type
"""
return self.__io.get(TSI_HDRX_CEC_CONTROL, c_uint32)[1] & 0x1 == 1
@property
def logical_address(self) -> LogicalAddressEnum:
"""
Set/Get CEC logical address.
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(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)
@property
def destination(self) -> LogicalAddressEnum:
"""
Set/Get CEC destination address.
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(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)
@property
def phy_address(self) -> int:
"""
Set/Get CEC physical address.
Returns:
object of `int` type
"""
return self.__io.get(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)
@property
def op_code(self) -> int:
"""
Set/Get CEC operation code.
Returns:
object of `int` type
"""
return self.__io.get(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)
@property
def op_code_param(self) -> Union[int, list]:
"""
Set/Get CEC additional parameter for operation code.
Returns:
object of `int` type
"""
return self.__io.get(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)
@property
def device_type(self) -> DeviceType:
"""
Set/Get CEC Device type.
Returns:
object of `DeviceType` type
"""
data = self.__io.get(TSI_HDRX_CEC_DEVICE_TYPE, DeviceTypePrivate)[1]
return DeviceType(data.cecSwitch, data.audioSystem, data.pbDevice, data.tuner, data.recDev, data.tv)
@device_type.setter
def device_type(self, dev_type: Union[DeviceTypeEnum, DeviceType, int]):
if isinstance(dev_type, DeviceType):
dev_type_value = DeviceTypePrivate()
dev_type_value.value = dev_type
value = dev_type_value.value
elif isinstance(dev_type, DeviceTypeEnum):
value = dev_type.value
elif isinstance(dev_type, int):
value = dev_type & 0xFF
else:
raise TypeError(f"Unsupported type: {type(dev_type)}")
self.__io.set(TSI_HDRX_CEC_DEVICE_TYPE, value, c_uint32)
@property
def status(self) -> CECStatus:
"""
Get CEC status.
Returns:
object of `CECStatus` type
"""
data = self.__io.get(TSI_HDRX_CEC_STATUS_R, CECStatusPrivate)[1]
return CECStatus(data.bufferOverflowed)
@property
def command_number(self) -> int:
"""
Get CEC command number.
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDRX_CEC_RECEIVED_CNT_R, c_uint32)[1]
@property
def data(self) -> list:
"""
Get CEC raw data.
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]
def reset_data(self, command: CecResetDataCommand):
"""
Get CEC reset data.
Returns:
object of `CecResetDataCommand` type
"""
self.__io.set(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]
return version.minor, version.major
def add_command(self, command: CECCommand = CECCommand()):
"""
Add CEC command in list.
Args:
command (`CECCommand`)
"""
self.__commands.append(command)
def delete_command(self, index: int = 0):
"""
Delete CEC command in list by index.
Args:
index (`int`)
"""
self.__commands.pop(index)
def send_command(self, logical_address: LogicalAddressEnum = LogicalAddressEnum.Tv,
destination: LogicalAddressEnum = LogicalAddressEnum.Broadcast,
phy_address: int = 0x0, op_code: int = 0x0, op_code_param: Union[int, list] = 0x0,
device_type: Union[DeviceTypeEnum, DeviceType, int] = DeviceTypeEnum.TV):
"""
Send CEC command with the transferred parameters.
Args:
logical_address (`LogicalAddressEnum`)
destination (`LogicalAddressEnum`)
phy_address (`int`)
op_code (`int`)
op_code_param (`int`)
device_type (`DeviceTypeEnum` | `DeviceType`)
"""
self.enable(True)
self.logical_address = logical_address
self.phy_address = phy_address
self.op_code = op_code
self.op_code_param = op_code_param
self.device_type = device_type
self.destination = destination
self.__send_cec_command()
def send_command_by_index(self, index: int):
"""
Send CEC command from the list by index.
Args:
index (`int`)
"""
if len(self.__commands) > 0 and 0 <= index < len(self.__commands):
self.__send_command(self.__commands[index])
def send_commands(self):
"""
Send all saved commands.
"""
for command in self.__commands:
self.__send_command(command)
def __send_command(self, command: CECCommand = CECCommand()):
self.logical_address = command.logical_address
self.destination = command.destination
self.phy_address = command.phy_address
self.op_code = command.op_code
self.op_code_param = command.op_code_param
self.device_type = command.device_type
self.__send_cec_command()
def __send_cec_command(self):
self.__io.set(TSI_HDRX_CEC_COMMAND, 1, c_uint32)
@property
def commands(self) -> list:
"""
Get CEC command list.
Returns:
object of `list` type
"""
return self.__commands
def clear_commands(self):
"""
Clear saved commands.
"""
self.__commands.clear()

View File

@@ -0,0 +1,269 @@
from UniTAP.libs.lib_tsi.tsi_io import PortIO
from UniTAP.libs.lib_tsi.tsi import *
from .cec_types import *
from .cec_private_types import *
from typing import Union
class CecTx:
def __init__(self, port_io: PortIO):
self.__io = port_io
self.__version = self.__read_version()
self.__commands = []
@property
def version(self) -> (int, int):
"""
Read CEC version from the TX side.
Returns:
object of tuple of `int` type
"""
return self.__version
def enable(self, state: bool):
"""
Enable/Disable CEC.
Args:
state (`bool`)
"""
self.__io.set(TSI_HDTX_CEC_CONTROL, state, c_uint32)
def is_enabled(self) -> bool:
"""
Return state of CEC (enabled or not).
Returns:
object of `bool` type
"""
return self.__io.get(TSI_HDTX_CEC_CONTROL, c_uint32)[1] & 0x1 == 1
@property
def logical_address(self) -> LogicalAddressEnum:
"""
Set/Get CEC logical address.
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(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)
@property
def destination(self) -> LogicalAddressEnum:
"""
Set/Get CEC destination address.
Returns:
object of `LogicalAddressEnum` type
"""
return LogicalAddressEnum(self.__io.get(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)
@property
def phy_address(self) -> int:
"""
Set/Get CEC physical address.
Returns:
object of `int` type
"""
return self.__io.get(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)
@property
def op_code(self) -> int:
"""
Set/Get CEC operation code.
Returns:
object of `int` type
"""
return self.__io.get(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)
@property
def op_code_param(self) -> Union[int, list]:
"""
Set/Get CEC additional parameter for operation code.
Returns:
object of `int` type
"""
return self.__io.get(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)
@property
def device_type(self) -> DeviceType:
"""
Set/Get CEC Device type.
Returns:
object of `DeviceType` type
"""
data = self.__io.get(TSI_HDTX_CEC_DEVICE_TYPE, DeviceTypePrivate)[1]
return DeviceType(data.cecSwitch, data.audioSystem, data.pbDevice, data.tuner, data.recDev, data.tv)
@device_type.setter
def device_type(self, dev_type: Union[DeviceTypeEnum, DeviceType, int]):
if isinstance(dev_type, DeviceType):
dev_type_value = DeviceTypePrivate()
dev_type_value.value = dev_type
value = dev_type_value.value
elif isinstance(dev_type, DeviceTypeEnum):
value = dev_type.value
elif isinstance(dev_type, int):
value = dev_type & 0xFF
else:
raise TypeError(f"Unsupported type: {type(dev_type)}")
self.__io.set(TSI_HDTX_CEC_DEVICE_TYPE, value, c_uint32)
@property
def status(self) -> CECStatus:
"""
Get CEC status.
Returns:
object of `CECStatus` type
"""
data = self.__io.get(TSI_HDTX_CEC_STATUS_R, CECStatusPrivate)[1]
return CECStatus(data.bufferOverflowed)
@property
def command_number(self) -> int:
"""
Get CEC command number.
Returns:
object of `int` type
"""
return self.__io.get(TSI_HDTX_CEC_RECEIVED_CNT_R, c_uint32)[1]
@property
def data(self) -> list:
"""
Get CEC raw data.
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]
def reset_data(self, command: CecResetDataCommand):
"""
Get CEC reset data.
Returns:
object of `CecResetDataCommand` type
"""
self.__io.set(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]
return version.minor, version.major
def add_command(self, command: CECCommand = CECCommand()):
"""
Add CEC command in list.
Args:
command (`CECCommand`)
"""
self.__commands.append(command)
def delete_command(self, index: int = 0):
"""
Delete CEC command in list by index.
Args:
index (`int`)
"""
self.__commands.pop(index)
def send_command(self, logical_address: LogicalAddressEnum = LogicalAddressEnum.Tv,
destination: LogicalAddressEnum = LogicalAddressEnum.Broadcast,
phy_address: int = 0x0, op_code: int = 0x0, op_code_param: Union[int, list] = 0x0,
device_type: Union[DeviceTypeEnum, DeviceType, int] = DeviceTypeEnum.TV):
"""
Send CEC command with the transferred parameters.
Args:
logical_address (`LogicalAddressEnum`)
destination (`LogicalAddressEnum`)
phy_address (`int`)
op_code (`int`)
op_code_param (`int`)
device_type (`DeviceTypeEnum` | `DeviceType`)
"""
self.enable(True)
self.logical_address = logical_address
self.phy_address = phy_address
self.op_code = op_code
self.op_code_param = op_code_param
self.device_type = device_type
self.destination = destination
self.__send_cec_command()
def send_command_by_index(self, index: int):
"""
Send CEC command from the list by index.
Args:
index (`int`)
"""
if len(self.__commands) > 0 and 0 <= index < len(self.__commands):
self.__send_command(self.__commands[index])
def send_commands(self):
"""
Send all saved commands.
"""
for command in self.__commands:
self.__send_command(command)
def __send_command(self, command: CECCommand = CECCommand()):
self.logical_address = command.logical_address
self.destination = command.destination
self.phy_address = command.phy_address
self.op_code = command.op_code
self.op_code_param = command.op_code_param
self.device_type = command.device_type
self.__send_cec_command()
def __send_cec_command(self):
self.__io.set(TSI_HDTX_CEC_COMMAND, 1, c_uint32)
@property
def commands(self) -> list:
"""
Get CEC command list.
Returns:
object of `list` type
"""
return self.__commands
def clear_commands(self):
"""
Clear saved commands.
"""
self.__commands.clear()

View File

@@ -0,0 +1,134 @@
from enum import IntEnum
from typing import Union
class LogicalAddressEnum(IntEnum):
"""
Class `PRCommand` contains all possible variants of Panel Replay Command.
"""
Tv = 0x0,
RecDevice1 = 0x1,
RecDevice2 = 0x2,
Tuner1 = 0x3,
PlayDevice1 = 0x4,
AudioSystem = 0x5,
Tuner2 = 0x6,
Tuner3 = 0x7,
PlayDevice2 = 0x8,
RecDevice3 = 0x9,
Tuner4 = 0xA,
PlayDevice3 = 0xB,
Reserved1 = 0xC,
Reserved2 = 0xD,
SpecificUse = 0xE,
Broadcast = 0xF,
Unregistered = Broadcast
class DeviceTypeEnum(IntEnum):
CECSwitch = 0x1 << 2,
AudioSystem = 0x1 << 3,
PlayBack = 0x1 << 4,
Tuner = 0x1 << 5,
Rec = 0x1 << 6,
TV = 0x1 << 7
class CecResetDataCommand(IntEnum):
"""
Class `PRCommand` contains all possible variants of Panel Replay Command.
"""
OneFrame = 1,
AllFrames = 2
class DeviceType:
def __init__(self, cec_switch: bool = False, audio_system: bool = False, pb_device: bool = False,
tuner: bool = False, rec_dev: bool = False, tv: bool = False):
self.cec_switch = cec_switch
self.audio_system = audio_system
self.pb_device = pb_device
self.tuner = tuner
self.rec_dev = rec_dev
self.tv = tv
def __str__(self) -> str:
return f"CEC switch - {self.cec_switch}\n" \
f"Audio System - {self.audio_system}\n" \
f"PD Device - {self.pb_device}\n" \
f"Tuner - {self.tuner}\n" \
f"Rec dev - {self.rec_dev}\n" \
f"TV - {self.tv}\n"
class CECStatus:
def __init__(self, buffer_overflowed: bool = False):
self.buffer_overflowed = buffer_overflowed
def __str__(self) -> str:
return f"Buffer Overflowed - {self.buffer_overflowed}\n"
class CECCommand:
def __init__(self, logical_address: LogicalAddressEnum = LogicalAddressEnum.Tv,
phy_address: int = 0x0, op_code: int = 0x0, op_code_param: Union[int, list] = 0x0,
device_type: DeviceType = DeviceType(),
destination: LogicalAddressEnum = LogicalAddressEnum.Broadcast):
self.__logical_address = logical_address
self.__phy_address = phy_address
self.__op_code = op_code
self.__op_code_param = op_code_param
self.__device_type = device_type
self.__destination = destination
@property
def logical_address(self) -> LogicalAddressEnum:
return self.__logical_address
@logical_address.setter
def logical_address(self, address: LogicalAddressEnum):
self.__logical_address = address
@property
def phy_address(self) -> int:
return self.__phy_address
@phy_address.setter
def phy_address(self, address: int):
self.__phy_address = address
@property
def op_code(self) -> int:
return self.__op_code
@op_code.setter
def op_code(self, op_code: int):
self.__op_code = op_code
@property
def op_code_param(self) -> Union[int, list]:
return self.__op_code_param
@op_code_param.setter
def op_code_param(self, param: Union[int, list]):
self.__op_code_param = param
@property
def device_type(self) -> DeviceType:
return self.__device_type
@device_type.setter
def device_type(self, dev_type: DeviceType):
self.__device_type = dev_type
@property
def destination(self) -> LogicalAddressEnum:
return self.__destination
@destination.setter
def destination(self, address: LogicalAddressEnum):
self.__destination = address