From 6bb2b922dd15dfa268be6b74e12ab6f97970a40b Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Sat, 6 Apr 2024 17:56:46 +0300 Subject: [PATCH] feat(espefuse): Adds support extend efuse table by user CSV file --- docs/en/espefuse/index.rst | 53 ++++ espefuse/__init__.py | 24 +- espefuse/efuse/csv_table_parser.py | 266 ++++++++++++++++++ .../efuse/esp32/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32/fields.py | 11 +- espefuse/efuse/esp32/mem_definition.py | 4 +- .../efuse/esp32c2/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32c2/fields.py | 11 +- espefuse/efuse/esp32c2/mem_definition.py | 4 +- .../efuse/esp32c3/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32c3/fields.py | 11 +- espefuse/efuse/esp32c3/mem_definition.py | 4 +- .../efuse/esp32c5/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32c5/fields.py | 11 +- espefuse/efuse/esp32c5/mem_definition.py | 4 +- .../esp32c5beta3/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32c5beta3/fields.py | 11 +- espefuse/efuse/esp32c5beta3/mem_definition.py | 4 +- .../efuse/esp32c6/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32c6/fields.py | 11 +- espefuse/efuse/esp32c6/mem_definition.py | 4 +- .../esp32c61/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32c61/fields.py | 11 +- espefuse/efuse/esp32c61/mem_definition.py | 4 +- .../efuse/esp32h2/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32h2/fields.py | 11 +- espefuse/efuse/esp32h2/mem_definition.py | 4 +- .../esp32h2beta1/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32h2beta1/fields.py | 11 +- espefuse/efuse/esp32h2beta1/mem_definition.py | 4 +- .../efuse/esp32p4/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32p4/fields.py | 11 +- espefuse/efuse/esp32p4/mem_definition.py | 4 +- .../efuse/esp32s2/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32s2/fields.py | 11 +- espefuse/efuse/esp32s2/mem_definition.py | 4 +- .../efuse/esp32s3/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32s3/fields.py | 11 +- espefuse/efuse/esp32s3/mem_definition.py | 4 +- .../esp32s3beta2/emulate_efuse_controller.py | 2 +- espefuse/efuse/esp32s3beta2/fields.py | 11 +- espefuse/efuse/esp32s3beta2/mem_definition.py | 4 +- espefuse/efuse/mem_definition_base.py | 64 ++++- test/images/efuse/esp_efuse_custom_table.csv | 13 + test/test_espefuse.py | 29 ++ 45 files changed, 600 insertions(+), 70 deletions(-) create mode 100644 espefuse/efuse/csv_table_parser.py create mode 100644 test/images/efuse/esp_efuse_custom_table.csv diff --git a/docs/en/espefuse/index.rst b/docs/en/espefuse/index.rst index ba5009123..26e19cb49 100644 --- a/docs/en/espefuse/index.rst +++ b/docs/en/espefuse/index.rst @@ -56,6 +56,7 @@ Optional General Arguments Of Commands - ``--virt`` - For host tests. The tool will work in the virtual mode (without connecting to a chip). - ``--path-efuse-file`` - For host tests. Use it together with ``--virt`` option. The tool will work in the virtual mode (without connecting to a chip) and save eFuse memory to a given file. If the file does not exists the tool creates it. To reset written eFuses just delete the file. Usage: ``--path-efuse-file efuse_memory.bin``. - ``--do-not-confirm`` - Do not pause for confirmation before permanently writing eFuses. Use with caution. If this option is not used, a manual confirmation step is required, you need to enter the word ``BURN`` to continue burning. +- ``--extend-efuse-table`` - CSV file from `ESP-IDF `_ (esp_efuse_custom_table.csv). Virtual mode ^^^^^^^^^^^^ @@ -113,6 +114,58 @@ The example below shows how to use the two commands ``burn_key_digest`` and ``bu burn_key_digest secure_images/ecdsa256_secure_boot_signing_key_v2.pem \ burn_key BLOCK_KEY0 images/efuse/128bit_key.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS +Extend Efuse Table +------------------ + +This tool supports the use of `CSV files `_ from the `ESP-IDF `_ (e.g., ``esp_efuse_custom_table.csv``) to add custom eFuse fields. You can use this argument with any supported commands to access these custom eFuses. + +.. code-block:: none + + > espefuse.py -c esp32 --extend-efuse-table path/esp_efuse_custom_table.csv summary + +Below is an example of an ``esp_efuse_custom_table.csv`` file. This example demonstrates how to define single eFuse fields, ``structured eFuse fields`` and ``non-sequential bit fields``: + +.. code-block:: none + + MODULE_VERSION, EFUSE_BLK3, 56, 8, Module version + DEVICE_ROLE, EFUSE_BLK3, 64, 3, Device role + SETTING_1, EFUSE_BLK3, 67, 6, [SETTING_1_ALT_NAME] Setting 1 + SETTING_2, EFUSE_BLK3, 73, 5, Setting 2 + ID_NUM, EFUSE_BLK3, 140, 8, [MY_ID_NUM] comment + , EFUSE_BLK3, 132, 8, [MY_ID_NUM] comment + , EFUSE_BLK3, 122, 8, [MY_ID_NUM] comment + CUSTOM_SECURE_VERSION, EFUSE_BLK3, 78, 16, Custom secure version + ID_NUMK, EFUSE_BLK3, 150, 8, [MY_ID_NUMK] comment + , EFUSE_BLK3, 182, 8, [MY_ID_NUMK] comment + MY_DATA, EFUSE_BLK3, 190, 10, My data + MY_DATA.FIELD1, EFUSE_BLK3, 190, 7, Field1 + +When you include this CSV file, the tool will generate a new section in the summary called ``User fuses``. + +.. code-block:: none + + User fuses: + MODULE_VERSION (BLOCK3) Module version (56-63) = 0 R/W (0x00) + DEVICE_ROLE (BLOCK3) Device role (64-66) = 0 R/W (0b000) + SETTING_1 (BLOCK3) [SETTING_1_ALT_NAME] Setting 1 (67-72) = 0 R/W (0b000000) + SETTING_2 (BLOCK3) Setting 2 (73-77) = 0 R/W (0b00000) + ID_NUM_0 (BLOCK3) [MY_ID_NUM] comment (140-147) = 0 R/W (0x00) + ID_NUM_1 (BLOCK3) [MY_ID_NUM] comment (132-139) = 0 R/W (0x00) + ID_NUM_2 (BLOCK3) [MY_ID_NUM] comment (122-129) = 0 R/W (0x00) + CUSTOM_SECURE_VERSION (BLOCK3) Custom secure version (78-93) = 0 R/W (0x0000) + ID_NUMK_0 (BLOCK3) [MY_ID_NUMK] comment (150-157) = 0 R/W (0x00) + ID_NUMK_1 (BLOCK3) [MY_ID_NUMK] comment (182-189) = 0 R/W (0x00) + MY_DATA (BLOCK3) My data (190-199) = 0 R/W (0b0000000000) + MY_DATA_FIELD1 (BLOCK3) Field1 (190-196) = 0 R/W (0b0000000) + +You can reference these fields using the names and aliases provided in the CSV file. For non-sequential bits, the names are modified slightly with the addition of _0 and _1 postfixes for every sub-field, to ensure safer handling. + +For the current example, you can reference the custom fields with the following names: MODULE_VERSION, DEVICE_ROLE, SETTING_1, SETTING_2, ID_NUM_0, ID_NUM_1, ID_NUM_2, CUSTOM_SECURE_VERSION, ID_NUMK_0, ID_NUMK_1, MY_DATA, MY_DATA_FIELD1; and alises: SETTING_1_ALT_NAME, MY_ID_NUM_0, MY_ID_NUM_1, MY_ID_NUM_2, MY_ID_NUMK_0, MY_ID_NUMK_1. + +For convenience, the espefuse summary command includes the used bit range of the field in a comment, such as ``(150-157)`` len = 8 bits. + +For more details on the structure and usage of the CSV file, refer to the `eFuse Manager `_ chapter in the ESP-IDF documentation. + Recommendations --------------- diff --git a/espefuse/__init__.py b/espefuse/__init__.py index 6158a3bf0..1ec0e2f23 100755 --- a/espefuse/__init__.py +++ b/espefuse/__init__.py @@ -101,12 +101,20 @@ def get_esp( return esp -def get_efuses(esp, skip_connect=False, debug_mode=False, do_not_confirm=False): +def get_efuses( + esp, + skip_connect=False, + debug_mode=False, + do_not_confirm=False, + extend_efuse_table=None, +): for name in SUPPORTED_CHIPS: if SUPPORTED_CHIPS[name].chip_name == esp.CHIP_NAME: efuse = SUPPORTED_CHIPS[name].efuse_lib return ( - efuse.EspEfuses(esp, skip_connect, debug_mode, do_not_confirm), + efuse.EspEfuses( + esp, skip_connect, debug_mode, do_not_confirm, extend_efuse_table + ), efuse.operations, ) else: @@ -228,6 +236,12 @@ def main(custom_commandline=None, esp=None): "(efuses which disable access to blocks or chip).", action="store_true", ) + init_parser.add_argument( + "--extend-efuse-table", + help="CSV file from ESP-IDF (esp_efuse_custom_table.csv)", + type=argparse.FileType("r"), + default=None, + ) common_args, remaining_args = init_parser.parse_known_args(custom_commandline) debug_mode = common_args.debug @@ -257,7 +271,11 @@ def main(custom_commandline=None, esp=None): # TODO: Require the --port argument in the next major release, ESPTOOL-490 efuses, efuse_operations = get_efuses( - esp, just_print_help, debug_mode, common_args.do_not_confirm + esp, + just_print_help, + debug_mode, + common_args.do_not_confirm, + common_args.extend_efuse_table, ) parser = argparse.ArgumentParser(parents=[init_parser]) diff --git a/espefuse/efuse/csv_table_parser.py b/espefuse/efuse/csv_table_parser.py new file mode 100644 index 000000000..4bebbb02a --- /dev/null +++ b/espefuse/efuse/csv_table_parser.py @@ -0,0 +1,266 @@ +# This file helps to parse CSV eFuse tables +# +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import re +import sys + + +class CSVFuseTable(list): + @classmethod + def from_csv(cls, csv_contents): + res = CSVFuseTable() + lines = csv_contents.splitlines() + + def expand_vars(f): + f = os.path.expandvars(f) + m = re.match(r"(? 1) + for dname in duplicates: + i_count = 0 + for p in res: + if p.field_name != dname: + continue + if len(duplicates.intersection([p.field_name])) != 0: + p.field_name = f"{p.field_name}_{i_count}" + if p.alt_names: + p.alt_names = f"{p.alt_names}_{i_count}" + i_count += 1 + else: + i_count = 0 + + for p in res: + p.field_name = p.field_name.replace(".", "_") + if p.alt_names: + p.alt_names = p.alt_names.replace(".", "_") + res.verify_duplicate_name() + return res + + def verify_duplicate_name(self): + # check on duplicate name + names = [p.field_name for p in self] + names += [name.replace(".", "_") for name in names if "." in name] + duplicates = set(n for n in names if names.count(n) > 1) + + # print sorted duplicate partitions by name + if len(duplicates) != 0: + fl_error = False + for p in self: + field_name = p.field_name + p.group + if field_name != "" and len(duplicates.intersection([field_name])) != 0: + fl_error = True + print( + f"Field at {p.field_name}, {p.efuse_block}, " + f"{p.bit_start}, {p.bit_count} have duplicate field_name" + ) + if fl_error is True: + raise InputError("Field names must be unique") + + def check_struct_field_name(self): + # check that structured fields have a root field + for p in self: + if "." in p.field_name: + name = "" + for sub in p.field_name.split(".")[:-1]: + name = sub if name == "" else name + "." + sub + missed_name = True + for d in self: + if ( + p is not d + and p.efuse_block == d.efuse_block + and name == d.field_name + ): + missed_name = False + if missed_name: + raise InputError(f"{name} is not found") + + def verify(self, type_table=None): + def check(p, n): + left = n.bit_start + right = n.bit_start + n.bit_count - 1 + start = p.bit_start + end = p.bit_start + p.bit_count - 1 + if left <= start <= right: + if left <= end <= right: + return "included in" # [n [p...p] n] + return "intersected with" # [n [p..n]..p] + if left <= end <= right: + return "intersected with" # [p..[n..p] n] + if start <= left and right <= end: + return "wraps" # [p [n...n] p] + return "ok" # [p] [n] or [n] [p] + + def print_error(p, n, state): + raise InputError( + f"Field at {p.field_name}, {p.efuse_block}, {p.bit_start}, {p.bit_count} {state} {n.field_name}, {n.efuse_block}, {n.bit_start}, {n.bit_count}" + ) + + for p in self: + p.verify(type_table) + + self.verify_duplicate_name() + if type_table != "custom_table": + # check will be done for common and custom tables together + self.check_struct_field_name() + + # check for overlaps + for p in self: + for n in self: + if p is not n and p.efuse_block == n.efuse_block: + state = check(p, n) + if state != "ok": + if "." in p.field_name: + name = "" + for sub in p.field_name.split("."): + name = sub if name == "" else name + "." + sub + for d in self: + if ( + p is not d + and p.efuse_block == d.efuse_block + and name == d.field_name + ): + state = check(p, d) + if state == "included in": + break + elif state != "intersected with": + state = "out of range" + print_error(p, d, state) + continue + elif "." in n.field_name: + continue + print_error(p, n, state) + + +class FuseDefinition(object): + def __init__(self): + self.field_name = "" + self.group = "" + self.efuse_block = "" + self.bit_start = None + self.bit_count = None + self.define = None + self.comment = "" + self.alt_names = "" + self.MAX_BITS_OF_BLOCK = 256 + + @classmethod + def from_csv(cls, line): + """Parse a line from the CSV""" + line_w_defaults = line + ",,,," + fields = [f.strip() for f in line_w_defaults.split(",")] + + res = FuseDefinition() + res.field_name = fields[0] + res.efuse_block = res.parse_block(fields[1]) + res.bit_start = res.parse_num(fields[2]) + res.bit_count = res.parse_bit_count(fields[3]) + if res.bit_count is None or res.bit_count == 0: + raise InputError("Field bit_count can't be empty") + res.comment = fields[4].rstrip("\\").rstrip() + res.comment += f" ({res.bit_start}-{res.bit_start + res.bit_count - 1})" + res.alt_names = res.get_alt_names(res.comment) + return res + + def parse_num(self, strval): + if strval == "": + return None + return self.parse_int(strval) + + def parse_bit_count(self, strval): + if strval == "MAX_BLK_LEN": + self.define = strval + return self.MAX_BITS_OF_BLOCK + else: + return self.parse_num(strval) + + def parse_int(self, v): + try: + return int(v, 0) + except ValueError: + raise InputError(f"Invalid field value {v}") + + def parse_block(self, strval): + if strval == "": + raise InputError("Field 'efuse_block' can't be left empty.") + return self.parse_int(strval.lstrip("EFUSE_BLK")) + + def verify(self, type_table): + if self.efuse_block is None: + raise ValidationError(self, "efuse_block field is not set") + if self.bit_count is None: + raise ValidationError(self, "bit_count field is not set") + max_bits = self.MAX_BITS_OF_BLOCK + if self.bit_start + self.bit_count > max_bits: + raise ValidationError( + self, + f"The field is outside the boundaries(max_bits = {max_bits}) of the {self.efuse_block} block", + ) + + def get_bit_count(self, check_define=True): + if check_define is True and self.define is not None: + return self.define + else: + return self.bit_count + + def get_alt_names(self, comment): + result = re.search(r"^\[(.*?)\]", comment) + if result: + return result.group(1) + return "" + + +class InputError(RuntimeError): + def __init__(self, e): + super(InputError, self).__init__(e) + + +class ValidationError(InputError): + def __init__(self, p, message): + super(ValidationError, self).__init__( + f"Entry {p.field_name} invalid: {message}" + ) diff --git a/espefuse/efuse/esp32/emulate_efuse_controller.py b/espefuse/efuse/esp32/emulate_efuse_controller.py index 6771a0b39..03011fa59 100644 --- a/espefuse/efuse/esp32/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) diff --git a/espefuse/efuse/esp32/fields.py b/espefuse/efuse/esp32/fields.py index 7a9c9d46a..c1a625bcb 100644 --- a/espefuse/efuse/esp32/fields.py +++ b/espefuse/efuse/esp32/fields.py @@ -68,9 +68,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32/mem_definition.py b/espefuse/efuse/esp32/mem_definition.py index 7d29a010a..60f30935a 100644 --- a/espefuse/efuse/esp32/mem_definition.py +++ b/espefuse/efuse/esp32/mem_definition.py @@ -89,7 +89,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: self.EFUSES = [] # if MAC_VERSION is set "1", these efuse fields are in BLOCK3: self.CUSTOM_MAC = [] @@ -109,7 +109,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name == "BLOCK1" or efuse.name == "BLOCK2": diff --git a/espefuse/efuse/esp32c2/emulate_efuse_controller.py b/espefuse/efuse/esp32c2/emulate_efuse_controller.py index 26796dff8..a7d4693e4 100644 --- a/espefuse/efuse/esp32c2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c2/emulate_efuse_controller.py @@ -21,7 +21,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32c2/fields.py b/espefuse/efuse/esp32c2/fields.py index bfbcae632..a9fe33cce 100644 --- a/espefuse/efuse/esp32c2/fields.py +++ b/espefuse/efuse/esp32c2/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32c2/mem_definition.py b/espefuse/efuse/esp32c2/mem_definition.py index 7adb0111f..47cd18c04 100644 --- a/espefuse/efuse/esp32c2/mem_definition.py +++ b/espefuse/efuse/esp32c2/mem_definition.py @@ -94,7 +94,7 @@ def get_blocks_for_keys(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -110,7 +110,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in ["BLOCK_KEY0"]: diff --git a/espefuse/efuse/esp32c3/emulate_efuse_controller.py b/espefuse/efuse/esp32c3/emulate_efuse_controller.py index 2d812a10d..fca2f102b 100644 --- a/espefuse/efuse/esp32c3/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c3/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32c3/fields.py b/espefuse/efuse/esp32c3/fields.py index 05914e429..f367540a8 100644 --- a/espefuse/efuse/esp32c3/fields.py +++ b/espefuse/efuse/esp32c3/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32c3/mem_definition.py b/espefuse/efuse/esp32c3/mem_definition.py index 610d64e17..bd13bd773 100644 --- a/espefuse/efuse/esp32c3/mem_definition.py +++ b/espefuse/efuse/esp32c3/mem_definition.py @@ -127,7 +127,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -145,7 +145,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32c5/emulate_efuse_controller.py b/espefuse/efuse/esp32c5/emulate_efuse_controller.py index 40cc06fdc..f81caeb70 100644 --- a/espefuse/efuse/esp32c5/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c5/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32c5/fields.py b/espefuse/efuse/esp32c5/fields.py index c3d44649d..b61ba6077 100644 --- a/espefuse/efuse/esp32c5/fields.py +++ b/espefuse/efuse/esp32c5/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32c5/mem_definition.py b/espefuse/efuse/esp32c5/mem_definition.py index 9a9212681..0520328ba 100644 --- a/espefuse/efuse/esp32c5/mem_definition.py +++ b/espefuse/efuse/esp32c5/mem_definition.py @@ -111,7 +111,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -129,7 +129,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py b/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py index 27816831a..3fdab6f81 100644 --- a/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32c5beta3/fields.py b/espefuse/efuse/esp32c5beta3/fields.py index fc345686e..351d73667 100644 --- a/espefuse/efuse/esp32c5beta3/fields.py +++ b/espefuse/efuse/esp32c5beta3/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32c5beta3/mem_definition.py b/espefuse/efuse/esp32c5beta3/mem_definition.py index f1b99495b..67ffff60e 100644 --- a/espefuse/efuse/esp32c5beta3/mem_definition.py +++ b/espefuse/efuse/esp32c5beta3/mem_definition.py @@ -111,7 +111,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -129,7 +129,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32c6/emulate_efuse_controller.py b/espefuse/efuse/esp32c6/emulate_efuse_controller.py index a9e7d4d4a..47c403ce8 100644 --- a/espefuse/efuse/esp32c6/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c6/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32c6/fields.py b/espefuse/efuse/esp32c6/fields.py index 5e0a449e5..70df55cec 100644 --- a/espefuse/efuse/esp32c6/fields.py +++ b/espefuse/efuse/esp32c6/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32c6/mem_definition.py b/espefuse/efuse/esp32c6/mem_definition.py index 25e4caf01..4574fdf63 100644 --- a/espefuse/efuse/esp32c6/mem_definition.py +++ b/espefuse/efuse/esp32c6/mem_definition.py @@ -111,7 +111,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -129,7 +129,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32c61/emulate_efuse_controller.py b/espefuse/efuse/esp32c61/emulate_efuse_controller.py index 22e4da277..1118daada 100644 --- a/espefuse/efuse/esp32c61/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32c61/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32c61/fields.py b/espefuse/efuse/esp32c61/fields.py index db00fb0eb..5f6fe7b8c 100644 --- a/espefuse/efuse/esp32c61/fields.py +++ b/espefuse/efuse/esp32c61/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32c61/mem_definition.py b/espefuse/efuse/esp32c61/mem_definition.py index 94b57b959..2f8f818a5 100644 --- a/espefuse/efuse/esp32c61/mem_definition.py +++ b/espefuse/efuse/esp32c61/mem_definition.py @@ -111,7 +111,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -129,7 +129,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32h2/emulate_efuse_controller.py b/espefuse/efuse/esp32h2/emulate_efuse_controller.py index c8d3cd91a..b482eab09 100644 --- a/espefuse/efuse/esp32h2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32h2/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32h2/fields.py b/espefuse/efuse/esp32h2/fields.py index 46182607b..91ef6c15c 100644 --- a/espefuse/efuse/esp32h2/fields.py +++ b/espefuse/efuse/esp32h2/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32h2/mem_definition.py b/espefuse/efuse/esp32h2/mem_definition.py index d08a71f0c..87663e95f 100644 --- a/espefuse/efuse/esp32h2/mem_definition.py +++ b/espefuse/efuse/esp32h2/mem_definition.py @@ -111,7 +111,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -129,7 +129,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py b/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py index b81e8e08f..1c336cbfe 100644 --- a/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32h2beta1/fields.py b/espefuse/efuse/esp32h2beta1/fields.py index 165734989..90fb72bb5 100644 --- a/espefuse/efuse/esp32h2beta1/fields.py +++ b/espefuse/efuse/esp32h2beta1/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32h2beta1/mem_definition.py b/espefuse/efuse/esp32h2beta1/mem_definition.py index 8c694306e..73bfb370e 100644 --- a/espefuse/efuse/esp32h2beta1/mem_definition.py +++ b/espefuse/efuse/esp32h2beta1/mem_definition.py @@ -107,7 +107,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -126,7 +126,7 @@ def __init__(self) -> None: efuse_file = efuse_file.replace("esp32h2beta1", "esp32h2") with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32p4/emulate_efuse_controller.py b/espefuse/efuse/esp32p4/emulate_efuse_controller.py index aa670aff7..adae384df 100644 --- a/espefuse/efuse/esp32p4/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32p4/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32p4/fields.py b/espefuse/efuse/esp32p4/fields.py index 415a6b33d..e28d788dc 100644 --- a/espefuse/efuse/esp32p4/fields.py +++ b/espefuse/efuse/esp32p4/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32p4/mem_definition.py b/espefuse/efuse/esp32p4/mem_definition.py index 9d3d2a5b7..c1427e516 100644 --- a/espefuse/efuse/esp32p4/mem_definition.py +++ b/espefuse/efuse/esp32p4/mem_definition.py @@ -111,7 +111,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -129,7 +129,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32s2/emulate_efuse_controller.py b/espefuse/efuse/esp32s2/emulate_efuse_controller.py index 497c91a5f..6c88ed54b 100644 --- a/espefuse/efuse/esp32s2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32s2/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32s2/fields.py b/espefuse/efuse/esp32s2/fields.py index 15d927529..1339fdb14 100644 --- a/espefuse/efuse/esp32s2/fields.py +++ b/espefuse/efuse/esp32s2/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32s2/mem_definition.py b/espefuse/efuse/esp32s2/mem_definition.py index b83ea9139..4799751db 100644 --- a/espefuse/efuse/esp32s2/mem_definition.py +++ b/espefuse/efuse/esp32s2/mem_definition.py @@ -150,7 +150,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -168,7 +168,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32s3/emulate_efuse_controller.py b/espefuse/efuse/esp32s3/emulate_efuse_controller.py index 7e767b954..9446c6af3 100644 --- a/espefuse/efuse/esp32s3/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32s3/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32s3/fields.py b/espefuse/efuse/esp32s3/fields.py index bbf08a37e..9bb4eeaf3 100644 --- a/espefuse/efuse/esp32s3/fields.py +++ b/espefuse/efuse/esp32s3/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32s3/mem_definition.py b/espefuse/efuse/esp32s3/mem_definition.py index 54c88712c..11aecfa65 100644 --- a/espefuse/efuse/esp32s3/mem_definition.py +++ b/espefuse/efuse/esp32s3/mem_definition.py @@ -112,7 +112,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -130,7 +130,7 @@ def __init__(self) -> None: efuse_file = os.path.join(dir_name, "efuse_defs", file_name) with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py b/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py index 0d81c0832..949fc562b 100644 --- a/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py +++ b/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py @@ -19,7 +19,7 @@ class EmulateEfuseController(EmulateEfuseControllerBase): def __init__(self, efuse_file=None, debug=False): self.Blocks = EfuseDefineBlocks - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(None) self.REGS = EfuseDefineRegisters super(EmulateEfuseController, self).__init__(efuse_file, debug) self.write_reg(self.REGS.EFUSE_CMD_REG, 0) diff --git a/espefuse/efuse/esp32s3beta2/fields.py b/espefuse/efuse/esp32s3beta2/fields.py index 9bb774a2c..28e03e9cf 100644 --- a/espefuse/efuse/esp32s3beta2/fields.py +++ b/espefuse/efuse/esp32s3beta2/fields.py @@ -58,9 +58,16 @@ class EspEfuses(base_fields.EspEfusesBase): debug = False do_not_confirm = False - def __init__(self, esp, skip_connect=False, debug=False, do_not_confirm=False): + def __init__( + self, + esp, + skip_connect=False, + debug=False, + do_not_confirm=False, + extend_efuse_table=None, + ): self.Blocks = EfuseDefineBlocks() - self.Fields = EfuseDefineFields() + self.Fields = EfuseDefineFields(extend_efuse_table) self.REGS = EfuseDefineRegisters self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names() self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys() diff --git a/espefuse/efuse/esp32s3beta2/mem_definition.py b/espefuse/efuse/esp32s3beta2/mem_definition.py index eabf76781..0fb1ec8ba 100644 --- a/espefuse/efuse/esp32s3beta2/mem_definition.py +++ b/espefuse/efuse/esp32s3beta2/mem_definition.py @@ -112,7 +112,7 @@ def get_burn_block_data_names(self): class EfuseDefineFields(EfuseFieldsBase): - def __init__(self) -> None: + def __init__(self, extend_efuse_table) -> None: # List of efuse fields from TRM the chapter eFuse Controller. self.EFUSES = [] @@ -131,7 +131,7 @@ def __init__(self) -> None: efuse_file = efuse_file.replace("esp32s3beta2", "esp32s3") with open(f"{efuse_file}", "r") as r_file: e_desc = yaml.safe_load(r_file) - super().__init__(e_desc) + super().__init__(e_desc, extend_efuse_table) for i, efuse in enumerate(self.ALL_EFUSES): if efuse.name in [ diff --git a/espefuse/efuse/mem_definition_base.py b/espefuse/efuse/mem_definition_base.py index 434b3a911..f6e2bdc0b 100644 --- a/espefuse/efuse/mem_definition_base.py +++ b/espefuse/efuse/mem_definition_base.py @@ -4,9 +4,12 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -from collections import namedtuple +from collections import Counter, namedtuple +import esptool from typing import Optional, List +from .csv_table_parser import CSVFuseTable + class EfuseRegistersBase(object): # Coding Scheme values @@ -61,7 +64,7 @@ class Field: class EfuseFieldsBase(object): - def __init__(self, e_desc) -> None: + def __init__(self, e_desc, extend_efuse_table_file) -> None: self.ALL_EFUSES: List = [] def set_category_and_class_type(efuse, name): @@ -170,3 +173,60 @@ def includes(name, names): ) set_category_and_class_type(d, e_name) self.ALL_EFUSES.append(d) + + if self.extend_efuses(extend_efuse_table_file): + self.check_name_duplicates() + + def check_name_duplicates(self): + names = [n.name for n in self.ALL_EFUSES] + for n in self.ALL_EFUSES: + if n.alt_names: + names.extend(n.alt_names) + + name_counts = Counter(names) + duplicates = {name for name, count in name_counts.items() if count > 1} + if duplicates: + print("Names that are not unique: " + ", ".join(duplicates)) + raise esptool.FatalError("Duplicate names found in eFuses") + + def extend_efuses(self, extend_efuse_table_file): + if extend_efuse_table_file: + table = CSVFuseTable.from_csv(extend_efuse_table_file.read()) + for p in table: + item = Field() + item.name = p.field_name + item.block = p.efuse_block + item.word = p.bit_start // 32 + item.pos = p.bit_start % 32 + item.bit_len = p.bit_count + if p.bit_count == 1: + str_type = "bool" + else: + if p.bit_count > 32 and p.bit_count % 8 == 0: + str_type = f"bytes:{p.bit_count // 8}" + else: + str_type = f"uint:{p.bit_count}" + item.type = str_type + item.write_disable_bit = None + item.read_disable_bit = None + if item.block != 0: + # look for an already configured field associated with this field + # to take the WR_DIS and RID_DIS bits + for field in self.ALL_EFUSES: + if field.block == item.block: + if field.write_disable_bit is not None: + item.write_disable_bit = field.write_disable_bit + if field.read_disable_bit is not None: + item.read_disable_bit = field.read_disable_bit + if ( + item.read_disable_bit is not None + and item.write_disable_bit is not None + ): + break + item.category = "User" + item.description = p.comment + item.alt_names = p.alt_names.split(" ") if p.alt_names else [] + item.dictionary = "" + self.ALL_EFUSES.append(item) + return True + return False diff --git a/test/images/efuse/esp_efuse_custom_table.csv b/test/images/efuse/esp_efuse_custom_table.csv new file mode 100644 index 000000000..bb784a998 --- /dev/null +++ b/test/images/efuse/esp_efuse_custom_table.csv @@ -0,0 +1,13 @@ +# field_name, | efuse_block, | bit_start, | bit_count, | comment +MODULE_VERSION, EFUSE_BLK3, 56, 8, Module version +DEVICE_ROLE, EFUSE_BLK3, 64, 3, Device role +SETTING_1, EFUSE_BLK3, 67, 6, [SETTING_1_ALT_NAME] Setting 1 +SETTING_2, EFUSE_BLK3, 73, 5, Setting 2 +ID_NUM, EFUSE_BLK3, 140, 8, [MY_ID_NUM] comment +, EFUSE_BLK3, 132, 8, [MY_ID_NUM] comment +, EFUSE_BLK3, 122, 8, [MY_ID_NUM] comment +CUSTOM_SECURE_VERSION, EFUSE_BLK3, 78, 16, Custom secure version +ID_NUMK, EFUSE_BLK3, 150, 8, [MY_ID_NUMK] comment +, EFUSE_BLK3, 182, 8, [MY_ID_NUMK] comment +MY_DATA, EFUSE_BLK3, 190, 10, My data +MY_DATA.FIELD1, EFUSE_BLK3, 190, 7, Field1 \ No newline at end of file diff --git a/test/test_espefuse.py b/test/test_espefuse.py index 26daf8c49..40adf0669 100755 --- a/test/test_espefuse.py +++ b/test/test_espefuse.py @@ -2101,3 +2101,32 @@ def test_postpone_efuses(self): assert "Burn postponed efuses from BLOCK0" in output assert "BURN BLOCK0 - OK" in output assert "Successful" in output + + +class TestCSVEfuseTable(EfuseTestCase): + def test_extend_efuse_table_with_csv_file(self): + csv_file = f"{IMAGES_DIR}/esp_efuse_custom_table.csv" + output = self.espefuse_py(f" --extend-efuse-table {csv_file} summary") + assert "MODULE_VERSION (BLOCK3)" in output + assert "DEVICE_ROLE (BLOCK3)" in output + assert "SETTING_2 (BLOCK3)" in output + assert "ID_NUM_0 (BLOCK3)" in output + assert "ID_NUM_1 (BLOCK3)" in output + assert "ID_NUM_2 (BLOCK3)" in output + assert "CUSTOM_SECURE_VERSION (BLOCK3)" in output + assert "ID_NUMK_0 (BLOCK3)" in output + assert "ID_NUMK_1 (BLOCK3)" in output + + self.espefuse_py( + f"--extend-efuse-table {csv_file} burn_efuse \ + MODULE_VERSION 1 \ + CUSTOM_SECURE_VERSION 4 \ + SETTING_1_ALT_NAME 7 \ + SETTING_2 1 \ + ID_NUM_0 1 \ + ID_NUM_1 1 \ + ID_NUM_2 1 \ + MY_ID_NUMK_0 1 \ + MY_ID_NUMK_1 1 \ + MY_DATA_FIELD1 1" + )