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