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.
Files changed (179) hide show
  1. {esptool-4.9.dev5/esptool.egg-info → esptool-4.9.dev7}/PKG-INFO +3 -2
  2. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/__init__.py +2 -0
  3. esptool-4.9.dev7/espefuse/efuse/esp32h4/emulate_efuse_controller.py +92 -0
  4. esptool-4.9.dev7/espefuse/efuse/esp32h4/fields.py +452 -0
  5. esptool-4.9.dev7/espefuse/efuse/esp32h4/mem_definition.py +169 -0
  6. esptool-4.9.dev7/espefuse/efuse/esp32h4/operations.py +389 -0
  7. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/operations.py +6 -2
  8. esptool-4.9.dev7/espefuse/efuse/esp32s3beta2/__init__.py +3 -0
  9. esptool-4.9.dev7/espefuse/efuse_defs/esp32h4.yaml +92 -0
  10. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32p4.yaml +1 -1
  11. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/__init__.py +11 -5
  12. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/bin_image.py +44 -38
  13. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/cmds.py +104 -55
  14. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/__init__.py +2 -0
  15. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c5.py +2 -0
  16. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h21.py +30 -0
  17. esptool-4.9.dev7/esptool/targets/esp32h4.py +213 -0
  18. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/README.md +1 -1
  19. esptool-4.9.dev7/esptool/targets/stub_flasher/1/esp32p4.json +8 -0
  20. esptool-4.9.dev7/esptool/targets/stub_flasher/1/esp32s3.json +8 -0
  21. {esptool-4.9.dev5 → esptool-4.9.dev7/esptool.egg-info}/PKG-INFO +3 -2
  22. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/SOURCES.txt +7 -0
  23. esptool-4.9.dev5/esptool/targets/stub_flasher/1/esp32p4.json +0 -8
  24. esptool-4.9.dev5/esptool/targets/stub_flasher/1/esp32s3.json +0 -8
  25. {esptool-4.9.dev5 → esptool-4.9.dev7}/LICENSE +0 -0
  26. {esptool-4.9.dev5 → esptool-4.9.dev7}/MANIFEST.in +0 -0
  27. {esptool-4.9.dev5 → esptool-4.9.dev7}/README.md +0 -0
  28. {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/__init__.py +0 -0
  29. {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/__main__.py +0 -0
  30. {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/esp_port_manager.py +0 -0
  31. {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server/redirector.py +0 -0
  32. {esptool-4.9.dev5 → esptool-4.9.dev7}/esp_rfc2217_server.py +0 -0
  33. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/__main__.py +0 -0
  34. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/__init__.py +0 -0
  35. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/base_fields.py +0 -0
  36. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/base_operations.py +0 -0
  37. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/csv_table_parser.py +0 -0
  38. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/emulate_efuse_controller_base.py +0 -0
  39. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/__init__.py +0 -0
  40. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/emulate_efuse_controller.py +0 -0
  41. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/fields.py +0 -0
  42. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/mem_definition.py +0 -0
  43. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32/operations.py +0 -0
  44. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/__init__.py +0 -0
  45. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/emulate_efuse_controller.py +0 -0
  46. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/fields.py +0 -0
  47. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/mem_definition.py +0 -0
  48. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c2/operations.py +0 -0
  49. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/__init__.py +0 -0
  50. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/emulate_efuse_controller.py +0 -0
  51. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/fields.py +0 -0
  52. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/mem_definition.py +0 -0
  53. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c3/operations.py +0 -0
  54. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/__init__.py +0 -0
  55. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/emulate_efuse_controller.py +0 -0
  56. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/fields.py +0 -0
  57. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/mem_definition.py +0 -0
  58. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5/operations.py +0 -0
  59. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/__init__.py +0 -0
  60. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py +0 -0
  61. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/fields.py +0 -0
  62. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/mem_definition.py +0 -0
  63. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c5beta3/operations.py +0 -0
  64. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/__init__.py +0 -0
  65. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/emulate_efuse_controller.py +0 -0
  66. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/fields.py +0 -0
  67. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/mem_definition.py +0 -0
  68. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c6/operations.py +0 -0
  69. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/__init__.py +0 -0
  70. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/emulate_efuse_controller.py +0 -0
  71. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/fields.py +0 -0
  72. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/mem_definition.py +0 -0
  73. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32c61/operations.py +0 -0
  74. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/__init__.py +0 -0
  75. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/emulate_efuse_controller.py +0 -0
  76. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/fields.py +0 -0
  77. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/mem_definition.py +0 -0
  78. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2/operations.py +0 -0
  79. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/__init__.py +0 -0
  80. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/emulate_efuse_controller.py +0 -0
  81. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/fields.py +0 -0
  82. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/mem_definition.py +0 -0
  83. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h21/operations.py +0 -0
  84. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/__init__.py +0 -0
  85. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py +0 -0
  86. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/fields.py +0 -0
  87. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/mem_definition.py +0 -0
  88. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32h2beta1/operations.py +0 -0
  89. {esptool-4.9.dev5/espefuse/efuse/esp32p4 → esptool-4.9.dev7/espefuse/efuse/esp32h4}/__init__.py +0 -0
  90. {esptool-4.9.dev5/espefuse/efuse/esp32s2 → esptool-4.9.dev7/espefuse/efuse/esp32p4}/__init__.py +0 -0
  91. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/emulate_efuse_controller.py +0 -0
  92. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/fields.py +0 -0
  93. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32p4/mem_definition.py +0 -0
  94. {esptool-4.9.dev5/espefuse/efuse/esp32s3 → esptool-4.9.dev7/espefuse/efuse/esp32s2}/__init__.py +0 -0
  95. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/emulate_efuse_controller.py +0 -0
  96. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/fields.py +0 -0
  97. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/mem_definition.py +0 -0
  98. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s2/operations.py +0 -0
  99. {esptool-4.9.dev5/espefuse/efuse/esp32s3beta2 → esptool-4.9.dev7/espefuse/efuse/esp32s3}/__init__.py +0 -0
  100. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/emulate_efuse_controller.py +0 -0
  101. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/fields.py +0 -0
  102. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/mem_definition.py +0 -0
  103. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3/operations.py +0 -0
  104. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py +0 -0
  105. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/fields.py +0 -0
  106. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/mem_definition.py +0 -0
  107. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/esp32s3beta2/operations.py +0 -0
  108. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/mem_definition_base.py +0 -0
  109. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse/util.py +0 -0
  110. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32.yaml +0 -0
  111. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c2.yaml +0 -0
  112. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c3.yaml +0 -0
  113. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c5.yaml +0 -0
  114. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c5beta3.yaml +0 -0
  115. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c6.yaml +0 -0
  116. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32c61.yaml +0 -0
  117. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32h2.yaml +0 -0
  118. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32h21.yaml +0 -0
  119. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32h2_v0.0_v1.1.yaml +0 -0
  120. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32s2.yaml +0 -0
  121. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse/efuse_defs/esp32s3.yaml +0 -0
  122. {esptool-4.9.dev5 → esptool-4.9.dev7}/espefuse.py +0 -0
  123. {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/__init__.py +0 -0
  124. {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/__main__.py +0 -0
  125. {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/esp_hsm_sign/__init__.py +0 -0
  126. {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure/esp_hsm_sign/exceptions.py +0 -0
  127. {esptool-4.9.dev5 → esptool-4.9.dev7}/espsecure.py +0 -0
  128. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/__main__.py +0 -0
  129. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/config.py +0 -0
  130. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/loader.py +0 -0
  131. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/reset.py +0 -0
  132. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32.py +0 -0
  133. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c2.py +0 -0
  134. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c3.py +0 -0
  135. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c5beta3.py +0 -0
  136. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c6.py +0 -0
  137. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c61.py +0 -0
  138. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32c6beta.py +0 -0
  139. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h2.py +0 -0
  140. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h2beta1.py +0 -0
  141. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32h2beta2.py +0 -0
  142. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32p4.py +0 -0
  143. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32s2.py +0 -0
  144. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32s3.py +0 -0
  145. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp32s3beta2.py +0 -0
  146. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/esp8266.py +0 -0
  147. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32.json +0 -0
  148. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c2.json +0 -0
  149. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c3.json +0 -0
  150. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c5.json +0 -0
  151. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c5beta3.json +0 -0
  152. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c6.json +0 -0
  153. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c61.json +0 -0
  154. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32c6beta.json +0 -0
  155. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32h2.json +0 -0
  156. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32h2beta1.json +0 -0
  157. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32h2beta2.json +0 -0
  158. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32s2.json +0 -0
  159. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp32s3beta2.json +0 -0
  160. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/1/esp8266.json +0 -0
  161. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/LICENSE-APACHE +0 -0
  162. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/LICENSE-MIT +0 -0
  163. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/README.md +0 -0
  164. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32.json +0 -0
  165. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32c2.json +0 -0
  166. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32c3.json +0 -0
  167. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32c6.json +0 -0
  168. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32h2.json +0 -0
  169. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32s2.json +0 -0
  170. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/targets/stub_flasher/2/esp32s3.json +0 -0
  171. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/uf2_writer.py +0 -0
  172. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool/util.py +0 -0
  173. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/dependency_links.txt +0 -0
  174. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/requires.txt +0 -0
  175. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.egg-info/top_level.txt +0 -0
  176. {esptool-4.9.dev5 → esptool-4.9.dev7}/esptool.py +0 -0
  177. {esptool-4.9.dev5 → esptool-4.9.dev7}/pyproject.toml +0 -0
  178. {esptool-4.9.dev5 → esptool-4.9.dev7}/setup.cfg +0 -0
  179. {esptool-4.9.dev5 → esptool-4.9.dev7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: esptool
3
- Version: 4.9.dev5
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)