first commit

This commit is contained in:
wongyiekheng 2025-12-15 09:23:52 +08:00
commit 211ef38d9c
59 changed files with 17238 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/devices/
*.pyc

36
AGENTS.md Normal file
View File

@ -0,0 +1,36 @@
# Repository Guidelines
## Project Structure & Module Organization
- Root Python app: `pro3_uart.py` (Tkinter UI for dual UART + J-Link debugger).
- Firmware flashing logic: `flash.py`, `fw/` assets, and `devices/Profiles/`.
- Build artifacts/specs: `dist/`, `build/`, `*.spec`, `package_pro3_exe.py`.
- Configs: `Settings.json`, `Reburn.cfg`, `Reset.cfg`.
- J-Link support: `pylink/JLinkARM.dll`; requirements in `requirements.txt`.
## Build, Test, and Development Commands
- Run UI: `python3 pro3_uart.py` (requires Tkinter, pyserial, pylink DLL, connected devices).
- Smoke syntax check: `python3 -m py_compile pro3_uart.py`.
- Flash utility (when needed): `python3 flash.py --help` to view options.
## Coding Style & Naming Conventions
- Python 3, 4-space indentation; prefer explicit names (`dev1`, `dev2`, `debugger`).
- Keep UI text short; avoid non-ASCII unless already present.
- Mirror existing Tkinter patterns (use `ttk`, queue logs via `DevicePanel.queue_message`); never sacrifice clarity for micro-reuse—duplicate a few lines if it keeps behavior explicit.
## Testing Guidelines
- No automated test suite present; rely on manual verification:
- Connect UART devices; verify console input/history and macros.
- Connect J-Link; confirm AP/core selection, scripts (J-Link/GDB), and command execution.
- Run `python3 -m py_compile pro3_uart.py` before sharing changes.
## Commit & Pull Request Guidelines
- Use concise, imperative commit messages (e.g., `Add pylink AP selection UI`).
- Describe device setup and manual steps taken (UART ports, J-Link serial/AP, scripts used).
- Include screenshots/GIFs of UI changes when applicable.
- Link related issues/tasks; call out any required firmware/config files.
## Agent-Specific Instructions
- Do not modify bundled binaries/DLLs unless requested; keep `pylink/JLinkARM.dll` in place.
- Preserve existing flashing and UART workflows; avoid regressions to `DevicePanel` and `PylinkDebuggerPanel`.
- When adding UI, mirror current Tkinter style and keep labels compact for the horizontal layout.
- Favor clear, independent modules over tightly coupled helpers; avoid “minimal coding” shortcuts that hide control flow (e.g., do not overuse shared globals—pass explicit parameters and keep per-panel state encapsulated).

7
Reburn.cfg Normal file
View File

@ -0,0 +1,7 @@
dtr=0
rts=1
delay=200
dtr=1
rts=0
delay=100
dtr=0

5
Reset.cfg Normal file
View File

@ -0,0 +1,5 @@
dtr=0
rts=1
delay=200
rts=0
dtr=0

26
Settings.json Normal file
View File

@ -0,0 +1,26 @@
{
"SensePacketCount": 32,
"RequestRetryCount": 3,
"RequestRetryIntervalInMillisecond": 10,
"AsyncResponseTimeoutInMilliseccond": 1000,
"SyncResponseTimeoutInMillisecond": 1000,
"BaudrateSwitchDelayInMillisecond": 200,
"RomBootDelayInMillisecond": 100,
"UsbRomBootDelayInMillisecond": 1000,
"UsbFloaderBootDelayInMillisecond": 1000,
"SwitchBaudrateAtFloader": 0,
"WriteResponseTimeoutInMillisecond": 2000,
"FloaderBootDelayInMillisecond": 1000,
"AutoSwitchToDownloadModeWithDtrRts": 0,
"AutoResetDeviceWithDtrRts": 0,
"FlashProtectionProcess": 0,
"EraseByBlock": 0,
"ProgramConfig1": 0,
"ProgramConfig2": 0,
"DisableNandAccessWithUart": 0,
"RamDownloadPaddingByte": 0,
"AutoProgramSpicAddrMode4Byte": 0,
"AutoSwitchToDownloadModeWithDtrRtsTimingFile": "Reburn.cfg",
"AutoResetDeviceWithDtrRtsTimingFile": "Reset.cfg",
"PostProcess": "RESET"
}

3
base/__init__.py Normal file
View File

@ -0,0 +1,3 @@
from .download_handler import *
from .rtk_logging import *
from .rt_settings import *

30
base/config_utils.py Normal file
View File

@ -0,0 +1,30 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import os
class ConfigUtils:
@staticmethod
def get_key_value_pairs(logger, file_path):
result = []
with open(file_path, 'r') as file:
for line in file:
line = line.strip()
if not line:
continue
parts = line.split("=", 1)
if len(parts) == 2:
key, value = parts
try:
result.append({key: int(value)})
except ValueError:
logger.warning(f"Skipping line with non-integer value: {line}")
else:
logger.warning(f"Skipping improperly formatted line: {line}")
return result

42
base/device_info.py Normal file
View File

@ -0,0 +1,42 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
from .rtk_flash_type import *
from .memory_info import *
class DeviceInfo(object):
def __init__(self):
self.did = 0
self.image_type = 0
self.cmd_set_version = 0
self.wifi_mac = None
self.memory_type = None
self.flash_mid = None
self.flash_did = None
self.flash_mfg = ""
self.flash_model = ""
self.flash_page_size = 0
self.flash_oob_size = 0
self.flash_pages_per_block = 0
self.flash_blocks_per_lun = 0
self.flash_luns_per_target = None
self.flash_max_bad_block_per_lun = 0
self.flash_req_host_ecc_level = None
self.flash_targets = None
self.flash_capacity = 0
def get_wifi_mac_text(self):
mac_list = []
for chr in self.wifi_mac:
mac_list.append(hex(chr)[2:].zfill(2).upper())
return ":".join(mac_list)
def flash_block_size(self):
return self.flash_page_size * self.flash_pages_per_block
def is_boot_from_nand(self):
return self.memory_type == MemoryInfo.MEMORY_TYPE_NAND

79
base/device_profile.py Normal file
View File

@ -0,0 +1,79 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
from .image_info import *
from .efuse_data import *
from .version import *
class RtkDeviceProfile():
DEFAULT_FLASH_START_ADDR = 0x08000000
DEFAULT_RAM_START_ADDR = 0x20000000
DEVICE_ID_AMEBAD = 0x6548
DEVICE_ID_AMEBAZ = 0x6547
def __init__(self, **kwargs):
self.version = kwargs.get("Version", "1.1.1")
self.device_name = kwargs.get("DeviceName", "")
self.device_id = kwargs.get("DeviceID", 0)
self.memory_type = kwargs.get("MemoryType", 0)
self.support_usb_download = kwargs.get("SupportUsbDownload", False)
self.flash_start_address = kwargs.get("FlashStartAddress", self.DEFAULT_FLASH_START_ADDR)
self.ram_start_address = kwargs.get("RamStartAddress", self.DEFAULT_RAM_START_ADDR)
self.floader = kwargs.get("Floader", "")
self.floader_address = kwargs.get("FloaderAddress", 0)
self.handshake_baudrate = kwargs.get("HandshakeBaudrate", 0)
self.log_baudrate = kwargs.get("LogBaudrate", 0)
self.logical_efuse_len = kwargs.get("LogicalEfuseLen", 0)
self.physical_efuse_len = kwargs.get("PhysicalEfuseLen", 0)
self.images = []
self.default_efuse_map = []
for image_info in kwargs.get("Images", []):
self.images.append(ImageInfo(**image_info))
for efuse_data in kwargs.get("DefaultEfuseMap", []):
self.default_efuse_map.append(EfuseData(**efuse_data))
def is_amebad(self):
return (self.device_id == self.DEVICE_ID_AMEBAD)
def is_amebaz(self):
return (self.device_id == self.DEVICE_ID_AMEBAZ)
def is_ram_address(self, address):
return (address >= self.DEFAULT_RAM_START_ADDR)
def is_flash_address(self, address):
return (address >= self.DEFAULT_FLASH_START_ADDR)
def get_version(self):
if self.version:
return Version(self.version)
else:
return Version("1.0.0")
def __repr__(self):
image_info_list = [ii.__repr__() for ii in self.images]
efuse_data_list = [ed.__repr__() for ed in self.default_efuse_map]
profile_dict = {
"Images": image_info_list,
"DefaultEfuseMap": efuse_data_list,
"Version": f"{self.version}",
"DeviceName": self.device_name,
"DeviceID": self.device_id,
"MemoryType": self.memory_type.value,
"SupportUsbDownload": self.support_usb_download,
"FlashStartAddress": self.flash_start_address,
"RamStartAddress": self.ram_start_address,
"Floader": self.floader,
"FloaderAddress": self.floader_address,
"HandshakeBaudrate": self.handshake_baudrate,
"LogBaudrate": self.log_baudrate,
"LogicalEfuseLen": self.logical_efuse_len,
"PhysicalEfuseLen": self.physical_efuse_len
}
return profile_dict

1415
base/download_handler.py Normal file

File diff suppressed because it is too large Load Diff

20
base/efuse_data.py Normal file
View File

@ -0,0 +1,20 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
class EfuseData():
def __init__(self, **kwargs):
self.length = 16
self.offset = kwargs.get("Offset", 0)
self.value = kwargs.get("Value", [0] * self.length)
def __repr__(self):
efuse_data_dict = {
"Value": self.value,
"Offset": self.offset
}
return efuse_data_dict

41
base/errno.py Normal file
View File

@ -0,0 +1,41 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import enum
_DEV_ERR_BASE = 0X00E0
_SYS_ERR_BASE = 0x0100
class ErrType(enum.Enum):
OK = 0X00
DEV_ERR_BASE = _DEV_ERR_BASE
DEV_BUSY = _DEV_ERR_BASE + 0X1 # Busy
DEV_TIMEOUT = _DEV_ERR_BASE + 0X2 # Operation timeout
DEV_FULL = _DEV_ERR_BASE + 0X4 # Operation timeout
DEV_INVALID = _DEV_ERR_BASE + 0x5 # device invalid
DEV_LENGTH = _DEV_ERR_BASE + 0x6 # device length
DEV_CHECKSUM = _DEV_ERR_BASE + 0x7 # device checksum
DEV_ADDRESS = _DEV_ERR_BASE + 0x8 # device address
DEV_NAND_BAD_BLOCK = _DEV_ERR_BASE + 0x9 # device nand bad block
DEV_NAND_WORN_BLOCK = _DEV_ERR_BASE + 0xA # device nand worn block
DEV_NAND_BIT_FLIP_WARNING = _DEV_ERR_BASE + 0xB # device nand bit flip warning
DEV_NAND_BIT_FLIP_ERROR = _DEV_ERR_BASE + 0xC # device nand bit flip error
DEV_NAND_BIT_FLIP_FATAL = _DEV_ERR_BASE + 0xD # device nand bit flip fatal
SYS_ERR_BASE = _SYS_ERR_BASE
SYS_TIMEOUT = _SYS_ERR_BASE + 0x02 # Operation timeout
SYS_PARAMETER = _SYS_ERR_BASE + 0X3 # Invalid parameter
SYS_IO = _SYS_ERR_BASE + 0x05 # IO error
SYS_NAK = _SYS_ERR_BASE + 0x15 # Device NAK
SYS_PROTO = _SYS_ERR_BASE + 0x22 # Protocol error
SYS_CHECKSUM = _SYS_ERR_BASE + 0x23 # checksum error
SYS_OVERRANGE = _SYS_ERR_BASE + 0x24 # operation overrange
SYS_CANCEL = _SYS_ERR_BASE + 0x30 # Operation cancelled
SYS_UNKNOWN = _SYS_ERR_BASE + 0xEE # Unknown error

145
base/flash_utils.py Normal file
View File

@ -0,0 +1,145 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
from enum import Enum
from .sys_utils import *
class FlashBPS:
def __init__(self):
self.need_unlock = False
self.protection = 0
self.is_locked = False
class FlashUtils(Enum):
# NAND Flash MID
NandMfgDosilicon = 0xE5
NandMfgGigadevice = 0xC8
NandMfgMacronix = 0xC2
NandMfgMicron = 0x2C
NandMfgWinbond = 0xEF
# NAND Flash commands
NandCmdGetFeatures = 0x0F
NandCmdSetFeatures = 0x1F
# NAND Flash registers
NandRegProtection = 0xA0
NandRegFeature = 0xB0
NandRegStatus = 0xC0
NandRegProtectionBpMask = 0x38
NandRegProtectionBpMaskWinbondMicron = 0x78
# NOR Flash command & registers
NorCmdReadStatusReg1 = 0x05
NorCmdWriteStatusReg1 = 0x01
NorStatusReg1BpMask = 0x3C
# NOR Flash default page/block size
NorDefaultPageSize = 1024
NorDefaultPagePerBlock = 4
NorDefaultBlockSize = (NorDefaultPageSize * NorDefaultPagePerBlock)
# NAND Flash default page/block size
NandDefaultPageSize = 2048
NandDefaultPagePerBlock = 64
NandDefaultBlockSize = (NandDefaultPageSize * NandDefaultPagePerBlock)
# Flash write padding data
FlashWritePaddingData = 0xFF
MinFlashProcessTimeoutInSecond = 1
# NOR Flash program / read / erase timeout
# Max page program time: typical 0.5ms for GD25Q128E, max 3ms for W25Q256JV
# Take 0.5ms * 10 = 5ms
NorPageProgramTimeoutInSeconds = 0.005
# Max 4KB sector erase time: typical 70ms for GD25Q256D, max 400ms for GD25Q256D
# Take(400ms * 2) > (70ms * 10 = 700ms)
Nor4kSectorEraseTimeoutInSenonds = 0.8
# Max 32KB block erase time: typical 0.16s for GD25Q128E, max 1.6s for W25Q256JV
# Take 2s > 0.16s * 10 = 1.6s
Nor32kBlockEraseTimeoutInSeconds = 2 # larger than max
# Max 64KB block erase time: typical 0.25s for GD25Q128E, max 1.6s for GD25Q128E
# Take 0.25s * 10 = 2.5s
Nor64kBlockEraseTimeoutInSeconds = 2.5
# Max chip erase time: typical 150s for W25Q256JV, max 400s for W25Q256JV
# Take 1000s > 400s * 2 = 800s
NorChipEraseTimeoutInSeconds = 1000
# Read flash with 1IO @ 10MHz(10Mbps)
NorRead1KiBTimeoutInSecond = 0.001
# NOR calculate checksum with 1.5MB / s, test data(15.8MB / 8s)
NorCalculate1KiBChecksumTimeoutInSeconds = 0.001
# NAND Flash 4KB page size read / program / block erase timeout
# Page size read from Array with ECC(900us) + page size(4KB) read from cache with 1IO @ 10MHz(4KB / 10Mbps=3.2ms)
# Max read from array with ECC: 90us for MT29F4G01ABBF, max 170us for MT29F4G01ABBF
# Take 90us * 10 = 900us + 3.2ms
NandPageReadTimeoutInSeconds = 0.004
# page program with ECC(4ms) + page size(4KB) load with 1IO @ 10MHz(4KB / 10Mbps=3.2ms)
# Max page program with ECC: 400us for MX35LF4GE4AD, max 800us for MX35LF4GE4AD
# Take 400us * 10 = 4ms + 3.2ms
NandPageProgramTimeoutInSeconds = 0.007
# Max block erase time: typical 4ms for MX35LFxG24AD, max 10ms for MT29F2G01ABAG
# Take 4ms * 10 = 40ms
NandBlockEraseTimeoutInSeconds = 0.04
# NAND calculate checksum with 1.5MB / s, test data(2KB / 4KB:47MB / 23s)
NandCalculate1KiBChecksumTimeoutInSeconds = 0.001
def nor_read_timeout_in_second(size_in_byte):
return int(max(divide_then_round_up(size_in_byte, 1024) * FlashUtils.NorRead1KiBTimeoutInSecond.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
def nor_erase_timeout_in_second(size_in_kbyte):
if size_in_kbyte == 0xFFFFFFFF:
return int(max(FlashUtils.NorChipEraseTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
elif size_in_kbyte == 4:
return int(max(FlashUtils.Nor4kSectorEraseTimeoutInSenonds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
elif size_in_kbyte == 32:
return int(max(FlashUtils.Nor32kBlockEraseTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
elif size_in_kbyte == 64:
return int(max(FlashUtils.Nor64kBlockEraseTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
else:
return int(
max(divide_then_round_up(size_in_kbyte, 4) * FlashUtils.Nor4kSectorEraseTimeoutInSenonds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
def nor_checksum_timeout_in_second(size_in_byte):
return int(max(divide_then_round_up(size_in_byte,
1024) * FlashUtils.NorCalculate1KiBChecksumTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
def nand_read_timeout_in_second(size_in_byte, page_size):
return int(max(
divide_then_round_up(size_in_byte, page_size) * FlashUtils.NandPageReadTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
def nand_program_timeout_in_second(size_in_byte, page_size):
return int(max(
divide_then_round_up(size_in_byte, page_size) * FlashUtils.NandPageProgramTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
def nand_erase_timeout_in_second(size_in_byte, block_size):
return int(max(
divide_then_round_up(size_in_byte, block_size) * FlashUtils.NandBlockEraseTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))
def nand_checksum_timeout_in_second(size_in_byte, page_size):
return int(max(
divide_then_round_up(size_in_byte, 1024) * FlashUtils.NandCalculate1KiBChecksumTimeoutInSeconds.value,
FlashUtils.MinFlashProcessTimeoutInSecond.value))

646
base/floader_handler.py Normal file
View File

@ -0,0 +1,646 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import time
import ctypes
from .sense_status import *
from .device_info import *
from .next_op import *
from .flash_utils import *
BAUDSET = 0x81
QUERY = 0x02
CONFIG = 0x83
WRITE = 0x84
READ = 0x05
CHKSM = 0x06
SENSE = 0x07
NEXTOP = 0x08
FS_ERASE = 0xA0
FS_RDSTS = 0x21
FS_WTSTS = 0xA2
FS_MKBAD = 0xA3
FS_CHKMAP = 0x24
FS_CHKBAD = 0x25
FS_CHKBLK = 0x26
OTP_RRAW = 0x40
OTP_WRAW = 0xC1
OTP_RMAP = 0x42
OTP_WMAP = 0xC3
ACK_BUF_EMPTY = 0xB0
ACK_BUF_FULL = 0xB1
NP_EXIT = 0x01
NP_BAUDRATE_RECOVER = 0x02
SOF = 0xA5
QUERY_DATA_OFFSET_DID = 0
QUERY_DATA_OFFSET_IMAGE_TYPE = 2
QUERY_DATA_OFFSET_CMD_SET_VERSION = 4
QUERY_DATA_OFFSET_MEMORY_TYPE = 6
QUERY_DATA_OFFSET_FLASH_MID = 7
QUERY_DATA_OFFSET_FLASH_DID = 8
QUERY_DATA_OFFSET_FLASH_MFG = 10
QUERY_DATA_OFFSET_FLASH_MODEL = 22
QUERY_DATA_OFFSET_FLASH_PAGE_SIZE = 42
QUERY_DATA_OFFSET_FLASH_OOB_SIZE = 46
QUERY_DATA_OFFSET_FLASH_PAGES_PER_BLOCK = 48
QUERY_DATA_OFFSET_FLASH_BLOCKS_PER_LUN = 52
QUERY_DATA_OFFSET_FLASH_LUNS_PER_TARGET = 56
QUERY_DATA_OFFSET_FLASH_MAX_BAD_BLOCKS_PER_LUN = 57
QUERY_DATA_OFFSET_FLASH_REQ_HOST_ECC_LEVEL = 59
QUERY_DATA_OFFSET_FLASH_TARGETS = 60
QUERY_DATA_OFFSET_FLASH_CAPACITY = 61
QUERY_DATA_OFFSET_WIFI_MAC = 65
# Read otp logical map time:26ms, physical map time: 170ms
# Program otp logical map time: 7ms
OTP_READ_TIMEOUT_IN_SECONDS = 10
class FloaderHandler(object):
def __init__(self, ameba_obj):
self.ameba = ameba_obj
self.serial_port = ameba_obj.serial_port
self.profile = ameba_obj.profile_info
self.logger = ameba_obj.logger
self.setting = ameba_obj.setting
super().__init__()
def send_request(self, request, length, timeout, is_sync=True):
ret = ErrType.SYS_UNKNOWN
response_bytes = None
len_l = length & 0xFF
len_h = (length >> 8) & 0xFF
frame_data = [(SOF)]
frame_data.append(len_l)
frame_data.append(len_h)
frame_data.append((len_l ^ len_h) & 0xFF)
frame_bytes = bytearray(frame_data)
frame_bytes += request[:length]
checksum = sum(request)
frame_bytes += (checksum & 0xFF).to_bytes(1, byteorder="little")
try:
retry = 0
while retry < self.setting.request_retry_count:
retry += 1
self.serial_port.flushInput()
self.serial_port.flushOutput()
self.ameba.write_bytes(frame_bytes)
self.logger.debug(f"Request: len={length}, payload={request.hex()}")
ret, ret_byte = self.ameba.read_bytes(timeout)
if ret != ErrType.OK:
self.logger.error(f"Response error: {ret}, timeout:{timeout}")
continue
if is_sync:
if ret_byte[0] == SOF:
ret, ret_bytes = self.ameba.read_bytes(timeout, size=3)
if ret == ErrType.OK:
len_l = ret_bytes[0]
len_h = ret_bytes[1]
len_xor = ret_bytes[2]
response_len = (len_h << 8) + len_l
if len_xor == (len_l ^ len_h):
ret, response_bytes = self.ameba.read_bytes(self.setting.async_response_timeout_in_second,
size=response_len + 1)
if ret == ErrType.OK:
if response_len >= len(response_bytes) - 1:
self.logger.debug(
f"Response: len={response_len}, payload={response_bytes.hex()}")
checksm = sum(response_bytes[:response_len]) % 256
if checksm == response_bytes[response_len]:
self.logger.debug(f"Checksum={checksm}({hex(checksm)}), ok")
break
else:
self.logger.debug(
f"Response checksum error: expect {hex(checksm)}, get {hex(response_bytes[response_len + 1])}")
ret = ErrType.SYS_CHECKSUM
else:
ret = ErrType.SYS_PROTO
self.logger.debug(
f"Response length error: expect {len_xor}, get {len_l ^ len_h}")
else:
self.logger.debug(f"Read response payload error: {ret}")
else:
ret = ErrType.SYS_PROTO
self.logger.debug(f"Response length check error: {ret_bytes.hex()}")
else:
ret = ErrType.SYS_PROTO
self.logger.error(f"Read response length error: {ret}")
elif ret_byte[0] >= ErrType.DEV_ERR_BASE.value:
ret = ret_byte
self.logger.debug(f"Negative response 0x{ret_byte.hex()}: ")
if ret_byte[0] == ErrType.DEV_FULL.value:
time.sleep(self.setting.request_retry_interval_second)
else:
ret = ErrType.SYS_PROTO
self.logger.debug(f"Unexpected response opcode {ret_byte.hex()}")
else:
if ret_byte[0] == ACK_BUF_FULL:
self.logger.debug(f"ACK: Rx buffer full, wait {self.setting.request_retry_interval_second}s")
time.sleep(self.setting.request_retry_interval_second)
ret = ErrType.OK
elif ret_byte[0] == ACK_BUF_EMPTY:
self.logger.debug(f"Response: ACK")
ret = ErrType.OK
break
elif ret_byte[0] >= ErrType.DEV_ERR_BASE.value:
ret = ret_byte
self.logger.debug(f"Negative response: {ret_byte}")
if ret_byte[0] == ErrType.DEV_FULL.value or ErrType.DEV_BUSY.value:
time.sleep(self.setting.request_retry_interval_second)
else:
ret = ErrType.SYS_PROTO
self.logger.debug(f"Unexpected response {ret_byte}")
if ret == ErrType.OK or ret == ErrType.SYS_CANCEL:
break
else:
time.sleep(self.setting.request_retry_interval_second)
except Exception as err:
self.logger.debug(f"Response exception: {err}")
ret = ErrType.SYS_IO
return ret, response_bytes
def sense(self, timeout, op_code=None, data=None):
self.logger.debug(f"Sense...")
ret, sense_ack = self.send_request(SENSE.to_bytes(1, byteorder="little"), length=1, timeout=timeout)
if ret == ErrType.OK:
sense_status = SenseStatus()
self.logger.debug(f"Sense response raw data: {sense_ack.hex()}")
if sense_ack[0] == (SENSE):
ret = sense_status.parse(sense_ack, 1)
if ret == ErrType.OK:
self.logger.debug(
f"Sense response: opcode={hex(sense_status.op_code)}, status=0x{format(sense_status.status, '02x')}, data={hex(sense_status.data)}")
if sense_status.status != ErrType.OK.value:
ret = sense_status.status
self.logger.warning(
f"Sense fail: opcode={hex(sense_status.op_code)}, data={sense_status.data}, status={ret}")
elif (op_code is not None) and (sense_status.op_code != op_code):
ret = ErrType.SYS_PROTO
self.logger.error(
f"Sense protocol error: expect opcode-data {op_code.hex()}-{hex(data)}, get {hex(sense_status.op_code)}-{hex(sense_status.data)}")
else:
if (data is not None) and sense_status.data != data:
self.logger.debug(
f"Sense protocol warning: opcode {op_code} expect data {data}, get {sense_status.data}, ignored")
self.logger.debug("Sense ok")
else:
self.logger.debug(f"Sense fail to parse sense response")
else:
self.logger.debug(f"Sense fail: unexpected opcode {sense_ack[0]}")
else:
self.logger.debug(f"Sense fail: {ret}")
return ret, sense_ack
def handshake(self, baudrate):
ret = ErrType.SYS_UNKNOWN
self.logger.debug(f"Floader handshake start")
try:
if self.serial_port.baudrate != baudrate and self.setting.switch_baudrate_at_floader == 1:
baudset = [BAUDSET]
baudset.extend(list(baudrate.to_bytes(4, byteorder="little")))
self.logger.debug(f"BAUDSET {baudrate}")
baudset_bytes = bytearray(baudset)
ret, _ = self.send_request(baudset_bytes, len(baudset_bytes), self.setting.async_response_timeout_in_second,
is_sync=False)
if ret != ErrType.OK:
self.logger.debug(f"BAUDSET fail: {ret}")
return ret
ret = self.ameba.switch_baudrate(baudrate, self.setting.baudrate_switch_delay_in_second, True)
if ret != ErrType.OK:
self.logger.error(f"Fail to switch baudrate to {baudrate}: {ret}")
return ret
for retry in range(3):
if retry > 0:
self.logger.debug(f"Sense retry {retry}#")
else:
self.logger.debug("Sense")
ret, resp = self.sense(self.setting.sync_response_timeout_in_second)
if ret == ErrType.OK:
break
else:
self.logger.debug(f"Sense failed: {ret}")
time.sleep(self.setting.request_retry_interval_second)
continue
if ret == ErrType.OK:
self.logger.debug(f"Floader handshake done")
else:
self.logger.error(f"Floader handshake timeout")
except Exception as err:
self.logger.error(f"Floader handshake exception: {err}")
return ret
def query(self):
device_info = DeviceInfo()
self.logger.debug(f"QUERY...")
ret, resp = self.send_request(QUERY.to_bytes(1, byteorder="little"), length=1,
timeout=self.setting.sync_response_timeout_in_second)
if ret == ErrType.OK:
if resp[0] == (QUERY):
device_info.did = resp[QUERY_DATA_OFFSET_DID + 1] + (resp[QUERY_DATA_OFFSET_DID + 2] << 8)
device_info.image_type = resp[QUERY_DATA_OFFSET_IMAGE_TYPE + 1] + (
resp[QUERY_DATA_OFFSET_IMAGE_TYPE + 2] << 8)
device_info.cmd_set_version = resp[QUERY_DATA_OFFSET_CMD_SET_VERSION + 1] + (
resp[QUERY_DATA_OFFSET_CMD_SET_VERSION + 2] << 8)
device_info.wifi_mac = resp[QUERY_DATA_OFFSET_WIFI_MAC + 1: QUERY_DATA_OFFSET_WIFI_MAC + 1 + 6]
device_info.memory_type = resp[QUERY_DATA_OFFSET_MEMORY_TYPE + 1]
device_info.flash_mid = resp[QUERY_DATA_OFFSET_FLASH_MID + 1]
device_info.flash_did = resp[QUERY_DATA_OFFSET_FLASH_DID + 1] + (
resp[QUERY_DATA_OFFSET_FLASH_DID + 2] << 8)
device_info.flash_mfg = resp[
QUERY_DATA_OFFSET_FLASH_MFG + 1: QUERY_DATA_OFFSET_FLASH_MFG + 1 + 12].decode("utf-8")
device_info.flash_model = resp[
QUERY_DATA_OFFSET_FLASH_MODEL + 1: QUERY_DATA_OFFSET_FLASH_MODEL + 1 + 20].decode("utf-8")
device_info.flash_page_size = (resp[QUERY_DATA_OFFSET_FLASH_PAGE_SIZE + 1]
+ (resp[QUERY_DATA_OFFSET_FLASH_PAGE_SIZE + 2] << 8)
+ (resp[QUERY_DATA_OFFSET_FLASH_PAGE_SIZE + 3] << 16)
+ (resp[QUERY_DATA_OFFSET_FLASH_PAGE_SIZE + 4] << 24))
device_info.flash_oob_size = (resp[QUERY_DATA_OFFSET_FLASH_OOB_SIZE + 1] + (
resp[QUERY_DATA_OFFSET_FLASH_OOB_SIZE + 2] << 8))
device_info.flash_pages_per_block = (resp[QUERY_DATA_OFFSET_FLASH_PAGES_PER_BLOCK + 1]
+ (resp[QUERY_DATA_OFFSET_FLASH_PAGES_PER_BLOCK + 2] << 8)
+ (resp[QUERY_DATA_OFFSET_FLASH_PAGES_PER_BLOCK + 3] << 16)
+ (resp[QUERY_DATA_OFFSET_FLASH_PAGES_PER_BLOCK + 4] << 24))
device_info.flash_blocks_per_lun = (resp[QUERY_DATA_OFFSET_FLASH_BLOCKS_PER_LUN + 1]
+ (resp[QUERY_DATA_OFFSET_FLASH_BLOCKS_PER_LUN + 2] << 8)
+ (resp[QUERY_DATA_OFFSET_FLASH_BLOCKS_PER_LUN + 3] << 16)
+ (resp[QUERY_DATA_OFFSET_FLASH_BLOCKS_PER_LUN + 4] << 24))
device_info.flash_luns_per_target = resp[QUERY_DATA_OFFSET_FLASH_LUNS_PER_TARGET + 1]
device_info.flash_max_bad_block_per_lun = (resp[QUERY_DATA_OFFSET_FLASH_MAX_BAD_BLOCKS_PER_LUN + 1]
+ (resp[
QUERY_DATA_OFFSET_FLASH_MAX_BAD_BLOCKS_PER_LUN + 2] << 8))
device_info.flash_req_host_ecc_level = resp[QUERY_DATA_OFFSET_FLASH_REQ_HOST_ECC_LEVEL + 1]
device_info.flash_targets = resp[QUERY_DATA_OFFSET_FLASH_TARGETS + 1]
device_info.flash_capacity = (resp[QUERY_DATA_OFFSET_FLASH_CAPACITY + 1]
+ (resp[QUERY_DATA_OFFSET_FLASH_CAPACITY + 2] << 8)
+ (resp[QUERY_DATA_OFFSET_FLASH_CAPACITY + 3] << 16)
+ (resp[QUERY_DATA_OFFSET_FLASH_CAPACITY + 4] << 24))
else:
self.logger.debug(f"Query: unexpected response: {resp[0]}")
ret = ErrType.SYS_PROTO
return ret, device_info
def config(self, configs):
config_data = [(CONFIG)]
config_data.append(configs[0][0])
config_data.append(configs[0][1])
config_data.append(configs[0][2])
config_data.append(configs[0][3])
config_data.append(configs[0][4])
config_data.append(configs[0][5])
config_data.append(configs[0][6])
config_data.append(configs[0][7])
config_data.append(configs[1][0])
config_data.append(configs[1][1])
config_data.append(configs[1][2])
config_data.append(configs[1][3])
config_data.append(configs[1][4])
config_data.append(configs[1][5])
config_data.append(configs[1][6])
config_data.append(configs[1][7])
request_bytes = bytearray(config_data)
self.logger.debug(f"CONFIG: {configs[0].hex()} {configs[1].hex()}")
ret, _ = self.send_request(request_bytes, len(request_bytes), self.setting.async_response_timeout_in_second, is_sync=False)
return ret
def next_operation(self, opcode, operand):
request_data = [NEXTOP]
request_data.append((opcode.value) & 0xFF)
request_data.extend(list(operand.to_bytes(4, byteorder="little")))
self.logger.debug(f"NEXTOTP: opecode={opcode}, operand={operand}")
request_bytes = bytearray(request_data)
ret, _ = self.send_request(request_bytes, len(request_bytes), self.setting.sync_response_timeout_in_second, is_sync=False)
return ret
def reset_in_download_mode(self):
self.logger.debug(f"Reset in download mode")
return self.next_operation(NextOpType.REBURN, 0)
def write(self, mem_type, src, size, addr, timeout, need_sense=False):
sense_status = SenseStatus()
write_data = [WRITE]
write_data.append(mem_type&0xFF)
write_data.extend(list(addr.to_bytes(4, byteorder="little")))
write_array = bytearray(write_data)
write_array += src[:size]
self.logger.debug(f"WRITE: addr={hex(addr)}, size={size}, mem_type={mem_type}, need_sense={need_sense}")
ret, _ = self.send_request(write_array, len(write_array), self.setting.write_response_timeout_in_second, is_sync=False)
if ret == ErrType.OK:
if need_sense:
ret, sense_ack = self.sense(timeout, op_code=WRITE, data=addr)
if ret != ErrType.OK:
self.logger.error(f"WRITE addr={hex(addr)} fail: {ret}")
return ret
def read(self, mem_type, addr, size, timeout):
resp = None
read_data = [READ]
read_data.append((mem_type & 0xFF))
read_data.extend(list(addr.to_bytes(4, byteorder="little")))
read_data.extend(list(size.to_bytes(4, byteorder="little")))
self.logger.debug(f"READ: addr={hex(addr)}, size={size}, mem_type={mem_type}")
read_bytes = bytearray(read_data)
ret, resp_ack = self.send_request(read_bytes, len(read_bytes), timeout)
if ret == ErrType.OK:
if resp_ack[0] == READ:
resp = resp_ack[1:]
else:
self.logger.debug(f"READ got unexpected response {hex(resp_ack[0])}")
ret = ErrType.SYS_PROTO
else:
self.logger.debug(f"READ fail: {ret}")
return ret
def checksum(self, mem_type, start_addr, end_addr, size, timeout):
chk_rest = 0
request_data = [CHKSM]
request_data.append((mem_type & 0xFF))
request_data.extend(list(start_addr.to_bytes(4, byteorder='little')))
request_data.extend(list(end_addr.to_bytes(4, byteorder='little')))
request_data.extend(list(size.to_bytes(4, byteorder='little')))
self.logger.debug(f"CHKSM: start={hex(start_addr)}, end={hex(end_addr)}, size={size}, mem_type={mem_type}")
request_bytes = bytearray(request_data)
ret, resp = self.send_request(request_bytes, len(request_bytes), timeout)
if ret == ErrType.OK:
if resp[0] == int(CHKSM):
chk_rest = resp[1] + (resp[2] << 8) + (resp[3] << 16) + (resp[4] << 24)
self.logger.debug(f"CHKSM: result={hex(chk_rest)}")
else:
self.logger.debug(f"CHKSM: unexpected response {resp[0]}")
ret = ErrType.SYS_PROTO
else:
self.logger.error(f"CHKSM fail: {ret}")
return ret, chk_rest
def erase_flash(self, mem_type, start_addr, end_addr, size, timeout, sense=False, force=False):
self.logger.debug(f"Erase flash: start_addr={hex(start_addr)}, end_addr={hex(end_addr)} size={size}")
request_data = [FS_ERASE]
request_data.append((mem_type & 0xFF))
request_data.append(1 if force else 0)
request_data.extend(list(start_addr.to_bytes(4, byteorder="little")))
request_data.extend(list((end_addr & 0xFFFFFFFF).to_bytes(4, byteorder="little")))
request_data.extend(list((size & 0xFFFFFFFF).to_bytes(4, byteorder="little")))
if force:
self.logger.warning(f"FS_ERASE: start_addr={hex(start_addr)}, end_addr={hex(end_addr)}, size={size}, mem_type={mem_type} force")
else:
self.logger.debug(f"FS_ERASE: start_addr={hex(start_addr)}, end_addr={hex(end_addr)}, size={size}, mem_type={mem_type}")
request_bytes = bytearray(request_data)
ret, _ = self.send_request(request_bytes, len(request_bytes), self.setting.async_response_timeout_in_second, is_sync=False)
if ret != ErrType.OK:
self.logger.warning(f"FS_ERASE start_addr={hex(start_addr)}, end_addr={hex(end_addr)}, size={size}, force={force}, fail:{ret}")
return ret
if sense:
ret, sense_status = self.sense(timeout, op_code=FS_ERASE, data=start_addr)
if ret != ErrType.OK:
self.logger.error(f"FS_ERASE start_addr={hex(start_addr)}, size={size} force={force} fail: {ret}")
return ret
def read_status_register(self, cmd, address):
status = None
request_data = [FS_RDSTS]
request_data.append(cmd)
request_data.append(address)
self.logger.debug(f"FS_RDSTS: cmd={cmd}, address={address}")
request_bytes = bytearray(request_data)
ret, resp = self.send_request(request_bytes, len(request_bytes), self.setting.sync_response_timeout_in_second)
if ret == ErrType.OK:
if resp[0] == FS_RDSTS:
status = resp[1]
self.logger.debug(f"FS_RDSTS: status={status}")
else:
self.logger.debug(f"FS_RDSTS: got unexpected response, {resp[0]}")
ret = ErrType.SYS_PROTO
else:
self.logger.debug(f"FS_RDSTS failed: {ret}")
return ret, status
def write_status_register(self, cmd, addr, value):
request_data = [FS_WTSTS]
request_data.append(cmd)
request_data.append(addr)
request_data.append(value)
self.logger.debug(f"FS_WTSTS: cmd={hex(cmd)}, addr={hex(addr)}, value={hex(value)}")
request_bytes = bytearray(request_data)
ret, _ = self.send_request(request_bytes, len(request_bytes), self.setting.async_response_timeout_in_second, is_sync=False)
return ret
def mark_bad_block(self, address):
request_data = [FS_MKBAD]
request_data.extend(list(address.to_bytes(4, byteorder="little")))
request_bytes = bytearray(request_data)
self.logger.debug(f"FS_MKBAD: addr={format(address, '08x')}")
return self.send_request(request_bytes, len(request_bytes), self.setting.async_response_timeout_in_second, is_sync=False)
def check_bad_block(self, address):
ret = ErrType.OK
status = None
request_data = [FS_CHKBAD]
request_data.extend(list(address.to_bytes(4, byteorder="little")))
request_bytes = bytearray(request_data)
self.logger.debug(f"FS_CHKBAD: addr={format(address, '08x')}")
ret, resp = self.send_request(request_bytes, len(request_bytes), self.setting.sync_response_timeout_in_second)
if ret == ErrType.OK:
if resp[0] == FS_CHKBAD:
status = resp[1]
else:
self.logger.debug(f"FS_CHKBAD got unexpected response {hex(resp[0])}")
ret = ErrType.SYS_PROTO
else:
self.logger.debug(f"FS_CHKBAD fail: {ret}")
return ret, status
def check_block_status(self, address):
ret = ErrType.OK
block_status = 0
page_status = [0, 0]
request_data = [FS_CHKBLK]
request_data.extend(list(address.to_bytes(4, byteorder="little")))
request_bytes = bytearray(request_data)
self.logger.debug(f"FS_CHKBLK: addr={format(address, '08x')}")
ret, resp = self.send_request(request_bytes, len(request_bytes), self.setting.sync_response_timeout_in_second)
if ret == ErrType.OK:
if resp[0] == FS_CHKBLK:
block_status = resp[1]
page_status[0] = ctypes.c_uint64(resp[2] + (resp[3] << 8) + (resp[4] << 16) +
(resp[5] << 24) + (resp[6] << 32) + (resp[7] << 40) +
(resp[8] << 48) + (resp[9] << 56)).value
page_status[1] = ctypes.c_uint64(resp[10] + (resp[11] << 8) + (resp[12] << 16) +
(resp[13] << 24) + (resp[14] << 32) + (resp[15] << 40) +
(resp[16] << 48) + (resp[17] << 56)).value
self.logger.debug(
f"FS_CHKBLK: block_status={hex(block_status)}, page status={format(page_status[0], '16x')} {format(page_status[1], '16x')}")
else:
self.logger.debug(f"FS_CHKBLK fail: {ret}")
return ret, block_status
def check_map_status(self, address):
ret = ErrType.OK
status = 0
request_data = [FS_CHKMAP]
request_data.extend(list(address.to_bytes(4, byteorder="little")))
request_bytes = bytearray(request_data)
self.logger.debug(f"FS_CHKMAP: addr={format(address, '08x')}")
ret, resp = self.send_request(request_bytes, len(request_bytes), self.setting.sync_response_timeout_in_second)
if ret == ErrType.OK:
if resp[0] == FS_CHKMAP:
status = (resp[1] + (resp[2] << 8) + (resp[3] << 16) + (resp[4] << 24)) & 0xFFFFFFFF
self.logger.debug(f"FS_CHKMAP: status={format(status, '08x')}")
else:
self.logger.debug(f"FS_CHKMAP fail: {ret}")
return ret, status
def otp_read_map(self, cmd, address, size):
request_data = [cmd]
request_data.extend(list(address.to_bytes(4, byteorder="little")))
request_data.extend(list(size.to_bytes(4, byteorder="little")))
request_bytes = bytearray(request_data)
ret, buf = self.send_request(request_bytes, len(request_bytes), OTP_READ_TIMEOUT_IN_SECONDS)
if ret == ErrType.OK:
if buf[0] == cmd:
self.logger.debug(f"Otp read: {buf[0]}")
return ret, buf[1:-1]
else:
self.logger.debug(f"Otp read fail: unexpected response {buf[0]}")
ret = ErrType.SYS_PROTO
return ret, buf
def otp_write_map(self, cmd, address, size, data):
request_data = [cmd]
request_data.extend(list(address.to_bytes(4, byteorder="little")))
request_data.extend(list(size.to_bytes(4, byteorder="little")))
for idx in range(size):
request_data.append(data[address + idx])
request_bytes = bytearray(request_data)
ret, _ = self.send_request(request_bytes, len(request_bytes), self.setting.async_response_timeout_in_second, is_sync=False)
return ret
def otp_read_physical_map(self, address, size):
self.logger.debug(f"OTP_RRAW: addr={hex(address)}, size={size}")
ret, buf = self.otp_read_map(OTP_RRAW, address, size)
if ret == ErrType.OK:
self.logger.debug(f"OTP_RRAW: {buf}")
self.logger.debug("OTP_RRAW done")
else:
self.logger.debug(f"OTP_RRAW fail: {ret}")
return ret, buf
def otp_write_physical_map(self, address, size, data):
self.logger.debug(f"OTP_WRAW: addr={hex(address)}, size={size}, data={data}")
ret = self.otp_write_map(OTP_WMAP, address, size, data)
if ret == ErrType.OK:
self.logger.debug("OTP_WRAW done")
else:
self.logger.debug(f"OTP_WRAW fail: {ret}")
return ret
def otp_read_logical_map(self, address, size):
self.logger.debug(f"OTP_RMAP: addr={hex(address)}, size={size}")
ret, buf = self.otp_read_map(OTP_RMAP, address, size)
if ret == ErrType.OK:
self.logger.debug(f"OTP_RMAP: {buf}")
self.logger.debug("OTP_RMAP done")
else:
self.logger.debug(f"OTP_RMAP fail: {ret}")
return ret, buf
def otp_write_logical_map(self, address, size, data):
self.logger.debug(f"OTP_WMAP: addr={hex(address)}, size={size}, data={data}")
ret = self.otp_write_map(OTP_WMAP, address, size, data)
if ret == ErrType.OK:
self.logger.debug("OTP_WMAP done")
else:
self.logger.debug(f"OTP_WMAP fail: {ret}")
return ret

28
base/image_info.py Normal file
View File

@ -0,0 +1,28 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
class ImageInfo():
def __init__(self, **kwargs):
self.image_name = kwargs.get("ImageName", "")
self.start_address = kwargs.get("StartAddress", 0)
self.end_address = kwargs.get("EndAddress", 0)
self.memory_type = kwargs.get("MemoryType", 0)
self.full_erase = kwargs.get("FullErase", False)
self.mandatory = kwargs.get("Mandatory", False)
self.description = kwargs.get("Description", "")
def __repr__(self):
image_info_dict = {
"ImageName": self.image_name,
"StartAddress": self.start_address,
"EndAddress": self.end_address,
"MemoryType": self.memory_type,
"FullErase": self.full_erase,
"Mandatory": self.mandatory,
"Description": self.description
}
return image_info_dict

48
base/json_utils.py Normal file
View File

@ -0,0 +1,48 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import os
import json
import base64
from pyDes import *
_DES_KEY = "574C414E" # 0x574C414E, WLAN
_DES_IV = [0x40, 0x52, 0x65, 0x61, 0x6C, 0x73, 0x69, 0x6C] # @Realsil
class JsonUtils:
@staticmethod
def load_from_file(file_path, need_decrypt=True):
result = None
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
f_content = f.read()
if need_decrypt:
k = des(_DES_KEY, CBC, _DES_IV, padmode=PAD_PKCS5)
des_k = k.decrypt(base64.b64decode(f_content))
profile_str = des_k.decode("utf-8")
result = json.loads(profile_str)
else:
result = json.loads(f_content)
return result
@staticmethod
def save_to_file(file_path, data, need_encrypt=False):
path_dir = os.path.dirname(file_path)
os.makedirs(path_dir, exist_ok=True)
if need_encrypt:
ek = des(_DES_KEY.encode("utf-8"), CBC, _DES_IV, pad=None, padmode=PAD_PKCS5)
en_bytes = ek.encrypt(json.dumps(data).encode("utf-8"))
save_data = base64.b64encode(en_bytes)
with open(file_path, "wb") as json_file:
json_file.write(save_data)
else:
save_data = data
with open(file_path, "w") as json_file:
json.dump(save_data, json_file, indent=2)

24
base/memory_info.py Normal file
View File

@ -0,0 +1,24 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
class MemoryInfo:
MEMORY_TYPE_RAM = 0
MEMORY_TYPE_NOR = 1
MEMORY_TYPE_NAND = 2
MEMORY_TYPE_VENDOR = 3
MEMORY_TYPE_HYBRID = 4
MAX_PARTITION_MEMORY_TYPE = MEMORY_TYPE_VENDOR
MAX_DEVICE_MEMORY_TYPE = MEMORY_TYPE_HYBRID
def __init__(self):
self.start_address = 0
self.end_address = 0
self.memory_type = self.MEMORY_TYPE_RAM
self.size_in_kbyte = 0
def size_in_byte(self):
return self.size_in_kbyte * 1024

15
base/next_op.py Normal file
View File

@ -0,0 +1,15 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
from enum import Enum
class NextOpType(Enum):
NONE = 0 # Do nothing, hold on in download mode
INDICATION = 1 # Indicate download result via PWM/GPIO
RESET = 2 # Exit download mode
BOOT = 3 # Jump to Ram
REBURN = 4 # Reset into download mode again

371
base/remote_serial.py Normal file
View File

@ -0,0 +1,371 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import socket
import json
import time
import threading
import base64
from typing import Optional, Dict, Any
import serial
from serial.serialutil import SerialException, SerialTimeoutException
from datetime import datetime
class RemoteSerial:
def __init__(self, logger, remote_server: str, remote_port: int, port: str, baudrate: int = 9600):
"""
Initialize remote serial proxy
:param logger: logger object (external input, for unified log format)
:param remote_server: remote serial server IP
:param remote_port: remote serial server port
:param port: remote serial port name (e.g. "COM3", "/dev/ttyUSB0")
:param baudrate: serial baud rate
"""
self.logger = logger
self.remote_server = remote_server
self.remote_port = remote_port
self.port = port
self.baudrate = baudrate
# Core state variables
self.tcp_socket: Optional[socket.socket] = None
self.receive_buffer = b"" # Binary receive buffer
self.receive_thread: Optional[threading.Thread] = None
self.is_open = False # Whether serial is open (TCP connected + serial command succeeds)
self.response_event = threading.Event() # Command response synchronization event
self.last_response: Dict[str, Any] = {} # Last command response
# Initialize logger
self.logger.debug(
f"[RemoteSerial][{self.port}] Initialize remote serial proxy - "
f"Server: {self.remote_server}:{self.remote_port}, baudrate: {self.baudrate}"
)
# 1. Establish TCP connection (just connect, not start the receive thread)
self._connect_tcp()
self.receive_thread = threading.Thread(
target=self._receive_loop,
daemon=True,
name=f"RemoteSerialRecv-{self.port}"
)
self.receive_thread.start()
self.logger.debug(f"[RemoteSerial][{self.port}] Receive thread started: {self.receive_thread.name}")
def _connect_tcp(self) -> bool:
"""
Establish TCP connection with remote serial server
:return: Returns True if connected successfully, raises SerialException on failure
"""
self.logger.debug(f"[RemoteSerial][{self.port}] Trying TCP connection: {self.remote_server}:{self.remote_port}")
try:
self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# self.tcp_socket.settimeout(10) # TCP connect timeout 10s
self.tcp_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.logger.debug(f"[RemoteSerial][{self.port}] TCP_NODELAY set")
self.tcp_socket.connect((self.remote_server, self.remote_port))
self.logger.debug(f"[RemoteSerial][{self.port}] TCP connection succeeded")
return True
except socket.timeout:
raise SerialException(f"[RemoteSerial][{self.port}] TCP connection timed out (10s)- {self.remote_server}:{self.remote_port}")
except ConnectionRefusedError:
raise SerialException(f"[RemoteSerial][{self.port}] TCP connection refused - server not started or wrong port")
except Exception as e:
raise SerialException(f"[RemoteSerial][{self.port}] TCP connection failed: {str(e)}")
def _receive_loop(self):
"""
Core logic of receive thread: continuously read TCP data, parse into buffer or trigger response
"""
self.logger.debug(f"[RemoteSerial][{self.port}] Receive thread running")
buffer = ""
while self.tcp_socket:
try:
# Read TCP data (as text, as server sends JSON+newline-delimited)
data = self.tcp_socket.recv(4096).decode('utf-8', errors='strict')
if not data:
self.logger.error(f"[RemoteSerial][{self.port}] Server closed connection, recv returned empty data")
raise ConnectionAbortedError("Server closed connection")
buffer += data
# Split by newline for complete messages (handle sticky packets)
while '\n' in buffer:
msg_str, buffer = buffer.split('\n', 1)
msg_str = msg_str.strip()
if not msg_str:
continue
self._parse_message(msg_str)
except ConnectionResetError as e:
self.logger.error(f"[RemoteSerial][{self.port}] Connection reset: {str(e)}")
break
except ConnectionAbortedError as e:
self.logger.error(f"[RemoteSerial][{self.port}] Receive thread exception: {str(e)}")
break
except Exception as e:
self.logger.error(f"[RemoteSerial][{self.port}] Receive thread exception: {str(e)}", exc_info=True)
break
self.is_open = False
if self.tcp_socket:
self.tcp_socket.close()
self.logger.info(f"[RemoteSerial][{self.port}] Receive thread exited")
def _parse_message(self, msg_str: str):
"""
Parse JSON message from server
:param msg_str: Complete JSON string (without newline)
"""
try:
msg = json.loads(msg_str)
msg_type = msg.get("type")
if msg_type == "command_response":
self.last_response = msg
self.logger.debug(
f"[RemoteSerial][{self.port}] Received command response - "
f"Success: {msg.get('success')}, message: {msg.get('message', '')}"
)
self.response_event.set()
elif msg_type == "serial_data":
if msg.get("port") != self.port:
self.logger.warning(f"[RemoteSerial][{self.port}] Received data from other port (ignored): {msg.get('port')}")
return
base64_data = msg.get("data", "")
if not base64_data:
self.logger.warning(f"[RemoteSerial][{self.port}] Serial data empty (Base64)")
return
try:
raw_data = base64.b64decode(base64_data, validate=True)
self.receive_buffer += raw_data
except base64.binascii.Error as e:
self.logger.error(f"[RemoteSerial][{self.port}] Base64 decode failed: {str(e)}, data: {base64_data[:100]}...")
else:
self.logger.warning(f"[RemoteSerial][{self.port}] Unknown message type: {msg_type}, message: {msg_str[:200]}...")
except json.JSONDecodeError as e:
self.logger.error(f"[RemoteSerial][{self.port}] JSON parse failed: {str(e)}, raw: {msg_str[:200]}...")
def _send_command(self, cmd: Dict[str, Any], timeout: float = 5.0) -> Dict[str, Any]:
"""
Send command to remote server and wait for response
:param cmd: command dict (will be converted to JSON)
:param timeout: response timeout (seconds)
:return: server response dict
"""
if not self.is_open or not self.tcp_socket:
raise SerialException(f"[RemoteSerial][{self.port}] Send command failed: serial not open")
self.response_event.clear()
self.last_response = {}
cmd_str = json.dumps(cmd) + "\n"
try:
self.logger.debug(f"[RemoteSerial][{self.port}] Sending command (timeout {timeout}s): {cmd_str.strip()[:300]}...")
self.tcp_socket.sendall(cmd_str.encode('utf-8'))
# Wait for response or timeout
if self.response_event.wait(timeout):
return self.last_response
else:
raise SerialTimeoutException(
f"[RemoteSerial][{self.port}] Command response timeout ({timeout}s) - Command: {cmd.get('type')}"
)
except Exception as e:
raise SerialException(f"[RemoteSerial][{self.port}] Send command exception: {str(e)}")
def validate(self, password):
try:
validate_cmd = {
"type": "validate",
"password": password
}
self.is_open = True
resp = self._send_command(validate_cmd, timeout=10.0)
if not resp.get("success", False):
self.logger.debug(f"[RemoteSerial][{self.port}] Validate failed")
raise SerialException(f"[RemoteSerial][{self.port}] Remote serial validate failed: Wrong password")
self.is_open = False
self.logger.debug(f"[RemoteSerial][{self.port}] Remote serial port validate successfully")
except Exception as e:
self.close()
raise SerialException(f"[RemoteSerial][{self.port}] Validate serial failed: {str(e)}")
def open(self):
if self.is_open:
self.logger.debug(f"[RemoteSerial][{self.port}] Serial already opened, skip")
return
self.logger.debug(f"[RemoteSerial][{self.port}] Trying to open serial")
try:
self.is_open = True
open_cmd = {
"type": "open_port",
"port": self.port,
"options": {
"baudRate": self.baudrate,
"dataBits": 8,
"stopBits": 1,
"parity": "none",
"timeout": 0.1
}
}
resp = self._send_command(open_cmd, timeout=10.0)
if not resp.get("success", False):
self.logger.debug(f"[RemoteSerial][{self.port}] Open failed")
self.is_open = False
err_msg = resp.get("message", "Unknown error")
raise SerialException(f"[RemoteSerial][{self.port}] Remote serial open failed: {err_msg}")
# set is_open and start receive thread
self.is_open = True
self.logger.debug(f"[RemoteSerial][{self.port}] Remote serial port opened successfully (baudrate: {self.baudrate})")
except Exception as e:
self.close()
raise SerialException(f"[RemoteSerial][{self.port}] Open serial failed: {str(e)}")
def close(self):
"""
Close remote serial: send close_port command + cleanup TCP and thread
"""
self.logger.debug(f"[RemoteSerial][{self.port}] Start closing remote serial")
# 1. Mark state as closed (end receive thread loop)
if not self.is_open:
self.logger.debug(f"[RemoteSerial][{self.port}] Serial already closed, skip")
return
# 2. Send close serial command (try even if TCP error)
try:
if self.tcp_socket:
close_cmd = {"type": "close_port", "port": self.port}
resp = self._send_command(close_cmd, timeout=3.0)
if resp.get("success", False):
self.logger.debug(f"[RemoteSerial][{self.port}] Remote serial close command succeeded")
else:
self.logger.warning(f"[RemoteSerial][{self.port}] Remote serial close command failed: {resp.get('message', 'No response')}")
except Exception as e:
self.logger.error(f"[RemoteSerial][{self.port}] Send close command exception: {str(e)}")
self.is_open = False
self.receive_buffer = b""
self.logger.debug(f"[RemoteSerial][{self.port}] Remote serial closed")
def write(self, data: bytes):
"""
Write binary data to remote serial (Base64 encode first)
:param data: binary data to send
"""
if not self.is_open:
raise SerialException(f"[RemoteSerial][{self.port}] Write failed: serial not open")
if not data:
self.logger.debug(f"[RemoteSerial][{self.port}] Write empty data (ignored)")
return
try:
base64_data = base64.b64encode(data).decode('utf-8')
write_cmd = {
"type": "write_data",
"port": self.port,
"data": base64_data
}
self.logger.debug(
f"[RemoteSerial][{self.port}] Write data - "
f"Raw length: {len(data)}B, Base64 length: {len(base64_data)}B"
)
resp = self._send_command(write_cmd, timeout=10.0)
if not resp.get("success", False):
raise SerialException(f"[RemoteSerial][{self.port}] Write data failed: {resp.get('message', 'Unknown error')}")
self.logger.debug(f"[RemoteSerial][{self.port}] Write data succeeded")
except Exception as e:
raise SerialException(f"[RemoteSerial][{self.port}] Write exception: {str(e)}")
def read(self, size: int = 1) -> bytes:
"""
Read specified length of binary data from receive buffer
:param size: length to read (bytes)
:return: binary data read (returns actual length if less than size)
"""
if not self.is_open:
raise SerialException(f"[RemoteSerial][{self.port}] Read failed: serial not open")
# Get data from buffer
read_data = self.receive_buffer[:size]
self.receive_buffer = self.receive_buffer[size:]
self.logger.debug(
f"[RemoteSerial][{self.port}] Read data - "
f"Requested: {size}B, Read: {len(read_data)}B, Buffer left: {len(self.receive_buffer)}B"
)
return read_data
def inWaiting(self) -> int:
"""
Return number of bytes waiting in receive buffer
:return: buffer length
"""
if not self.is_open:
raise SerialException(f"[RemoteSerial][{self.port}] Read failed: serial not open")
waiting = len(self.receive_buffer)
return waiting
def flushInput(self):
"""
Clear receive buffer (local only, no server interaction)
"""
old_len = len(self.receive_buffer)
self.receive_buffer = b""
self.logger.debug(f"[RemoteSerial][{self.port}] Cleared receive buffer - old length: {old_len}B")
def flushOutput(self):
"""
Flush output buffer (no local output buffer for remote serial, just for serial.Serial API compatibility)
"""
self.logger.debug(f"[RemoteSerial][{self.port}] flushOutput: No action required for remote serial (no local output buffer)")
# ------------------------------
# Simulate serial.Serial's DTR/RTS properties
# ------------------------------
@property
def dtr(self):
self.logger.debug(f"[RemoteSerial][{self.port}] Get DTR: not supported, return False")
return False
@dtr.setter
def dtr(self, value):
self.logger.debug(f"[RemoteSerial][{self.port}] Set DTR: not supported, ignored value={value}")
@property
def rts(self):
self.logger.debug(f"[RemoteSerial][{self.port}] Get RTS: not supported, return False")
return False
@rts.setter
def rts(self, value):
self.logger.debug(f"[RemoteSerial][{self.port}] Set RTS: not supported, ignored value={value}")
# ------------------------------
# Context manager support (with statement)
# ------------------------------
def __enter__(self):
self.open()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
self.logger.info(f"[RemoteSerial][{self.port}] __exit__ close")
if exc_type:
self.logger.error(f"[RemoteSerial][{self.port}] Context manager exception: {exc_type.__name__}: {exc_val}")
def __del__(self):
"""Destructor: make sure to close resource"""
if self.is_open:
self.logger.debug(f"[RemoteSerial][{self.port}] Destructor: closing unreleased remote serial")
self.close()

322
base/rom_handler.py Normal file
View File

@ -0,0 +1,322 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import io
import os
import sys
import time
from .errno import *
from .rtk_utils import *
STX = 0x02 # Transfer data
EOT = 0x04 # End of transfer
BAUDSET = 0x05 # For handshake
BAUDCHK = 0x07 # For handshake, only for UART
ACK = 0x06 # Acknowledge
NAK = 0x15 # Negativ acknowledge
CAN = 0x18 # Cancel transfer, only for UART
ESC = 0x1B # Cancel transfer
STX_BASE_LEN = 8
STX_UART_RAM_DATA_LEN = 1024
STX_USB_RAM_DATA_LEN = 2048
STX_MAX_LEN = STX_BASE_LEN + STX_USB_RAM_DATA_LEN
FloaderSizeLimit = 1024 * 1024 # 1MB
StxBaseLen = 1024
StxUartDataLen = 1024
StxUsbDataLen = 2048
StxMaxDataLen = StxBaseLen + StxUsbDataLen
DEFAULT_TIMEOUT = 0.5
STX_TIMEOUT = 1
FloaderDictionary = "Devices/Floaders"
class RomHandler(object):
def __init__(self, ameba_obj, padding="FF"):
self.ameba = ameba_obj
self.serial_port = ameba_obj.serial_port
self.logger = ameba_obj.logger
self.profile = ameba_obj.profile_info
self.baudrate = ameba_obj.baudrate
self.is_usb = ameba_obj.is_usb
self.stx_packet_no = 1
self.padding = padding
self.setting = ameba_obj.setting
def get_baudrate_idx(self, rate):
''' rom built-in rate table '''
return {
110: 0,
300: 1,
600: 2,
1200: 3,
2400: 4,
4800: 5,
9600: 6,
14400: 7,
19200: 8,
28800: 9,
38400: 10,
57600: 11,
76800: 12,
115200: 13,
128000: 14,
153600: 15,
230400: 16,
380400: 17,
460800: 18,
500000: 19,
921600: 20,
1000000: 21,
1382400: 22,
1444400: 23,
1500000: 24,
1843200: 25,
2000000: 26,
2100000: 27,
2764800: 28,
3000000: 29,
3250000: 30,
3692300: 31,
3750000: 32,
4000000: 33,
6000000: 34
}.get(rate, 13)
def send_request(self, request, length, timeout):
ret = ErrType.SYS_UNKNOWN
response = []
try:
for retry in range(2):
if retry > 0:
self.logger.debug(f"Request retry {retry}#: len={length}, payload={request.hex()}")
else:
self.logger.debug(f"Request: len={length}, payload={request.hex()}")
self.serial_port.flushInput()
self.serial_port.flushOutput()
self.ameba.write_bytes(request)
for resp_retry in range(3):
ret, ch = self.ameba.read_bytes(timeout)
if ret != ErrType.OK:
self.logger.debug(f"Reponse error: {ret}")
break
if ch[0] == ACK:
self.logger.debug(f"Response ACK")
break
elif ch[0] == NAK:
ret = ErrType.SYS_NAK
self.logger.debug(f"Response NAK")
continue
elif ch[0] == CAN:
ret = ErrType.SYS_CANCEL
self.logger.debug(f"Response CAN")
break
else:
ret = ErrType.SYS_PROTO
self.logger.debug(f"Unexpected reponse: 0x{ch.hex()}")
continue
if ret == ErrType.OK or ret == ErrType.SYS_CANCEL:
break
else:
time.sleep(self.setting.request_retry_interval_second)
except Exception as err:
self.logger.error(f"Send request exception: {err}")
ret = ErrType.SYS_IO
return ret
def reset(self):
self.stx_packet_no = 1
def handshake(self):
ret = ErrType.OK
self.logger.debug(f"Handshake:{'USB' if self.is_usb else 'UART'}")
index = self.get_baudrate_idx(self.baudrate)
if not self.is_usb:
ret = self.check_alive()
if ret != ErrType.OK:
self.logger.debug(f"Handshake fail: device not alive")
return ret
retry = 0
while retry < 2:
if retry > 0:
self.logger.debug(f"Handshake retry {retry}#")
retry += 1
if self.setting.switch_baudrate_at_floader == 0:
self.logger.debug(f"BAUDSET: {index} ({self.baudrate})")
_bytes = [BAUDSET]
_bytes.append(index)
cmd = bytearray(_bytes)
ret = self.send_request(cmd, 2, DEFAULT_TIMEOUT)
if ret == ErrType.OK:
self.logger.debug(f"BAUDSET ok")
else:
self.logger.debug(f"BAUDSET fail: {ret}")
continue
if self.is_usb:
break
ret = self.ameba.switch_baudrate(self.baudrate, self.setting.baudrate_switch_delay_in_second)
if ret != ErrType.OK:
continue
self.logger.debug(f"BAUDCHK")
ret = self.send_request(BAUDCHK.to_bytes(1, byteorder="little"), 1, DEFAULT_TIMEOUT)
if ret == ErrType.OK:
self.logger.debug("BAUDCHK ok")
break
else:
self.logger.error(f"BAUDCHK fail: {ret}")
else:
if self.is_usb:
self.logger.debug(f"BAUDSET")
_bytes = [BAUDSET]
_bytes.append(index)
cmd = bytearray(_bytes)
ret = self.send_request(cmd, 2, DEFAULT_TIMEOUT)
if ret == ErrType.OK:
self.logger.debug(f"Baudset ok")
break
else:
self.logger.debug(f"Baudset fail: {ret}")
else:
self.logger.debug("BAUDCHK")
ret = self.send_request(BAUDCHK.to_bytes(1, byteorder="little"), 1, DEFAULT_TIMEOUT)
if ret == ErrType.OK:
self.logger.debug(f"Baudchk ok")
break
else:
self.logger.debug(f"Baudchk fail: {ret}")
if ret == ErrType.OK:
self.logger.debug("Handshake done")
else:
self.logger.debug(f"Handshake fail: {ret}")
return ret
def check_alive(self):
ret, ch = self.ameba.read_bytes(DEFAULT_TIMEOUT)
if ret == ErrType.OK:
if ch[0] != NAK:
self.logger.debug(f"Check alive error,expect NAK, get 0x{ch.hex()}")
else:
self.logger.debug(f"Check alive error: {ret}")
return ret
def transfer(self, address, data_bytes):
self.logger.debug(f"STX {self.stx_packet_no}#: addr={hex(address)}")
stx_data = [STX]
stx_data.append(self.stx_packet_no & 0xFF)
stx_data.append((~self.stx_packet_no) & 0xFF)
stx_data.extend(list(address.to_bytes(4, byteorder='little')))
stx_bytes = bytearray(stx_data)
stx_bytes += data_bytes
checksum = sum(stx_bytes[3:]) % 256
stx_bytes += checksum.to_bytes(1, byteorder="little")
ret = self.send_request(stx_bytes, len(stx_bytes), STX_TIMEOUT)
if ret == ErrType.OK:
self.logger.debug(f"STX {self.stx_packet_no}# done")
self.stx_packet_no += 1
else:
self.logger.debug(f"STX {self.stx_packet_no}# fail: {ret}")
return ret
def end_transfer(self):
self.logger.debug(f"EOT")
return self.send_request(EOT.to_bytes(1, byteorder="little"), 1, DEFAULT_TIMEOUT)
def abort(self):
self.logger.debug(f"ESC")
self.send_request(ESC.to_bytes(1, byteorder="little"), 1, DEFAULT_TIMEOUT)
def get_page_aligned_size(self, size, page_size):
result = size
if (size % page_size) != 0:
result = (size // page_size + 1) * page_size
return result
def get_floader_path(self):
floader_path = None
if self.profile.floader:
floader_path = os.path.realpath(os.path.join(RtkUtils.get_executable_root_path(), FloaderDictionary, self.profile.floader))
if floader_path is None:
self.logger.error("Flashloader not specified in device profile")
elif not os.path.exists(floader_path):
self.logger.error(f"Flashloader not exists: {floader_path}")
return floader_path
def download_floader(self):
ret = ErrType.OK
page_size = StxUsbDataLen if self.is_usb else StxUartDataLen
self.reset()
floader = self.get_floader_path()
if floader is None:
return ErrType.SYS_PARAMETER
with open(floader, 'rb') as stream:
floader_content = stream.read()
floader_size = len(floader_content)
if floader_size > FloaderSizeLimit:
self.logger.error(f"Invalid floader {floader} with too large size: {floader_size}")
return ErrType.SYS_OVERRANGE
_baud_bytes = self.serial_port.baudrate.to_bytes(4, byteorder='little')
floader_aligned_size = self.get_page_aligned_size(floader_size, page_size)
datas = io.BytesIO(floader_content)
data_bytes = datas.read(floader_size)
data_bytes += _baud_bytes
data_bytes = data_bytes.ljust(floader_aligned_size, b"\x00")
idx = 0
floader_addr = self.profile.floader_address
while idx < floader_aligned_size:
trans_data = data_bytes[idx:idx+page_size]
ret = self.transfer(floader_addr, trans_data)
if ret != ErrType.OK:
return ret
idx += page_size
floader_addr += page_size
ret = self.end_transfer()
if ret != ErrType.OK:
if self.profile.is_amebaz():
# AmebaZ would tx ACK after rx EOT but would not wait tx ACK done, so in low baudrate(115200...),
# ACK will not be received
# This issue has been fixed after AmebaD
ret = ErrType.OK
return ret

72
base/rt_settings.py Normal file
View File

@ -0,0 +1,72 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
class RtSettings():
MIN_ROM_BOOT_DELAY_IN_MILLISECOND = 50
MIN_USB_ROM_BOOT_DELAY_IN_MILLISECOND = 200
MIN_USB_FLOADER_BOOT_DELAY_IN_MILLISECOND = 200
FLASH_PROTECTION_PROCESS_PROMPT = 0
FLASH_PROTECTION_PROCESS_TRY = 1
FLASH_PROTECTION_PROCESS_UNLOCK = 2
FLASH_PROTECTION_PROCESS_ABORT = 3
def __init__(self, **kwargs):
self.sense_packet_count = kwargs.get("SensePacketCount", 32)
self.request_retry_count = kwargs.get("RequestRetryCount", 3)
self.request_retry_interval_second = round(kwargs.get("RequestRetryIntervalInMillisecond", 10) / 1000, 2)
self.async_response_timeout_in_second = round(kwargs.get("AsyncResponseTimeoutInMilliseccond", 1000) / 1000, 2)
self.sync_response_timeout_in_second = round(kwargs.get("SyncResponseTimeoutInMillisecond", 1000) / 1000, 2)
self.baudrate_switch_delay_in_second = round(kwargs.get("BaudrateSwitchDelayInMillisecond", 200) / 1000, 2)
self.rom_boot_delay_in_second = round(max(kwargs.get("RomBootDelayInMillisecond", 100), self.MIN_ROM_BOOT_DELAY_IN_MILLISECOND) / 1000, 2)
self.usb_rom_boot_delay_in_second = round(max(kwargs.get("UsbRomBootDelayInMillisecond", 1000), self.MIN_USB_ROM_BOOT_DELAY_IN_MILLISECOND) / 1000, 2)
self.usb_floader_boot_delay_in_second = round(max(kwargs.get("UsbFloaderBootDelayInMillisecond", 1000), self.MIN_USB_FLOADER_BOOT_DELAY_IN_MILLISECOND) / 1000, 2)
self.switch_baudrate_at_floader = kwargs.get("SwitchBaudrateAtFloader", 0)
self.write_response_timeout_in_second = round(kwargs.get("WriteResponseTimeoutInMillisecond", 2000) / 1000, 2)
self.floader_boot_delay_in_second = round(kwargs.get("FloaderBootDelayInMillisecond", 1000) / 1000, 2)
self.auto_switch_to_download_mode_with_dtr_rts = kwargs.get("AutoSwitchToDownloadModeWithDtrRts", 0)
self.auto_reset_device_with_dtr_rts = kwargs.get("AutoResetDeviceWithDtrRts", 0)
self.flash_protection_process = kwargs.get("FlashProtectionProcess", self.FLASH_PROTECTION_PROCESS_PROMPT)
self.erase_by_block = kwargs.get("EraseByBlock", 0)
self.program_config1 = kwargs.get("ProgramConfig1", 0)
self.program_config2 = kwargs.get("ProgramConfig2", 0)
self.disable_nand_access_with_uart = kwargs.get("DisableNandAccessWithUart", 0)
self.ram_download_padding_byte = kwargs.get("RamDownloadPaddingByte", 0x00)
self.auto_program_spic_addr_mode_4byte = kwargs.get("AutoProgramSpicAddrMode4Byte", 0)
self.auto_switch_to_download_mode_with_dtr_rts_file = kwargs.get("AutoSwitchToDownloadModeWithDtrRtsTimingFile", "Reburn.cfg")
self.auto_reset_device_with_dtr_rts_file = kwargs.get("AutoResetDeviceWithDtrRtsTimingFile", "Reset.cfg")
self.post_process = kwargs.get("PostProcess", "RESET")
def __repr__(self):
profile_dict = {
"SensePacketCount": self.sense_packet_count,
"RequestRetryCount": self.request_retry_count,
"RequestRetryIntervalInMillisecond": int(self.request_retry_interval_second * 1000),
"AsyncResponseTimeoutInMilliseccond": int(self.async_response_timeout_in_second * 1000),
"SyncResponseTimeoutInMillisecond": int(self.sync_response_timeout_in_second * 1000),
"BaudrateSwitchDelayInMillisecond": int(self.baudrate_switch_delay_in_second * 1000),
"RomBootDelayInMillisecond": int(self.rom_boot_delay_in_second * 1000),
"UsbRomBootDelayInMillisecond": int(self.usb_rom_boot_delay_in_second * 1000),
"UsbFloaderBootDelayInMillisecond": int(self.usb_floader_boot_delay_in_second * 1000),
"SwitchBaudrateAtFloader": self.switch_baudrate_at_floader,
"WriteResponseTimeoutInMillisecond": int(self.write_response_timeout_in_second * 1000),
"FloaderBootDelayInMillisecond": int(self.floader_boot_delay_in_second * 1000),
"AutoSwitchToDownloadModeWithDtrRts": self.auto_switch_to_download_mode_with_dtr_rts,
"AutoResetDeviceWithDtrRts": self.auto_reset_device_with_dtr_rts,
"FlashProtectionProcess": self.flash_protection_process,
"EraseByBlock": self.erase_by_block,
"ProgramConfig1": self.program_config1,
"ProgramConfig2": self.program_config2,
"DisableNandAccessWithUart": self.disable_nand_access_with_uart,
"RamDownloadPaddingByte": self.ram_download_padding_byte,
"AutoProgramSpicAddrMode4Byte": self.auto_program_spic_addr_mode_4byte,
"AutoSwitchToDownloadModeWithDtrRtsTimingFile": self.auto_switch_to_download_mode_with_dtr_rts_file,
"AutoResetDeviceWithDtrRtsTimingFile": self.auto_reset_device_with_dtr_rts_file,
"PostProcess": self.post_process
}
return profile_dict

12
base/rtk_flash_type.py Normal file
View File

@ -0,0 +1,12 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
from enum import Enum
class RtkFlashType(Enum):
NOR = 0
NAND = 1

49
base/rtk_logging.py Normal file
View File

@ -0,0 +1,49 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import sys
import logging
from colorama import Fore, Style, init
# init Colorama
init(autoreset=True)
def create_logger(name, log_level="INFO", stream=sys.stdout, file=None):
if log_level == "DEBUG":
level = logging.DEBUG
elif log_level == "WARNING":
level = logging.WARNING
elif log_level == "ERROR":
level = logging.ERROR
elif log_level == "FATAL":
level = logging.FATAL
else:
level = logging.INFO
logger = logging.getLogger(name)
if not logger.handlers:
formatter = logging.Formatter(
fmt=f'[%(asctime)s.%(msecs)03d][%(levelname)s] [{name}]%(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
logging.addLevelName(logging.DEBUG, f"D")
logging.addLevelName(logging.INFO, f"I")
logging.addLevelName(logging.WARNING, f"{Fore.YELLOW}W{Style.RESET_ALL}")
logging.addLevelName(logging.ERROR, f"{Fore.RED}E{Style.RESET_ALL}")
logging.addLevelName(logging.FATAL, f"{Fore.RED}{Style.BRIGHT}F{Style.RESET_ALL}")
consoleHandler = logging.StreamHandler(stream)
consoleHandler.setFormatter(formatter)
logger.addHandler(consoleHandler)
if file is not None:
fileHandler = logging.FileHandler(file, mode='a')
fileHandler.setFormatter(formatter)
logger.addHandler(fileHandler)
logger.propagate = False # Prevent logging from propagating to the root logger
logger.setLevel(level)
return logger

21
base/rtk_utils.py Normal file
View File

@ -0,0 +1,21 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import os
import sys
class RtkUtils:
@staticmethod
def get_executable_root_path():
if getattr(sys, 'frozen', False): # judge if frozen as exe
# get exe dir
executable_root = os.path.dirname(os.path.abspath(sys.executable))
else:
# get py dir
executable_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
return executable_root

24
base/sense_status.py Normal file
View File

@ -0,0 +1,24 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
from .errno import *
class SenseStatus:
def __init__(self):
self.op_code = None
self.status = None
self.data = None
def parse(self, data, offset):
ret = ErrType.SYS_OVERRANGE
if len(data) >= offset + 6:
self.op_code = data[offset]
self.status = data[offset + 1]
self.data = data[offset+2] + (data[offset+3]<<8) + (data[offset+4]<<16) + (data[offset+5]<<24)
ret = ErrType.OK
return ret

12
base/spic_addr_mode.py Normal file
View File

@ -0,0 +1,12 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
from enum import Enum
class SpicAddrMode(Enum):
THREE_BYTE_MODE = 0
FOUR_BYTE_MODE = 1

9
base/sys_utils.py Normal file
View File

@ -0,0 +1,9 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
def divide_then_round_up(dividend, divisor):
return int((dividend + divisor - 1) / divisor)

16
base/version.py Normal file
View File

@ -0,0 +1,16 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
class Version:
def __init__(self, version_str):
# parser version_str with pattern major.minor.micro
parts = version_str.split(".")
self.major = int(parts[0])
self.minor = int(parts[1] if len(parts) > 1 else 0)
self.micro = int(parts[2] if len(parts) > 2 else 0)
def __repr__(self):
return f"{self.major}.{self.minor}.{self.micro}"

997
build/flash/Analysis-01.toc Normal file
View File

@ -0,0 +1,997 @@
(['C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\flash.py'],
['C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2'],
[],
[('C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\numpy\\_pyinstaller',
0),
('C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\pygame\\__pyinstaller',
0),
('C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\webview\\__pyinstaller',
0),
('C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\_pyinstaller_hooks_contrib\\stdhooks',
-1000),
('C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\_pyinstaller_hooks_contrib',
-1000)],
{},
[],
[],
False,
{},
0,
[],
[],
'3.11.4 (tags/v3.11.4:d2340ef, Jun 7 2023, 05:45:37) [MSC v.1934 64 bit '
'(AMD64)]',
[('pyi_rth_inspect',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
'PYSOURCE'),
('flash',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\flash.py',
'PYSOURCE')],
[('zipfile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\zipfile.py',
'PYMODULE'),
('py_compile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\py_compile.py',
'PYMODULE'),
('importlib.machinery',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\machinery.py',
'PYMODULE'),
('importlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\__init__.py',
'PYMODULE'),
('importlib._bootstrap',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap.py',
'PYMODULE'),
('importlib._bootstrap_external',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap_external.py',
'PYMODULE'),
('importlib.metadata',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\__init__.py',
'PYMODULE'),
('typing',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\typing.py',
'PYMODULE'),
('importlib.abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\abc.py',
'PYMODULE'),
('importlib.resources.abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\abc.py',
'PYMODULE'),
('importlib.resources',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\__init__.py',
'PYMODULE'),
('importlib.resources._legacy',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_legacy.py',
'PYMODULE'),
('importlib.resources._common',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_common.py',
'PYMODULE'),
('importlib.resources._adapters',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_adapters.py',
'PYMODULE'),
('tempfile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tempfile.py',
'PYMODULE'),
('random',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\random.py',
'PYMODULE'),
('statistics',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\statistics.py',
'PYMODULE'),
('decimal',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\decimal.py',
'PYMODULE'),
('_pydecimal',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_pydecimal.py',
'PYMODULE'),
('contextvars',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextvars.py',
'PYMODULE'),
('fractions',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fractions.py',
'PYMODULE'),
('numbers',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\numbers.py',
'PYMODULE'),
('hashlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\hashlib.py',
'PYMODULE'),
('logging',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\logging\\__init__.py',
'PYMODULE'),
('pickle',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pickle.py',
'PYMODULE'),
('pprint',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pprint.py',
'PYMODULE'),
('dataclasses',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dataclasses.py',
'PYMODULE'),
('_compat_pickle',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compat_pickle.py',
'PYMODULE'),
('string',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\string.py',
'PYMODULE'),
('bisect',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bisect.py',
'PYMODULE'),
('importlib._abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_abc.py',
'PYMODULE'),
('importlib.metadata._itertools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_itertools.py',
'PYMODULE'),
('importlib.metadata._functools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_functools.py',
'PYMODULE'),
('importlib.metadata._collections',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_collections.py',
'PYMODULE'),
('importlib.metadata._meta',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_meta.py',
'PYMODULE'),
('importlib.metadata._adapters',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_adapters.py',
'PYMODULE'),
('importlib.metadata._text',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_text.py',
'PYMODULE'),
('email.message',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\message.py',
'PYMODULE'),
('email.policy',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\policy.py',
'PYMODULE'),
('email.contentmanager',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\contentmanager.py',
'PYMODULE'),
('email.quoprimime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\quoprimime.py',
'PYMODULE'),
('email.headerregistry',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\headerregistry.py',
'PYMODULE'),
('email._header_value_parser',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_header_value_parser.py',
'PYMODULE'),
('urllib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\__init__.py',
'PYMODULE'),
('email.iterators',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\iterators.py',
'PYMODULE'),
('email.generator',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\generator.py',
'PYMODULE'),
('email._encoded_words',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_encoded_words.py',
'PYMODULE'),
('email.charset',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\charset.py',
'PYMODULE'),
('email.encoders',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\encoders.py',
'PYMODULE'),
('email.base64mime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\base64mime.py',
'PYMODULE'),
('email._policybase',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_policybase.py',
'PYMODULE'),
('email.header',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\header.py',
'PYMODULE'),
('email.errors',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\errors.py',
'PYMODULE'),
('email.utils',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\utils.py',
'PYMODULE'),
('email._parseaddr',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_parseaddr.py',
'PYMODULE'),
('calendar',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\calendar.py',
'PYMODULE'),
('urllib.parse',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\parse.py',
'PYMODULE'),
('ipaddress',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ipaddress.py',
'PYMODULE'),
('datetime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\datetime.py',
'PYMODULE'),
('_strptime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_strptime.py',
'PYMODULE'),
('socket',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\socket.py',
'PYMODULE'),
('selectors',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\selectors.py',
'PYMODULE'),
('quopri',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\quopri.py',
'PYMODULE'),
('getopt',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\getopt.py',
'PYMODULE'),
('gettext',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gettext.py',
'PYMODULE'),
('textwrap',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\textwrap.py',
'PYMODULE'),
('email',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\__init__.py',
'PYMODULE'),
('email.parser',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\parser.py',
'PYMODULE'),
('email.feedparser',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\feedparser.py',
'PYMODULE'),
('csv',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\csv.py',
'PYMODULE'),
('importlib.readers',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\readers.py',
'PYMODULE'),
('importlib.resources.readers',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\readers.py',
'PYMODULE'),
('importlib.resources._itertools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_itertools.py',
'PYMODULE'),
('tokenize',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tokenize.py',
'PYMODULE'),
('token',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\token.py',
'PYMODULE'),
('lzma',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\lzma.py',
'PYMODULE'),
('_compression',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compression.py',
'PYMODULE'),
('bz2',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bz2.py',
'PYMODULE'),
('pathlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pathlib.py',
'PYMODULE'),
('fnmatch',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fnmatch.py',
'PYMODULE'),
('contextlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextlib.py',
'PYMODULE'),
('struct',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\struct.py',
'PYMODULE'),
('shutil',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\shutil.py',
'PYMODULE'),
('tarfile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tarfile.py',
'PYMODULE'),
('gzip',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gzip.py',
'PYMODULE'),
('importlib.util',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\util.py',
'PYMODULE'),
('inspect',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\inspect.py',
'PYMODULE'),
('dis',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dis.py',
'PYMODULE'),
('opcode',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\opcode.py',
'PYMODULE'),
('ast',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ast.py',
'PYMODULE'),
('tracemalloc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tracemalloc.py',
'PYMODULE'),
('_py_abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_py_abc.py',
'PYMODULE'),
('stringprep',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\stringprep.py',
'PYMODULE'),
('version_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\version_info.py',
'PYMODULE'),
('base',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\__init__.py',
'PYMODULE'),
('base.rt_settings',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rt_settings.py',
'PYMODULE'),
('base.rtk_logging',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rtk_logging.py',
'PYMODULE'),
('colorama',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\__init__.py',
'PYMODULE'),
('colorama.ansitowin32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\ansitowin32.py',
'PYMODULE'),
('colorama.winterm',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\winterm.py',
'PYMODULE'),
('colorama.ansi',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\ansi.py',
'PYMODULE'),
('colorama.initialise',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\initialise.py',
'PYMODULE'),
('colorama.win32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\win32.py',
'PYMODULE'),
('ctypes.wintypes',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ctypes\\wintypes.py',
'PYMODULE'),
('ctypes',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ctypes\\__init__.py',
'PYMODULE'),
('ctypes._endian',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ctypes\\_endian.py',
'PYMODULE'),
('base.download_handler',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\download_handler.py',
'PYMODULE'),
('base.remote_serial',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\remote_serial.py',
'PYMODULE'),
('serial.serialutil',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialutil.py',
'PYMODULE'),
('__future__',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\__future__.py',
'PYMODULE'),
('json',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\__init__.py',
'PYMODULE'),
('json.encoder',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\encoder.py',
'PYMODULE'),
('json.decoder',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\decoder.py',
'PYMODULE'),
('json.scanner',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\scanner.py',
'PYMODULE'),
('base.config_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\config_utils.py',
'PYMODULE'),
('base.memory_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\memory_info.py',
'PYMODULE'),
('base.spic_addr_mode',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\spic_addr_mode.py',
'PYMODULE'),
('base.json_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\json_utils.py',
'PYMODULE'),
('pyDes',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\pyDes.py',
'PYMODULE'),
('base.device_profile',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\device_profile.py',
'PYMODULE'),
('base.version',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\version.py',
'PYMODULE'),
('base.efuse_data',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\efuse_data.py',
'PYMODULE'),
('base.image_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\image_info.py',
'PYMODULE'),
('base.flash_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\flash_utils.py',
'PYMODULE'),
('base.sys_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\sys_utils.py',
'PYMODULE'),
('base.floader_handler',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\floader_handler.py',
'PYMODULE'),
('base.next_op',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\next_op.py',
'PYMODULE'),
('base.device_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\device_info.py',
'PYMODULE'),
('base.rtk_flash_type',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rtk_flash_type.py',
'PYMODULE'),
('base.sense_status',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\sense_status.py',
'PYMODULE'),
('base.errno',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\errno.py',
'PYMODULE'),
('base.rom_handler',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rom_handler.py',
'PYMODULE'),
('base.rtk_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rtk_utils.py',
'PYMODULE'),
('serial',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\__init__.py',
'PYMODULE'),
('serial.serialjava',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialjava.py',
'PYMODULE'),
('serial.serialposix',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialposix.py',
'PYMODULE'),
('serial.serialwin32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialwin32.py',
'PYMODULE'),
('serial.win32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\win32.py',
'PYMODULE'),
('serial.serialcli',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialcli.py',
'PYMODULE'),
('serial.tools.list_ports',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports.py',
'PYMODULE'),
('serial.tools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\__init__.py',
'PYMODULE'),
('serial.tools.list_ports_common',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_common.py',
'PYMODULE'),
('glob',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\glob.py',
'PYMODULE'),
('serial.tools.list_ports_posix',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_posix.py',
'PYMODULE'),
('serial.tools.list_ports_osx',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_osx.py',
'PYMODULE'),
('serial.tools.list_ports_linux',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_linux.py',
'PYMODULE'),
('serial.tools.list_ports_windows',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_windows.py',
'PYMODULE'),
('copy',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\copy.py',
'PYMODULE'),
('threading',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\threading.py',
'PYMODULE'),
('_threading_local',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_threading_local.py',
'PYMODULE'),
('base64',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\base64.py',
'PYMODULE'),
('argparse',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\argparse.py',
'PYMODULE'),
('subprocess',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\subprocess.py',
'PYMODULE'),
('signal',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\signal.py',
'PYMODULE')],
[('python311.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\python311.dll',
'BINARY'),
('_decimal.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_decimal.pyd',
'EXTENSION'),
('_hashlib.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_hashlib.pyd',
'EXTENSION'),
('unicodedata.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\unicodedata.pyd',
'EXTENSION'),
('select.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\select.pyd',
'EXTENSION'),
('_socket.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_socket.pyd',
'EXTENSION'),
('_lzma.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_lzma.pyd',
'EXTENSION'),
('_bz2.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_bz2.pyd',
'EXTENSION'),
('_ctypes.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_ctypes.pyd',
'EXTENSION'),
('VCRUNTIME140.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\VCRUNTIME140.dll',
'BINARY'),
('libcrypto-1_1.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\libcrypto-1_1.dll',
'BINARY'),
('libffi-8.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\libffi-8.dll',
'BINARY')],
[],
[],
[('base_library.zip',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\base_library.zip',
'DATA')],
[('warnings',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\warnings.py',
'PYMODULE'),
('genericpath',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\genericpath.py',
'PYMODULE'),
('reprlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\reprlib.py',
'PYMODULE'),
('copyreg',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\copyreg.py',
'PYMODULE'),
('posixpath',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\posixpath.py',
'PYMODULE'),
('keyword',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\keyword.py',
'PYMODULE'),
('abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\abc.py',
'PYMODULE'),
('_collections_abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_collections_abc.py',
'PYMODULE'),
('ntpath',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ntpath.py',
'PYMODULE'),
('weakref',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\weakref.py',
'PYMODULE'),
('operator',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\operator.py',
'PYMODULE'),
('io',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\io.py',
'PYMODULE'),
('locale',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\locale.py',
'PYMODULE'),
('stat',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\stat.py',
'PYMODULE'),
('enum',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\enum.py',
'PYMODULE'),
('types',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\types.py',
'PYMODULE'),
('traceback',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\traceback.py',
'PYMODULE'),
('sre_compile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\sre_compile.py',
'PYMODULE'),
('heapq',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\heapq.py',
'PYMODULE'),
('re._parser',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\re\\_parser.py',
'PYMODULE'),
('re._constants',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\re\\_constants.py',
'PYMODULE'),
('re._compiler',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\re\\_compiler.py',
'PYMODULE'),
('re._casefix',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\re\\_casefix.py',
'PYMODULE'),
('_weakrefset',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_weakrefset.py',
'PYMODULE'),
('functools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\functools.py',
'PYMODULE'),
('collections.abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\collections\\abc.py',
'PYMODULE'),
('collections',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\collections\\__init__.py',
'PYMODULE'),
('sre_constants',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\sre_constants.py',
'PYMODULE'),
('sre_parse',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\sre_parse.py',
'PYMODULE'),
('encodings.zlib_codec',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\zlib_codec.py',
'PYMODULE'),
('encodings.uu_codec',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\uu_codec.py',
'PYMODULE'),
('encodings.utf_8_sig',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_8_sig.py',
'PYMODULE'),
('encodings.utf_8',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_8.py',
'PYMODULE'),
('encodings.utf_7',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_7.py',
'PYMODULE'),
('encodings.utf_32_le',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_32_le.py',
'PYMODULE'),
('encodings.utf_32_be',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_32_be.py',
'PYMODULE'),
('encodings.utf_32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_32.py',
'PYMODULE'),
('encodings.utf_16_le',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_16_le.py',
'PYMODULE'),
('encodings.utf_16_be',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_16_be.py',
'PYMODULE'),
('encodings.utf_16',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\utf_16.py',
'PYMODULE'),
('encodings.unicode_escape',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\unicode_escape.py',
'PYMODULE'),
('encodings.undefined',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\undefined.py',
'PYMODULE'),
('encodings.tis_620',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\tis_620.py',
'PYMODULE'),
('encodings.shift_jisx0213',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\shift_jisx0213.py',
'PYMODULE'),
('encodings.shift_jis_2004',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\shift_jis_2004.py',
'PYMODULE'),
('encodings.shift_jis',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\shift_jis.py',
'PYMODULE'),
('encodings.rot_13',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\rot_13.py',
'PYMODULE'),
('encodings.raw_unicode_escape',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\raw_unicode_escape.py',
'PYMODULE'),
('encodings.quopri_codec',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\quopri_codec.py',
'PYMODULE'),
('encodings.punycode',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\punycode.py',
'PYMODULE'),
('encodings.ptcp154',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\ptcp154.py',
'PYMODULE'),
('encodings.palmos',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\palmos.py',
'PYMODULE'),
('encodings.oem',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\oem.py',
'PYMODULE'),
('encodings.mbcs',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mbcs.py',
'PYMODULE'),
('encodings.mac_turkish',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_turkish.py',
'PYMODULE'),
('encodings.mac_romanian',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_romanian.py',
'PYMODULE'),
('encodings.mac_roman',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_roman.py',
'PYMODULE'),
('encodings.mac_latin2',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_latin2.py',
'PYMODULE'),
('encodings.mac_iceland',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_iceland.py',
'PYMODULE'),
('encodings.mac_greek',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_greek.py',
'PYMODULE'),
('encodings.mac_farsi',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_farsi.py',
'PYMODULE'),
('encodings.mac_cyrillic',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_cyrillic.py',
'PYMODULE'),
('encodings.mac_croatian',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_croatian.py',
'PYMODULE'),
('encodings.mac_arabic',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\mac_arabic.py',
'PYMODULE'),
('encodings.latin_1',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\latin_1.py',
'PYMODULE'),
('encodings.kz1048',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\kz1048.py',
'PYMODULE'),
('encodings.koi8_u',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\koi8_u.py',
'PYMODULE'),
('encodings.koi8_t',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\koi8_t.py',
'PYMODULE'),
('encodings.koi8_r',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\koi8_r.py',
'PYMODULE'),
('encodings.johab',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\johab.py',
'PYMODULE'),
('encodings.iso8859_9',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_9.py',
'PYMODULE'),
('encodings.iso8859_8',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_8.py',
'PYMODULE'),
('encodings.iso8859_7',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_7.py',
'PYMODULE'),
('encodings.iso8859_6',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_6.py',
'PYMODULE'),
('encodings.iso8859_5',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_5.py',
'PYMODULE'),
('encodings.iso8859_4',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_4.py',
'PYMODULE'),
('encodings.iso8859_3',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_3.py',
'PYMODULE'),
('encodings.iso8859_2',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_2.py',
'PYMODULE'),
('encodings.iso8859_16',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_16.py',
'PYMODULE'),
('encodings.iso8859_15',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_15.py',
'PYMODULE'),
('encodings.iso8859_14',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_14.py',
'PYMODULE'),
('encodings.iso8859_13',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_13.py',
'PYMODULE'),
('encodings.iso8859_11',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_11.py',
'PYMODULE'),
('encodings.iso8859_10',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_10.py',
'PYMODULE'),
('encodings.iso8859_1',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso8859_1.py',
'PYMODULE'),
('encodings.iso2022_kr',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso2022_kr.py',
'PYMODULE'),
('encodings.iso2022_jp_ext',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso2022_jp_ext.py',
'PYMODULE'),
('encodings.iso2022_jp_3',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso2022_jp_3.py',
'PYMODULE'),
('encodings.iso2022_jp_2004',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso2022_jp_2004.py',
'PYMODULE'),
('encodings.iso2022_jp_2',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso2022_jp_2.py',
'PYMODULE'),
('encodings.iso2022_jp_1',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso2022_jp_1.py',
'PYMODULE'),
('encodings.iso2022_jp',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\iso2022_jp.py',
'PYMODULE'),
('encodings.idna',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\idna.py',
'PYMODULE'),
('encodings.hz',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\hz.py',
'PYMODULE'),
('encodings.hp_roman8',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\hp_roman8.py',
'PYMODULE'),
('encodings.hex_codec',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\hex_codec.py',
'PYMODULE'),
('encodings.gbk',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\gbk.py',
'PYMODULE'),
('encodings.gb2312',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\gb2312.py',
'PYMODULE'),
('encodings.gb18030',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\gb18030.py',
'PYMODULE'),
('encodings.euc_kr',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\euc_kr.py',
'PYMODULE'),
('encodings.euc_jp',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\euc_jp.py',
'PYMODULE'),
('encodings.euc_jisx0213',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\euc_jisx0213.py',
'PYMODULE'),
('encodings.euc_jis_2004',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\euc_jis_2004.py',
'PYMODULE'),
('encodings.cp950',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp950.py',
'PYMODULE'),
('encodings.cp949',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp949.py',
'PYMODULE'),
('encodings.cp932',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp932.py',
'PYMODULE'),
('encodings.cp875',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp875.py',
'PYMODULE'),
('encodings.cp874',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp874.py',
'PYMODULE'),
('encodings.cp869',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp869.py',
'PYMODULE'),
('encodings.cp866',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp866.py',
'PYMODULE'),
('encodings.cp865',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp865.py',
'PYMODULE'),
('encodings.cp864',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp864.py',
'PYMODULE'),
('encodings.cp863',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp863.py',
'PYMODULE'),
('encodings.cp862',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp862.py',
'PYMODULE'),
('encodings.cp861',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp861.py',
'PYMODULE'),
('encodings.cp860',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp860.py',
'PYMODULE'),
('encodings.cp858',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp858.py',
'PYMODULE'),
('encodings.cp857',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp857.py',
'PYMODULE'),
('encodings.cp856',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp856.py',
'PYMODULE'),
('encodings.cp855',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp855.py',
'PYMODULE'),
('encodings.cp852',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp852.py',
'PYMODULE'),
('encodings.cp850',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp850.py',
'PYMODULE'),
('encodings.cp775',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp775.py',
'PYMODULE'),
('encodings.cp737',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp737.py',
'PYMODULE'),
('encodings.cp720',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp720.py',
'PYMODULE'),
('encodings.cp500',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp500.py',
'PYMODULE'),
('encodings.cp437',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp437.py',
'PYMODULE'),
('encodings.cp424',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp424.py',
'PYMODULE'),
('encodings.cp273',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp273.py',
'PYMODULE'),
('encodings.cp1258',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1258.py',
'PYMODULE'),
('encodings.cp1257',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1257.py',
'PYMODULE'),
('encodings.cp1256',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1256.py',
'PYMODULE'),
('encodings.cp1255',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1255.py',
'PYMODULE'),
('encodings.cp1254',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1254.py',
'PYMODULE'),
('encodings.cp1253',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1253.py',
'PYMODULE'),
('encodings.cp1252',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1252.py',
'PYMODULE'),
('encodings.cp1251',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1251.py',
'PYMODULE'),
('encodings.cp1250',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1250.py',
'PYMODULE'),
('encodings.cp1140',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1140.py',
'PYMODULE'),
('encodings.cp1125',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1125.py',
'PYMODULE'),
('encodings.cp1026',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1026.py',
'PYMODULE'),
('encodings.cp1006',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp1006.py',
'PYMODULE'),
('encodings.cp037',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\cp037.py',
'PYMODULE'),
('encodings.charmap',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\charmap.py',
'PYMODULE'),
('encodings.bz2_codec',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\bz2_codec.py',
'PYMODULE'),
('encodings.big5hkscs',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\big5hkscs.py',
'PYMODULE'),
('encodings.big5',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\big5.py',
'PYMODULE'),
('encodings.base64_codec',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\base64_codec.py',
'PYMODULE'),
('encodings.ascii',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\ascii.py',
'PYMODULE'),
('encodings.aliases',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\aliases.py',
'PYMODULE'),
('encodings',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\encodings\\__init__.py',
'PYMODULE'),
('linecache',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\linecache.py',
'PYMODULE'),
('codecs',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\codecs.py',
'PYMODULE'),
('re',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\re\\__init__.py',
'PYMODULE'),
('os',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\os.py',
'PYMODULE')])

107
build/flash/EXE-01.toc Normal file
View File

@ -0,0 +1,107 @@
('C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\dist\\flash.exe',
False,
False,
False,
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\PyInstaller\\bootloader\\images\\icon-windowed.ico',
versioninfo.VSVersionInfo(ffi=versioninfo.FixedFileInfo(filevers=(1, 2, 2, 0), prodvers=(1, 2, 2, 0), mask=0x3f, flags=0x0, OS=0x40004, fileType=1, subtype=0x0, date=(0, 0)), kids=[versioninfo.StringFileInfo([versioninfo.StringTable('040904B0', [versioninfo.StringStruct('CompanyName', 'Realtek Semiconductor Corp.'), versioninfo.StringStruct('FileDescription', 'Flash Tool for Realtek Ameba SoCs'), versioninfo.StringStruct('FileVersion', '1.2.2.0'), versioninfo.StringStruct('InternalName', 'flash.exe'), versioninfo.StringStruct('LegalCopyright', 'Copyright (c) 2025 Realtek Semiconductor Corp.'), versioninfo.StringStruct('OriginalFilename', 'flash.exe'), versioninfo.StringStruct('ProductName', 'Ameba Flash Tool'), versioninfo.StringStruct('ProductVersion', '1.2.2.0')])]), versioninfo.VarFileInfo([versioninfo.VarStruct('Translation', [1033, 1200])])]),
False,
False,
b'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<assembly xmlns='
b'"urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\n <trustInfo x'
b'mlns="urn:schemas-microsoft-com:asm.v3">\n <security>\n <requested'
b'Privileges>\n <requestedExecutionLevel level="asInvoker" uiAccess='
b'"false"/>\n </requestedPrivileges>\n </security>\n </trustInfo>\n '
b'<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">\n <'
b'application>\n <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f'
b'0}"/>\n <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>\n '
b' <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>\n <s'
b'upportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>\n <supporte'
b'dOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>\n </application>\n <'
b'/compatibility>\n <application xmlns="urn:schemas-microsoft-com:asm.v3">'
b'\n <windowsSettings>\n <longPathAware xmlns="http://schemas.micros'
b'oft.com/SMI/2016/WindowsSettings">true</longPathAware>\n </windowsSett'
b'ings>\n </application>\n <dependency>\n <dependentAssembly>\n <ass'
b'emblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version='
b'"6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" langua'
b'ge="*"/>\n </dependentAssembly>\n </dependency>\n</assembly>',
True,
False,
None,
None,
None,
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\flash.pkg',
[('pyi-contents-directory _internal', '', 'OPTION'),
('PYZ-01.pyz',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\PYZ-01.pyz',
'PYZ'),
('struct',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\struct.pyc',
'PYMODULE'),
('pyimod01_archive',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod01_archive.pyc',
'PYMODULE'),
('pyimod02_importers',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod02_importers.pyc',
'PYMODULE'),
('pyimod03_ctypes',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod03_ctypes.pyc',
'PYMODULE'),
('pyimod04_pywin32',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod04_pywin32.pyc',
'PYMODULE'),
('pyiboot01_bootstrap',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
'PYSOURCE'),
('pyi_rth_inspect',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
'PYSOURCE'),
('flash',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\flash.py',
'PYSOURCE'),
('python311.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\python311.dll',
'BINARY'),
('_decimal.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_decimal.pyd',
'EXTENSION'),
('_hashlib.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_hashlib.pyd',
'EXTENSION'),
('unicodedata.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\unicodedata.pyd',
'EXTENSION'),
('select.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\select.pyd',
'EXTENSION'),
('_socket.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_socket.pyd',
'EXTENSION'),
('_lzma.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_lzma.pyd',
'EXTENSION'),
('_bz2.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_bz2.pyd',
'EXTENSION'),
('_ctypes.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_ctypes.pyd',
'EXTENSION'),
('VCRUNTIME140.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\VCRUNTIME140.dll',
'BINARY'),
('libcrypto-1_1.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\libcrypto-1_1.dll',
'BINARY'),
('libffi-8.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\libffi-8.dll',
'BINARY'),
('base_library.zip',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\base_library.zip',
'DATA')],
[],
False,
False,
1765693469,
[('runw.exe',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\PyInstaller\\bootloader\\Windows-64bit-intel\\runw.exe',
'EXECUTABLE')],
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\python311.dll')

85
build/flash/PKG-01.toc Normal file
View File

@ -0,0 +1,85 @@
('C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\flash.pkg',
{'BINARY': True,
'DATA': True,
'EXECUTABLE': True,
'EXTENSION': True,
'PYMODULE': True,
'PYSOURCE': True,
'PYZ': False,
'SPLASH': True,
'SYMLINK': False},
[('pyi-contents-directory _internal', '', 'OPTION'),
('PYZ-01.pyz',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\PYZ-01.pyz',
'PYZ'),
('struct',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\struct.pyc',
'PYMODULE'),
('pyimod01_archive',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod01_archive.pyc',
'PYMODULE'),
('pyimod02_importers',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod02_importers.pyc',
'PYMODULE'),
('pyimod03_ctypes',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod03_ctypes.pyc',
'PYMODULE'),
('pyimod04_pywin32',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\localpycs\\pyimod04_pywin32.pyc',
'PYMODULE'),
('pyiboot01_bootstrap',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\PyInstaller\\loader\\pyiboot01_bootstrap.py',
'PYSOURCE'),
('pyi_rth_inspect',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks\\pyi_rth_inspect.py',
'PYSOURCE'),
('flash',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\flash.py',
'PYSOURCE'),
('python311.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\python311.dll',
'BINARY'),
('_decimal.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_decimal.pyd',
'EXTENSION'),
('_hashlib.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_hashlib.pyd',
'EXTENSION'),
('unicodedata.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\unicodedata.pyd',
'EXTENSION'),
('select.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\select.pyd',
'EXTENSION'),
('_socket.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_socket.pyd',
'EXTENSION'),
('_lzma.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_lzma.pyd',
'EXTENSION'),
('_bz2.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_bz2.pyd',
'EXTENSION'),
('_ctypes.pyd',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\_ctypes.pyd',
'EXTENSION'),
('VCRUNTIME140.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\VCRUNTIME140.dll',
'BINARY'),
('libcrypto-1_1.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\libcrypto-1_1.dll',
'BINARY'),
('libffi-8.dll',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\DLLs\\libffi-8.dll',
'BINARY'),
('base_library.zip',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\base_library.zip',
'DATA')],
'python311.dll',
False,
False,
False,
[],
None,
None,
None)

BIN
build/flash/PYZ-01.pyz Normal file

Binary file not shown.

460
build/flash/PYZ-01.toc Normal file
View File

@ -0,0 +1,460 @@
('C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\build\\flash\\PYZ-01.pyz',
[('__future__',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\__future__.py',
'PYMODULE'),
('_compat_pickle',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compat_pickle.py',
'PYMODULE'),
('_compression',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_compression.py',
'PYMODULE'),
('_py_abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_py_abc.py',
'PYMODULE'),
('_pydecimal',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_pydecimal.py',
'PYMODULE'),
('_strptime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_strptime.py',
'PYMODULE'),
('_threading_local',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\_threading_local.py',
'PYMODULE'),
('argparse',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\argparse.py',
'PYMODULE'),
('ast',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ast.py',
'PYMODULE'),
('base',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\__init__.py',
'PYMODULE'),
('base.config_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\config_utils.py',
'PYMODULE'),
('base.device_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\device_info.py',
'PYMODULE'),
('base.device_profile',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\device_profile.py',
'PYMODULE'),
('base.download_handler',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\download_handler.py',
'PYMODULE'),
('base.efuse_data',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\efuse_data.py',
'PYMODULE'),
('base.errno',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\errno.py',
'PYMODULE'),
('base.flash_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\flash_utils.py',
'PYMODULE'),
('base.floader_handler',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\floader_handler.py',
'PYMODULE'),
('base.image_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\image_info.py',
'PYMODULE'),
('base.json_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\json_utils.py',
'PYMODULE'),
('base.memory_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\memory_info.py',
'PYMODULE'),
('base.next_op',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\next_op.py',
'PYMODULE'),
('base.remote_serial',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\remote_serial.py',
'PYMODULE'),
('base.rom_handler',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rom_handler.py',
'PYMODULE'),
('base.rt_settings',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rt_settings.py',
'PYMODULE'),
('base.rtk_flash_type',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rtk_flash_type.py',
'PYMODULE'),
('base.rtk_logging',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rtk_logging.py',
'PYMODULE'),
('base.rtk_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\rtk_utils.py',
'PYMODULE'),
('base.sense_status',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\sense_status.py',
'PYMODULE'),
('base.spic_addr_mode',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\spic_addr_mode.py',
'PYMODULE'),
('base.sys_utils',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\sys_utils.py',
'PYMODULE'),
('base.version',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\base\\version.py',
'PYMODULE'),
('base64',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\base64.py',
'PYMODULE'),
('bisect',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bisect.py',
'PYMODULE'),
('bz2',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\bz2.py',
'PYMODULE'),
('calendar',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\calendar.py',
'PYMODULE'),
('colorama',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\__init__.py',
'PYMODULE'),
('colorama.ansi',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\ansi.py',
'PYMODULE'),
('colorama.ansitowin32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\ansitowin32.py',
'PYMODULE'),
('colorama.initialise',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\initialise.py',
'PYMODULE'),
('colorama.win32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\win32.py',
'PYMODULE'),
('colorama.winterm',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\colorama\\winterm.py',
'PYMODULE'),
('contextlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextlib.py',
'PYMODULE'),
('contextvars',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\contextvars.py',
'PYMODULE'),
('copy',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\copy.py',
'PYMODULE'),
('csv',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\csv.py',
'PYMODULE'),
('ctypes',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ctypes\\__init__.py',
'PYMODULE'),
('ctypes._endian',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ctypes\\_endian.py',
'PYMODULE'),
('ctypes.wintypes',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ctypes\\wintypes.py',
'PYMODULE'),
('dataclasses',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dataclasses.py',
'PYMODULE'),
('datetime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\datetime.py',
'PYMODULE'),
('decimal',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\decimal.py',
'PYMODULE'),
('dis',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\dis.py',
'PYMODULE'),
('email',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\__init__.py',
'PYMODULE'),
('email._encoded_words',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_encoded_words.py',
'PYMODULE'),
('email._header_value_parser',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_header_value_parser.py',
'PYMODULE'),
('email._parseaddr',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_parseaddr.py',
'PYMODULE'),
('email._policybase',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\_policybase.py',
'PYMODULE'),
('email.base64mime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\base64mime.py',
'PYMODULE'),
('email.charset',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\charset.py',
'PYMODULE'),
('email.contentmanager',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\contentmanager.py',
'PYMODULE'),
('email.encoders',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\encoders.py',
'PYMODULE'),
('email.errors',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\errors.py',
'PYMODULE'),
('email.feedparser',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\feedparser.py',
'PYMODULE'),
('email.generator',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\generator.py',
'PYMODULE'),
('email.header',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\header.py',
'PYMODULE'),
('email.headerregistry',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\headerregistry.py',
'PYMODULE'),
('email.iterators',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\iterators.py',
'PYMODULE'),
('email.message',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\message.py',
'PYMODULE'),
('email.parser',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\parser.py',
'PYMODULE'),
('email.policy',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\policy.py',
'PYMODULE'),
('email.quoprimime',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\quoprimime.py',
'PYMODULE'),
('email.utils',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\email\\utils.py',
'PYMODULE'),
('fnmatch',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fnmatch.py',
'PYMODULE'),
('fractions',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\fractions.py',
'PYMODULE'),
('getopt',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\getopt.py',
'PYMODULE'),
('gettext',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gettext.py',
'PYMODULE'),
('glob',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\glob.py',
'PYMODULE'),
('gzip',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\gzip.py',
'PYMODULE'),
('hashlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\hashlib.py',
'PYMODULE'),
('importlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\__init__.py',
'PYMODULE'),
('importlib._abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_abc.py',
'PYMODULE'),
('importlib._bootstrap',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap.py',
'PYMODULE'),
('importlib._bootstrap_external',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\_bootstrap_external.py',
'PYMODULE'),
('importlib.abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\abc.py',
'PYMODULE'),
('importlib.machinery',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\machinery.py',
'PYMODULE'),
('importlib.metadata',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\__init__.py',
'PYMODULE'),
('importlib.metadata._adapters',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_adapters.py',
'PYMODULE'),
('importlib.metadata._collections',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_collections.py',
'PYMODULE'),
('importlib.metadata._functools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_functools.py',
'PYMODULE'),
('importlib.metadata._itertools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_itertools.py',
'PYMODULE'),
('importlib.metadata._meta',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_meta.py',
'PYMODULE'),
('importlib.metadata._text',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\metadata\\_text.py',
'PYMODULE'),
('importlib.readers',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\readers.py',
'PYMODULE'),
('importlib.resources',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\__init__.py',
'PYMODULE'),
('importlib.resources._adapters',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_adapters.py',
'PYMODULE'),
('importlib.resources._common',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_common.py',
'PYMODULE'),
('importlib.resources._itertools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_itertools.py',
'PYMODULE'),
('importlib.resources._legacy',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\_legacy.py',
'PYMODULE'),
('importlib.resources.abc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\abc.py',
'PYMODULE'),
('importlib.resources.readers',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\resources\\readers.py',
'PYMODULE'),
('importlib.util',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\importlib\\util.py',
'PYMODULE'),
('inspect',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\inspect.py',
'PYMODULE'),
('ipaddress',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\ipaddress.py',
'PYMODULE'),
('json',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\__init__.py',
'PYMODULE'),
('json.decoder',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\decoder.py',
'PYMODULE'),
('json.encoder',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\encoder.py',
'PYMODULE'),
('json.scanner',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\json\\scanner.py',
'PYMODULE'),
('logging',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\logging\\__init__.py',
'PYMODULE'),
('lzma',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\lzma.py',
'PYMODULE'),
('numbers',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\numbers.py',
'PYMODULE'),
('opcode',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\opcode.py',
'PYMODULE'),
('pathlib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pathlib.py',
'PYMODULE'),
('pickle',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pickle.py',
'PYMODULE'),
('pprint',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\pprint.py',
'PYMODULE'),
('pyDes',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\pyDes.py',
'PYMODULE'),
('py_compile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\py_compile.py',
'PYMODULE'),
('quopri',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\quopri.py',
'PYMODULE'),
('random',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\random.py',
'PYMODULE'),
('selectors',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\selectors.py',
'PYMODULE'),
('serial',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\__init__.py',
'PYMODULE'),
('serial.serialcli',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialcli.py',
'PYMODULE'),
('serial.serialjava',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialjava.py',
'PYMODULE'),
('serial.serialposix',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialposix.py',
'PYMODULE'),
('serial.serialutil',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialutil.py',
'PYMODULE'),
('serial.serialwin32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\serialwin32.py',
'PYMODULE'),
('serial.tools',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\__init__.py',
'PYMODULE'),
('serial.tools.list_ports',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports.py',
'PYMODULE'),
('serial.tools.list_ports_common',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_common.py',
'PYMODULE'),
('serial.tools.list_ports_linux',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_linux.py',
'PYMODULE'),
('serial.tools.list_ports_osx',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_osx.py',
'PYMODULE'),
('serial.tools.list_ports_posix',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_posix.py',
'PYMODULE'),
('serial.tools.list_ports_windows',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\tools\\list_ports_windows.py',
'PYMODULE'),
('serial.win32',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\serial\\win32.py',
'PYMODULE'),
('shutil',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\shutil.py',
'PYMODULE'),
('signal',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\signal.py',
'PYMODULE'),
('socket',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\socket.py',
'PYMODULE'),
('statistics',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\statistics.py',
'PYMODULE'),
('string',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\string.py',
'PYMODULE'),
('stringprep',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\stringprep.py',
'PYMODULE'),
('subprocess',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\subprocess.py',
'PYMODULE'),
('tarfile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tarfile.py',
'PYMODULE'),
('tempfile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tempfile.py',
'PYMODULE'),
('textwrap',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\textwrap.py',
'PYMODULE'),
('threading',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\threading.py',
'PYMODULE'),
('token',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\token.py',
'PYMODULE'),
('tokenize',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tokenize.py',
'PYMODULE'),
('tracemalloc',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\tracemalloc.py',
'PYMODULE'),
('typing',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\typing.py',
'PYMODULE'),
('urllib',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\__init__.py',
'PYMODULE'),
('urllib.parse',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\urllib\\parse.py',
'PYMODULE'),
('version_info',
'C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\version_info.py',
'PYMODULE'),
('zipfile',
'C:\\Users\\wongyiekheng\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\zipfile.py',
'PYMODULE')])

Binary file not shown.

BIN
build/flash/flash.pkg Normal file

Binary file not shown.

View File

@ -0,0 +1,29 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean this module is required for running your program. Python and
Python 3rd-party packages include a lot of conditional or optional modules. For
example the module 'ntpath' only exists on Windows, whereas the module
'posixpath' only exists on Posix systems.
Types if import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional)
missing module named org - imported by pickle (optional)
missing module named posix - imported by os (conditional, optional), posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional)
missing module named resource - imported by posix (top-level)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional)
missing module named termios - imported by serial.serialposix (top-level)
missing module named fcntl - imported by subprocess (optional), serial.serialposix (top-level)
missing module named 'System.IO' - imported by serial.serialcli (top-level)
missing module named System - imported by serial.serialcli (top-level)
missing module named 'org.python' - imported by copy (optional)
missing module named _posixsubprocess - imported by subprocess (conditional)

8402
build/flash/xref-flash.html Normal file

File diff suppressed because it is too large Load Diff

25
changelog.txt Normal file
View File

@ -0,0 +1,25 @@
ChangeLog:
20250218 v1.0.0.1 (1) Support erase user area
(2) Support chip erase before download
(3) Add version info
20250220 v1.0.0.2 Tune command args
20250221 v1.0.0.3 (1) Fix log-file output bug
(2) Tune log format
(3) Add FileVersion in FileVersionInfo
20250321 v1.0.1.0 (1) Support linux images download
(2) Optimize request timeout
(3) Support check flash block protection before process flash
20250401 v1.0.1.1 (1) Check and program otp for flash size >=16MB
(2) Fix dtr/rts level unexpectedly changed issue when open/close serial port
20250408 v1.0.1.2 Fix nand flash download error with bad block
20250423 v1.0.1.3 (1) Fix download fail in 4byte address mode
(2) Supported otp about flash size >=16MB work for download
20250605 v1.0.2.0 Seperate flashloaders from flash.exe
20250701 v1.0.3.0 (1) Support compatibility with MinGW path format
(2) Support customized DTR/RTS timing for reset/reburn
20250703 v1.1.0.0 Support 1-N download/erase
20251105 v1.1.1.0 (1) Support for remote server port download
(2) Set PostProcess as reset after flashing finished
(3) Add no_reset param
(4) Change some log level
(5) Rename flashloader folder with Devices

470
flash.py Normal file
View File

@ -0,0 +1,470 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
import os
import sys
import argparse
import base64
import re
import threading
from copy import deepcopy
from base import *
import version_info
MinSupportedDeviceProfileMajorVersion = 1
MinSupportedDeviceProfileMinorVersion = 1
setting_file = "Settings.json"
def convert_mingw_path_to_windows(mingw_path):
drive_match = re.match(r'^/([a-zA-Z])/', mingw_path)
if drive_match:
drive_letter = drive_match.group(1).upper() + ":\\"
windows_path_tail = mingw_path[3:]
else:
drive_letter = ""
windows_path_tail = mingw_path
windows_path_tail = windows_path_tail.replace('/', '\\')
windows_path = drive_letter + windows_path_tail
return windows_path
def sys_exit(logger, status, ret):
if status:
logger.info(f"Finished PASS") # customized, do not modify
sys.exit(0)
else:
logger.error(f"Finished FAIL: {ret}") # customized, do not modify
sys.exit(1)
def decoder_partition_string(partition_table_base64):
try:
if partition_table_base64 is None:
return None
partition_value = base64.b64decode(partition_table_base64).decode("utf-8")
partition_list = json.loads(partition_value)
return partition_list
except Exception as err:
raise argparse.ArgumentTypeError("Invalid partition table format with base64") from err
# --- add remote server params ---
def flash_process_entry(profile_info, serial_port, serial_baudrate, image_dir, settings, images_info,
chip_erase,
memory_type, memory_info, download,
log_level, log_f,
remote_server=None, remote_port=None, remote_password=None):
logger = create_logger(serial_port, log_level=log_level, file=log_f)
ameba = Ameba(profile_info, serial_port, serial_baudrate, image_dir, settings, logger,
download_img_info=images_info,
chip_erase=chip_erase,
memory_type=memory_type,
erase_info=memory_info,
remote_server=remote_server,
remote_port=remote_port,
remote_password=remote_password)
if download:
# download
if not ameba.check_protocol_for_download():
ret = ErrType.SYS_PROTO
sys_exit(logger, False, ret)
ret, is_reburn = ameba.check_supported_flash_size(memory_type)
if ret != ErrType.OK:
logger.error(f"Check supported flash size fail")
sys_exit(logger, False, ret)
if is_reburn:
ameba.__del__()
# reset with remote params
ameba = Ameba(profile_info, serial_port, serial_baudrate, image_dir, settings, logger,
download_img_info=images_info,
chip_erase=chip_erase,
memory_type=memory_type,
erase_info=memory_info,
remote_server=remote_server,
remote_port=remote_port,
remote_password=remote_password)
logger.info(f"Image download start...") # customized, do not modify
ret = ameba.prepare()
if ret != ErrType.OK:
logger.error("Download prepare fail")
sys_exit(logger, False, ret)
ret = ameba.verify_images()
if ret != ErrType.OK:
sys_exit(logger, False, ret)
if not ameba.is_all_ram:
ret = ameba.post_verify_images()
if ret != ErrType.OK:
sys_exit(logger, False, ret)
if not ameba.is_all_ram:
flash_status = FlashBPS()
ret = ameba.check_and_process_flash_lock(flash_status)
if ret != ErrType.OK:
logger.error("Download image fail")
sys_exit(logger, False, ret)
ret = ameba.download_images()
if ret != ErrType.OK:
logger.error("Download image fail")
sys_exit(logger, False, ret)
if (not ameba.is_all_ram) and flash_status.need_unlock:
logger.info("Restore the flash block protection...")
ret = ameba.lock_flash(flash_status.protection)
if ret != ErrType.OK:
logger.error(f"Fail to restore the flash block protection")
sys_exit(logger, False, ret)
ret = ameba.post_process()
if ret != ErrType.OK:
logger.error("Post process fail")
sys_exit(logger, False, ret)
else:
# erase
ret = ameba.prepare()
if ret != ErrType.OK:
logger.error("Erase prepare fail")
sys_exit(logger, False, ret)
if chip_erase:
ret = ameba.erase_flash_chip()
if ret != ErrType.OK:
logger.error("Chip erase fail")
sys_exit(logger, False, ret)
sys_exit(logger, True, ret)
ret = ameba.validate_config_for_erase()
if ret != ErrType.OK:
sys_exit(logger, False, ret)
ret = ameba.post_validate_config_for_erase()
if ret != ErrType.OK:
sys_exit(logger, False, ret)
if (not profile_info.is_ram_address(memory_info.start_address)):
flash_status = FlashBPS()
ret = ameba.check_and_process_flash_lock(flash_status)
if ret != ErrType.OK:
logger.error("Erase fail")
sys_exit(logger, False, ret)
ret = ameba.erase_flash()
if ret != ErrType.OK:
logger.error(f"Erase {memory_type} failed")
sys_exit(logger, False, ret)
if (not profile_info.is_ram_address(memory_info.start_address)) and flash_status.need_unlock:
logger.info("Restore the flash block protection...")
ret = ameba.lock_flash(flash_status.protection)
if ret != ErrType.OK:
logger.error(f"Fail to restore the flash block protection")
sys_exit(logger, False, ret)
sys_exit(logger, True, ret)
def main(argc, argv):
parser = argparse.ArgumentParser(description=None)
parser.add_argument('-d', '--download', action='store_true', help='download images')
parser.add_argument('-f', '--profile', type=str, help='device profile')
parser.add_argument('-p', '--port', nargs="+", help='serial port')
parser.add_argument('-b', '--baudrate', type=int, help='serial port baud rate')
parser.add_argument('-i', '--image', type=str, help='single image')
parser.add_argument('-r', '--image-dir', type=str, help='image directory')
parser.add_argument('-a', '--start-address', type=str, help='start address, hex')
parser.add_argument('-n', '--end-address', type=str, help='end address, hex')
parser.add_argument('-z', '--size', type=int, help='size in KB')
parser.add_argument('-m', '--memory-type', choices=['nor', 'nand', 'ram'], default="nor",
help='specified memory type')
parser.add_argument('-e', '--erase', action='store_true', help='erase flash')
parser.add_argument('-o', '--log-file', type=str, help='output log file with path')
parser.add_argument('-v', '--version', action='version', version=f'%(prog)s {version_info.version}')
parser.add_argument('--chip-erase', action='store_true', help='chip erase')
parser.add_argument('--log-level', default='info', help='log level')
parser.add_argument('--partition-table', help="layout info, list")
parser.add_argument('--remote-server', type=str, help='remote serial server IP address')
parser.add_argument('--remote-password', type=str, help='remote serial server validation password')
parser.add_argument('--no-reset', action='store_true', help='do not reset after flashing finished')
args = parser.parse_args()
download = args.download
profile = args.profile
image = args.image
image_dir = args.image_dir
chip_erase = args.chip_erase
serial_ports = args.port
serial_baudrate = args.baudrate
log_level = args.log_level.upper()
log_file = args.log_file
erase = args.erase
start_addr = args.start_address
end_addr = args.end_address
size = args.size
mem_t = args.memory_type
partition_table = decoder_partition_string(args.partition_table)
remote_server = args.remote_server
remote_port = 58916
remote_password = args.remote_password
no_reset = args.no_reset
if mem_t is not None:
if mem_t == "nand":
memory_type = MemoryInfo.MEMORY_TYPE_NAND
elif mem_t == "ram":
memory_type = MemoryInfo.MEMORY_TYPE_RAM
else:
memory_type = MemoryInfo.MEMORY_TYPE_NOR
else:
memory_type = None
if log_file is not None:
log_path = os.path.dirname(log_file)
if log_path:
if not os.path.exists(log_path):
os.makedirs(log_path, exist_ok=True)
log_f = log_file
else:
log_f = os.path.join(os.getcwd(), log_file)
else:
log_f = None
logger = create_logger("main", log_level=log_level, file=log_f)
if log_file is not None:
logger.info(f"Log file: {log_file}")
logger.info(f"Flash Version: {version_info.version}")
if remote_server:
logger.info(f"Using remote serial server: {remote_server}:{remote_port}")
if profile is None:
logger.error('Invalid arguments, no device profile specified')
parser.print_usage()
sys.exit(1)
if not os.path.exists(profile):
logger.error("Device profile '" + profile + "' does not exist")
sys.exit(1)
logger.info(f'Device profile: {profile}')
if serial_ports is None:
logger.error('Invalid arguments, no serial port specified')
parser.print_usage()
sys.exit(1)
logger.info(f'Serial port: {serial_ports}')
if serial_baudrate is None:
logger.error('Invalid arguments, no serial baudrate specified')
parser.print_usage()
sys.exit(1)
logger.info(f'Baudrate: {serial_baudrate}')
if all([download, erase]):
logger.warning("Download and erase are set true, only do image download ")
elif not (download or erase or chip_erase):
logger.error("Download or erase or chip-erase should be set")
sys.exit(1)
memory_info = None
images_info = None
if download:
# download
if (image is None) and (image_dir is None) and (partition_table is None):
logger.error('Invalid arguments, no image or image_dir input')
parser.print_usage()
sys.exit(1)
if image is not None:
download_img_info = ImageInfo()
if not os.path.exists(image):
logger.error(f"Image {image} does not exist")
sys.exit(1)
download_img_info.image_name = image
download_img_info.description = os.path.basename(image)
if memory_type is None:
logger.error(f"Memory type is required for single image download")
sys.exit(1)
if start_addr is None:
logger.error(f"Start address is required for single image download")
sys.exit(1)
try:
start_address = int(start_addr, 16)
except Exception as err:
logger.error(f"Start address is invalid: {err}")
sys.exit(1)
download_img_info.start_address = start_address
if memory_type == MemoryInfo.MEMORY_TYPE_NAND:
if end_addr is None:
logger.error(f"End address is required for nand flash download")
sys.exit(1)
try:
end_address = int(end_addr, 16)
except Exception as err:
logger.error(f"End address is invalid: {err}")
sys.exit(1)
else:
end_address = start_address + os.path.getsize(image)
download_img_info.end_address = end_address
download_img_info.memory_type = memory_type
download_img_info.mandatory = True
images_info = [download_img_info]
elif partition_table is not None:
images_info = []
for img_info in partition_table:
img_json = ImageInfo(** img_info)
if sys.platform == "win32":
img_p = convert_mingw_path_to_windows(img_json.image_name)
img_json.image_name = img_p
img_json.description = os.path.basename(img_json.image_name)
images_info.append(img_json)
else:
images_info = None
if not os.path.exists(image_dir):
logger.error(f"Image directory {image_dir} does not exist")
sys.exit(1)
logger.info(f'Image dir: {image_dir}')
if images_info:
logger.info(f'Image info:')
for img_info in images_info:
for key, value in img_info.__repr__().items():
if key == "ImageName":
key = "Image"
logger.info(f'> {key}: {value}')
else:
# erase
if all([chip_erase, erase]):
logger.warning(f"Both chip erase and erase are enabled, do chip erase only")
if not chip_erase:
memory_info = MemoryInfo()
if start_addr is None:
logger.error(f"Start address is required for erase flash")
sys.exit(1)
try:
start_address = int(start_addr, 16)
except Exception as err:
logger.error(f"Start address is invalid: {err}")
sys.exit(1)
memory_info.start_address = start_address
if memory_type is None:
logger.error("Memory type is required for erase")
sys.exit(1)
memory_info.memory_type = memory_type
if memory_type == MemoryInfo.MEMORY_TYPE_NAND:
if end_addr is None:
logger.error(f"End address is required for nand flash download")
sys.exit(1)
else:
if size is None:
logger.error(f"Erase size is required")
sys.exit(1)
if end_addr:
try:
end_address = int(end_addr, 16)
except Exception as err:
logger.error(f"End address is invalid: {err}")
sys.exit(1)
else:
end_address = 0
memory_info.size_in_kbyte = size
if end_address == 0:
end_address = start_address + size
memory_info.end_address = end_address
if chip_erase:
logger.info(f"Chip erase: {chip_erase}")
if memory_type is None:
logger.warning("Memory type is required for chip erase")
sys.exit(1)
if memory_type != MemoryInfo.MEMORY_TYPE_NOR:
logger.warning("Memory type should be 'nor' for chip erase")
else:
logger.info(f"Chip erase: False")
# check device profile
try:
profile_json = JsonUtils.load_from_file(profile)
if profile_json is None:
logger.error(f"Fail to load device profile {profile}")
sys.exit(1)
profile_info = RtkDeviceProfile(**profile_json)
ver = profile_info.get_version()
if ver.major >= MinSupportedDeviceProfileMajorVersion and ver.minor >= MinSupportedDeviceProfileMinorVersion and profile_info.device_id != 0:
logger.info(f"Device profile {profile} loaded")
else:
logger.error(f"Fail to load device profile {profile}, unsupported version {ver.__repr__()}")
sys.exit(1)
except Exception as err:
logger.error(f"Load device profile {profile} exception: {err}")
sys.exit(1)
# load settings
setting_path = os.path.realpath(os.path.join(RtkUtils.get_executable_root_path(), setting_file))
logger.info(f"Settings path: {setting_path}")
try:
if os.path.exists(setting_path):
dt = JsonUtils.load_from_file(setting_path, need_decrypt=False)
settings = RtSettings(** dt)
else:
logger.debug(f"{setting_file} not exists!")
settings = RtSettings(**{})
except Exception as err:
logger.error(f"Load settings exception: {err}")
settings = RtSettings(** {})
# save Setting.json
try:
if no_reset:
settings.post_process = "NONE"
else:
settings.post_process = "RESET"
JsonUtils.save_to_file(setting_path, settings.__repr__())
except Exception as err:
logger.debug(f"save {setting_file} exception: {err}")
threads_list = []
for sp in serial_ports:
flash_thread = threading.Thread(target=flash_process_entry, args=(
profile_info, sp, serial_baudrate, image_dir, settings, deepcopy(images_info), chip_erase,
memory_type, memory_info, download, log_level, log_f,
remote_server, remote_port, remote_password))
threads_list.append(flash_thread)
flash_thread.start()
for thred in threads_list:
thred.join()
logger.info(f"All flash threads have completed")
if __name__ == "__main__":
main(len(sys.argv), sys.argv[1:])

81
flash.spec Normal file
View File

@ -0,0 +1,81 @@
# -*- mode: python ; coding: utf-8 -*-
import sys
from pathlib import Path
sys.path.insert(0, str((Path("__name__").parent)))
from tempfile import NamedTemporaryFile
from version_info import version
temp_version_file=Path("version.tmp")
temp_version_file.write_text(
f"""# UTF-8 encoding
# UTF-8
#
# Fields to define the version info for a Windows executable
VSVersionInfo(
ffi=FixedFileInfo(
filevers=({version.replace(".",",")}), # 文件版本号
prodvers=({version.replace(".",",")}), # 产品版本号
mask=0x3f,
flags=0x0,
OS=0x40004,
fileType=0x1,
subtype=0x0,
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'040904B0',
[StringStruct(u'CompanyName', u'Realtek Semiconductor Corp.'),
StringStruct(u'FileDescription', u'Flash Tool for Realtek Ameba SoCs'),
StringStruct(u'FileVersion', u'{version}'),
StringStruct(u'InternalName', u'flash.exe'),
StringStruct(u'LegalCopyright', u'Copyright (c) 2025 Realtek Semiconductor Corp.'),
StringStruct(u'OriginalFilename', u'flash.exe'),
StringStruct(u'ProductName', u'Ameba Flash Tool'),
StringStruct(u'ProductVersion', u'{version}')])
]),
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
]
)
""",encoding='utf-8')
a = Analysis(
['flash.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='flash',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
version=temp_version_file.name,
)
os.remove(temp_version_file.name)

BIN
fw/all_app.bin Normal file

Binary file not shown.

BIN
fw/all_app_en.bin Normal file

Binary file not shown.

BIN
fw/amebapro3_app.bin Normal file

Binary file not shown.

BIN
fw/amebapro3_boot.bin Normal file

Binary file not shown.

0
fw/ap_app.bin Normal file
View File

BIN
fw/cert.bin Normal file

Binary file not shown.

0
fw/fp_app.bin Normal file
View File

BIN
fw/fw_en.bin Normal file

Binary file not shown.

BIN
fw/fw_plain.bin Normal file

Binary file not shown.

BIN
fw/manifest.bin Normal file

Binary file not shown.

BIN
fw/np_app.bin Normal file

Binary file not shown.

BIN
fw/np_boot.bin Normal file

Binary file not shown.

0
fw/vp_app.bin Normal file
View File

223
package_pro3_exe.py Normal file
View File

@ -0,0 +1,223 @@
#!/usr/bin/env python3
"""
Helper script to bundle pro3_uart.py into an executable together with the
files that flash.py expects.
Usage:
python package_pro3_exe.py
Prerequisites:
pip install pyinstaller
"""
from __future__ import annotations
import shutil
import sys
from pathlib import Path
import re
try:
from PyInstaller import __main__ as pyinstaller_main
except ImportError as exc:
print("PyInstaller is required. Install it with 'pip install pyinstaller'.")
raise SystemExit(1) from exc
APP_ROOT = Path(__file__).resolve().parent
PROJECT_BASE_NAME = "pro3_uart"
def derive_version_from_folder() -> str:
root_name = APP_ROOT.name
match = re.search(r"_v([0-9][0-9.\-_]*)$", root_name, re.IGNORECASE)
if not match:
return ""
return match.group(1)
def read_version_file() -> tuple[str, str]:
version_file = APP_ROOT / "version_info.py"
if not version_file.exists():
return "", ""
namespace: dict[str, str] = {}
try:
with version_file.open("r", encoding="utf-8") as handle:
exec(handle.read(), namespace)
except Exception:
return "", ""
canonical = str(namespace.get("version", "")).strip()
display = str(namespace.get("display_version", "")).strip()
return canonical, display
def write_version_file(version: str, display: str) -> None:
version_file = APP_ROOT / "version_info.py"
template = f'''#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
version = "{version}"
display_version = "{display}"
'''
with version_file.open("w", encoding="utf-8") as handle:
handle.write(template)
def determine_version_tag() -> str:
folder_version = derive_version_from_folder()
stored_canonical, stored_display = read_version_file()
chosen = folder_version or stored_display or stored_canonical
sanitized = re.sub(r"[^0-9A-Za-z._-]", "_", chosen)
if not sanitized:
sanitized = "unknown"
canonical = canonicalize_version_number(sanitized)
if canonical != stored_canonical or sanitized != stored_display:
write_version_file(canonical, sanitized)
return sanitized
def canonicalize_version_number(tag: str) -> str:
cleaned = tag.replace("-", ".").replace("_", ".")
parts = [re.sub(r"\D+", "", chunk) or "0" for chunk in cleaned.split(".") if chunk]
if not parts:
parts = ["0"]
while len(parts) < 4:
parts.append("0")
return ".".join(parts[:4])
VERSION_TAG = determine_version_tag()
RESOURCE_VERSION = canonicalize_version_number(VERSION_TAG)
DIST_NAME = f"{PROJECT_BASE_NAME}_v{VERSION_TAG}"
DIST_DIR = APP_ROOT / "dist" / DIST_NAME
BUILD_DIR = APP_ROOT / "build"
FLASH_SPEC = APP_ROOT / "flash.spec"
FLASH_EXE_NAME = "flash.exe"
FLASH_OUTPUT_PATHS = [
APP_ROOT / "dist" / FLASH_EXE_NAME,
APP_ROOT / "dist" / "flash" / FLASH_EXE_NAME,
]
RESOURCE_ITEMS = [
("base", "base"),
("devices", "devices"),
("fw", "fw"),
("Reburn.cfg", "Reburn.cfg"),
("Reset.cfg", "Reset.cfg"),
("Settings.json", "Settings.json"),
("pylink", "pylink"),
]
PYLINK_DIR = APP_ROOT / "pylink"
JLINK_DLL_NAME = "JLinkARM.dll"
JLINK_DLL_SOURCE = PYLINK_DIR / JLINK_DLL_NAME
def clean_path(path: Path) -> None:
if path.exists():
shutil.rmtree(path)
def cleanup_old_version_specs() -> None:
pattern = f"{PROJECT_BASE_NAME}_v*.spec"
for spec_path in APP_ROOT.glob(pattern):
try:
spec_path.unlink()
print(f"Removed outdated spec: {spec_path.name}")
except Exception as exc:
print(f"Warning: unable to remove {spec_path}: {exc}")
def run_pyinstaller_for_pro3() -> None:
if DIST_DIR.exists():
shutil.rmtree(DIST_DIR)
clean_path(BUILD_DIR)
args = [
"--noconfirm",
"--clean",
"--windowed",
"--onedir",
"--name",
DIST_NAME,
str(APP_ROOT / "pro3_uart.py"),
]
print("Running PyInstaller...")
pyinstaller_main.run(args)
def run_pyinstaller_for_flash() -> None:
if not FLASH_SPEC.exists():
raise SystemExit(f"flash.spec not found at {FLASH_SPEC}")
clean_path(BUILD_DIR)
print("Building flash.exe via flash.spec...")
pyinstaller_main.run(["--noconfirm", str(FLASH_SPEC)])
def copy_resources() -> None:
if not DIST_DIR.exists():
raise SystemExit(f"PyInstaller output not found: {DIST_DIR}")
for src, dest in RESOURCE_ITEMS:
src_path = APP_ROOT / src
dest_path = DIST_DIR / dest
if not src_path.exists():
print(f"Warning: resource '{src}' not found, skipping.")
continue
if src_path.is_dir():
if dest_path.exists():
shutil.rmtree(dest_path)
shutil.copytree(src_path, dest_path)
else:
dest_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src_path, dest_path)
print(f"Copied {src_path} -> {dest_path}")
if src == "pylink":
dll_path = dest_path / JLINK_DLL_NAME
if not dll_path.exists():
raise SystemExit(f"{JLINK_DLL_NAME} was not found in '{src_path}'.")
def copy_flash_executable() -> None:
source = None
for candidate in FLASH_OUTPUT_PATHS:
if candidate.exists():
source = candidate
break
if not source:
print("Warning: flash.exe build not found, skipping copy.")
return
dest = DIST_DIR / FLASH_EXE_NAME
shutil.copy2(source, dest)
print(f"Copied {source} -> {dest}")
def verify_jlink_dll() -> None:
if not JLINK_DLL_SOURCE.exists():
raise SystemExit(
f"{JLINK_DLL_NAME} is required but missing from '{PYLINK_DIR}'. "
"Copy the DLL into the pylink folder before packaging."
)
def main() -> None:
cleanup_old_version_specs()
verify_jlink_dll()
run_pyinstaller_for_pro3()
run_pyinstaller_for_flash()
copy_resources()
copy_flash_executable()
exe_path = DIST_DIR / f"{DIST_NAME}.exe"
if exe_path.exists():
print(f"\nBuild complete: {exe_path}")
else:
print("\nBuild complete. Exe is located inside:", DIST_DIR)
if __name__ == "__main__":
main()

2783
pro3_uart.py Normal file

File diff suppressed because it is too large Load Diff

44
pro3_uart_v1.2.2.spec Normal file
View File

@ -0,0 +1,44 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['C:\\D_Drive\\A-Important\\work\\Pro3_control_panel_v1.2.2\\pro3_uart.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='pro3_uart_v1.2.2',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='pro3_uart_v1.2.2',
)

BIN
pylink/JLinkARM.dll Normal file

Binary file not shown.

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
// python3.11.4
pyDes==2.0.1
colorama==0.4.6
pyserial==3.5

8
version_info.py Normal file
View File

@ -0,0 +1,8 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 Realtek Semiconductor Corp.
# SPDX-License-Identifier: Apache-2.0
version = "1.2.2.0"
display_version = "1.2.2"