esptool 4.8.dev3__tar.gz → 4.8.dev5__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 (161) hide show
  1. {esptool-4.8.dev3 → esptool-4.8.dev5}/MANIFEST.in +2 -2
  2. esptool-4.8.dev5/PKG-INFO +53 -0
  3. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/__init__.py +54 -6
  4. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/base_fields.py +22 -4
  5. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/base_operations.py +121 -49
  6. esptool-4.8.dev5/espefuse/efuse/csv_table_parser.py +266 -0
  7. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32/emulate_efuse_controller.py +2 -7
  8. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32/fields.py +9 -2
  9. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32/mem_definition.py +2 -2
  10. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c2/emulate_efuse_controller.py +1 -1
  11. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c2/fields.py +9 -2
  12. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c2/mem_definition.py +2 -2
  13. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c3/emulate_efuse_controller.py +1 -1
  14. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c3/fields.py +9 -2
  15. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c3/mem_definition.py +2 -2
  16. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5/emulate_efuse_controller.py +1 -1
  17. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5/fields.py +9 -2
  18. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5/mem_definition.py +3 -3
  19. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5/operations.py +9 -2
  20. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5beta3/emulate_efuse_controller.py +1 -1
  21. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5beta3/fields.py +9 -2
  22. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5beta3/mem_definition.py +2 -2
  23. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5beta3/operations.py +9 -2
  24. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c6/emulate_efuse_controller.py +1 -1
  25. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c6/fields.py +9 -2
  26. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c6/mem_definition.py +2 -2
  27. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c61/emulate_efuse_controller.py +1 -1
  28. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c61/fields.py +9 -2
  29. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c61/mem_definition.py +4 -3
  30. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c61/operations.py +1 -1
  31. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2/emulate_efuse_controller.py +1 -1
  32. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2/fields.py +9 -2
  33. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2/mem_definition.py +2 -2
  34. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2beta1/emulate_efuse_controller.py +1 -1
  35. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2beta1/fields.py +9 -2
  36. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2beta1/mem_definition.py +4 -3
  37. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32p4/emulate_efuse_controller.py +1 -1
  38. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32p4/fields.py +9 -2
  39. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32p4/mem_definition.py +4 -3
  40. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s2/emulate_efuse_controller.py +1 -1
  41. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s2/fields.py +9 -2
  42. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s2/mem_definition.py +2 -2
  43. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3/emulate_efuse_controller.py +1 -1
  44. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3/fields.py +31 -2
  45. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3/mem_definition.py +2 -2
  46. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3beta2/emulate_efuse_controller.py +1 -1
  47. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3beta2/fields.py +31 -2
  48. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3beta2/mem_definition.py +2 -2
  49. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/mem_definition_base.py +67 -6
  50. {esptool-4.8.dev3 → esptool-4.8.dev5}/espsecure/__init__.py +157 -71
  51. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/__init__.py +67 -7
  52. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/bin_image.py +34 -18
  53. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/cmds.py +127 -60
  54. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/loader.py +51 -20
  55. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/reset.py +29 -16
  56. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32.py +3 -1
  57. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32c2.py +3 -0
  58. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32c3.py +22 -3
  59. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32c5.py +84 -2
  60. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32c5beta3.py +18 -0
  61. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32c6.py +7 -3
  62. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32c61.py +21 -0
  63. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32h2.py +18 -0
  64. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32h2beta1.py +26 -4
  65. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32p4.py +26 -4
  66. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32s2.py +24 -3
  67. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32s3.py +34 -3
  68. esptool-4.8.dev5/esptool/targets/stub_flasher/1/README.md +3 -0
  69. esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32c5.json +8 -0
  70. esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32c5beta3.json +8 -0
  71. esptool-4.8.dev5/esptool/targets/stub_flasher/2/LICENSE-APACHE +201 -0
  72. esptool-4.8.dev5/esptool/targets/stub_flasher/2/LICENSE-MIT +25 -0
  73. esptool-4.8.dev5/esptool/targets/stub_flasher/2/README.md +3 -0
  74. esptool-4.8.dev5/esptool/targets/stub_flasher/2/esp32.json +1 -0
  75. esptool-4.8.dev5/esptool/targets/stub_flasher/2/esp32c2.json +1 -0
  76. esptool-4.8.dev5/esptool/targets/stub_flasher/2/esp32c3.json +1 -0
  77. esptool-4.8.dev5/esptool/targets/stub_flasher/2/esp32c6.json +1 -0
  78. esptool-4.8.dev5/esptool/targets/stub_flasher/2/esp32h2.json +1 -0
  79. esptool-4.8.dev5/esptool/targets/stub_flasher/2/esp32s2.json +1 -0
  80. esptool-4.8.dev5/esptool/targets/stub_flasher/2/esp32s3.json +1 -0
  81. esptool-4.8.dev5/esptool.egg-info/PKG-INFO +53 -0
  82. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool.egg-info/SOURCES.txt +28 -14
  83. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool.egg-info/requires.txt +3 -0
  84. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool.egg-info/top_level.txt +3 -0
  85. esptool-4.8.dev5/pyproject.toml +166 -0
  86. esptool-4.8.dev5/setup.py +21 -0
  87. esptool-4.8.dev3/PKG-INFO +0 -46
  88. esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32c5beta3.json +0 -8
  89. esptool-4.8.dev3/esptool.egg-info/PKG-INFO +0 -46
  90. esptool-4.8.dev3/setup.py +0 -137
  91. {esptool-4.8.dev3 → esptool-4.8.dev5}/LICENSE +0 -0
  92. {esptool-4.8.dev3 → esptool-4.8.dev5}/README.md +0 -0
  93. {esptool-4.8.dev3 → esptool-4.8.dev5}/esp_rfc2217_server.py +0 -0
  94. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/__main__.py +0 -0
  95. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/__init__.py +0 -0
  96. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/emulate_efuse_controller_base.py +0 -0
  97. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32/__init__.py +0 -0
  98. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32/operations.py +0 -0
  99. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c2/__init__.py +0 -0
  100. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c2/operations.py +0 -0
  101. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c3/__init__.py +0 -0
  102. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c3/operations.py +0 -0
  103. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5/__init__.py +0 -0
  104. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c5beta3/__init__.py +0 -0
  105. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c6/__init__.py +0 -0
  106. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c6/operations.py +0 -0
  107. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32c61/__init__.py +0 -0
  108. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2/__init__.py +0 -0
  109. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2/operations.py +0 -0
  110. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2beta1/__init__.py +0 -0
  111. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32h2beta1/operations.py +0 -0
  112. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32p4/__init__.py +0 -0
  113. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32p4/operations.py +0 -0
  114. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s2/__init__.py +0 -0
  115. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s2/operations.py +0 -0
  116. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3/__init__.py +0 -0
  117. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3/operations.py +0 -0
  118. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3beta2/__init__.py +0 -0
  119. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/esp32s3beta2/operations.py +0 -0
  120. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse/util.py +0 -0
  121. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32.yaml +0 -0
  122. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32c2.yaml +0 -0
  123. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32c3.yaml +0 -0
  124. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32c5.yaml +0 -0
  125. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32c5beta3.yaml +0 -0
  126. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32c6.yaml +0 -0
  127. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32c61.yaml +0 -0
  128. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32h2.yaml +0 -0
  129. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32p4.yaml +0 -0
  130. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32s2.yaml +0 -0
  131. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse/efuse_defs/esp32s3.yaml +0 -0
  132. {esptool-4.8.dev3 → esptool-4.8.dev5}/espefuse.py +0 -0
  133. {esptool-4.8.dev3 → esptool-4.8.dev5}/espsecure/__main__.py +0 -0
  134. {esptool-4.8.dev3 → esptool-4.8.dev5}/espsecure/esp_hsm_sign/__init__.py +0 -0
  135. {esptool-4.8.dev3 → esptool-4.8.dev5}/espsecure/esp_hsm_sign/exceptions.py +0 -0
  136. {esptool-4.8.dev3 → esptool-4.8.dev5}/espsecure.py +0 -0
  137. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/__main__.py +0 -0
  138. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/config.py +0 -0
  139. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/__init__.py +0 -0
  140. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32c6beta.py +0 -0
  141. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32h2beta2.py +0 -0
  142. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp32s3beta2.py +0 -0
  143. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/targets/esp8266.py +0 -0
  144. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32.json +0 -0
  145. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32c2.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32c2.json +0 -0
  146. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32c3.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32c3.json +0 -0
  147. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32c6.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32c6.json +0 -0
  148. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32c6beta.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32c6beta.json +0 -0
  149. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32h2.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32h2.json +0 -0
  150. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32h2beta1.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32h2beta1.json +0 -0
  151. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32h2beta2.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32h2beta2.json +0 -0
  152. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32p4.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32p4.json +0 -0
  153. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32s2.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32s2.json +0 -0
  154. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32s3.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32s3.json +0 -0
  155. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_32s3beta2.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp32s3beta2.json +0 -0
  156. /esptool-4.8.dev3/esptool/targets/stub_flasher/stub_flasher_8266.json → /esptool-4.8.dev5/esptool/targets/stub_flasher/1/esp8266.json +0 -0
  157. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/uf2_writer.py +0 -0
  158. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool/util.py +0 -0
  159. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool.egg-info/dependency_links.txt +0 -0
  160. {esptool-4.8.dev3 → esptool-4.8.dev5}/esptool.py +0 -0
  161. {esptool-4.8.dev3 → esptool-4.8.dev5}/setup.cfg +0 -0
@@ -1,11 +1,11 @@
1
1
  include README.md
2
2
  include LICENSE
3
- include esptool/targets/stub_flasher/*.json
3
+ include esptool/targets/stub_flasher/1/*
4
+ include esptool/targets/stub_flasher/2/*
4
5
  include espefuse/efuse_defs/*.yaml
5
6
  # sdist includes test/test*.py by default, but esptool.py tests
6
7
  # are so far only intended to run from the git repo itself
7
8
  prune test
8
- prune flasher_stub
9
9
  prune .github
10
10
  prune docs
11
11
  exclude .git*
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.1
2
+ Name: esptool
3
+ Version: 4.8.dev5
4
+ Summary: A serial utility to communicate & flash code to Espressif chips.
5
+ Author: Fredrik Ahlberg (themadinventor), Angus Gratton (projectgus), Espressif Systems
6
+ License: GPLv2+
7
+ Project-URL: Homepage, https://github.com/espressif/esptool/
8
+ Project-URL: Documentation, https://docs.espressif.com/projects/esptool/
9
+ Project-URL: Source, https://github.com/espressif/esptool/
10
+ Project-URL: Tracker, https://github.com/espressif/esptool/issues/
11
+ Project-URL: Changelog, https://github.com/espressif/esptool/blob/master/CHANGELOG.md
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Natural Language :: English
15
+ Classifier: Operating System :: POSIX
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: MacOS :: MacOS X
18
+ Classifier: Topic :: Software Development :: Embedded Systems
19
+ Classifier: Environment :: Console
20
+ Classifier: License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
21
+ Classifier: Programming Language :: Python :: 3.7
22
+ Classifier: Programming Language :: Python :: 3.8
23
+ Classifier: Programming Language :: Python :: 3.9
24
+ Classifier: Programming Language :: Python :: 3.10
25
+ Classifier: Programming Language :: Python :: 3.11
26
+ Classifier: Programming Language :: Python :: 3.12
27
+ Requires-Python: >=3.7
28
+ Description-Content-Type: text/markdown
29
+ Provides-Extra: dev
30
+ Provides-Extra: hsm
31
+ License-File: LICENSE
32
+
33
+ # esptool.py
34
+
35
+ A Python-based, open-source, platform-independent utility to communicate with the ROM bootloader in Espressif chips.
36
+
37
+ [![Test esptool](https://github.com/espressif/esptool/actions/workflows/test_esptool.yml/badge.svg?branch=master)](https://github.com/espressif/esptool/actions/workflows/test_esptool.yml) [![Build esptool](https://github.com/espressif/esptool/actions/workflows/build_esptool.yml/badge.svg?branch=master)](https://github.com/espressif/esptool/actions/workflows/build_esptool.yml)
38
+
39
+ ## Documentation
40
+
41
+ Visit the [documentation](https://docs.espressif.com/projects/esptool/) or run `esptool.py -h`.
42
+
43
+ ## Contribute
44
+
45
+ If you're interested in contributing to esptool.py, please check the [contributions guide](https://docs.espressif.com/projects/esptool/en/latest/contributing.html).
46
+
47
+ ## About
48
+
49
+ esptool.py was initially created by Fredrik Ahlberg (@[themadinventor](https://github.com/themadinventor/)), and later maintained by Angus Gratton (@[projectgus](https://github.com/projectgus/)). It is now supported by Espressif Systems. It has also received improvements from many members of the community.
50
+
51
+ ## License
52
+
53
+ This document and the attached source code are released as Free Software under GNU General Public License Version 2 or later. See the accompanying [LICENSE file](https://github.com/espressif/esptool/blob/master/LICENSE) for a copy.
@@ -1,6 +1,7 @@
1
1
  # SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
2
2
  #
3
3
  # SPDX-License-Identifier: GPL-2.0-or-later
4
+ # PYTHON_ARGCOMPLETE_OK
4
5
 
5
6
  import argparse
6
7
  import os
@@ -39,13 +40,15 @@ SUPPORTED_BURN_COMMANDS = [
39
40
  "execute_scripts",
40
41
  ]
41
42
 
42
- SUPPORTED_COMMANDS = [
43
+ SUPPORTED_READ_COMMANDS = [
43
44
  "summary",
44
45
  "dump",
45
46
  "get_custom_mac",
46
47
  "adc_info",
47
48
  "check_error",
48
- ] + SUPPORTED_BURN_COMMANDS
49
+ ]
50
+
51
+ SUPPORTED_COMMANDS = SUPPORTED_READ_COMMANDS + SUPPORTED_BURN_COMMANDS
49
52
 
50
53
  SUPPORTED_CHIPS = {
51
54
  "esp32": DefChip("ESP32", esp32_efuse, esptool.targets.ESP32ROM),
@@ -94,15 +97,25 @@ def get_esp(
94
97
  )
95
98
  if not skip_connect:
96
99
  esp.connect(connect_mode)
100
+ if esp.sync_stub_detected:
101
+ esp = esp.STUB_CLASS(esp)
97
102
  return esp
98
103
 
99
104
 
100
- def get_efuses(esp, skip_connect=False, debug_mode=False, do_not_confirm=False):
105
+ def get_efuses(
106
+ esp,
107
+ skip_connect=False,
108
+ debug_mode=False,
109
+ do_not_confirm=False,
110
+ extend_efuse_table=None,
111
+ ):
101
112
  for name in SUPPORTED_CHIPS:
102
113
  if SUPPORTED_CHIPS[name].chip_name == esp.CHIP_NAME:
103
114
  efuse = SUPPORTED_CHIPS[name].efuse_lib
104
115
  return (
105
- efuse.EspEfuses(esp, skip_connect, debug_mode, do_not_confirm),
116
+ efuse.EspEfuses(
117
+ esp, skip_connect, debug_mode, do_not_confirm, extend_efuse_table
118
+ ),
106
119
  efuse.operations,
107
120
  )
108
121
  else:
@@ -224,9 +237,15 @@ def main(custom_commandline=None, esp=None):
224
237
  "(efuses which disable access to blocks or chip).",
225
238
  action="store_true",
226
239
  )
240
+ init_parser.add_argument(
241
+ "--extend-efuse-table",
242
+ help="CSV file from ESP-IDF (esp_efuse_custom_table.csv)",
243
+ type=argparse.FileType("r"),
244
+ default=None,
245
+ )
227
246
 
228
247
  common_args, remaining_args = init_parser.parse_known_args(custom_commandline)
229
- debug_mode = common_args.debug or ("dump" in remaining_args)
248
+ debug_mode = common_args.debug
230
249
  just_print_help = [
231
250
  True for arg in remaining_args if arg in ["--help", "-h"]
232
251
  ] or remaining_args == []
@@ -253,7 +272,11 @@ def main(custom_commandline=None, esp=None):
253
272
  # TODO: Require the --port argument in the next major release, ESPTOOL-490
254
273
 
255
274
  efuses, efuse_operations = get_efuses(
256
- esp, just_print_help, debug_mode, common_args.do_not_confirm
275
+ esp,
276
+ just_print_help,
277
+ debug_mode,
278
+ common_args.do_not_confirm,
279
+ common_args.extend_efuse_table,
257
280
  )
258
281
 
259
282
  parser = argparse.ArgumentParser(parents=[init_parser])
@@ -263,6 +286,15 @@ def main(custom_commandline=None, esp=None):
263
286
 
264
287
  efuse_operations.add_commands(subparsers, efuses)
265
288
 
289
+ # Enable argcomplete only on Unix-like systems
290
+ if sys.platform != "win32":
291
+ try:
292
+ import argcomplete
293
+
294
+ argcomplete.autocomplete(parser)
295
+ except ImportError:
296
+ pass
297
+
266
298
  grouped_remaining_args, used_cmds = split_on_groups(remaining_args)
267
299
  if len(grouped_remaining_args) == 0:
268
300
  parser.print_help()
@@ -302,6 +334,22 @@ def main(custom_commandline=None, esp=None):
302
334
  if not efuses.burn_all(check_batch_mode=True):
303
335
  raise esptool.FatalError("BURN was not done")
304
336
  print("Successful")
337
+
338
+ if (
339
+ sum(cmd in SUPPORTED_BURN_COMMANDS for cmd in used_cmds) > 0
340
+ and sum(cmd in SUPPORTED_READ_COMMANDS for cmd in used_cmds) > 0
341
+ ):
342
+ # [burn_cmd1] [burn_cmd2] [read_cmd1] [burn_cmd3] [read_cmd2]
343
+ print("\n=== Run read commands after burn commands ===")
344
+ for rem_args in grouped_remaining_args:
345
+ args, unused_args = parser.parse_known_args(
346
+ rem_args, namespace=common_args
347
+ )
348
+ current_cmd = args.operation
349
+ if current_cmd in SUPPORTED_READ_COMMANDS:
350
+ print(f"\n=== Run {args.operation} command ===")
351
+ operation_func = vars(efuse_operations)[current_cmd]
352
+ operation_func(esp, efuses, args)
305
353
  finally:
306
354
  if not external_esp and not common_args.virt and esp._port:
307
355
  esp._port.close()
@@ -12,6 +12,7 @@ from bitstring import BitArray, BitStream, CreationError
12
12
  import esptool
13
13
 
14
14
  from . import util
15
+ from typing import List
15
16
 
16
17
 
17
18
  class CheckArgValue(object):
@@ -227,13 +228,14 @@ class EfuseBlockBase(EfuseProtectBase):
227
228
 
228
229
  return [self.parent.read_reg(offs) for offs in get_offsets(self)]
229
230
 
230
- def read(self):
231
+ def read(self, print_info=True):
231
232
  words = self.get_words()
232
233
  data = BitArray()
233
234
  for word in reversed(words):
234
235
  data.append("uint:32=%d" % word)
235
236
  self.bitarray.overwrite(data, pos=0)
236
- self.print_block(self.bitarray, "read_regs")
237
+ if print_info:
238
+ self.print_block(self.bitarray, "read_regs")
237
239
 
238
240
  def print_block(self, bit_string, comment, debug=False):
239
241
  if self.parent.debug or debug:
@@ -385,6 +387,18 @@ class EfuseBlockBase(EfuseProtectBase):
385
387
  )
386
388
  break
387
389
  if not self.fail and self.num_errors == 0:
390
+ self.read(print_info=False)
391
+ if self.wr_bitarray & self.bitarray != self.wr_bitarray:
392
+ # if the required bits are not set then we need to re-burn it again.
393
+ if burns < 2:
394
+ print(
395
+ f"\nRepeat burning BLOCK{self.id} (#{burns + 2}) because not all bits were set"
396
+ )
397
+ continue
398
+ else:
399
+ print(
400
+ f"\nAfter {burns + 1} attempts, the required data was not set to BLOCK{self.id}"
401
+ )
388
402
  break
389
403
 
390
404
  def burn(self):
@@ -441,8 +455,8 @@ class EspEfusesBase(object):
441
455
  """
442
456
 
443
457
  _esp = None
444
- blocks = []
445
- efuses = []
458
+ blocks: List[EfuseBlockBase] = []
459
+ efuses: List = []
446
460
  coding_scheme = None
447
461
  force_write_always = None
448
462
  batch_mode_cnt = 0
@@ -635,6 +649,10 @@ class EspEfusesBase(object):
635
649
  """Returns (error count, failure boolean flag)"""
636
650
  return self.blocks[block_num].num_errors, self.blocks[block_num].fail
637
651
 
652
+ def is_efuses_incompatible_for_burn(self):
653
+ # Overwrite this function for a specific target if you want to check if a certain eFuse(s) can be burned.
654
+ return False
655
+
638
656
 
639
657
  class EfuseFieldBase(EfuseProtectBase):
640
658
  def __init__(self, parent, param):
@@ -5,6 +5,7 @@
5
5
  # SPDX-License-Identifier: GPL-2.0-or-later
6
6
 
7
7
  import argparse
8
+ import os
8
9
  import json
9
10
  import sys
10
11
 
@@ -65,16 +66,20 @@ def add_common_commands(subparsers, efuses):
65
66
  )
66
67
  burn.add_argument(
67
68
  "name_value_pairs",
68
- help="Name of efuse register and New value pairs to burn",
69
+ help="Name of efuse field and new value pairs to burn. EFUSE_NAME: "
70
+ "[{}].".format(", ".join([e.name for e in efuses.efuses])),
69
71
  action=ActionEfuseValuePair,
70
72
  nargs="+",
71
- metavar="[EFUSE_NAME VALUE] [{} VALUE".format(
72
- " VALUE] [".join([e.name for e in efuses.efuses])
73
- ),
73
+ metavar="[EFUSE_NAME VALUE]",
74
74
  efuse_choices=[e.name for e in efuses.efuses]
75
75
  + [name for e in efuses.efuses for name in e.alt_names if name != ""],
76
76
  efuses=efuses,
77
77
  )
78
+ burn.add_argument(
79
+ "--force",
80
+ help="Suppress an error to burn eFuses",
81
+ action="store_true",
82
+ )
78
83
 
79
84
  read_protect_efuse = subparsers.add_parser(
80
85
  "read_protect_efuse",
@@ -169,12 +174,22 @@ def add_common_commands(subparsers, efuses):
169
174
  help="Display information about ADC calibration data stored in efuse.",
170
175
  )
171
176
 
172
- dump_cmd = subparsers.add_parser("dump", help="Dump raw hex values of all efuses")
177
+ dump_cmd = subparsers.add_parser("dump", help="Dump raw hex values of all eFuses")
178
+ dump_cmd.add_argument(
179
+ "--format",
180
+ help="Select the dump format: "
181
+ "default - usual console eFuse dump; "
182
+ "joint - all eFuse blocks are stored in one file; "
183
+ "split - each eFuse block is placed into its own file. The tool will create multiple files based on "
184
+ "the given --file_name (/path/blk.bin): blk0.bin, blk1.bin ... blkN.bin. Use the burn_block_data cmd "
185
+ "to write it back to another chip.",
186
+ choices=["default", "split", "joint"],
187
+ default="default",
188
+ )
173
189
  dump_cmd.add_argument(
174
190
  "--file_name",
175
- help="Saves dump for each block into separate file. Provide the common "
176
- "path name /path/blk.bin, it will create: blk0.bin, blk1.bin ... blkN.bin. "
177
- "Use burn_block_data to write it back to another chip.",
191
+ help="The path to the file in which to save the dump, if not specified, output to the console.",
192
+ default=sys.stdout,
178
193
  )
179
194
 
180
195
  summary_cmd = subparsers.add_parser(
@@ -183,7 +198,7 @@ def add_common_commands(subparsers, efuses):
183
198
  summary_cmd.add_argument(
184
199
  "--format",
185
200
  help="Select the summary format",
186
- choices=["summary", "json"],
201
+ choices=["summary", "json", "value_only"],
187
202
  default="summary",
188
203
  )
189
204
  summary_cmd.add_argument(
@@ -192,6 +207,11 @@ def add_common_commands(subparsers, efuses):
192
207
  type=argparse.FileType("w"),
193
208
  default=sys.stdout,
194
209
  )
210
+ summary_cmd.add_argument(
211
+ "efuses_to_show",
212
+ help="The efuses to show. If not provided, all efuses will be shown.",
213
+ nargs="*",
214
+ )
195
215
 
196
216
  execute_scripts = subparsers.add_parser(
197
217
  "execute_scripts", help="Executes scripts to burn at one time."
@@ -246,14 +266,21 @@ def add_show_sensitive_info_option(p):
246
266
 
247
267
 
248
268
  def summary(esp, efuses, args):
249
- """Print a human-readable summary of efuse contents"""
269
+ """Print a human-readable or json summary of efuse contents"""
250
270
  ROW_FORMAT = "%-50s %-50s%s = %s %s %s"
251
- human_output = args.format == "summary"
271
+ human_output = args.format in ["summary", "value_only"]
272
+ value_only = args.format == "value_only"
273
+ if value_only and len(args.efuses_to_show) != 1:
274
+ raise esptool.FatalError(
275
+ "The 'value_only' format can be used exactly for one efuse."
276
+ )
277
+ do_filtering = bool(args.efuses_to_show)
252
278
  json_efuse = {}
279
+ summary_efuse = []
253
280
  if args.file != sys.stdout:
254
281
  print("Saving efuse values to " + args.file.name)
255
- if human_output:
256
- print(
282
+ if human_output and not value_only:
283
+ summary_efuse.append(
257
284
  ROW_FORMAT.replace("-50", "-12")
258
285
  % (
259
286
  "EFUSE_NAME (Block)",
@@ -262,13 +289,12 @@ def summary(esp, efuses, args):
262
289
  "[Meaningful Value]",
263
290
  "[Readable/Writeable]",
264
291
  "(Hex Value)",
265
- ),
266
- file=args.file,
292
+ )
267
293
  )
268
- print("-" * 88, file=args.file)
294
+ summary_efuse.append("-" * 88)
269
295
  for category in sorted(set(e.category for e in efuses), key=lambda c: c.title()):
270
- if human_output:
271
- print("%s fuses:" % category.title(), file=args.file)
296
+ if human_output and not value_only:
297
+ summary_efuse.append(f"{category.title()} fuses:")
272
298
  for e in (e for e in efuses if e.category == category):
273
299
  if e.efuse_type.startswith("bytes"):
274
300
  raw = ""
@@ -297,8 +323,12 @@ def summary(esp, efuses, args):
297
323
  value = "".join(v)
298
324
  else:
299
325
  value = value.replace("0", "?")
300
- if human_output:
301
- print(
326
+ if (
327
+ human_output
328
+ and (not do_filtering or e.name in args.efuses_to_show)
329
+ and not value_only
330
+ ):
331
+ summary_efuse.append(
302
332
  ROW_FORMAT
303
333
  % (
304
334
  e.get_info(),
@@ -307,18 +337,20 @@ def summary(esp, efuses, args):
307
337
  value,
308
338
  perms,
309
339
  raw,
310
- ),
311
- file=args.file,
340
+ )
312
341
  )
313
342
  desc_len = len(e.description[50:])
314
343
  if desc_len:
315
344
  desc_len += 50
316
345
  for i in range(50, desc_len, 50):
317
- print(
318
- "%-50s %-50s" % ("", e.description[i : (50 + i)]),
319
- file=args.file,
346
+ summary_efuse.append(
347
+ f"{'':<50} {e.description[i : (50 + i)]:<50}"
320
348
  )
321
- if args.format == "json":
349
+ elif human_output and value_only and e.name in args.efuses_to_show:
350
+ summary_efuse.append(f"{value}")
351
+ elif args.format == "json" and (
352
+ not do_filtering or e.name in args.efuses_to_show
353
+ ):
322
354
  json_efuse[e.name] = {
323
355
  "name": e.name,
324
356
  "value": base_value if readable else value,
@@ -332,42 +364,74 @@ def summary(esp, efuses, args):
332
364
  "efuse_type": e.efuse_type,
333
365
  "bit_len": e.bit_len,
334
366
  }
335
- if human_output:
336
- print("", file=args.file)
337
- if human_output:
338
- print(efuses.summary(), file=args.file)
367
+ if human_output and not value_only:
368
+ # Remove empty category if efuses are filtered and there are none to show
369
+ if do_filtering and summary_efuse[-1] == f"{category.title()} fuses:":
370
+ summary_efuse.pop()
371
+ else:
372
+ summary_efuse.append("")
373
+ if human_output and not value_only:
374
+ summary_efuse.append(efuses.summary())
339
375
  warnings = efuses.get_coding_scheme_warnings()
340
376
  if warnings:
341
- print(
342
- "WARNING: Coding scheme has encoding bit error warnings", file=args.file
377
+ summary_efuse.append(
378
+ "WARNING: Coding scheme has encoding bit error warnings"
343
379
  )
380
+ if human_output:
381
+ for line in summary_efuse:
382
+ print(line, file=args.file)
344
383
  if args.file != sys.stdout:
345
384
  args.file.close()
346
385
  print("Done")
347
- if args.format == "json":
386
+ elif args.format == "json":
348
387
  json.dump(json_efuse, args.file, sort_keys=True, indent=4)
349
388
  print("")
350
389
 
351
390
 
352
391
  def dump(esp, efuses, args):
353
392
  """Dump raw efuse data registers"""
354
- # Using --debug option allows to print dump.
355
- # Nothing to do here. The log will be printed
356
- # during EspEfuses.__init__() in self.read_blocks()
357
- if args.file_name:
358
- # save dump to the file
393
+ dump_file = args.file_name
394
+ to_console = args.file_name == sys.stdout
395
+
396
+ def output_block_to_file(block, f, to_console):
397
+ block_dump = BitStream(block.get_bitstring())
398
+ block_dump.byteswap()
399
+ if to_console:
400
+ f.write(block_dump.hex + "\n")
401
+ else:
402
+ block_dump.tofile(f)
403
+
404
+ if args.format == "default":
405
+ if to_console:
406
+ # for "espefuse.py dump" cmd
407
+ for block in efuses.blocks:
408
+ block.print_block(block.get_bitstring(), "dump", debug=True)
409
+ return
410
+ else:
411
+ # for back compatibility to support "espefuse.py dump --file_name dump.bin"
412
+ args.format = "split"
413
+
414
+ if args.format == "split":
415
+ # each efuse block is placed into its own file
359
416
  for block in efuses.blocks:
360
- file_dump_name = args.file_name
361
- place_for_index = file_dump_name.find(".bin")
362
- file_dump_name = (
363
- file_dump_name[:place_for_index]
364
- + str(block.id)
365
- + file_dump_name[place_for_index:]
366
- )
367
- print(file_dump_name)
368
- with open(file_dump_name, "wb") as f:
369
- block.get_bitstring().byteswap()
370
- block.get_bitstring().tofile(f)
417
+ if not to_console:
418
+ file_dump_name = args.file_name
419
+ fname, fextension = os.path.splitext(file_dump_name)
420
+ file_dump_name = f"{fname}{block.id}{fextension}"
421
+ print(f"Dump efuse block{block.id} -> {file_dump_name}")
422
+ dump_file = open(file_dump_name, "wb")
423
+ output_block_to_file(block, dump_file, to_console)
424
+ if not to_console:
425
+ dump_file.close()
426
+ elif args.format == "joint":
427
+ # all efuse blocks are stored in one file
428
+ if not to_console:
429
+ print(f"Dump efuse blocks -> {args.file_name}")
430
+ dump_file = open(args.file_name, "wb")
431
+ for block in efuses.blocks:
432
+ output_block_to_file(block, dump_file, to_console)
433
+ if not to_console:
434
+ dump_file.close()
371
435
 
372
436
 
373
437
  def burn_efuse(esp, efuses, args):
@@ -457,6 +521,14 @@ def burn_efuse(esp, efuses, args):
457
521
  )
458
522
  print(" espefuse/esptool will not work.")
459
523
 
524
+ if efuses.is_efuses_incompatible_for_burn():
525
+ if args.force:
526
+ print("Ignore incompatible eFuse settings.")
527
+ else:
528
+ raise esptool.FatalError(
529
+ "Incompatible eFuse settings detected, abort. (use --force flag to skip it)."
530
+ )
531
+
460
532
  if not efuses.burn_all(check_batch_mode=True):
461
533
  return
462
534