esptool 4.9.dev5__tar.gz → 4.9.dev7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {esptool-4.9.dev5/esptool.egg-info → esptool-4.9.dev7}/PKG-INFO +3 -2
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/__init__.py +2 -0
- esptool-4.9.dev7/espefuse/efuse/esp32h4/emulate_efuse_controller.py +92 -0
- esptool-4.9.dev7/espefuse/efuse/esp32h4/fields.py +452 -0
- esptool-4.9.dev7/espefuse/efuse/esp32h4/mem_definition.py +169 -0
- esptool-4.9.dev7/espefuse/efuse/esp32h4/operations.py +389 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/operations.py +6 -2
- esptool-4.9.dev7/espefuse/efuse/esp32s3beta2/__init__.py +3 -0
- esptool-4.9.dev7/espefuse/efuse_defs/esp32h4.yaml +92 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32p4.yaml +1 -1
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/__init__.py +11 -5
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/bin_image.py +44 -38
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/cmds.py +104 -55
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/__init__.py +2 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c5.py +2 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h21.py +30 -0
- esptool-4.9.dev7/esptool/targets/esp32h4.py +213 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/README.md +1 -1
- esptool-4.9.dev7/esptool/targets/stub_flasher/1/esp32p4.json +8 -0
- esptool-4.9.dev7/esptool/targets/stub_flasher/1/esp32s3.json +8 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7/esptool.egg-info}/PKG-INFO +3 -2
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/SOURCES.txt +7 -0
- esptool-4.9.dev5/esptool/targets/stub_flasher/1/esp32p4.json +0 -8
- esptool-4.9.dev5/esptool/targets/stub_flasher/1/esp32s3.json +0 -8
- {esptool-4.9.dev5 → esptool-4.9.dev7}/LICENSE +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/MANIFEST.in +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/README.md +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/__main__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/esp_port_manager.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/redirector.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/__main__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/base_fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/base_operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/csv_table_parser.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/emulate_efuse_controller_base.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/operations.py +0 -0
- {esptool-4.9.dev5/espefuse/efuse/esp32p4 → esptool-4.9.dev7/espefuse/efuse/esp32h4}/__init__.py +0 -0
- {esptool-4.9.dev5/espefuse/efuse/esp32s2 → esptool-4.9.dev7/espefuse/efuse/esp32p4}/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/mem_definition.py +0 -0
- {esptool-4.9.dev5/espefuse/efuse/esp32s3 → esptool-4.9.dev7/espefuse/efuse/esp32s2}/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/operations.py +0 -0
- {esptool-4.9.dev5/espefuse/efuse/esp32s3beta2 → esptool-4.9.dev7/espefuse/efuse/esp32s3}/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/fields.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/mem_definition.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/operations.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/mem_definition_base.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/util.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c2.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c3.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c5.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c5beta3.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c6.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c61.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32h2.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32h21.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32h2_v0.0_v1.1.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32s2.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32s3.yaml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/__main__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/esp_hsm_sign/__init__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/esp_hsm_sign/exceptions.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/__main__.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/config.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/loader.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/reset.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c2.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c3.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c5beta3.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c6.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c61.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c6beta.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h2.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h2beta1.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h2beta2.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32p4.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32s2.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32s3.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32s3beta2.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp8266.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c3.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c5.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c5beta3.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c6.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c61.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c6beta.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32h2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32h2beta1.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32h2beta2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32s2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32s3beta2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp8266.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/LICENSE-APACHE +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/LICENSE-MIT +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/README.md +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32c2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32c3.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32c6.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32h2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32s2.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32s3.json +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/uf2_writer.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/util.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/dependency_links.txt +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/requires.txt +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/top_level.txt +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.py +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/pyproject.toml +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/setup.cfg +0 -0
- {esptool-4.9.dev5 → esptool-4.9.dev7}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: esptool
|
|
3
|
-
Version: 4.9.
|
|
3
|
+
Version: 4.9.dev7
|
|
4
4
|
Summary: A serial utility to communicate & flash code to Espressif chips.
|
|
5
5
|
Author: Fredrik Ahlberg (themadinventor), Angus Gratton (projectgus), Espressif Systems
|
|
6
6
|
License: GPLv2+
|
|
@@ -46,6 +46,7 @@ Requires-Dist: requests; extra == "dev"
|
|
|
46
46
|
Requires-Dist: commitizen; extra == "dev"
|
|
47
47
|
Provides-Extra: hsm
|
|
48
48
|
Requires-Dist: python-pkcs11; extra == "hsm"
|
|
49
|
+
Dynamic: license-file
|
|
49
50
|
|
|
50
51
|
# esptool.py
|
|
51
52
|
|
|
@@ -19,6 +19,7 @@ import espefuse.efuse.esp32c61 as esp32c61_efuse
|
|
|
19
19
|
import espefuse.efuse.esp32h2 as esp32h2_efuse
|
|
20
20
|
import espefuse.efuse.esp32h21 as esp32h21_efuse
|
|
21
21
|
import espefuse.efuse.esp32h2beta1 as esp32h2beta1_efuse
|
|
22
|
+
import espefuse.efuse.esp32h4 as esp32h4_efuse
|
|
22
23
|
import espefuse.efuse.esp32p4 as esp32p4_efuse
|
|
23
24
|
import espefuse.efuse.esp32s2 as esp32s2_efuse
|
|
24
25
|
import espefuse.efuse.esp32s3 as esp32s3_efuse
|
|
@@ -63,6 +64,7 @@ SUPPORTED_CHIPS = {
|
|
|
63
64
|
),
|
|
64
65
|
"esp32h2": DefChip("ESP32-H2", esp32h2_efuse, esptool.targets.ESP32H2ROM),
|
|
65
66
|
"esp32h21": DefChip("ESP32-H21", esp32h21_efuse, esptool.targets.ESP32H21ROM),
|
|
67
|
+
"esp32h4": DefChip("ESP32-H4", esp32h4_efuse, esptool.targets.ESP32H4ROM),
|
|
66
68
|
"esp32p4": DefChip("ESP32-P4", esp32p4_efuse, esptool.targets.ESP32P4ROM),
|
|
67
69
|
"esp32h2beta1": DefChip(
|
|
68
70
|
"ESP32-H2(beta1)", esp32h2beta1_efuse, esptool.targets.ESP32H2BETA1ROM
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# This file describes eFuses controller for ESP32-H4 chip
|
|
2
|
+
#
|
|
3
|
+
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
|
4
|
+
#
|
|
5
|
+
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
6
|
+
|
|
7
|
+
import reedsolo
|
|
8
|
+
|
|
9
|
+
from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters
|
|
10
|
+
from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class EmulateEfuseController(EmulateEfuseControllerBase):
|
|
14
|
+
"""The class for virtual efuse operation. Using for HOST_TEST."""
|
|
15
|
+
|
|
16
|
+
CHIP_NAME = "ESP32-H4"
|
|
17
|
+
mem = None
|
|
18
|
+
debug = False
|
|
19
|
+
|
|
20
|
+
def __init__(self, efuse_file=None, debug=False):
|
|
21
|
+
self.Blocks = EfuseDefineBlocks
|
|
22
|
+
self.Fields = EfuseDefineFields(None)
|
|
23
|
+
self.REGS = EfuseDefineRegisters
|
|
24
|
+
super(EmulateEfuseController, self).__init__(efuse_file, debug)
|
|
25
|
+
self.write_reg(self.REGS.EFUSE_CMD_REG, 0)
|
|
26
|
+
|
|
27
|
+
""" esptool method start >>"""
|
|
28
|
+
|
|
29
|
+
def get_major_chip_version(self):
|
|
30
|
+
return 0
|
|
31
|
+
|
|
32
|
+
def get_minor_chip_version(self):
|
|
33
|
+
return 0
|
|
34
|
+
|
|
35
|
+
def get_crystal_freq(self):
|
|
36
|
+
return 32 # MHz
|
|
37
|
+
|
|
38
|
+
def get_security_info(self):
|
|
39
|
+
return {
|
|
40
|
+
"flags": 0,
|
|
41
|
+
"flash_crypt_cnt": 0,
|
|
42
|
+
"key_purposes": 0,
|
|
43
|
+
"chip_id": 0,
|
|
44
|
+
"api_version": 0,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
""" << esptool method end """
|
|
48
|
+
|
|
49
|
+
def handle_writing_event(self, addr, value):
|
|
50
|
+
if addr == self.REGS.EFUSE_CMD_REG:
|
|
51
|
+
if value & self.REGS.EFUSE_PGM_CMD:
|
|
52
|
+
self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF)
|
|
53
|
+
self.clean_blocks_wr_regs()
|
|
54
|
+
self.check_rd_protection_area()
|
|
55
|
+
self.write_reg(addr, 0)
|
|
56
|
+
self.write_reg(self.REGS.EFUSE_CMD_REG, 0)
|
|
57
|
+
elif value == self.REGS.EFUSE_READ_CMD:
|
|
58
|
+
self.write_reg(addr, 0)
|
|
59
|
+
self.write_reg(self.REGS.EFUSE_CMD_REG, 0)
|
|
60
|
+
self.save_to_file()
|
|
61
|
+
|
|
62
|
+
def get_bitlen_of_block(self, blk, wr=False):
|
|
63
|
+
if blk.id == 0:
|
|
64
|
+
if wr:
|
|
65
|
+
return 32 * 8
|
|
66
|
+
else:
|
|
67
|
+
return 32 * blk.len
|
|
68
|
+
else:
|
|
69
|
+
if wr:
|
|
70
|
+
rs_coding = 32 * 3
|
|
71
|
+
return 32 * 8 + rs_coding
|
|
72
|
+
else:
|
|
73
|
+
return 32 * blk.len
|
|
74
|
+
|
|
75
|
+
def handle_coding_scheme(self, blk, data):
|
|
76
|
+
if blk.id != 0:
|
|
77
|
+
# CODING_SCHEME RS applied only for all blocks except BLK0.
|
|
78
|
+
coded_bytes = 12
|
|
79
|
+
data.pos = coded_bytes * 8
|
|
80
|
+
plain_data = data.readlist("32*uint:8")[::-1]
|
|
81
|
+
# takes 32 bytes
|
|
82
|
+
# apply RS encoding
|
|
83
|
+
rs = reedsolo.RSCodec(coded_bytes)
|
|
84
|
+
# 32 byte of data + 12 bytes RS
|
|
85
|
+
calc_encoded_data = list(rs.encode([x for x in plain_data]))
|
|
86
|
+
data.pos = 0
|
|
87
|
+
if calc_encoded_data != data.readlist("44*uint:8")[::-1]:
|
|
88
|
+
raise FatalError("Error in coding scheme data")
|
|
89
|
+
data = data[coded_bytes * 8 :]
|
|
90
|
+
if blk.len < 8:
|
|
91
|
+
data = data[(8 - blk.len) * 32 :]
|
|
92
|
+
return data
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# This file describes eFuses for ESP32-H4 chip
|
|
2
|
+
#
|
|
3
|
+
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
|
4
|
+
#
|
|
5
|
+
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
6
|
+
|
|
7
|
+
import binascii
|
|
8
|
+
import struct
|
|
9
|
+
import time
|
|
10
|
+
|
|
11
|
+
from bitstring import BitArray
|
|
12
|
+
|
|
13
|
+
import esptool
|
|
14
|
+
|
|
15
|
+
import reedsolo
|
|
16
|
+
|
|
17
|
+
from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters
|
|
18
|
+
from .. import base_fields
|
|
19
|
+
from .. import util
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class EfuseBlock(base_fields.EfuseBlockBase):
|
|
23
|
+
def len_of_burn_unit(self):
|
|
24
|
+
# The writing register window is 8 registers for any blocks.
|
|
25
|
+
# len in bytes
|
|
26
|
+
return 8 * 4
|
|
27
|
+
|
|
28
|
+
def __init__(self, parent, param, skip_read=False):
|
|
29
|
+
parent.read_coding_scheme()
|
|
30
|
+
super(EfuseBlock, self).__init__(parent, param, skip_read=skip_read)
|
|
31
|
+
|
|
32
|
+
def apply_coding_scheme(self):
|
|
33
|
+
data = self.get_raw(from_read=False)[::-1]
|
|
34
|
+
if len(data) < self.len_of_burn_unit():
|
|
35
|
+
add_empty_bytes = self.len_of_burn_unit() - len(data)
|
|
36
|
+
data = data + (b"\x00" * add_empty_bytes)
|
|
37
|
+
if self.get_coding_scheme() == self.parent.REGS.CODING_SCHEME_RS:
|
|
38
|
+
# takes 32 bytes
|
|
39
|
+
# apply RS encoding
|
|
40
|
+
rs = reedsolo.RSCodec(12)
|
|
41
|
+
# 32 byte of data + 12 bytes RS
|
|
42
|
+
encoded_data = rs.encode([x for x in data])
|
|
43
|
+
words = struct.unpack("<" + "I" * 11, encoded_data)
|
|
44
|
+
# returns 11 words (8 words of data + 3 words of RS coding)
|
|
45
|
+
else:
|
|
46
|
+
# takes 32 bytes
|
|
47
|
+
words = struct.unpack("<" + ("I" * (len(data) // 4)), data)
|
|
48
|
+
# returns 8 words
|
|
49
|
+
return words
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class EspEfuses(base_fields.EspEfusesBase):
|
|
53
|
+
"""
|
|
54
|
+
Wrapper object to manage the efuse fields in a connected ESP bootloader
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
debug = False
|
|
58
|
+
do_not_confirm = False
|
|
59
|
+
|
|
60
|
+
def __init__(
|
|
61
|
+
self,
|
|
62
|
+
esp,
|
|
63
|
+
skip_connect=False,
|
|
64
|
+
debug=False,
|
|
65
|
+
do_not_confirm=False,
|
|
66
|
+
extend_efuse_table=None,
|
|
67
|
+
):
|
|
68
|
+
self.Blocks = EfuseDefineBlocks()
|
|
69
|
+
self.Fields = EfuseDefineFields(extend_efuse_table)
|
|
70
|
+
self.REGS = EfuseDefineRegisters
|
|
71
|
+
self.BURN_BLOCK_DATA_NAMES = self.Blocks.get_burn_block_data_names()
|
|
72
|
+
self.BLOCKS_FOR_KEYS = self.Blocks.get_blocks_for_keys()
|
|
73
|
+
self._esp = esp
|
|
74
|
+
self.debug = debug
|
|
75
|
+
self.do_not_confirm = do_not_confirm
|
|
76
|
+
if esp.CHIP_NAME != "ESP32-H4":
|
|
77
|
+
raise esptool.FatalError(
|
|
78
|
+
"Expected the 'esp' param for ESP32-H4 chip but got for '%s'."
|
|
79
|
+
% (esp.CHIP_NAME)
|
|
80
|
+
)
|
|
81
|
+
if not skip_connect:
|
|
82
|
+
flags = self._esp.get_security_info()["flags"]
|
|
83
|
+
GET_SECURITY_INFO_FLAG_SECURE_DOWNLOAD_ENABLE = 1 << 2
|
|
84
|
+
if flags & GET_SECURITY_INFO_FLAG_SECURE_DOWNLOAD_ENABLE:
|
|
85
|
+
raise esptool.FatalError(
|
|
86
|
+
"Secure Download Mode is enabled. The tool can not read eFuses."
|
|
87
|
+
)
|
|
88
|
+
self.blocks = [
|
|
89
|
+
EfuseBlock(self, self.Blocks.get(block), skip_read=skip_connect)
|
|
90
|
+
for block in self.Blocks.BLOCKS
|
|
91
|
+
]
|
|
92
|
+
if not skip_connect:
|
|
93
|
+
self.get_coding_scheme_warnings()
|
|
94
|
+
self.efuses = [EfuseField.convert(self, efuse) for efuse in self.Fields.EFUSES]
|
|
95
|
+
self.efuses += [
|
|
96
|
+
EfuseField.convert(self, efuse) for efuse in self.Fields.KEYBLOCKS
|
|
97
|
+
]
|
|
98
|
+
if skip_connect:
|
|
99
|
+
self.efuses += [
|
|
100
|
+
EfuseField.convert(self, efuse)
|
|
101
|
+
for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES
|
|
102
|
+
]
|
|
103
|
+
else:
|
|
104
|
+
if False: # self["BLK_VERSION_MINOR"].get() == 1:
|
|
105
|
+
self.efuses += [
|
|
106
|
+
EfuseField.convert(self, efuse)
|
|
107
|
+
for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES
|
|
108
|
+
]
|
|
109
|
+
self.efuses += [
|
|
110
|
+
EfuseField.convert(self, efuse) for efuse in self.Fields.CALC
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
def __getitem__(self, efuse_name):
|
|
114
|
+
"""Return the efuse field with the given name"""
|
|
115
|
+
for e in self.efuses:
|
|
116
|
+
if efuse_name == e.name or any(x == efuse_name for x in e.alt_names):
|
|
117
|
+
return e
|
|
118
|
+
new_fields = False
|
|
119
|
+
for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES:
|
|
120
|
+
if efuse.name == efuse_name or any(
|
|
121
|
+
x == efuse_name for x in efuse.alt_names
|
|
122
|
+
):
|
|
123
|
+
self.efuses += [
|
|
124
|
+
EfuseField.convert(self, efuse)
|
|
125
|
+
for efuse in self.Fields.BLOCK2_CALIBRATION_EFUSES
|
|
126
|
+
]
|
|
127
|
+
new_fields = True
|
|
128
|
+
if new_fields:
|
|
129
|
+
for e in self.efuses:
|
|
130
|
+
if efuse_name == e.name or any(x == efuse_name for x in e.alt_names):
|
|
131
|
+
return e
|
|
132
|
+
raise KeyError
|
|
133
|
+
|
|
134
|
+
def read_coding_scheme(self):
|
|
135
|
+
self.coding_scheme = self.REGS.CODING_SCHEME_RS
|
|
136
|
+
|
|
137
|
+
def print_status_regs(self):
|
|
138
|
+
print("")
|
|
139
|
+
self.blocks[0].print_block(self.blocks[0].err_bitarray, "err__regs", debug=True)
|
|
140
|
+
print(
|
|
141
|
+
"{:27} 0x{:08x}".format(
|
|
142
|
+
"EFUSE_RD_RS_ERR0_REG", self.read_reg(self.REGS.EFUSE_RD_RS_ERR0_REG)
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
print(
|
|
146
|
+
"{:27} 0x{:08x}".format(
|
|
147
|
+
"EFUSE_RD_RS_ERR1_REG", self.read_reg(self.REGS.EFUSE_RD_RS_ERR1_REG)
|
|
148
|
+
)
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def efuse_controller_setup(self):
|
|
152
|
+
self.set_efuse_timing()
|
|
153
|
+
self.clear_pgm_registers()
|
|
154
|
+
self.wait_efuse_idle()
|
|
155
|
+
|
|
156
|
+
def write_efuses(self, block):
|
|
157
|
+
self.efuse_program(block)
|
|
158
|
+
return self.get_coding_scheme_warnings(silent=True)
|
|
159
|
+
|
|
160
|
+
def clear_pgm_registers(self):
|
|
161
|
+
self.wait_efuse_idle()
|
|
162
|
+
for r in range(
|
|
163
|
+
self.REGS.EFUSE_PGM_DATA0_REG, self.REGS.EFUSE_PGM_DATA0_REG + 32, 4
|
|
164
|
+
):
|
|
165
|
+
self.write_reg(r, 0)
|
|
166
|
+
|
|
167
|
+
def wait_efuse_idle(self):
|
|
168
|
+
deadline = time.time() + self.REGS.EFUSE_BURN_TIMEOUT
|
|
169
|
+
while time.time() < deadline:
|
|
170
|
+
cmds = self.REGS.EFUSE_PGM_CMD | self.REGS.EFUSE_READ_CMD
|
|
171
|
+
if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0:
|
|
172
|
+
if self.read_reg(self.REGS.EFUSE_CMD_REG) & cmds == 0:
|
|
173
|
+
# Due to a hardware error, we have to read READ_CMD again
|
|
174
|
+
# to make sure the efuse clock is normal.
|
|
175
|
+
# For PGM_CMD it is not necessary.
|
|
176
|
+
return
|
|
177
|
+
raise esptool.FatalError(
|
|
178
|
+
"Timed out waiting for Efuse controller command to complete"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def efuse_program(self, block):
|
|
182
|
+
self.wait_efuse_idle()
|
|
183
|
+
self.write_reg(self.REGS.EFUSE_CONF_REG, self.REGS.EFUSE_WRITE_OP_CODE)
|
|
184
|
+
self.write_reg(self.REGS.EFUSE_CMD_REG, self.REGS.EFUSE_PGM_CMD | (block << 2))
|
|
185
|
+
self.wait_efuse_idle()
|
|
186
|
+
self.clear_pgm_registers()
|
|
187
|
+
self.efuse_read()
|
|
188
|
+
|
|
189
|
+
def efuse_read(self):
|
|
190
|
+
self.wait_efuse_idle()
|
|
191
|
+
self.write_reg(self.REGS.EFUSE_CONF_REG, self.REGS.EFUSE_READ_OP_CODE)
|
|
192
|
+
# need to add a delay after triggering EFUSE_READ_CMD, as ROM loader checks some
|
|
193
|
+
# efuse registers after each command is completed
|
|
194
|
+
# if ENABLE_SECURITY_DOWNLOAD or DIS_DOWNLOAD_MODE is enabled by the current cmd, then we need to try to reconnect to the chip.
|
|
195
|
+
try:
|
|
196
|
+
self.write_reg(
|
|
197
|
+
self.REGS.EFUSE_CMD_REG, self.REGS.EFUSE_READ_CMD, delay_after_us=1000
|
|
198
|
+
)
|
|
199
|
+
self.wait_efuse_idle()
|
|
200
|
+
except esptool.FatalError:
|
|
201
|
+
secure_download_mode_before = self._esp.secure_download_mode
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
self._esp = self.reconnect_chip(self._esp)
|
|
205
|
+
except esptool.FatalError:
|
|
206
|
+
print("Can not re-connect to the chip")
|
|
207
|
+
if not self["DIS_DOWNLOAD_MODE"].get() and self[
|
|
208
|
+
"DIS_DOWNLOAD_MODE"
|
|
209
|
+
].get(from_read=False):
|
|
210
|
+
print(
|
|
211
|
+
"This is the correct behavior as we are actually burning "
|
|
212
|
+
"DIS_DOWNLOAD_MODE which disables the connection to the chip"
|
|
213
|
+
)
|
|
214
|
+
print("DIS_DOWNLOAD_MODE is enabled")
|
|
215
|
+
print("Successful")
|
|
216
|
+
exit(0) # finish without errors
|
|
217
|
+
raise
|
|
218
|
+
|
|
219
|
+
print("Established a connection with the chip")
|
|
220
|
+
if self._esp.secure_download_mode and not secure_download_mode_before:
|
|
221
|
+
print("Secure download mode is enabled")
|
|
222
|
+
if not self["ENABLE_SECURITY_DOWNLOAD"].get() and self[
|
|
223
|
+
"ENABLE_SECURITY_DOWNLOAD"
|
|
224
|
+
].get(from_read=False):
|
|
225
|
+
print(
|
|
226
|
+
"espefuse tool can not continue to work in Secure download mode"
|
|
227
|
+
)
|
|
228
|
+
print("ENABLE_SECURITY_DOWNLOAD is enabled")
|
|
229
|
+
print("Successful")
|
|
230
|
+
exit(0) # finish without errors
|
|
231
|
+
raise
|
|
232
|
+
|
|
233
|
+
def set_efuse_timing(self):
|
|
234
|
+
"""Set timing registers for burning efuses"""
|
|
235
|
+
# Configure clock
|
|
236
|
+
apb_freq = self.get_crystal_freq()
|
|
237
|
+
if apb_freq != 32:
|
|
238
|
+
raise esptool.FatalError(
|
|
239
|
+
"The eFuse supports only xtal=32M (xtal was %d)" % apb_freq
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# TODO: [ESP32H4] IDF-12268
|
|
243
|
+
|
|
244
|
+
def get_coding_scheme_warnings(self, silent=False):
|
|
245
|
+
"""Check if the coding scheme has detected any errors."""
|
|
246
|
+
old_addr_reg = 0
|
|
247
|
+
reg_value = 0
|
|
248
|
+
ret_fail = False
|
|
249
|
+
for block in self.blocks:
|
|
250
|
+
if block.id == 0:
|
|
251
|
+
words = [
|
|
252
|
+
self.read_reg(self.REGS.EFUSE_RD_REPEAT_ERR0_REG + offs * 4)
|
|
253
|
+
for offs in range(5)
|
|
254
|
+
]
|
|
255
|
+
block.err_bitarray.pos = 0
|
|
256
|
+
for word in reversed(words):
|
|
257
|
+
block.err_bitarray.overwrite(BitArray("uint:32=%d" % word))
|
|
258
|
+
block.num_errors = block.err_bitarray.count(True)
|
|
259
|
+
block.fail = block.num_errors != 0
|
|
260
|
+
else:
|
|
261
|
+
addr_reg, err_num_mask, err_num_offs, fail_bit = self.REGS.BLOCK_ERRORS[
|
|
262
|
+
block.id
|
|
263
|
+
]
|
|
264
|
+
if err_num_mask is None or err_num_offs is None or fail_bit is None:
|
|
265
|
+
continue
|
|
266
|
+
if addr_reg != old_addr_reg:
|
|
267
|
+
old_addr_reg = addr_reg
|
|
268
|
+
reg_value = self.read_reg(addr_reg)
|
|
269
|
+
block.fail = reg_value & (1 << fail_bit) != 0
|
|
270
|
+
block.num_errors = (reg_value >> err_num_offs) & err_num_mask
|
|
271
|
+
ret_fail |= block.fail
|
|
272
|
+
if not silent and (block.fail or block.num_errors):
|
|
273
|
+
print(
|
|
274
|
+
"Error(s) in BLOCK%d [ERRORS:%d FAIL:%d]"
|
|
275
|
+
% (block.id, block.num_errors, block.fail)
|
|
276
|
+
)
|
|
277
|
+
if (self.debug or ret_fail) and not silent:
|
|
278
|
+
self.print_status_regs()
|
|
279
|
+
return ret_fail
|
|
280
|
+
|
|
281
|
+
def summary(self):
|
|
282
|
+
# TODO add support set_flash_voltage - "Flash voltage (VDD_SPI)"
|
|
283
|
+
return ""
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class EfuseField(base_fields.EfuseFieldBase):
|
|
287
|
+
@staticmethod
|
|
288
|
+
def convert(parent, efuse):
|
|
289
|
+
return {
|
|
290
|
+
"mac": EfuseMacField,
|
|
291
|
+
"keypurpose": EfuseKeyPurposeField,
|
|
292
|
+
"t_sensor": EfuseTempSensor,
|
|
293
|
+
"adc_tp": EfuseAdcPointCalibration,
|
|
294
|
+
"wafer": EfuseWafer,
|
|
295
|
+
}.get(efuse.class_type, EfuseField)(parent, efuse)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class EfuseWafer(EfuseField):
|
|
299
|
+
def get(self, from_read=True):
|
|
300
|
+
# TODO: [ESP32H4] IDF-12268
|
|
301
|
+
return 0
|
|
302
|
+
|
|
303
|
+
def save(self, new_value):
|
|
304
|
+
raise esptool.FatalError("Burning %s is not supported" % self.name)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class EfuseTempSensor(EfuseField):
|
|
308
|
+
def get(self, from_read=True):
|
|
309
|
+
value = self.get_bitstring(from_read)
|
|
310
|
+
sig = -1 if value[0] else 1
|
|
311
|
+
return sig * value[1:].uint * 0.1
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
class EfuseAdcPointCalibration(EfuseField):
|
|
315
|
+
def get(self, from_read=True):
|
|
316
|
+
STEP_SIZE = 4
|
|
317
|
+
value = self.get_bitstring(from_read)
|
|
318
|
+
sig = -1 if value[0] else 1
|
|
319
|
+
return sig * value[1:].uint * STEP_SIZE
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class EfuseMacField(EfuseField):
|
|
323
|
+
def check_format(self, new_value_str):
|
|
324
|
+
if new_value_str is None:
|
|
325
|
+
raise esptool.FatalError(
|
|
326
|
+
"Required MAC Address in AA:CD:EF:01:02:03 format!"
|
|
327
|
+
)
|
|
328
|
+
num_bytes = 8 if self.name == "MAC_EUI64" else 6
|
|
329
|
+
if new_value_str.count(":") != num_bytes - 1:
|
|
330
|
+
raise esptool.FatalError(
|
|
331
|
+
f"MAC Address needs to be a {num_bytes}-byte hexadecimal format "
|
|
332
|
+
"separated by colons (:)!"
|
|
333
|
+
)
|
|
334
|
+
hexad = new_value_str.replace(":", "").split(" ", 1)[0]
|
|
335
|
+
hexad = hexad.split(" ", 1)[0] if self.is_field_calculated() else hexad
|
|
336
|
+
if len(hexad) != num_bytes * 2:
|
|
337
|
+
raise esptool.FatalError(
|
|
338
|
+
f"MAC Address needs to be a {num_bytes}-byte hexadecimal number "
|
|
339
|
+
f"({num_bytes * 2} hexadecimal characters)!"
|
|
340
|
+
)
|
|
341
|
+
# order of bytearray = b'\xaa\xcd\xef\x01\x02\x03',
|
|
342
|
+
bindata = binascii.unhexlify(hexad)
|
|
343
|
+
|
|
344
|
+
if not self.is_field_calculated():
|
|
345
|
+
# unicast address check according to
|
|
346
|
+
# https://tools.ietf.org/html/rfc7042#section-2.1
|
|
347
|
+
if esptool.util.byte(bindata, 0) & 0x01:
|
|
348
|
+
raise esptool.FatalError("Custom MAC must be a unicast MAC!")
|
|
349
|
+
return bindata
|
|
350
|
+
|
|
351
|
+
def check(self):
|
|
352
|
+
errs, fail = self.parent.get_block_errors(self.block)
|
|
353
|
+
if errs != 0 or fail:
|
|
354
|
+
output = "Block%d has ERRORS:%d FAIL:%d" % (self.block, errs, fail)
|
|
355
|
+
else:
|
|
356
|
+
output = "OK"
|
|
357
|
+
return "(" + output + ")"
|
|
358
|
+
|
|
359
|
+
def get(self, from_read=True):
|
|
360
|
+
if self.name == "CUSTOM_MAC":
|
|
361
|
+
mac = self.get_raw(from_read)[::-1]
|
|
362
|
+
elif self.name == "MAC":
|
|
363
|
+
mac = self.get_raw(from_read)
|
|
364
|
+
elif self.name == "MAC_EUI64":
|
|
365
|
+
mac = self.parent["MAC"].get_bitstring(from_read).copy()
|
|
366
|
+
mac_ext = self.parent["MAC_EXT"].get_bitstring(from_read)
|
|
367
|
+
mac.insert(mac_ext, 24)
|
|
368
|
+
mac = mac.bytes
|
|
369
|
+
else:
|
|
370
|
+
mac = self.get_raw(from_read)
|
|
371
|
+
return "%s %s" % (util.hexify(mac, ":"), self.check())
|
|
372
|
+
|
|
373
|
+
def save(self, new_value):
|
|
374
|
+
def print_field(e, new_value):
|
|
375
|
+
print(
|
|
376
|
+
" - '{}' ({}) {} -> {}".format(
|
|
377
|
+
e.name, e.description, e.get_bitstring(), new_value
|
|
378
|
+
)
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
if self.name == "CUSTOM_MAC":
|
|
382
|
+
bitarray_mac = self.convert_to_bitstring(new_value)
|
|
383
|
+
print_field(self, bitarray_mac)
|
|
384
|
+
super(EfuseMacField, self).save(new_value)
|
|
385
|
+
else:
|
|
386
|
+
# Writing the BLOCK1 (MAC_SPI_8M_0) default MAC is not possible,
|
|
387
|
+
# as it's written in the factory.
|
|
388
|
+
raise esptool.FatalError(f"Burning {self.name} is not supported")
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
# fmt: off
|
|
392
|
+
class EfuseKeyPurposeField(EfuseField):
|
|
393
|
+
# TODO: [ESP32H4] IDF-12268 need check
|
|
394
|
+
KEY_PURPOSES = [
|
|
395
|
+
("USER", 0, None, None, "no_need_rd_protect"), # User purposes (software-only use)
|
|
396
|
+
("ECDSA_KEY", 1, None, "Reverse", "need_rd_protect"), # ECDSA key
|
|
397
|
+
("XTS_AES_256_KEY_1", 2, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_1 (flash/PSRAM encryption)
|
|
398
|
+
("XTS_AES_256_KEY_2", 3, None, "Reverse", "need_rd_protect"), # XTS_AES_256_KEY_2 (flash/PSRAM encryption)
|
|
399
|
+
("XTS_AES_128_KEY", 4, None, "Reverse", "need_rd_protect"), # XTS_AES_128_KEY (flash/PSRAM encryption)
|
|
400
|
+
("HMAC_DOWN_ALL", 5, None, None, "need_rd_protect"), # HMAC Downstream mode
|
|
401
|
+
("HMAC_DOWN_JTAG", 6, None, None, "need_rd_protect"), # JTAG soft enable key (uses HMAC Downstream mode)
|
|
402
|
+
("HMAC_DOWN_DIGITAL_SIGNATURE", 7, None, None, "need_rd_protect"), # Digital Signature peripheral key (uses HMAC Downstream mode)
|
|
403
|
+
("HMAC_UP", 8, None, None, "need_rd_protect"), # HMAC Upstream mode
|
|
404
|
+
("SECURE_BOOT_DIGEST0", 9, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST0 (Secure Boot key digest)
|
|
405
|
+
("SECURE_BOOT_DIGEST1", 10, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST1 (Secure Boot key digest)
|
|
406
|
+
("SECURE_BOOT_DIGEST2", 11, "DIGEST", None, "no_need_rd_protect"), # SECURE_BOOT_DIGEST2 (Secure Boot key digest)
|
|
407
|
+
("KM_INIT_KEY", 12, None, None, "need_rd_protect"), # init key that is used for the generation of AES/ECDSA key
|
|
408
|
+
]
|
|
409
|
+
# fmt: on
|
|
410
|
+
|
|
411
|
+
KEY_PURPOSES_NAME = [name[0] for name in KEY_PURPOSES]
|
|
412
|
+
DIGEST_KEY_PURPOSES = [name[0] for name in KEY_PURPOSES if name[2] == "DIGEST"]
|
|
413
|
+
|
|
414
|
+
def check_format(self, new_value_str):
|
|
415
|
+
# str convert to int: "XTS_AES_128_KEY" - > str(4)
|
|
416
|
+
# if int: 4 -> str(4)
|
|
417
|
+
raw_val = new_value_str
|
|
418
|
+
for purpose_name in self.KEY_PURPOSES:
|
|
419
|
+
if purpose_name[0] == new_value_str:
|
|
420
|
+
raw_val = str(purpose_name[1])
|
|
421
|
+
break
|
|
422
|
+
if raw_val.isdigit():
|
|
423
|
+
if int(raw_val) not in [p[1] for p in self.KEY_PURPOSES if p[1] > 0]:
|
|
424
|
+
raise esptool.FatalError("'%s' can not be set (value out of range)" % raw_val)
|
|
425
|
+
else:
|
|
426
|
+
raise esptool.FatalError("'%s' unknown name" % raw_val)
|
|
427
|
+
return raw_val
|
|
428
|
+
|
|
429
|
+
def need_reverse(self, new_key_purpose):
|
|
430
|
+
for key in self.KEY_PURPOSES:
|
|
431
|
+
if key[0] == new_key_purpose:
|
|
432
|
+
return key[3] == "Reverse"
|
|
433
|
+
|
|
434
|
+
def need_rd_protect(self, new_key_purpose):
|
|
435
|
+
for key in self.KEY_PURPOSES:
|
|
436
|
+
if key[0] == new_key_purpose:
|
|
437
|
+
return key[4] == "need_rd_protect"
|
|
438
|
+
|
|
439
|
+
def get(self, from_read=True):
|
|
440
|
+
for p in self.KEY_PURPOSES:
|
|
441
|
+
if p[1] == self.get_raw(from_read):
|
|
442
|
+
return p[0]
|
|
443
|
+
return "FORBIDDEN_STATE"
|
|
444
|
+
|
|
445
|
+
def get_name(self, raw_val):
|
|
446
|
+
for key in self.KEY_PURPOSES:
|
|
447
|
+
if key[1] == raw_val:
|
|
448
|
+
return key[0]
|
|
449
|
+
|
|
450
|
+
def save(self, new_value):
|
|
451
|
+
raw_val = int(self.check_format(str(new_value)))
|
|
452
|
+
return super(EfuseKeyPurposeField, self).save(raw_val)
|