From bfb1e71d7ded5af3dd0e23344d2ee9d6b6d9882c Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Tue, 17 Feb 2026 22:28:51 +0100 Subject: [PATCH] proper driver for tef --- .gitignore | 2 + base_tef.py | 66 ++++++++++++ protocol.py | 3 +- tef.py | 167 ++++++++++++++++++++++++++++ tef_102_patch.py | 275 +++++++++++++++++++++++++++++++++++++++++++++++ test.py | 23 ++++ 6 files changed, 534 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 base_tef.py create mode 100644 tef.py create mode 100644 tef_102_patch.py create mode 100644 test.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7bfcd7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.pyc \ No newline at end of file diff --git a/base_tef.py b/base_tef.py new file mode 100644 index 0000000..31ef581 --- /dev/null +++ b/base_tef.py @@ -0,0 +1,66 @@ +from protocol import I2CPCClient, time +from tef_102_patch import * + +from typing import Callable, TypeVar, ParamSpec, Concatenate +from collections.abc import Callable as ABCCallable + +P = ParamSpec("P") +T = TypeVar("T") + +ADDRESS = 0x64 +class BaseTEF668X: + def __init__(self, p: I2CPCClient) -> None: + self.p = p + p.set_baudrate(1500000) + self.p.set_clock(400_000) + def close(self): + self.p.set_baudrate(115200) + self.p.close() + def _reset(self): + self.p.write_i2c(ADDRESS, b"\x1e\x5a\x01\x5a\x5a") + def _write_firmware(self, patch: bytes | list[int], patch_lut: bytes | list[int]): + self.p.write_i2c(ADDRESS, b"\x1c\x00\x00") + self.p.write_i2c(ADDRESS, b"\x1c\x00\x74") + def send_patch(_patch: bytes): + for i in range(0, len(_patch), 24): + data = _patch[i:i+24] + if self.p.write_i2c(ADDRESS, b"\x1b" + data)[1] != 0: raise Exception + send_patch(bytes(patch)) + self.p.write_i2c(ADDRESS, b"\x1c\x00\x00") + self.p.write_i2c(ADDRESS, b"\x1c\x00\x75") + send_patch(bytes(patch_lut)) + self.p.write_i2c(ADDRESS, b"\x1c\x00\x00") + + def APPL_Get_Operation_Status(self): + data = self.p.write_read_i2c(ADDRESS, b"\x40\x80\x01", 2) + while data[1] != 0: + data = self.p.write_read_i2c(ADDRESS, b"\x40\x80\x01", 2) + time.sleep(0.01) + return data[-1] + + @staticmethod + def _base_command_wrapper(func: Callable[Concatenate["BaseTEF668X", P], tuple[bytes, int | None, ABCCallable[[bytes], T] | None]]) -> Callable[Concatenate["BaseTEF668X", P], bytes | T]: + def inner(self: "BaseTEF668X", *args: P.args, **kwargs: P.kwargs ) -> bytes | T: + data, read_bytes, out_parser = func(self, *args, **kwargs) + if read_bytes: data = self.p.write_read_i2c(ADDRESS, data, read_bytes) + else: data = self.p.write_i2c(ADDRESS, data) + if out_parser: return out_parser(data) + return data + return inner + + @_base_command_wrapper + def APPL_Set_ReferenceClock(self, clock: int, type_clock: bool): + return b"\x40\x04\x01" + bytes(((clock >> 16) & 0xffff).to_bytes(2) + (clock & 0xffff).to_bytes(2) + bytes([0, int(type_clock)])), None, None + @_base_command_wrapper + def APPL_Activate(self): + return b"\x40\x05\x01\x00\x01", None, None + + def init(self): + self._reset() + while self.APPL_Get_Operation_Status() != 0: time.sleep(0.01) + self._write_firmware(tef_102_patch, tef_102_patch_lut) + self.p.write_i2c(ADDRESS, b"\x14\x00\x01") + while self.APPL_Get_Operation_Status() != 1: time.sleep(0.01) + self.APPL_Set_ReferenceClock(12000000, False) + self.APPL_Activate() + while self.APPL_Get_Operation_Status() != 2: time.sleep(0.01) \ No newline at end of file diff --git a/protocol.py b/protocol.py index e9123eb..7cff6d7 100644 --- a/protocol.py +++ b/protocol.py @@ -6,8 +6,7 @@ class I2CPCClient: def __init__(self, port, baudrate=115200, timeout=1): self.ser = serial.Serial(port=port, baudrate=baudrate, timeout=timeout) self.ser.write(b"~/") - self.ser.flush() - while not ((d := self.ser.read_all()) and b"\x01\xff" in d): time.sleep(0.01) + while not ((d := self.ser.read_all()) and (b"\x01" in d or b"\xff" in d)): time.sleep(0.01) def _send_packet(self, payload: bytes): self.ser.write(bytes([len(payload)]) + payload) diff --git a/tef.py b/tef.py new file mode 100644 index 0000000..8167d04 --- /dev/null +++ b/tef.py @@ -0,0 +1,167 @@ +from base_tef import BaseTEF668X, ADDRESS, Concatenate, P, T, Callable +from typing import overload, TypeVar +from functools import wraps + +T = TypeVar("T") + +@overload +def _command_wrapper(func: Callable[Concatenate["TEF6686", P],tuple[bytes, int | None, None],],) -> Callable[Concatenate["TEF6686", P], bytes]: ... +@overload +def _command_wrapper(func: Callable[Concatenate["TEF6686", P],tuple[bytes, int | None, Callable[[bytes], T]],],) -> Callable[Concatenate["TEF6686", P], T]: ... + +def _command_wrapper( + func: Callable[Concatenate["TEF6686", P], tuple[bytes, int | None, Callable[[bytes], T] | None], ]) -> Callable[Concatenate["TEF6686", P], bytes | T]: + @wraps(func) + def inner(self: "TEF6686", *args: P.args, **kwargs: P.kwargs) -> bytes | T: + data, read_bytes, out_parser = func(self, *args, **kwargs) + + if read_bytes: data = self.p.write_read_i2c(ADDRESS, data, read_bytes) + else: data = self.p.write_i2c(ADDRESS, data) + if out_parser: return out_parser(data) + return data + return inner + +class TEF6686(BaseTEF668X): + @_command_wrapper + def FM_Tune_To(self, mode: int, frequency: int | None): + return b"\x20\x01\x01" + mode.to_bytes(2, "big") + (frequency.to_bytes(2, "big") if frequency else b""), None, None + @_command_wrapper + def AM_Tune_To(self, mode: int, frequency: int | None): + return b"\x21\x01\x01" + mode.to_bytes(2, "big") + (frequency.to_bytes(2, "big") if frequency else b""), None, None + @_command_wrapper + def FM_Set_Tune_Options(self, afu_bw_mode: bool = False, afu_bandwidth: int = 2360, afu_mute_time: int = 1000, afu_sample_time: int = 2000): + return b"\x20\x02\x01" + afu_bw_mode.to_bytes(2, "big") + afu_bandwidth.to_bytes(2, "big") + afu_mute_time.to_bytes(2, "big") + afu_sample_time.to_bytes(2, "big"), None, None + @_command_wrapper + def FM_Set_Bandwidth(self, mode: bool = True, bandwidth: int = 2360, control_sensitivity: int = 1000, low_level_sensitivity: int = 1000): + return b"\x20\x0a\x01" + mode.to_bytes(2, "big") + bandwidth.to_bytes(2, "big") + control_sensitivity.to_bytes(2, "big") + low_level_sensitivity.to_bytes(2, "big"), None, None + @_command_wrapper + def AM_Set_Bandwidth(self, bandwidth: int = 40): + return b"\x21\x0a\x01\x00\x00" + bandwidth.to_bytes(2, "big"), None, None + # todo: Set_RFAGC + @_command_wrapper + def AM_Set_Antenna(self, attenuation: int = 0): + return b"\x21\x0c\x01" + attenuation.to_bytes(2, "big"), None, None + @_command_wrapper + def FM_Set_MphSuppression(self, mode: bool = False): + return b"\x20\x14\x01" + mode.to_bytes(2, "big"), None, None + @_command_wrapper + def FM_Set_ChannelEqualizer(self, mode: bool = False): + return b"\x20\x16\x01" + mode.to_bytes(2, "big"), None, None + @_command_wrapper + def FM_Set_Deemphasis(self, timeconstant: int = 500): + return b"\x20\x1f\x01" + timeconstant.to_bytes(2, "big"), None, None + @_command_wrapper + def AM_Set_LevelOffset(self, offset: int = 0): + return b"\x21\x27\x01" + offset.to_bytes(2, "big", signed=True), None, None + @_command_wrapper + def FM_Set_RDS(self, mode: int = 0, restart: int = 2, interface: int = 0): + return b"\x20\x51\x01" + mode.to_bytes(2, "big") + restart.to_bytes(2, "big") + interface.to_bytes(2, "big"), None, None + @_command_wrapper + def FM_Set_Specials(self, mode: int = 0): + return b"\x20\x55\x01" + mode.to_bytes(2, "big"), None, None + @_command_wrapper + def AUDIO_Set_Volume(self, volume: int = 0): + return b"\x30\x0a\x01" + volume.to_bytes(2, "big", signed=True), None, None + @_command_wrapper + def AUDIO_Set_Mute(self, mute: bool = True): + return b"\x30\x0b\x01" + int(mute).to_bytes(2, "big"), None, None + @_command_wrapper + def AUDIO_Set_Input(self, source: int = 0): + return b"\x30\x0c\x01" + source.to_bytes(2, "big"), None, None + @_command_wrapper + def AUDIO_Set_Output_Source(self, signal: int, source: int = 224): + return b"\x30\x0d\x01" + signal.to_bytes(2, "big") + source.to_bytes(2, "big"), None, None + @_command_wrapper + def AUDIO_Set_Ana_Out(self, signal: int, mode: bool = True): + return b"\x30\x15\x01" + signal.to_bytes(2, "big") + mode.to_bytes(2, "big"), None, None + @_command_wrapper + def AUDIO_Set_WaveGen(self, mode: int = 0, offset: int = 0, amplitude1: int = -200, frequency1: int = 400, amplitude2: int = -200, frequency2: int = 1000): + return b"\x30\x18\x01" + mode.to_bytes(2, "big") + offset.to_bytes(2, "big") + amplitude1.to_bytes(2, "big", signed=True) + frequency1.to_bytes(2, "big") + amplitude2.to_bytes(2, "big", signed=True) + frequency2.to_bytes(2, "big"), None, None + @_command_wrapper + def APPL_Set_OperationMode(self, mode: bool = True): + return b"\x40\x01\x01" + mode.to_bytes(2, "big"), None, None + + @staticmethod + def _get_quality_data(data) -> tuple[None, None, None, None, None, None, None] | tuple[int, int, int, int, int, int, int]: + if data[1] != 0: return None, None, None, None, None, None, None + status = (data[2] << 8) | data[3] + level = int.from_bytes(bytes([data[4], data[5]]), "big", signed=True) + usn = (data[6] << 8) | data[7] # "noise" on AM + wam = (data[8] << 8) | data[9] # "co-channel" on AM + offset = int.from_bytes(bytes([data[10], data[11]]), "big", signed=True) + bandwidth = (data[12] << 8) | data[13] + modulation = (data[14] << 8) | data[15] + return status, level, usn, wam, offset, bandwidth, modulation + @_command_wrapper + def FM_Get_Quality_Status(self): + return b"\x20\x80\x01", 14, self._get_quality_data + @_command_wrapper + def FM_Get_Quality_Data(self): + return b"\x20\x81\x01", 14, self._get_quality_data + @_command_wrapper + def AM_Get_Quality_Status(self): + return b"\x21\x80\x01", 14, self._get_quality_data + @_command_wrapper + def AM_Get_Quality_Data(self): + return b"\x21\x81\x01", 14, self._get_quality_data + + @staticmethod + def _get_rds_data_proc_decoder(data): + if data[1] != 0: return None, None, None, None, None, None + status = (data[2] << 8) | data[3] + A_block = (data[4] << 8) | data[5] + B_block = (data[6] << 8) | data[7] + C_block = (data[8] << 8) | data[9] + D_block = (data[10] << 8) | data[11] + dec_error = (data[12] << 8) | data[13] + return status, A_block, B_block, C_block, D_block, dec_error + @staticmethod + def _get_rds_data_proc_demodulator(data): + if data[1] != 0: return None, None, None + status = (data[2] << 8) | data[3] + raw_data_high = (data[4] << 8) | data[5] + raw_data_low = (data[6] << 8) | data[7] + return status, (raw_data_high << 16) | raw_data_low + @_command_wrapper + def FM_Get_RDS_Status__decoder(self): + return b"\x20\x82\x01", 12, self._get_rds_data_proc_decoder + @_command_wrapper + def FM_Get_RDS_Data__decoder(self): + return b"\x20\x83\x01", 12, self._get_rds_data_proc_decoder + @_command_wrapper + def FM_Get_RDS_Status__demodulator(self): + return b"\x20\x82\x01", 12, self._get_rds_data_proc_demodulator + @_command_wrapper + def FM_Get_RDS_Data__demodulator(self): + return b"\x20\x83\x01", 12, self._get_rds_data_proc_demodulator + + @_command_wrapper + def FM_Get_AGC(self): + """ + Returns None if there was a I2C error, or a tuple of booleans (FM Stereo/Mono and Analog/Digital radio [DR models]) + """ + def proc(data): + if data[1] != 0: return None + input_att = (data[2] << 8) | data[3] + feedback_att = (data[4] << 8) | data[5] + return input_att, feedback_att + return b"\x20\x84\x01", 4, proc + @_command_wrapper + def FM_Get_Signal_Status(self): + """ + Returns None if there was a I2C error, or a tuple of booleans (FM Stereo/Mono and Analog/Digital radio [DR models]) + """ + def proc(data): + if data[1] != 0: return None + value = (data[-2] << 8) | data[-1] + return (value & (1 << 15)) != 0, (value & (1 << 14)) != 0 + return b"\x20\x85\x01", 2, proc + @_command_wrapper + def APPL_Get_Identification(self): + def proc(data): + if data[1] != 0: return None + device = (data[2] << 8) | data[3] + hw_version = (data[4] << 8) | data[5] + sw_version = (data[6] << 8) | data[7] + return device, hw_version, sw_version + return b"\x40\x82\x01", 6, proc \ No newline at end of file diff --git a/tef_102_patch.py b/tef_102_patch.py new file mode 100644 index 0000000..8d473ef --- /dev/null +++ b/tef_102_patch.py @@ -0,0 +1,275 @@ +tef_102_patch = [ + 0xF0, 0x00, 0x38, 0x3B, 0xD0, 0x80, 0xF0, 0x00, 0x38, 0x43, 0xD0, 0x80, 0x43, 0xB2, 0x38, 0x46, 0xD0, 0x80, 0xF0, 0x00, 0x70, 0x00, 0xC2, 0xF7, + 0xF0, 0x00, 0x38, 0x77, 0xD0, 0x80, 0xF0, 0x00, 0x38, 0x7B, 0xDF, 0x80, 0x80, 0xFC, 0x39, 0x0E, 0xD0, 0x80, 0xC2, 0x38, 0x20, 0x11, 0x40, 0xB7, + 0x9F, 0xA7, 0x39, 0x13, 0xD2, 0x80, 0x9F, 0xA7, 0x39, 0x1D, 0xD2, 0x80, 0xF0, 0x00, 0x39, 0x24, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0x27, 0xD0, 0x80, + 0x90, 0x41, 0x39, 0x49, 0xDD, 0x80, 0xF0, 0x00, 0x3A, 0x25, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0x4D, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0x27, 0xD0, 0x80, + 0xC4, 0xA2, 0x02, 0x18, 0x60, 0x04, 0xF0, 0x00, 0x39, 0xBF, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0xE7, 0xD0, 0x80, 0x90, 0x01, 0x39, 0x4F, 0xD0, 0x80, + 0xF0, 0x00, 0x38, 0xF0, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0x56, 0xD2, 0x80, 0xF0, 0x00, 0x39, 0x5A, 0xD0, 0x80, 0x43, 0x84, 0x39, 0x64, 0xD0, 0x80, + 0xF0, 0x00, 0x39, 0x67, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0x6B, 0xD0, 0x80, 0x78, 0x4D, 0x39, 0x71, 0xD0, 0x80, 0x9E, 0x30, 0x18, 0xF9, 0xD2, 0x80, + 0xF0, 0x00, 0x39, 0x76, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0x79, 0xD0, 0x80, 0x30, 0x77, 0x39, 0xDE, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0x7C, 0xD0, 0x80, + 0x32, 0x00, 0x39, 0x7E, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0x80, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0xC7, 0xD0, 0x80, 0xF0, 0x00, 0x39, 0xF5, 0xD0, 0x80, + 0xA8, 0x01, 0x3A, 0x13, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0x32, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0x39, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0x3B, 0xD0, 0x80, + 0xF0, 0x00, 0x3A, 0x4F, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0x52, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0x55, 0xD0, 0x80, 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x3A, 0x58, 0xD0, 0x80, 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x3A, 0x5D, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0x1E, 0xD2, 0x80, + 0xF0, 0x00, 0x3A, 0x6B, 0xD0, 0x80, 0x00, 0x43, 0x3A, 0x7A, 0xD9, 0x80, 0xF0, 0x00, 0x3A, 0x84, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0xDA, 0xD0, 0x80, + 0xF0, 0x00, 0x3A, 0xDD, 0xD0, 0x80, 0xF0, 0x00, 0x3A, 0xEE, 0xD0, 0x80, 0x2E, 0x40, 0x3B, 0x8C, 0xD0, 0x80, 0xF0, 0x00, 0x3B, 0x96, 0xD0, 0x80, + 0xF0, 0x00, 0x0E, 0x3F, 0x60, 0x00, 0x50, 0x10, 0x28, 0xD8, 0xD2, 0x80, 0x91, 0x01, 0x01, 0x36, 0x60, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xA0, 0x18, + 0xF0, 0x00, 0x70, 0x00, 0xA0, 0xCC, 0xF0, 0x00, 0x70, 0x00, 0xA0, 0xED, 0xF0, 0x00, 0x70, 0x00, 0xA1, 0xAE, 0xF0, 0x00, 0x70, 0x00, 0xA2, 0x02, + 0xF0, 0x00, 0x70, 0x00, 0xA2, 0x2D, 0xF0, 0x00, 0x70, 0x00, 0xA2, 0x45, 0xF0, 0x00, 0x20, 0x31, 0xD0, 0x80, 0xF0, 0x00, 0x04, 0xC1, 0x60, 0x08, + 0xF0, 0x00, 0x01, 0x01, 0xD2, 0x80, 0xF0, 0x00, 0x00, 0x30, 0xD0, 0x80, 0x00, 0x7F, 0x60, 0x02, 0xE2, 0x00, 0xF0, 0x00, 0x0E, 0x22, 0x60, 0x0A, + 0xF0, 0x00, 0x00, 0xFF, 0x60, 0x03, 0xF0, 0x00, 0x01, 0x42, 0xD2, 0x80, 0x90, 0x03, 0x40, 0x02, 0xF0, 0x00, 0x90, 0x43, 0x01, 0x70, 0xD1, 0x80, + 0xF0, 0x00, 0x01, 0x69, 0xD0, 0x80, 0x0E, 0x69, 0x60, 0x0A, 0xA3, 0x4C, 0x20, 0x23, 0x00, 0x01, 0x60, 0x01, 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, + 0xC4, 0xCB, 0x70, 0x00, 0xF0, 0x00, 0xCA, 0x09, 0x30, 0x23, 0xF0, 0x00, 0xC2, 0xCB, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0x23, 0xD0, 0x08, + 0x82, 0x00, 0x0D, 0x50, 0x60, 0x08, 0xF0, 0x00, 0x0D, 0x51, 0x60, 0x09, 0x30, 0x00, 0x21, 0x80, 0x60, 0x01, 0xF0, 0x00, 0x40, 0x32, 0xF0, 0x00, + 0x30, 0x11, 0x45, 0xF3, 0xF0, 0x00, 0x30, 0x92, 0x2D, 0x30, 0x60, 0x04, 0x31, 0x13, 0x2D, 0x40, 0x60, 0x05, 0x31, 0x94, 0x7F, 0xFF, 0x60, 0x06, + 0x32, 0x15, 0x0D, 0x61, 0x60, 0x0A, 0x32, 0x96, 0x0D, 0x6B, 0x60, 0x0B, 0x33, 0x10, 0x0D, 0x50, 0x60, 0x01, 0x33, 0x90, 0x0D, 0x5C, 0x60, 0x02, + 0x30, 0x21, 0x0D, 0x63, 0x60, 0x03, 0x30, 0x31, 0x0D, 0x75, 0x60, 0x0C, 0x30, 0xA2, 0x8D, 0x00, 0x60, 0x01, 0x30, 0xB3, 0x01, 0x73, 0x60, 0x02, + 0x30, 0x41, 0x00, 0x25, 0x60, 0x03, 0x30, 0xC2, 0x40, 0x44, 0xF0, 0x00, 0x31, 0x43, 0x40, 0x35, 0xF0, 0x00, 0x31, 0xC4, 0x64, 0x00, 0x60, 0x06, + 0x32, 0x45, 0x1F, 0x40, 0x60, 0x07, 0x32, 0xC6, 0x70, 0x00, 0xF0, 0x00, 0x33, 0x47, 0x1E, 0xBC, 0x60, 0x0D, 0x33, 0xC0, 0x01, 0x22, 0x60, 0x01, + 0x34, 0x40, 0xFD, 0xEE, 0x60, 0x02, 0x30, 0x51, 0x7B, 0x8F, 0x60, 0x03, 0x30, 0xD2, 0xC4, 0x29, 0x60, 0x04, 0x31, 0x51, 0x1E, 0xC2, 0x60, 0x0E, + 0x32, 0x53, 0xFF, 0x0D, 0x60, 0x02, 0x32, 0xD4, 0x7D, 0x2E, 0x60, 0x03, 0x30, 0x61, 0xC1, 0x9A, 0x60, 0x04, 0x30, 0xE2, 0x70, 0x00, 0xF0, 0x00, + 0x31, 0x61, 0x70, 0x00, 0xF0, 0x00, 0x32, 0x63, 0x05, 0x2C, 0x60, 0x08, 0x32, 0xE4, 0x40, 0x00, 0x83, 0x22, 0xF0, 0x00, 0x03, 0x70, 0xD2, 0x80, + 0xF0, 0x00, 0x70, 0x00, 0xA0, 0x08, 0xF0, 0x00, 0x70, 0x00, 0xA0, 0x4D, 0xF0, 0x00, 0x02, 0x15, 0xD0, 0x80, 0x40, 0x15, 0x20, 0x53, 0xA3, 0x1E, + 0xA0, 0xE8, 0x58, 0x06, 0xA3, 0x1D, 0xA0, 0x72, 0x20, 0x64, 0xF0, 0x00, 0xA8, 0x61, 0x70, 0x00, 0xF0, 0x00, 0xA1, 0x28, 0x70, 0x00, 0xF0, 0x00, + 0xA0, 0xB2, 0x02, 0xBB, 0xD0, 0x80, 0xF0, 0x00, 0x0D, 0x51, 0x60, 0x0F, 0xF0, 0x00, 0x05, 0x17, 0x60, 0x0E, 0x23, 0xF6, 0x70, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x21, 0x63, 0x41, 0xF5, 0x91, 0x8F, 0x21, 0xF8, 0x40, 0x74, 0xC3, 0xEF, 0x21, 0xE0, 0xF0, 0x00, 0xC3, 0xA4, 0x33, 0xF7, 0xF0, 0x00, + 0xD8, 0x5B, 0x70, 0x00, 0xF0, 0x00, 0x82, 0x18, 0x70, 0x00, 0xF0, 0x00, 0x9F, 0xAF, 0x18, 0x00, 0xF0, 0x00, 0x9F, 0x0F, 0x31, 0xF8, 0x90, 0x02, + 0xF0, 0x00, 0x70, 0x00, 0x90, 0x28, 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x08, 0xF0, 0x00, 0x22, 0x78, 0xF0, 0x00, 0x16, 0xD3, 0x60, 0x09, 0xA0, 0x6D, + 0x35, 0xF0, 0x1E, 0xBC, 0x60, 0x0D, 0xF0, 0x00, 0x0D, 0x61, 0x60, 0x08, 0xF0, 0x00, 0x03, 0xA5, 0xD2, 0x80, 0xF0, 0x00, 0x1E, 0xC2, 0x60, 0x0D, + 0xF0, 0x00, 0x0D, 0x6B, 0x60, 0x08, 0xF0, 0x00, 0x03, 0xA5, 0xD2, 0x80, 0xF0, 0x00, 0x21, 0x00, 0xF0, 0x00, 0x83, 0x6D, 0x22, 0xF1, 0xF0, 0x00, + 0xF0, 0x00, 0x23, 0x77, 0xF0, 0x00, 0x90, 0x41, 0x36, 0x70, 0xF0, 0x00, 0x9E, 0x79, 0x70, 0x00, 0x90, 0x01, 0xF0, 0x00, 0x32, 0xF1, 0xD0, 0x08, + 0x91, 0xC7, 0x33, 0x75, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0x70, 0xE6, 0x00, 0xF0, 0x00, 0x34, 0xF0, 0xE6, 0x00, 0xF0, 0x00, 0x24, 0x74, 0xF0, 0x00, + 0xF0, 0x00, 0x24, 0xF3, 0xF0, 0x00, 0x8C, 0x24, 0x26, 0xF2, 0x40, 0x16, 0x8A, 0x1B, 0x34, 0x74, 0x4F, 0xF5, 0x82, 0xB7, 0x34, 0xF3, 0xF0, 0x00, + 0xF0, 0x00, 0x20, 0x71, 0x90, 0x05, 0x83, 0x04, 0x70, 0x00, 0xF0, 0x00, 0x8E, 0x67, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x90, 0x02, + 0xF0, 0x00, 0x36, 0xF6, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0xF0, 0x80, 0x06, 0x82, 0xAF, 0x70, 0x00, 0xF0, 0x00, 0x82, 0x1B, 0x70, 0x00, 0xD0, 0x09, + 0x8E, 0x5F, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x09, 0xF0, 0x00, 0x36, 0xF5, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0x70, 0xF0, 0x00, + 0x40, 0x11, 0x27, 0x72, 0xA2, 0xE9, 0x90, 0x8A, 0x20, 0xF3, 0xA2, 0xE8, 0x8E, 0xD7, 0x37, 0x72, 0xF0, 0x00, 0xF0, 0x00, 0x37, 0xF1, 0xE6, 0x00, + 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x08, 0xF0, 0x00, 0x22, 0x7A, 0xF0, 0x00, 0x16, 0xC3, 0x60, 0x09, 0xA0, 0x46, 0xF0, 0x00, 0x18, 0x20, 0xF0, 0x00, + 0xF0, 0x00, 0x35, 0x70, 0xF0, 0x00, 0xF0, 0x00, 0x32, 0x7A, 0xD0, 0x08, 0x0D, 0x51, 0x60, 0x08, 0xA2, 0xDF, 0x82, 0x00, 0x21, 0x06, 0x40, 0x03, + 0x33, 0x80, 0x0D, 0x63, 0x60, 0x09, 0x37, 0x00, 0x0D, 0x6D, 0x60, 0x0A, 0x37, 0x80, 0x0D, 0x30, 0x60, 0x0B, 0x36, 0x83, 0x0D, 0x40, 0x60, 0x0C, + 0x35, 0x80, 0x70, 0x00, 0xC8, 0x88, 0xF0, 0x00, 0x10, 0x10, 0xF0, 0x00, 0xF0, 0x00, 0x10, 0x20, 0xF0, 0x00, 0x32, 0x86, 0x40, 0x15, 0xC8, 0x90, + 0xF0, 0x00, 0x10, 0x30, 0xF0, 0x00, 0xF0, 0x00, 0x10, 0x40, 0xF0, 0x00, 0xF0, 0x00, 0x33, 0x05, 0xD0, 0x08, 0xF0, 0x00, 0x0D, 0x75, 0x60, 0x0F, + 0xF0, 0x00, 0x05, 0x63, 0x60, 0x0E, 0x24, 0xF7, 0x05, 0x1D, 0x60, 0x0D, 0x25, 0x76, 0x70, 0x00, 0xF0, 0x00, 0x91, 0xC7, 0x20, 0xE8, 0x40, 0x15, + 0x91, 0x8F, 0x21, 0xE9, 0xD4, 0x09, 0xC3, 0xEF, 0x20, 0x00, 0x40, 0x12, 0x9F, 0xBE, 0x20, 0x11, 0x58, 0x03, 0xA0, 0x80, 0x35, 0x77, 0x90, 0x01, + 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x08, 0xF0, 0x00, 0x21, 0xF5, 0xF0, 0x00, 0xA0, 0xCA, 0x22, 0x54, 0xF0, 0x00, 0xCC, 0x09, 0x05, 0x17, 0x60, 0x0C, + 0x83, 0x2C, 0x70, 0x00, 0xF0, 0x00, 0x8A, 0x61, 0x70, 0x00, 0xF0, 0x00, 0xAE, 0x48, 0x22, 0x45, 0xA2, 0xC3, 0xA2, 0x28, 0x20, 0x78, 0xF0, 0x00, + 0xF0, 0x00, 0x35, 0xF0, 0xF0, 0x00, 0xF0, 0x00, 0x18, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0x78, 0xF0, 0x00, 0x16, 0xE3, 0x60, 0x09, 0xA0, 0x27, + 0x89, 0x01, 0x23, 0xF4, 0xF0, 0x00, 0xF0, 0x00, 0x20, 0xF2, 0xF0, 0x00, 0x82, 0x61, 0x21, 0x73, 0xF0, 0x00, 0xA0, 0x50, 0x36, 0x70, 0xF0, 0x00, + 0xA0, 0x58, 0x23, 0x72, 0xE1, 0x40, 0xA8, 0x01, 0x22, 0xF3, 0xF0, 0x00, 0x90, 0x49, 0x22, 0x75, 0xE0, 0x40, 0x80, 0x61, 0x70, 0x00, 0xF0, 0x00, + 0x8A, 0x51, 0x33, 0xF1, 0xF0, 0x00, 0xA0, 0x58, 0x70, 0x00, 0xF0, 0x00, 0xAF, 0x48, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0x70, 0xD0, 0x08, + 0x82, 0x00, 0x0D, 0x75, 0x60, 0x08, 0x90, 0x09, 0x0D, 0x00, 0x60, 0x09, 0xF0, 0x00, 0x35, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x33, 0x80, 0xC0, 0x28, + 0xF0, 0x00, 0x10, 0x10, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0x81, 0xD0, 0x08, 0x82, 0x49, 0x0D, 0x75, 0x60, 0x08, 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xFD, + 0x04, 0x00, 0x60, 0x00, 0xA2, 0xA9, 0x8E, 0xC0, 0x40, 0x00, 0x60, 0x05, 0x60, 0x00, 0x60, 0x05, 0xE6, 0x00, 0xC8, 0x1B, 0x70, 0x00, 0xF0, 0x00, + 0xD8, 0xDB, 0x0D, 0x51, 0x60, 0x08, 0x83, 0x5B, 0x70, 0x00, 0xF0, 0x00, 0x9E, 0xBA, 0x30, 0x03, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0x84, 0xD4, 0x09, + 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xC1, 0xF0, 0x00, 0x0D, 0x75, 0x60, 0x08, 0xF0, 0x00, 0x0D, 0x51, 0x60, 0x09, 0xF0, 0x00, 0x24, 0x03, 0xF0, 0x00, + 0xF0, 0x00, 0x27, 0x94, 0xD0, 0x08, 0xA0, 0x03, 0x70, 0x00, 0xF0, 0x00, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x00, 0x00, 0x11, 0x08, 0x00, 0xC0, 0x0E, + 0xA0, 0x09, 0x00, 0x11, 0x08, 0x00, 0xA0, 0x09, 0x70, 0x00, 0xF0, 0x00, 0xA4, 0x08, 0x70, 0x00, 0xD0, 0x08, 0xA0, 0x03, 0x70, 0x00, 0xF0, 0x00, + 0x00, 0x11, 0x08, 0x00, 0xF0, 0x00, 0x00, 0x11, 0x08, 0x00, 0xC0, 0x26, 0xA0, 0x09, 0x00, 0x11, 0x08, 0x00, 0xA0, 0x09, 0x70, 0x00, 0xF0, 0x00, + 0xA4, 0x08, 0x70, 0x00, 0xD0, 0x08, 0xF0, 0x00, 0x1D, 0x01, 0x60, 0x08, 0xF0, 0x00, 0x0A, 0x2C, 0x60, 0x00, 0xF0, 0x00, 0x01, 0x1A, 0x60, 0x01, + 0x31, 0x00, 0x70, 0x00, 0xF0, 0x00, 0x31, 0x81, 0x70, 0x00, 0xD0, 0x08, 0xA8, 0x01, 0x7F, 0xFF, 0x60, 0x06, 0xCC, 0x0A, 0x70, 0x00, 0xF0, 0x00, + 0x8E, 0xA1, 0x31, 0x06, 0xF0, 0x00, 0xF0, 0x00, 0x32, 0x06, 0xD4, 0x09, 0xAE, 0xE8, 0x04, 0xDF, 0xD0, 0x80, 0x90, 0x87, 0x70, 0x00, 0x98, 0x07, + 0xF0, 0x00, 0x0F, 0xB1, 0xD2, 0x80, 0x9E, 0x08, 0x41, 0x89, 0x60, 0x06, 0x14, 0x92, 0x60, 0x00, 0x90, 0x04, 0xA1, 0x98, 0x1D, 0x01, 0x60, 0x08, + 0xAA, 0x56, 0x70, 0x00, 0xF0, 0x00, 0xA2, 0x20, 0x32, 0x06, 0xF0, 0x00, 0xF0, 0x00, 0x32, 0x80, 0xF0, 0x00, 0x91, 0xC2, 0x06, 0x9A, 0x60, 0x08, + 0x41, 0xE6, 0x06, 0x00, 0xD0, 0x80, 0x82, 0x13, 0x70, 0x00, 0xD8, 0x09, 0xF0, 0x00, 0x0F, 0xB1, 0xD2, 0x80, 0x9E, 0x08, 0x10, 0x62, 0x60, 0x01, + 0x05, 0x1F, 0x60, 0x05, 0xD0, 0x09, 0xF0, 0x00, 0x06, 0xE6, 0x60, 0x08, 0xA3, 0x65, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0x85, 0xD0, 0x08, + 0x10, 0x00, 0x60, 0x03, 0xA2, 0x75, 0x30, 0x23, 0x07, 0x73, 0xD2, 0x80, 0xF0, 0x00, 0x07, 0xC6, 0xD0, 0x80, 0x08, 0x00, 0x60, 0x03, 0xA0, 0x02, + 0x0E, 0x6F, 0x60, 0x09, 0xF0, 0x00, 0x02, 0x00, 0x60, 0x03, 0x80, 0x00, 0xF0, 0x00, 0x07, 0x73, 0xD0, 0x80, 0x40, 0xE0, 0x00, 0x1F, 0x60, 0x01, + 0x13, 0xD5, 0x60, 0x07, 0xA0, 0x11, 0x90, 0x40, 0x70, 0x00, 0xF0, 0x00, 0x13, 0xFB, 0x60, 0x06, 0xA0, 0x0E, 0x14, 0x05, 0x60, 0x06, 0xA0, 0x0D, + 0x14, 0x0F, 0x60, 0x06, 0xA0, 0x0C, 0x45, 0x60, 0x00, 0x3A, 0x60, 0x01, 0x13, 0xB6, 0x60, 0x07, 0xA0, 0x0B, 0x90, 0x40, 0x70, 0x00, 0xF0, 0x00, + 0x13, 0xF7, 0x60, 0x06, 0xA0, 0x08, 0x14, 0x01, 0x60, 0x06, 0xA0, 0x07, 0x14, 0x0B, 0x60, 0x06, 0xA0, 0x06, 0x41, 0x80, 0x00, 0x3B, 0x60, 0x01, + 0x13, 0xB6, 0x60, 0x07, 0xA0, 0x05, 0x90, 0x40, 0x70, 0x00, 0xF0, 0x00, 0x13, 0xF7, 0x60, 0x06, 0xA0, 0x02, 0x14, 0x01, 0x60, 0x06, 0xA0, 0x01, + 0x14, 0x0B, 0x60, 0x06, 0x80, 0x00, 0xF0, 0x00, 0x0D, 0x28, 0xD0, 0x80, 0xD7, 0xCA, 0x00, 0xFF, 0x60, 0x04, 0x81, 0xD7, 0x0C, 0xF7, 0x60, 0x09, + 0xD0, 0x56, 0x70, 0x00, 0xF0, 0x00, 0x82, 0x76, 0x30, 0x17, 0xF0, 0x00, 0xD0, 0xF6, 0x40, 0x83, 0xF0, 0x00, 0xC1, 0xA4, 0x20, 0x19, 0xF0, 0x00, + 0x82, 0xF6, 0x70, 0x00, 0xF0, 0x00, 0xC1, 0x80, 0x20, 0x17, 0xA2, 0x54, 0xC3, 0xE7, 0x70, 0x00, 0xF0, 0x00, 0xC5, 0xC7, 0x70, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x30, 0x17, 0xD0, 0x08, 0x9A, 0x78, 0x70, 0x00, 0xF0, 0x00, 0x9A, 0x70, 0x70, 0x00, 0x90, 0xE3, 0xF0, 0x00, 0x70, 0x00, 0x90, 0xE3, + 0xF0, 0x00, 0x0D, 0x67, 0xD0, 0x80, 0xF0, 0x00, 0x70, 0x00, 0xA1, 0x19, 0xF0, 0x00, 0x70, 0x00, 0x80, 0xD2, 0x1E, 0xC8, 0x60, 0x08, 0xA2, 0x4A, + 0xF0, 0x00, 0x20, 0x00, 0xA2, 0x49, 0x90, 0x00, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xD4, 0x09, 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xA5, + 0x1E, 0xC8, 0x60, 0x08, 0xA2, 0x45, 0xF0, 0x00, 0x30, 0x00, 0xD0, 0x08, 0x00, 0x28, 0x60, 0x00, 0xA2, 0x43, 0x9E, 0x38, 0x0E, 0xF4, 0x60, 0x09, + 0x9E, 0x38, 0x70, 0x00, 0x9F, 0xFF, 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x08, 0x40, 0x40, 0x0C, 0x8A, 0xD5, 0x80, 0xF0, 0x00, 0x0C, 0x8B, 0xD2, 0x80, + 0xF0, 0x00, 0x0F, 0xB1, 0xD2, 0x80, 0x9C, 0x39, 0x70, 0x00, 0xF0, 0x00, 0x9C, 0x31, 0x70, 0x00, 0x90, 0x03, 0xF0, 0x00, 0x70, 0x00, 0x90, 0x02, + 0x40, 0x10, 0x70, 0x00, 0xAF, 0xF3, 0x41, 0xF1, 0x40, 0x40, 0x80, 0x0D, 0x40, 0x00, 0x70, 0x00, 0xAF, 0xF1, 0x41, 0xF1, 0x40, 0x40, 0x80, 0x0C, + 0x03, 0xE8, 0x60, 0x02, 0xA2, 0x35, 0x90, 0x83, 0x10, 0x44, 0xD1, 0x80, 0xF0, 0x00, 0x10, 0x42, 0xD0, 0x80, 0x40, 0x71, 0x40, 0x20, 0xA0, 0x08, + 0x43, 0xA1, 0x40, 0x30, 0xA0, 0x07, 0x43, 0xB1, 0x40, 0x30, 0xA0, 0x06, 0xF0, 0x00, 0x10, 0x75, 0xD0, 0x80, 0x40, 0x71, 0x40, 0x20, 0xA0, 0x04, + 0x43, 0xA1, 0x40, 0x30, 0xA0, 0x02, 0x43, 0xB1, 0x40, 0x30, 0xA0, 0x01, 0xF0, 0x00, 0x10, 0x81, 0xD0, 0x80, 0xF0, 0x00, 0x0C, 0x92, 0xD0, 0x80, + 0xF0, 0x00, 0x0C, 0x94, 0xD0, 0x80, 0xA0, 0x10, 0x70, 0x00, 0x31, 0x7C, 0xA6, 0x50, 0x7C, 0x4D, 0x20, 0x83, 0x80, 0x09, 0x21, 0xF8, 0xF0, 0x00, + 0xA0, 0xD0, 0x70, 0x00, 0x18, 0x41, 0xA6, 0x53, 0x15, 0x36, 0xD0, 0x80, 0xF0, 0x00, 0x0B, 0xC9, 0x60, 0x08, 0xF0, 0x00, 0x1D, 0x8D, 0xD2, 0x80, + 0xF0, 0x00, 0x16, 0xD5, 0xD0, 0x80, 0xF0, 0x00, 0x0B, 0xC9, 0x60, 0x08, 0xF0, 0x00, 0x1D, 0x8F, 0xD2, 0x80, 0xF0, 0x00, 0x16, 0xDA, 0xD0, 0x80, + 0x3E, 0x91, 0x1F, 0x5F, 0xD2, 0x80, 0xF0, 0x00, 0x23, 0x8A, 0xD0, 0x80, 0x0D, 0x85, 0x60, 0x08, 0xA2, 0x1B, 0xF0, 0x00, 0x30, 0x00, 0xD0, 0x08, + 0xF0, 0x00, 0x0F, 0x88, 0x60, 0x0B, 0xF0, 0x00, 0x02, 0x30, 0x60, 0x03, 0xF0, 0x00, 0x09, 0x38, 0x60, 0x04, 0x9F, 0x98, 0x01, 0x2C, 0x60, 0x05, + 0xF0, 0x00, 0x2E, 0xB3, 0xEE, 0x00, 0xF0, 0x00, 0x0F, 0xB1, 0xD2, 0x80, 0x9E, 0x09, 0x0D, 0x87, 0x60, 0x0C, 0x9F, 0x90, 0x70, 0x00, 0x90, 0x02, + 0x9F, 0x88, 0x2F, 0x34, 0xEE, 0x00, 0xF0, 0x00, 0x2F, 0xB5, 0xEE, 0x00, 0x30, 0x43, 0x0B, 0x42, 0x60, 0x08, 0xF0, 0x00, 0x30, 0xC4, 0xF0, 0x00, + 0xF0, 0x00, 0x31, 0x45, 0xF0, 0x00, 0xF0, 0x00, 0x2C, 0xB1, 0x40, 0x17, 0xF0, 0x00, 0x2D, 0x32, 0xF0, 0x00, 0xC6, 0x79, 0x22, 0x05, 0xF0, 0x00, + 0xF0, 0x00, 0x3D, 0x81, 0xF0, 0x00, 0xF0, 0x00, 0x3D, 0x01, 0xF0, 0x00, 0xDD, 0x6D, 0x1B, 0x93, 0xD2, 0x80, 0x90, 0x46, 0x0D, 0x85, 0x60, 0x0A, + 0x20, 0x42, 0x1B, 0x93, 0xD2, 0x80, 0xDA, 0xC9, 0x20, 0x25, 0xA2, 0x04, 0x8C, 0x69, 0x2D, 0xB3, 0xF0, 0x00, 0xDD, 0x49, 0x32, 0x01, 0xF0, 0x00, + 0x8D, 0x89, 0x70, 0x00, 0xF0, 0x00, 0x3C, 0x81, 0xFE, 0x35, 0x60, 0x00, 0x35, 0x81, 0x00, 0x16, 0x60, 0x01, 0xA0, 0x18, 0x21, 0x46, 0xF0, 0x00, + 0xAA, 0x07, 0x01, 0x2D, 0x60, 0x00, 0x81, 0xCF, 0x70, 0x00, 0xF0, 0x00, 0x8F, 0x80, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x94, 0x02, + 0x40, 0x45, 0x57, 0x4B, 0x60, 0x00, 0xE0, 0x00, 0x60, 0x01, 0x80, 0x02, 0x40, 0x65, 0x40, 0x00, 0x60, 0x00, 0xC6, 0x66, 0x60, 0x01, 0x80, 0x00, + 0xA0, 0x30, 0x40, 0x00, 0x60, 0x04, 0xAF, 0x4E, 0x00, 0xA4, 0x60, 0x05, 0x81, 0x8E, 0x0B, 0x75, 0x60, 0x08, 0xF0, 0x00, 0x14, 0x74, 0xD2, 0x80, + 0xF0, 0x00, 0x1B, 0x90, 0xD2, 0x80, 0x2E, 0x34, 0x04, 0x00, 0x60, 0x06, 0x20, 0xC2, 0x1B, 0x93, 0xD2, 0x80, 0xD2, 0xC9, 0x03, 0xE9, 0x60, 0x05, + 0x81, 0x8E, 0x0B, 0x59, 0x60, 0x08, 0x8F, 0x2D, 0x31, 0xC6, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x94, 0x02, 0x40, 0x45, 0xB1, 0x5C, 0x60, 0x03, + 0x46, 0x66, 0x60, 0x07, 0x80, 0x02, 0x40, 0x65, 0xAA, 0xCE, 0x60, 0x03, 0xC6, 0x66, 0x60, 0x07, 0x80, 0x00, 0xA0, 0xE0, 0x00, 0x38, 0x60, 0x04, + 0xAF, 0x48, 0x00, 0x1D, 0x60, 0x05, 0x81, 0xC7, 0x31, 0x84, 0xF0, 0x00, 0x31, 0x05, 0x14, 0x74, 0xD2, 0x80, 0xF0, 0x00, 0x1B, 0x90, 0xD2, 0x80, + 0xF0, 0x00, 0xD8, 0x00, 0x60, 0x00, 0xF0, 0x00, 0x0B, 0x67, 0x60, 0x08, 0x21, 0xC6, 0x20, 0x00, 0x60, 0x04, 0xF0, 0x00, 0x13, 0x33, 0x60, 0x05, + 0x81, 0x86, 0x31, 0x84, 0x40, 0x07, 0x31, 0x05, 0x14, 0x74, 0xD2, 0x80, 0xF0, 0x00, 0x1B, 0x90, 0xD0, 0x80, 0xF0, 0x00, 0x6E, 0x6C, 0x60, 0x03, + 0x40, 0x07, 0x00, 0xE5, 0x60, 0x05, 0xA0, 0x58, 0xFF, 0xFF, 0x60, 0x03, 0xAA, 0x24, 0x0B, 0x52, 0x60, 0x08, 0x81, 0x1C, 0x70, 0x00, 0xF0, 0x00, + 0x31, 0x05, 0x7F, 0xDF, 0x60, 0x06, 0x31, 0x84, 0x14, 0x74, 0xD2, 0x80, 0xF0, 0x00, 0x1B, 0x90, 0xD0, 0x80, 0x91, 0x83, 0x2E, 0x85, 0xF0, 0x00, + 0xF0, 0x00, 0x2F, 0x06, 0xF0, 0x00, 0xF0, 0x00, 0x2F, 0x87, 0xF0, 0x00, 0x0B, 0xC9, 0x60, 0x09, 0xA1, 0xCF, 0x3E, 0x11, 0x0D, 0x82, 0x60, 0x0A, + 0xF0, 0x00, 0x27, 0x11, 0xA1, 0xCD, 0xA0, 0x50, 0x27, 0x92, 0xF0, 0x00, 0xAA, 0x41, 0x0B, 0xB4, 0x60, 0x0C, 0x80, 0x52, 0x20, 0x21, 0xA1, 0xCA, + 0x9E, 0xCB, 0x35, 0x92, 0xF0, 0x00, 0x90, 0x41, 0x70, 0x00, 0xD8, 0x09, 0x88, 0x2D, 0x70, 0x00, 0xD4, 0x09, 0xF0, 0x00, 0x36, 0x15, 0xF0, 0x00, + 0xF0, 0x00, 0x36, 0x95, 0xF0, 0x00, 0x91, 0x00, 0x30, 0xA6, 0xF0, 0x00, 0x31, 0x27, 0x14, 0x62, 0xD2, 0x80, 0x90, 0x04, 0x31, 0xC0, 0xF0, 0x00, + 0x21, 0x45, 0x8C, 0xCD, 0x60, 0x06, 0xF0, 0x00, 0xFF, 0x55, 0x60, 0x07, 0xF0, 0x00, 0x14, 0x74, 0xD2, 0x80, 0xF0, 0x00, 0x32, 0x40, 0xF0, 0x00, + 0xF0, 0x00, 0x32, 0xC1, 0xF0, 0x00, 0xF0, 0x00, 0x33, 0x42, 0x80, 0x00, 0xF0, 0x00, 0x0D, 0x82, 0x60, 0x09, 0xF0, 0x00, 0x0B, 0xC9, 0x60, 0x0A, + 0xF0, 0x00, 0x20, 0x15, 0xA1, 0xB9, 0x91, 0x45, 0x7F, 0xEC, 0x60, 0x06, 0x40, 0x47, 0x70, 0x00, 0xD4, 0x09, 0x20, 0x90, 0x14, 0x47, 0xD2, 0x80, + 0xF0, 0x00, 0x34, 0xA0, 0xF0, 0x00, 0x21, 0x10, 0x14, 0x47, 0xD2, 0x80, 0xF0, 0x00, 0x35, 0x20, 0xD0, 0x08, 0x0A, 0x3D, 0x60, 0x07, 0xA1, 0xB2, + 0xA2, 0x79, 0x0B, 0xC9, 0x60, 0x09, 0xA2, 0xBA, 0x70, 0x00, 0xF0, 0x00, 0x90, 0xC0, 0x3B, 0x91, 0xF0, 0x00, 0x3B, 0x12, 0x14, 0x62, 0xD2, 0x80, + 0xF0, 0x00, 0x3C, 0x10, 0xD0, 0x08, 0xF0, 0x00, 0x0B, 0x60, 0x60, 0x0E, 0xF0, 0x00, 0x00, 0x04, 0x60, 0x03, 0x40, 0xA7, 0x3F, 0xFC, 0x60, 0x04, + 0x32, 0x63, 0x80, 0x08, 0x60, 0x05, 0x32, 0xE4, 0x19, 0x9A, 0x60, 0x06, 0x33, 0x65, 0x0D, 0x86, 0x60, 0x0F, 0x31, 0xE6, 0x70, 0x00, 0xF0, 0x00, + 0x30, 0x77, 0x70, 0x00, 0xD0, 0x08, 0x0D, 0x82, 0x60, 0x0A, 0xA1, 0xA4, 0xF0, 0x00, 0x30, 0x20, 0xF0, 0x00, 0x00, 0xD2, 0x60, 0x01, 0x94, 0x0B, + 0xF0, 0x00, 0x00, 0xD2, 0x60, 0x02, 0x00, 0xFA, 0x60, 0x03, 0xAF, 0xED, 0xF0, 0x00, 0xBE, 0x77, 0x60, 0x06, 0xF0, 0x00, 0x4B, 0x00, 0x60, 0x07, + 0x37, 0x06, 0x00, 0x01, 0x60, 0x01, 0x37, 0x87, 0x03, 0xE8, 0x60, 0x02, 0xF0, 0x00, 0x03, 0x84, 0x60, 0x04, 0xF0, 0x00, 0x00, 0x01, 0x60, 0x05, + 0xF0, 0x00, 0x00, 0x8C, 0x60, 0x06, 0xF0, 0x00, 0x0A, 0xF0, 0x60, 0x07, 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xC7, 0xF0, 0x00, 0x0B, 0xB4, 0x60, 0x09, + 0xF0, 0x00, 0x00, 0x11, 0x60, 0x05, 0xF0, 0x00, 0x00, 0x11, 0x60, 0x06, 0x3B, 0x05, 0x10, 0x00, 0x60, 0x07, 0x3B, 0x86, 0x00, 0x04, 0x60, 0x00, + 0x3C, 0x07, 0xAD, 0x84, 0x60, 0x01, 0x32, 0x10, 0x01, 0xFD, 0x60, 0x02, 0x32, 0x91, 0x0B, 0x5E, 0x60, 0x03, 0x33, 0x12, 0x0C, 0x80, 0x60, 0x04, + 0x31, 0x93, 0x00, 0xA0, 0x60, 0x05, 0x34, 0x84, 0xFF, 0xD0, 0x60, 0x06, 0x35, 0x05, 0xE3, 0x54, 0x60, 0x07, 0x36, 0x06, 0x34, 0x00, 0x60, 0x00, + 0x36, 0x86, 0x00, 0x01, 0x60, 0x01, 0x37, 0x07, 0x03, 0xE8, 0x60, 0x02, 0x37, 0x80, 0x70, 0x00, 0x8F, 0xB7, 0x80, 0xE5, 0x7F, 0xFF, 0x60, 0x00, + 0xCC, 0x0A, 0x70, 0x00, 0xF0, 0x00, 0x8E, 0xA9, 0x33, 0x70, 0xF0, 0x00, 0xAF, 0x20, 0x34, 0x70, 0xD4, 0x09, 0xAE, 0xE8, 0x70, 0x00, 0xF0, 0x00, + 0xA8, 0x05, 0x00, 0x80, 0x60, 0x07, 0xA8, 0xF6, 0x33, 0x75, 0xF0, 0x00, 0xC3, 0x86, 0x70, 0x00, 0xF0, 0x00, 0x8F, 0x7F, 0x33, 0xF6, 0xF0, 0x00, + 0xA8, 0x85, 0x1D, 0xE4, 0xD1, 0x80, 0xF0, 0x00, 0x34, 0x75, 0xD0, 0x08, 0x0D, 0x86, 0x60, 0x09, 0xA1, 0x7B, 0x20, 0x12, 0x1F, 0x32, 0xD2, 0x80, + 0xF0, 0x00, 0x35, 0x82, 0xD0, 0x08, 0x90, 0x82, 0x0D, 0x86, 0x60, 0x09, 0x40, 0xA7, 0x40, 0x77, 0xE6, 0x40, 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x30, 0x17, 0xD0, 0x08, 0x0B, 0xB4, 0x60, 0x08, 0xA1, 0x74, 0xF0, 0x00, 0x31, 0x82, 0xD0, 0x08, 0xF0, 0x00, 0x09, 0x61, 0x60, 0x08, + 0xF0, 0x00, 0x09, 0xC9, 0x60, 0x09, 0xF0, 0x00, 0x21, 0x80, 0xF0, 0x00, 0xF0, 0x00, 0x20, 0x91, 0xA1, 0x6F, 0xA2, 0x08, 0x70, 0x00, 0xD0, 0x08, + 0x00, 0xCF, 0x60, 0x02, 0xA0, 0x01, 0x01, 0x51, 0x60, 0x02, 0x80, 0x01, 0x0D, 0x8B, 0x60, 0x08, 0x80, 0x01, 0x0D, 0x8C, 0x60, 0x08, 0x80, 0x00, + 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0x02, 0xD0, 0x08, 0x0F, 0xF2, 0x60, 0x09, 0xA1, 0x67, 0x20, 0x11, 0x0D, 0x8B, 0x60, 0x0A, + 0xF0, 0x00, 0x2C, 0x92, 0xF0, 0x00, 0x90, 0x41, 0x20, 0x11, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x93, 0xFE, 0xF0, 0x00, 0x70, 0x00, 0xF2, 0x00, + 0x31, 0x22, 0x20, 0x31, 0xD0, 0x80, 0x0D, 0x8B, 0x60, 0x08, 0xA0, 0x03, 0xF0, 0x00, 0x20, 0x22, 0xD0, 0x80, 0x0D, 0x8C, 0x60, 0x08, 0xA0, 0x01, + 0xF0, 0x00, 0x20, 0x1E, 0xD0, 0x80, 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, 0x20, 0x00, 0x0E, 0x69, 0x60, 0x08, 0xF0, 0x00, 0x01, 0xD0, 0x60, 0x01, + 0xF0, 0x00, 0x30, 0x80, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0x01, 0xD0, 0x08, 0x83, 0x6D, 0x0C, 0x35, 0x60, 0x08, 0x40, 0x60, 0x3A, 0x4D, 0x60, 0x01, + 0x41, 0xE2, 0x21, 0x96, 0x60, 0x03, 0x33, 0x00, 0x41, 0x44, 0xF0, 0x00, 0x33, 0x81, 0x70, 0x00, 0xF0, 0x00, 0x34, 0x02, 0x70, 0x00, 0xF0, 0x00, + 0x34, 0x83, 0x0C, 0x29, 0x60, 0x09, 0x35, 0x04, 0x3A, 0x5B, 0x60, 0x00, 0x35, 0x85, 0x3A, 0x60, 0x60, 0x03, 0x30, 0x90, 0x70, 0x00, 0xF0, 0x00, + 0x33, 0x93, 0x70, 0x00, 0x8F, 0xDF, 0xF0, 0x00, 0x70, 0x00, 0xAE, 0x6C, 0xF0, 0x00, 0x70, 0x00, 0x8E, 0x9F, 0xF0, 0x00, 0x70, 0x00, 0xAE, 0x98, + 0xF0, 0x00, 0x0C, 0x51, 0xD2, 0x80, 0xF0, 0x00, 0x21, 0xA0, 0xD0, 0x80, 0xF0, 0x00, 0x05, 0x2E, 0xD2, 0x80, 0xF0, 0x00, 0x70, 0x00, 0xA0, 0x0E, + 0xF0, 0x00, 0x21, 0xB7, 0xD0, 0x80, 0xF0, 0x00, 0x1F, 0x32, 0xD2, 0x80, 0xF0, 0x00, 0x1E, 0x84, 0xD2, 0x80, 0xF0, 0x00, 0x21, 0xE0, 0xD0, 0x80, + 0xF0, 0x00, 0x1E, 0xA4, 0xD2, 0x80, 0xF0, 0x00, 0x07, 0xF7, 0xD2, 0x80, 0xF0, 0x00, 0x22, 0x15, 0xD0, 0x80, 0xF0, 0x00, 0x07, 0xFB, 0xD2, 0x80, + 0xF0, 0x00, 0x22, 0x8F, 0xD0, 0x80, 0x40, 0x40, 0x22, 0xE1, 0xD2, 0x80, 0x40, 0x80, 0x22, 0xE2, 0xD2, 0x80, 0xF0, 0x00, 0x22, 0x9C, 0xD0, 0x80, + 0xF0, 0x00, 0x07, 0xFB, 0xD2, 0x80, 0xF0, 0x00, 0x22, 0xB6, 0xD0, 0x80, 0xF0, 0x00, 0x20, 0xF0, 0xD2, 0x80, 0x90, 0x02, 0x27, 0xDF, 0xD2, 0x80, + 0x9E, 0x69, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x07, 0x00, 0xD1, 0x80, 0xF0, 0x00, 0x23, 0x20, 0xD0, 0x80, 0x90, 0x82, 0x0C, 0x29, 0x60, 0x09, + 0x40, 0x17, 0x40, 0x67, 0xE6, 0x40, 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x32, 0x17, 0xD0, 0x08, 0xF0, 0x00, 0x07, 0xF7, 0xD2, 0x80, + 0xF0, 0x00, 0x27, 0xEA, 0xD2, 0x80, 0xF0, 0x00, 0x11, 0xB5, 0xD0, 0x80, 0x40, 0x55, 0x15, 0x17, 0x60, 0x08, 0xF0, 0x00, 0x1D, 0x40, 0x60, 0x00, + 0x31, 0x05, 0x1E, 0x60, 0x60, 0x01, 0x31, 0x85, 0x70, 0x00, 0xF0, 0x00, 0x32, 0x05, 0x70, 0x00, 0xF0, 0x00, 0x32, 0x85, 0x70, 0x00, 0xF0, 0x00, + 0x33, 0x00, 0x70, 0x00, 0xF0, 0x00, 0x33, 0x81, 0x0D, 0x8E, 0x60, 0x09, 0x34, 0x00, 0x02, 0x54, 0x60, 0x02, 0x34, 0x81, 0x38, 0x80, 0x60, 0x03, + 0x30, 0x12, 0x70, 0x00, 0xF0, 0x00, 0x30, 0x93, 0x70, 0x00, 0xD0, 0x08, 0x17, 0x0B, 0x60, 0x0C, 0xA1, 0x1F, 0x00, 0x40, 0x40, 0x05, 0xF0, 0x00, + 0x00, 0x41, 0x24, 0x3F, 0xD0, 0x80, 0xF0, 0x00, 0x0C, 0x83, 0x60, 0x08, 0x90, 0x00, 0x0C, 0x6B, 0x60, 0x0B, 0xF0, 0x00, 0x70, 0x0C, 0xE6, 0x00, + 0xF0, 0x00, 0x20, 0x03, 0xF0, 0x00, 0xF0, 0x00, 0x22, 0x04, 0xF0, 0x00, 0xF0, 0x00, 0x3B, 0xB3, 0xF0, 0x00, 0xF0, 0x00, 0x3C, 0x34, 0xD0, 0x08, + 0xF0, 0x00, 0x70, 0x00, 0xAD, 0xC8, 0xF0, 0x00, 0x0C, 0x8D, 0x60, 0x08, 0xF0, 0x00, 0x26, 0x0A, 0xD0, 0x80, 0x83, 0xFF, 0x0D, 0x9B, 0x60, 0x08, + 0xF0, 0x00, 0x01, 0xF4, 0x60, 0x00, 0xF0, 0x00, 0x03, 0xB1, 0x60, 0x01, 0x10, 0x00, 0x03, 0xB2, 0x60, 0x02, 0x10, 0x01, 0x04, 0x0E, 0x60, 0x00, + 0x10, 0x02, 0x04, 0x0F, 0x60, 0x01, 0x10, 0x00, 0x04, 0x5C, 0x60, 0x02, 0x10, 0x01, 0x04, 0x5D, 0x60, 0x00, 0x10, 0x02, 0x13, 0x80, 0x60, 0x01, + 0x10, 0x00, 0x0D, 0xAB, 0x60, 0x09, 0x10, 0x01, 0x02, 0xEE, 0x60, 0x00, 0x10, 0x07, 0x43, 0x06, 0x60, 0x01, 0x10, 0x10, 0x04, 0x69, 0x60, 0x02, + 0x10, 0x11, 0x44, 0x87, 0x60, 0x00, 0x10, 0x12, 0x05, 0xE3, 0x60, 0x01, 0x10, 0x10, 0x46, 0x08, 0x60, 0x02, 0x10, 0x11, 0x06, 0xAE, 0x60, 0x00, + 0x10, 0x12, 0x0D, 0xA4, 0x60, 0x08, 0x10, 0x10, 0x9E, 0x3C, 0x60, 0x00, 0x10, 0x17, 0x0D, 0xB3, 0x60, 0x09, 0x10, 0x00, 0x25, 0xDA, 0x60, 0x00, + 0x10, 0x07, 0x80, 0x3D, 0x60, 0x01, 0x10, 0x10, 0x28, 0x82, 0x60, 0x02, 0x10, 0x11, 0xC0, 0x3D, 0x60, 0x00, 0x10, 0x12, 0x28, 0x87, 0x60, 0x01, + 0x10, 0x10, 0xC0, 0x3B, 0x60, 0x02, 0x10, 0x11, 0x28, 0x8C, 0x60, 0x00, 0x10, 0x12, 0xC0, 0x3B, 0x60, 0x01, 0x10, 0x10, 0x28, 0x91, 0x60, 0x02, + 0x10, 0x11, 0xC0, 0x3B, 0x60, 0x00, 0x10, 0x12, 0x28, 0x96, 0x60, 0x01, 0x10, 0x10, 0xC0, 0x3B, 0x60, 0x02, 0x10, 0x11, 0x28, 0x9B, 0x60, 0x00, + 0x10, 0x12, 0xC0, 0x3B, 0x60, 0x01, 0x10, 0x10, 0x28, 0xA0, 0x60, 0x02, 0x10, 0x11, 0x40, 0x3C, 0x60, 0x00, 0x10, 0x12, 0x28, 0xA5, 0x60, 0x01, + 0x10, 0x10, 0xC0, 0x3C, 0x60, 0x02, 0x10, 0x11, 0x28, 0xAA, 0x60, 0x00, 0x10, 0x12, 0xC0, 0x3C, 0x60, 0x01, 0x10, 0x10, 0x28, 0xAF, 0x60, 0x02, + 0x10, 0x11, 0xC0, 0x3C, 0x60, 0x00, 0x10, 0x12, 0x28, 0xB4, 0x60, 0x01, 0x10, 0x10, 0xC0, 0x3C, 0x60, 0x02, 0x10, 0x11, 0x28, 0xB9, 0x60, 0x00, + 0x10, 0x12, 0xC0, 0x3C, 0x60, 0x01, 0x10, 0x10, 0x28, 0xBE, 0x60, 0x02, 0x10, 0x11, 0xC0, 0x3C, 0x60, 0x00, 0x10, 0x12, 0x29, 0xCC, 0x60, 0x01, + 0x10, 0x10, 0x00, 0x37, 0x60, 0x02, 0x10, 0x11, 0x29, 0xD1, 0x60, 0x00, 0x10, 0x12, 0x00, 0x37, 0x60, 0x01, 0x10, 0x10, 0x29, 0xD6, 0x60, 0x02, + 0x10, 0x11, 0x00, 0x37, 0x60, 0x00, 0x10, 0x12, 0x29, 0xDB, 0x60, 0x01, 0x10, 0x10, 0x00, 0x37, 0x60, 0x02, 0x10, 0x11, 0x0D, 0xD8, 0x60, 0x08, + 0x10, 0x12, 0x27, 0x15, 0x60, 0x00, 0x10, 0x17, 0x40, 0x3E, 0x60, 0x01, 0x10, 0x00, 0x27, 0x1A, 0x60, 0x02, 0x10, 0x01, 0x80, 0x3C, 0x60, 0x00, + 0x10, 0x02, 0x28, 0x64, 0x60, 0x01, 0x10, 0x00, 0x40, 0x3C, 0x60, 0x02, 0x10, 0x01, 0x28, 0x69, 0x60, 0x00, 0x10, 0x02, 0x40, 0x3C, 0x60, 0x01, + 0x10, 0x00, 0x28, 0x6E, 0x60, 0x02, 0x10, 0x01, 0x80, 0x3A, 0x60, 0x00, 0x10, 0x02, 0x28, 0x73, 0x60, 0x01, 0x10, 0x00, 0x80, 0x3A, 0x60, 0x02, + 0x10, 0x01, 0x28, 0xA0, 0x60, 0x00, 0x10, 0x02, 0x40, 0x3C, 0x60, 0x01, 0x10, 0x00, 0x29, 0xCC, 0x60, 0x02, 0x10, 0x01, 0x00, 0x37, 0x60, 0x00, + 0x10, 0x02, 0x29, 0xD1, 0x60, 0x01, 0x10, 0x00, 0x00, 0x37, 0x60, 0x02, 0x10, 0x01, 0x29, 0xD6, 0x60, 0x00, 0x10, 0x02, 0x00, 0x37, 0x60, 0x01, + 0x10, 0x00, 0x29, 0xDB, 0x60, 0x02, 0x10, 0x01, 0x00, 0x37, 0x60, 0x00, 0x10, 0x02, 0x0D, 0xEF, 0x60, 0x09, 0x10, 0x00, 0x70, 0x00, 0xF0, 0x00, + 0x10, 0x07, 0x70, 0x00, 0xF0, 0x00, 0x10, 0x17, 0x70, 0x00, 0xD0, 0x08, 0x0C, 0xDF, 0x60, 0x0B, 0xA0, 0xBF, 0x30, 0x30, 0x23, 0xD6, 0xD2, 0x80, + 0xF0, 0x00, 0x26, 0xE8, 0xD0, 0x80, 0x0D, 0x9B, 0x60, 0x08, 0xA0, 0xBC, 0xF0, 0x00, 0x00, 0x02, 0xA0, 0xBB, 0x90, 0x82, 0x70, 0x00, 0xF0, 0x00, + 0x82, 0x8A, 0x70, 0x00, 0x90, 0x03, 0x90, 0x8A, 0x70, 0x00, 0x90, 0x01, 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xFB, 0x82, 0xBF, 0x70, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x01, 0x99, 0xD2, 0x80, 0xF0, 0x00, 0x0D, 0x9A, 0x60, 0x08, 0xF0, 0x00, 0x26, 0xC1, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x02, 0xA0, 0xB2, + 0x90, 0x82, 0x70, 0x00, 0xF0, 0x00, 0x82, 0x8A, 0x70, 0x00, 0x90, 0x03, 0x90, 0x8A, 0x70, 0x00, 0x90, 0x01, 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xFB, + 0x82, 0x80, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x08, 0xF0, 0x00, 0x0D, 0xAB, 0x60, 0x0D, 0xF0, 0x00, 0x3F, 0xFF, 0x60, 0x02, + 0xF0, 0x00, 0x00, 0x51, 0xA0, 0xA9, 0xC2, 0x53, 0x70, 0x00, 0xF0, 0x00, 0x8E, 0xC4, 0x70, 0x00, 0x90, 0x01, 0xF0, 0x00, 0x70, 0x00, 0x97, 0xFC, + 0xD4, 0x8F, 0x01, 0x99, 0xD2, 0x80, 0x40, 0x05, 0x0D, 0xA4, 0x60, 0x0D, 0x40, 0x17, 0x3F, 0xFF, 0x60, 0x02, 0x9F, 0x7D, 0x00, 0x51, 0xA0, 0xA2, + 0xC2, 0x53, 0x70, 0x00, 0xF0, 0x00, 0x82, 0xC4, 0x27, 0x1C, 0xD1, 0x80, 0xF0, 0x00, 0x70, 0x00, 0x97, 0xFC, 0x91, 0x46, 0x27, 0x20, 0xD0, 0x80, + 0x40, 0x07, 0x01, 0x99, 0xD2, 0x80, 0xF0, 0x00, 0x0D, 0x8E, 0x60, 0x0E, 0x40, 0x07, 0x25, 0xC1, 0xA0, 0x9B, 0x9E, 0x79, 0x2E, 0x40, 0x40, 0x14, + 0x40, 0x36, 0x31, 0x67, 0x90, 0x19, 0x2F, 0x45, 0x19, 0x64, 0x60, 0x02, 0x4F, 0xF0, 0x1A, 0x5E, 0x60, 0x03, 0x83, 0x54, 0x40, 0x36, 0xF0, 0x00, + 0x83, 0x5C, 0x40, 0x00, 0xE2, 0x00, 0xF0, 0x00, 0x40, 0x10, 0xE2, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xF0, 0x00, 0x90, 0x00, 0x70, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x70, 0x00, 0x9C, 0x11, 0xF0, 0x00, 0x0D, 0xD8, 0x60, 0x0D, 0x40, 0x36, 0x22, 0xF0, 0xD2, 0x80, 0x0D, 0xB3, 0x60, 0x0D, 0xE6, 0x00, + 0x40, 0x14, 0x21, 0x40, 0xF0, 0x00, 0xF0, 0x00, 0x20, 0x51, 0xA0, 0x8C, 0x90, 0x41, 0x70, 0x00, 0xF0, 0x00, 0x82, 0x45, 0x70, 0x00, 0x90, 0x1D, + 0xF0, 0x00, 0x70, 0x00, 0x90, 0x01, 0xF0, 0x00, 0x70, 0xDC, 0x8F, 0xFB, 0x20, 0xD1, 0x3F, 0xFF, 0x60, 0x02, 0xF0, 0x00, 0x0C, 0xDF, 0x60, 0x0B, + 0xC2, 0x53, 0x31, 0x61, 0xF0, 0x00, 0xD4, 0x8E, 0x30, 0x33, 0xF0, 0x00, 0xD4, 0x4A, 0x37, 0xC6, 0xF0, 0x00, 0xC6, 0xA2, 0x70, 0x00, 0xF0, 0x00, + 0xC3, 0xA0, 0x3D, 0x42, 0xF0, 0x00, 0xF0, 0x00, 0x31, 0xE0, 0xD0, 0x08, 0xC6, 0x24, 0x31, 0xE0, 0xF0, 0x00, 0x90, 0x00, 0x3D, 0x44, 0xF0, 0x00, + 0x83, 0xB6, 0x70, 0x00, 0xE0, 0x40, 0x40, 0xD5, 0x21, 0x41, 0xA0, 0x7C, 0xCC, 0x0B, 0x40, 0x00, 0xF0, 0x00, 0x80, 0xED, 0x23, 0xEA, 0xD2, 0x80, + 0xBF, 0x60, 0x20, 0x60, 0xF0, 0x00, 0xF0, 0x00, 0x20, 0xE1, 0xF0, 0x00, 0xF0, 0x00, 0x23, 0xEA, 0xD2, 0x80, 0x90, 0xC6, 0x23, 0xDE, 0xD2, 0x80, + 0x4F, 0x95, 0x40, 0x14, 0xA0, 0x75, 0x81, 0x75, 0x70, 0x00, 0xF0, 0x00, 0xAF, 0x43, 0x70, 0x00, 0xF0, 0x00, 0xC2, 0xE0, 0x70, 0x00, 0xF0, 0x00, + 0x80, 0xC3, 0x0C, 0xDF, 0x60, 0x0B, 0xF0, 0x00, 0x33, 0x63, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0xE3, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0x33, 0xA0, 0x41, + 0xF0, 0x00, 0x70, 0x00, 0x80, 0x12, 0x40, 0xD5, 0x21, 0x41, 0xA0, 0x6C, 0xCC, 0x0B, 0x40, 0x00, 0xF0, 0x00, 0x80, 0xED, 0x23, 0xEA, 0xD2, 0x80, + 0xBF, 0x60, 0x20, 0x60, 0xF0, 0x00, 0xF0, 0x00, 0x20, 0xE1, 0xF0, 0x00, 0xF0, 0x00, 0x23, 0xEA, 0xD2, 0x80, 0x90, 0xC6, 0x23, 0xDE, 0xD2, 0x80, + 0x4F, 0x95, 0x40, 0x14, 0xA0, 0x65, 0x81, 0x75, 0x70, 0x00, 0x40, 0x06, 0xAF, 0x43, 0x70, 0x00, 0xF0, 0x00, 0xC2, 0xE0, 0x0C, 0xDF, 0x60, 0x0B, + 0xF0, 0x00, 0x31, 0xE0, 0xF0, 0x00, 0x80, 0xC3, 0x40, 0x36, 0xE6, 0x00, 0xC6, 0x24, 0x30, 0x33, 0xF0, 0x00, 0xF0, 0x00, 0x33, 0x63, 0xF0, 0x00, + 0xF0, 0x00, 0x34, 0xE3, 0xF0, 0x00, 0xF0, 0x00, 0x3D, 0x44, 0xF0, 0x00, 0xF0, 0x00, 0x37, 0xC6, 0xA0, 0x2E, 0xF0, 0x00, 0x23, 0x66, 0xA0, 0x31, + 0x82, 0x92, 0x0B, 0xB8, 0x60, 0x03, 0x47, 0xF4, 0x23, 0xE0, 0xD2, 0x80, 0x52, 0x08, 0x60, 0x05, 0x98, 0x03, 0x82, 0x92, 0x52, 0x08, 0x60, 0x03, + 0x47, 0xF4, 0x23, 0xE0, 0xD2, 0x80, 0x52, 0x08, 0x60, 0x05, 0x98, 0x23, 0xF0, 0x00, 0x33, 0xE4, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0x65, 0xF0, 0x00, + 0xF0, 0x00, 0x35, 0x64, 0xF0, 0x00, 0xF0, 0x00, 0x35, 0xE5, 0xF0, 0x00, 0xF0, 0x00, 0x23, 0x66, 0xA0, 0x4F, 0x91, 0x8E, 0x70, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x33, 0x66, 0xA0, 0x24, 0x82, 0x92, 0x52, 0x08, 0x60, 0x03, 0xF0, 0x00, 0x23, 0xE0, 0xD2, 0x80, 0xF0, 0x00, 0x70, 0x00, 0x9C, 0x05, + 0x82, 0x92, 0x0B, 0xB8, 0x60, 0x03, 0xF0, 0x00, 0x23, 0xE0, 0xD2, 0x80, 0xF0, 0x00, 0x70, 0x00, 0x9B, 0xF7, 0x0D, 0x94, 0x60, 0x0D, 0xA0, 0x2B, + 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xF5, 0xF0, 0x00, 0x24, 0xE6, 0xA0, 0x44, 0x9F, 0xBE, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x34, 0xE6, 0xA0, 0x19, + 0x82, 0x92, 0x52, 0x08, 0x60, 0x03, 0xF0, 0x00, 0x23, 0xE0, 0xD2, 0x80, 0xF0, 0x00, 0x70, 0x00, 0x9C, 0x05, 0x82, 0x92, 0x0B, 0xB8, 0x60, 0x03, + 0xF0, 0x00, 0x23, 0xE0, 0xD2, 0x80, 0xF0, 0x00, 0x70, 0x00, 0x9B, 0xF7, 0x0D, 0x97, 0x60, 0x0D, 0xA0, 0x20, 0xF0, 0x00, 0x70, 0x00, 0x8F, 0xF5, + 0x40, 0x14, 0x23, 0xE1, 0xA0, 0x39, 0xC2, 0x63, 0x25, 0x62, 0xF0, 0x00, 0xF0, 0x00, 0x24, 0x65, 0x90, 0x07, 0xC2, 0xA3, 0x25, 0xE6, 0xF0, 0x00, + 0x90, 0x80, 0x70, 0x00, 0x90, 0x02, 0x83, 0x77, 0x70, 0x00, 0xF0, 0x00, 0x25, 0x60, 0x23, 0xE0, 0xEB, 0xC0, 0x0C, 0xDF, 0x60, 0x0B, 0xA0, 0x32, + 0xF0, 0x00, 0x30, 0x30, 0xF0, 0x00, 0xF0, 0x00, 0x21, 0xE0, 0xD0, 0x08, 0xC2, 0xA3, 0x25, 0xE6, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0x93, 0xF9, + 0x90, 0x40, 0x70, 0x00, 0x8F, 0xFA, 0xF0, 0x00, 0x21, 0xE0, 0xAF, 0x0F, 0xF0, 0x00, 0x24, 0x62, 0xD2, 0x80, 0xF0, 0x00, 0x32, 0x60, 0xF0, 0x00, + 0xF0, 0x00, 0x32, 0xE1, 0xD0, 0x08, 0xF0, 0x00, 0x23, 0xED, 0xD2, 0x80, 0xB8, 0x68, 0x22, 0x60, 0xF0, 0x00, 0xF0, 0x00, 0x22, 0xE1, 0xF0, 0x00, + 0xF0, 0x00, 0x23, 0xEA, 0xD2, 0x80, 0xF0, 0x00, 0x23, 0xDE, 0xD2, 0x80, 0xA9, 0x88, 0x70, 0x00, 0xF0, 0x00, 0xAB, 0xF8, 0x23, 0xE4, 0xD2, 0x80, + 0x46, 0x43, 0x21, 0x42, 0xA0, 0x21, 0xA0, 0x98, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x23, 0xE7, 0xD2, 0x80, 0xF0, 0x00, 0x23, 0xC6, 0xD2, 0x80, + 0x90, 0x00, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xDC, 0x09, 0xF0, 0x00, 0x23, 0xCE, 0xD0, 0x80, 0x47, 0xE5, 0x70, 0x00, 0xF0, 0x00, + 0x40, 0x16, 0x20, 0xD3, 0xA0, 0x19, 0x83, 0x5D, 0x20, 0x52, 0xF0, 0x00, 0xC2, 0xF5, 0x21, 0x54, 0x98, 0x07, 0xC2, 0xB6, 0x70, 0x00, 0x90, 0x02, + 0xF0, 0x00, 0x70, 0x00, 0x90, 0x05, 0xF0, 0x00, 0x70, 0x00, 0x80, 0x02, 0xC2, 0xB6, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xD4, 0x09, + 0x82, 0x64, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xDC, 0x09, 0xF0, 0x00, 0x31, 0x51, 0xF0, 0x00, 0xF0, 0x00, 0x30, 0xD2, 0xD0, 0x08, + 0x0D, 0xEF, 0x60, 0x0B, 0xA0, 0x0D, 0x9E, 0x79, 0x20, 0x36, 0xF0, 0x00, 0xF0, 0x00, 0x20, 0x45, 0xF0, 0x00, 0x9F, 0xBC, 0x70, 0x00, 0xE0, 0x40, + 0x91, 0x45, 0x70, 0x00, 0xD0, 0x09, 0x26, 0x44, 0x27, 0x2D, 0xD5, 0x80, 0x91, 0x86, 0x70, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x27, 0x32, 0xD5, 0x80, + 0xF0, 0x00, 0x70, 0x00, 0xAF, 0x67, 0x2F, 0x41, 0x27, 0x36, 0xD0, 0x80, 0xF0, 0x00, 0x29, 0x15, 0xD2, 0x80, 0xF0, 0x00, 0x3B, 0x9B, 0xD2, 0x80, + 0xF0, 0x00, 0x28, 0x88, 0xD0, 0x80, 0xF0, 0x00, 0x28, 0xDD, 0xD0, 0x80, 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x08, 0xF0, 0x00, 0x16, 0xC3, 0x60, 0x08, + 0xF0, 0x00, 0x00, 0x9A, 0x60, 0x00, 0xF0, 0x00, 0x02, 0xE3, 0x60, 0x00, 0x10, 0x00, 0x04, 0xF4, 0x60, 0x00, 0x10, 0x00, 0x06, 0xFF, 0x60, 0x00, + 0x10, 0x00, 0x09, 0x07, 0x60, 0x00, 0x10, 0x00, 0x0B, 0x10, 0x60, 0x00, 0x10, 0x00, 0x0D, 0x1F, 0x60, 0x00, 0x10, 0x00, 0x0F, 0x65, 0x60, 0x00, + 0x10, 0x00, 0x0F, 0x65, 0x60, 0x00, 0x10, 0x00, 0x0D, 0x1F, 0x60, 0x00, 0x10, 0x00, 0x0B, 0x10, 0x60, 0x00, 0x10, 0x00, 0x09, 0x07, 0x60, 0x00, + 0x10, 0x00, 0x06, 0xFF, 0x60, 0x00, 0x10, 0x00, 0x04, 0xF4, 0x60, 0x00, 0x10, 0x00, 0x02, 0xE3, 0x60, 0x00, 0x10, 0x00, 0x00, 0x9A, 0x60, 0x00, + 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x16, 0xD3, 0x60, 0x08, 0xF0, 0x00, 0xFF, 0x93, 0x60, 0x00, + 0xF0, 0x00, 0xFE, 0x37, 0x60, 0x00, 0x10, 0x00, 0xFD, 0xD9, 0x60, 0x00, 0x10, 0x00, 0xFE, 0x9F, 0x60, 0x00, 0x10, 0x00, 0x03, 0x85, 0x60, 0x00, + 0x10, 0x00, 0x0D, 0x6B, 0x60, 0x00, 0x10, 0x00, 0x16, 0x84, 0x60, 0x00, 0x10, 0x00, 0x1E, 0x49, 0x60, 0x00, 0x10, 0x00, 0x1E, 0x49, 0x60, 0x00, + 0x10, 0x00, 0x16, 0x84, 0x60, 0x00, 0x10, 0x00, 0x0D, 0x6B, 0x60, 0x00, 0x10, 0x00, 0x03, 0x85, 0x60, 0x00, 0x10, 0x00, 0xFE, 0x9F, 0x60, 0x00, + 0x10, 0x00, 0xFD, 0xD9, 0x60, 0x00, 0x10, 0x00, 0xFE, 0x37, 0x60, 0x00, 0x10, 0x00, 0xFF, 0x93, 0x60, 0x00, 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x16, 0xE3, 0x60, 0x08, 0xF0, 0x00, 0x00, 0x64, 0x60, 0x00, 0xF0, 0x00, 0xFF, 0xA8, 0x60, 0x00, + 0x10, 0x00, 0xFF, 0xA6, 0x60, 0x00, 0x10, 0x00, 0xFF, 0xDF, 0x60, 0x00, 0x10, 0x00, 0x00, 0x01, 0x60, 0x00, 0x10, 0x00, 0x01, 0x28, 0x60, 0x00, + 0x10, 0x00, 0x01, 0x2F, 0x60, 0x00, 0x10, 0x00, 0xFD, 0x23, 0x60, 0x00, 0x10, 0x00, 0xFD, 0xA1, 0x60, 0x00, 0x10, 0x00, 0x03, 0x89, 0x60, 0x00, + 0x10, 0x00, 0x02, 0x54, 0x60, 0x00, 0x10, 0x00, 0xFE, 0x7D, 0x60, 0x00, 0x10, 0x00, 0x00, 0x8C, 0x60, 0x00, 0x10, 0x00, 0xFB, 0xE1, 0x60, 0x00, + 0x10, 0x00, 0xF9, 0x42, 0x60, 0x00, 0x10, 0x00, 0x0C, 0x47, 0x60, 0x00, 0x10, 0x00, 0x0E, 0xA2, 0x60, 0x00, 0x10, 0x00, 0xEC, 0x43, 0x60, 0x00, + 0x10, 0x00, 0xEA, 0xCE, 0x60, 0x00, 0x10, 0x00, 0x17, 0x46, 0x60, 0x00, 0x10, 0x00, 0x17, 0x46, 0x60, 0x00, 0x10, 0x00, 0xEA, 0xCE, 0x60, 0x00, + 0x10, 0x00, 0xEC, 0x43, 0x60, 0x00, 0x10, 0x00, 0x0E, 0xA2, 0x60, 0x00, 0x10, 0x00, 0x0C, 0x47, 0x60, 0x00, 0x10, 0x00, 0xF9, 0x42, 0x60, 0x00, + 0x10, 0x00, 0xFB, 0xE1, 0x60, 0x00, 0x10, 0x00, 0x00, 0x8C, 0x60, 0x00, 0x10, 0x00, 0xFE, 0x7D, 0x60, 0x00, 0x10, 0x00, 0x02, 0x54, 0x60, 0x00, + 0x10, 0x00, 0x03, 0x89, 0x60, 0x00, 0x10, 0x00, 0xFD, 0xA1, 0x60, 0x00, 0x10, 0x00, 0xFD, 0x23, 0x60, 0x00, 0x10, 0x00, 0x01, 0x2F, 0x60, 0x00, + 0x10, 0x00, 0x01, 0x28, 0x60, 0x00, 0x10, 0x00, 0x00, 0x01, 0x60, 0x00, 0x10, 0x00, 0xFF, 0xDF, 0x60, 0x00, 0x10, 0x00, 0xFF, 0xA6, 0x60, 0x00, + 0x10, 0x00, 0xFF, 0xA8, 0x60, 0x00, 0x10, 0x00, 0x00, 0x64, 0x60, 0x00, 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x17, 0x0B, 0x60, 0x08, 0xF0, 0x00, 0x00, 0x03, 0x60, 0x00, 0xF0, 0x00, 0x54, 0xC0, 0x60, 0x00, 0x10, 0x00, 0x00, 0x05, 0x60, 0x00, + 0x10, 0x00, 0x00, 0x05, 0x60, 0x00, 0x10, 0x00, 0x00, 0x0F, 0x60, 0x00, 0x10, 0x00, 0x00, 0x0F, 0x60, 0x00, 0x10, 0x00, 0x09, 0xC0, 0x60, 0x00, + 0x10, 0x00, 0x0A, 0x20, 0x60, 0x00, 0x10, 0x00, 0x1D, 0x40, 0x60, 0x00, 0x10, 0x00, 0x1E, 0x60, 0x60, 0x00, 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0x10, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x70, 0x00, 0xD0, 0x08 +] + +tef_102_patch_lut = [ + 0x40, 0x13, 0x40, 0x2F, 0x41, 0x68, 0x41, 0xC1, + 0x42, 0x14, 0x42, 0xA6, 0x44, 0xDE, 0x44, 0xE9, + 0x45, 0xFB, 0x46, 0x11, 0x47, 0xC5, 0x47, 0xFC, + 0x4D, 0x5D, 0x4E, 0x56, 0x4E, 0x58, 0x4E, 0x5B, + 0x4D, 0x83, 0x4E, 0x0A, 0x4E, 0x0B, 0x4E, 0x49, + 0x4E, 0x53, 0x4F, 0x92, 0x4F, 0xEA, 0x50, 0x41, + 0x50, 0x74, 0x50, 0x80, 0x55, 0x31, 0x56, 0x60, + 0x56, 0xD4, 0x56, 0xD9, 0x58, 0x29, 0x59, 0xB4, + 0x5A, 0x3A, 0x5B, 0x79, 0x5B, 0xA2, 0x5B, 0xEF, + 0x5D, 0xDC, 0x60, 0x3A, 0x60, 0x88, 0x60, 0xA8, + 0x61, 0x9F, 0x61, 0xB6, 0x61, 0xDF, 0x61, 0xF5, + 0x62, 0x14, 0x62, 0x59, 0x62, 0x9B, 0x62, 0xA1, + 0x63, 0x69, 0x64, 0x3B, 0x66, 0x09, 0x66, 0xE7, + 0x67, 0x0B, 0x67, 0x1A, 0x67, 0x29, 0x68, 0x87, + 0x68, 0x99, 0x68, 0xA7, 0x68, 0xB2 +] \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..1bfd951 --- /dev/null +++ b/test.py @@ -0,0 +1,23 @@ +from tef import TEF6686 +from protocol import I2CPCClient + +p = I2CPCClient("COM17") +tef = TEF6686(p) +tef.init() +tef.FM_Tune_To(1, 9500) +tef.AUDIO_Set_Mute(False) +tef.AUDIO_Set_Volume(70) +tef.FM_Set_MphSuppression(True) +tef.FM_Set_ChannelEqualizer(True) +tef.FM_Set_Specials(1) +tef.FM_Set_Bandwidth(True) +import time +time.sleep(0.032) +try: + while True: + status, level, usn, wam, offset, bandwidth, modulation = tef.FM_Get_Quality_Data() + if not status or not level or not usn or not wam or not offset or not bandwidth or not modulation: continue + print(f"{level / 10} dbμV | {usn / 10}% USN | {wam / 10}% WAM | {offset / 10} kHz offset | {bandwidth / 10} kHz bandwidth | {modulation / 10}% modulation") + time.sleep(0.3) +finally: + tef.close() \ No newline at end of file