micropython-stubber 1.20.4__py3-none-any.whl → 1.20.6__py3-none-any.whl

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 (152) hide show
  1. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.6.dist-info}/LICENSE +30 -30
  2. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.6.dist-info}/METADATA +4 -4
  3. micropython_stubber-1.20.6.dist-info/RECORD +159 -0
  4. mpflash/README.md +184 -184
  5. mpflash/libusb_flash.ipynb +203 -203
  6. mpflash/mpflash/add_firmware.py +98 -98
  7. mpflash/mpflash/ask_input.py +236 -226
  8. mpflash/mpflash/bootloader/__init__.py +37 -0
  9. mpflash/mpflash/bootloader/manual.py +102 -0
  10. mpflash/mpflash/bootloader/micropython.py +10 -0
  11. mpflash/mpflash/bootloader/touch1200.py +45 -0
  12. mpflash/mpflash/cli_download.py +129 -128
  13. mpflash/mpflash/cli_flash.py +219 -212
  14. mpflash/mpflash/cli_group.py +98 -92
  15. mpflash/mpflash/cli_list.py +81 -77
  16. mpflash/mpflash/cli_main.py +41 -38
  17. mpflash/mpflash/common.py +164 -151
  18. mpflash/mpflash/config.py +47 -31
  19. mpflash/mpflash/connected.py +74 -74
  20. mpflash/mpflash/download.py +360 -361
  21. mpflash/mpflash/downloaded.py +129 -129
  22. mpflash/mpflash/errors.py +9 -5
  23. mpflash/mpflash/flash.py +52 -69
  24. mpflash/mpflash/flash_esp.py +59 -59
  25. mpflash/mpflash/flash_stm32.py +24 -24
  26. mpflash/mpflash/flash_stm32_cube.py +111 -111
  27. mpflash/mpflash/flash_stm32_dfu.py +101 -101
  28. mpflash/mpflash/flash_uf2.py +67 -67
  29. mpflash/mpflash/flash_uf2_boardid.py +15 -15
  30. mpflash/mpflash/flash_uf2_linux.py +123 -123
  31. mpflash/mpflash/flash_uf2_macos.py +34 -37
  32. mpflash/mpflash/flash_uf2_windows.py +34 -34
  33. mpflash/mpflash/list.py +89 -89
  34. mpflash/mpflash/logger.py +41 -41
  35. mpflash/mpflash/mpboard_id/__init__.py +93 -93
  36. mpflash/mpflash/mpboard_id/add_boards.py +255 -255
  37. mpflash/mpflash/mpboard_id/board.py +37 -37
  38. mpflash/mpflash/mpboard_id/board_id.py +86 -86
  39. mpflash/mpflash/mpboard_id/store.py +43 -43
  40. mpflash/mpflash/mpremoteboard/__init__.py +221 -221
  41. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +141 -141
  42. mpflash/mpflash/mpremoteboard/runner.py +140 -140
  43. mpflash/mpflash/uf2disk.py +12 -12
  44. mpflash/mpflash/vendor/basicgit.py +288 -288
  45. mpflash/mpflash/vendor/click_aliases.py +91 -0
  46. mpflash/mpflash/vendor/dfu.py +165 -165
  47. mpflash/mpflash/vendor/pydfu.py +605 -605
  48. mpflash/mpflash/vendor/readme.md +2 -2
  49. mpflash/mpflash/vendor/versions.py +119 -117
  50. mpflash/mpflash/worklist.py +170 -170
  51. mpflash/poetry.lock +1588 -1623
  52. mpflash/pyproject.toml +60 -60
  53. mpflash/stm32_udev_rules.md +62 -62
  54. stubber/__init__.py +3 -3
  55. stubber/basicgit.py +294 -288
  56. stubber/board/board_info.csv +193 -193
  57. stubber/board/boot.py +34 -34
  58. stubber/board/createstubs.py +986 -987
  59. stubber/board/createstubs_db.py +825 -826
  60. stubber/board/createstubs_db_min.py +331 -331
  61. stubber/board/createstubs_db_mpy.mpy +0 -0
  62. stubber/board/createstubs_lvgl.py +741 -741
  63. stubber/board/createstubs_lvgl_min.py +741 -741
  64. stubber/board/createstubs_mem.py +766 -767
  65. stubber/board/createstubs_mem_min.py +306 -306
  66. stubber/board/createstubs_mem_mpy.mpy +0 -0
  67. stubber/board/createstubs_min.py +294 -294
  68. stubber/board/createstubs_mpy.mpy +0 -0
  69. stubber/board/fw_info.py +141 -141
  70. stubber/board/info.py +183 -183
  71. stubber/board/main.py +19 -19
  72. stubber/board/modulelist.txt +247 -247
  73. stubber/board/pyrightconfig.json +34 -34
  74. stubber/bulk/mcu_stubber.py +454 -455
  75. stubber/codemod/_partials/__init__.py +48 -50
  76. stubber/codemod/_partials/db_main.py +147 -147
  77. stubber/codemod/_partials/lvgl_main.py +77 -77
  78. stubber/codemod/_partials/modules_reader.py +80 -80
  79. stubber/codemod/add_comment.py +53 -53
  80. stubber/codemod/add_method.py +65 -65
  81. stubber/codemod/board.py +317 -317
  82. stubber/codemod/enrich.py +145 -145
  83. stubber/codemod/merge_docstub.py +284 -284
  84. stubber/codemod/modify_list.py +54 -54
  85. stubber/codemod/utils.py +57 -57
  86. stubber/commands/build_cmd.py +94 -94
  87. stubber/commands/cli.py +51 -51
  88. stubber/commands/clone_cmd.py +66 -66
  89. stubber/commands/config_cmd.py +29 -29
  90. stubber/commands/enrich_folder_cmd.py +70 -70
  91. stubber/commands/get_core_cmd.py +69 -69
  92. stubber/commands/get_docstubs_cmd.py +87 -87
  93. stubber/commands/get_frozen_cmd.py +112 -112
  94. stubber/commands/get_mcu_cmd.py +56 -56
  95. stubber/commands/merge_cmd.py +66 -66
  96. stubber/commands/publish_cmd.py +119 -119
  97. stubber/commands/stub_cmd.py +30 -30
  98. stubber/commands/switch_cmd.py +54 -54
  99. stubber/commands/variants_cmd.py +48 -48
  100. stubber/cst_transformer.py +178 -178
  101. stubber/data/board_info.csv +193 -193
  102. stubber/data/board_info.json +1729 -1729
  103. stubber/data/micropython_tags.csv +15 -15
  104. stubber/data/requirements-core-micropython.txt +38 -38
  105. stubber/data/requirements-core-pycopy.txt +39 -39
  106. stubber/downloader.py +36 -36
  107. stubber/freeze/common.py +68 -68
  108. stubber/freeze/freeze_folder.py +69 -69
  109. stubber/freeze/freeze_manifest_2.py +113 -113
  110. stubber/freeze/get_frozen.py +127 -127
  111. stubber/get_cpython.py +101 -101
  112. stubber/get_lobo.py +59 -59
  113. stubber/minify.py +418 -418
  114. stubber/publish/bump.py +86 -86
  115. stubber/publish/candidates.py +262 -283
  116. stubber/publish/database.py +18 -18
  117. stubber/publish/defaults.py +45 -45
  118. stubber/publish/enums.py +24 -30
  119. stubber/publish/helpers.py +29 -29
  120. stubber/publish/merge_docstubs.py +130 -130
  121. stubber/publish/missing_class_methods.py +49 -49
  122. stubber/publish/package.py +146 -177
  123. stubber/publish/pathnames.py +51 -51
  124. stubber/publish/publish.py +120 -121
  125. stubber/publish/pypi.py +38 -38
  126. stubber/publish/stubpackage.py +1029 -1029
  127. stubber/rst/__init__.py +9 -9
  128. stubber/rst/classsort.py +77 -77
  129. stubber/rst/lookup.py +530 -530
  130. stubber/rst/output_dict.py +401 -401
  131. stubber/rst/reader.py +822 -823
  132. stubber/rst/report_return.py +69 -69
  133. stubber/rst/rst_utils.py +540 -540
  134. stubber/stubber.py +38 -38
  135. stubber/stubs_from_docs.py +90 -90
  136. stubber/tools/manifestfile.py +610 -610
  137. stubber/tools/readme.md +5 -5
  138. stubber/update_fallback.py +117 -117
  139. stubber/update_module_list.py +123 -125
  140. stubber/utils/__init__.py +5 -5
  141. stubber/utils/config.py +127 -127
  142. stubber/utils/makeversionhdr.py +54 -54
  143. stubber/utils/manifest.py +92 -92
  144. stubber/utils/post.py +79 -79
  145. stubber/utils/repos.py +157 -154
  146. stubber/utils/stubmaker.py +139 -139
  147. stubber/utils/typed_config_toml.py +77 -77
  148. stubber/utils/versions.py +128 -120
  149. stubber/variants.py +106 -106
  150. micropython_stubber-1.20.4.dist-info/RECORD +0 -154
  151. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.6.dist-info}/WHEEL +0 -0
  152. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.6.dist-info}/entry_points.txt +0 -0
@@ -1,129 +1,129 @@
1
- from pathlib import Path
2
- from typing import Dict, List, Optional
3
-
4
- import jsonlines
5
- from loguru import logger as log
6
-
7
- from mpflash.common import FWInfo
8
- from mpflash.vendor.versions import clean_version
9
-
10
- from .config import config
11
-
12
-
13
- # #########################################################################################################
14
- def downloaded_firmwares(fw_folder: Path) -> List[FWInfo]:
15
- """Load a list of locally downloaded firmwares from the jsonl file"""
16
- firmwares: List[FWInfo] = []
17
- try:
18
- with jsonlines.open(fw_folder / "firmware.jsonl") as reader:
19
- firmwares = [FWInfo.from_dict(item) for item in reader]
20
- except FileNotFoundError:
21
- log.error(f"No firmware.jsonl found in {fw_folder}")
22
- # sort by filename
23
- firmwares.sort(key=lambda x: x.filename)
24
- return firmwares
25
-
26
-
27
- def clean_downloaded_firmwares(fw_folder: Path) -> None:
28
- """
29
- Remove duplicate entries from the firmware.jsonl file, keeping the latest one
30
- uniqueness is based on the filename
31
- """
32
- firmwares = downloaded_firmwares(fw_folder)
33
- if not firmwares:
34
- return
35
- # keep the latest entry
36
- unique_fw = {fw.filename: fw for fw in firmwares}
37
- with jsonlines.open(fw_folder / "firmware.jsonl", "w") as writer:
38
- for fw in unique_fw.values():
39
- writer.write(fw.to_dict())
40
- log.info(f"Removed duplicate entries from firmware.jsonl in {fw_folder}")
41
-
42
-
43
- def find_downloaded_firmware(
44
- *,
45
- board_id: str,
46
- version: str = "", # v1.2.3
47
- port: str = "",
48
- variants: bool = False,
49
- fw_folder: Optional[Path] = None,
50
- trie: int = 1,
51
- selector: Optional[Dict[str, str]] = None,
52
- ) -> List[FWInfo]:
53
- if selector is None:
54
- selector = {}
55
- fw_folder = fw_folder or config.firmware_folder
56
- # Use the information in firmwares.jsonl to find the firmware file
57
- log.debug(f"{trie}] Looking for firmware for {board_id} {version} ")
58
- fw_list = downloaded_firmwares(fw_folder)
59
- if not fw_list:
60
- log.error("No firmware files found. Please download the firmware first.")
61
- return []
62
- # filter by version
63
- version = clean_version(version)
64
- fw_list = filter_downloaded_fwlist(fw_list, board_id, version, port, variants, selector)
65
-
66
- if not fw_list and trie < 3:
67
- log.info(f"Try ({trie+1}) to find a firmware for the board {board_id}")
68
- if trie == 1:
69
- # ESP board naming conventions have changed by adding a PORT prefix
70
- if port.startswith("esp") and not board_id.startswith(port.upper()):
71
- board_id = f"{port.upper()}_{board_id}"
72
- # RP2 board naming conventions have changed by adding a _RPI prefix
73
- if port == "rp2" and not board_id.startswith("RPI_"):
74
- board_id = f"RPI_{board_id}"
75
- elif trie == 2:
76
- board_id = board_id.replace("_", "-")
77
-
78
- fw_list = find_downloaded_firmware(
79
- fw_folder=fw_folder,
80
- board_id=board_id,
81
- version=version,
82
- port=port,
83
- trie=trie + 1,
84
- selector=selector,
85
- )
86
- # hope we have a match now for the board
87
- # sort by filename
88
- fw_list.sort(key=lambda x: x.filename)
89
- return fw_list
90
-
91
-
92
- def filter_downloaded_fwlist(
93
- fw_list: List[FWInfo],
94
- board_id: str,
95
- version: str, # v1.2.3
96
- port: str,
97
- # preview: bool,
98
- variants: bool,
99
- selector: dict,
100
- ) -> List[FWInfo]:
101
- """Filter the downloaded firmware list based on the provided parameters"""
102
- if "preview" in version:
103
- # never get a preview for an older version
104
- fw_list = [fw for fw in fw_list if fw.preview]
105
- else:
106
- # FWInfo version has no v1.2.3 prefix
107
- _version = {clean_version(version, drop_v=True), clean_version(version, drop_v=False)}
108
- fw_list = [fw for fw in fw_list if fw.version in _version]
109
- log.trace(f"Filtering firmware for {version} : {len(fw_list)} found.")
110
- # filter by port
111
- if port:
112
- fw_list = [fw for fw in fw_list if fw.port == port]
113
- log.trace(f"Filtering firmware for {port} : {len(fw_list)} found.")
114
-
115
- if board_id:
116
- if variants:
117
- # any variant of this board_id
118
- fw_list = [fw for fw in fw_list if fw.board == board_id]
119
- else:
120
- # the firmware variant should match exactly the board_id
121
- fw_list = [fw for fw in fw_list if fw.variant == board_id]
122
- log.trace(f"Filtering firmware for {board_id} : {len(fw_list)} found.")
123
- if selector and port in selector:
124
- fw_list = [fw for fw in fw_list if fw.filename.endswith(selector[port])]
125
- return fw_list
126
-
127
-
128
- # #########################################################################################################
129
- #
1
+ from pathlib import Path
2
+ from typing import Dict, List, Optional
3
+
4
+ import jsonlines
5
+ from loguru import logger as log
6
+
7
+ from mpflash.common import FWInfo
8
+ from mpflash.vendor.versions import clean_version
9
+
10
+ from .config import config
11
+
12
+
13
+ # #########################################################################################################
14
+ def downloaded_firmwares(fw_folder: Path) -> List[FWInfo]:
15
+ """Load a list of locally downloaded firmwares from the jsonl file"""
16
+ firmwares: List[FWInfo] = []
17
+ try:
18
+ with jsonlines.open(fw_folder / "firmware.jsonl") as reader:
19
+ firmwares = [FWInfo.from_dict(item) for item in reader]
20
+ except FileNotFoundError:
21
+ log.error(f"No firmware.jsonl found in {fw_folder}")
22
+ # sort by filename
23
+ firmwares.sort(key=lambda x: x.filename)
24
+ return firmwares
25
+
26
+
27
+ def clean_downloaded_firmwares(fw_folder: Path) -> None:
28
+ """
29
+ Remove duplicate entries from the firmware.jsonl file, keeping the latest one
30
+ uniqueness is based on the filename
31
+ """
32
+ firmwares = downloaded_firmwares(fw_folder)
33
+ if not firmwares:
34
+ return
35
+ # keep the latest entry
36
+ unique_fw = {fw.filename: fw for fw in firmwares}
37
+ with jsonlines.open(fw_folder / "firmware.jsonl", "w") as writer:
38
+ for fw in unique_fw.values():
39
+ writer.write(fw.to_dict())
40
+ log.info(f"Removed duplicate entries from firmware.jsonl in {fw_folder}")
41
+
42
+
43
+ def find_downloaded_firmware(
44
+ *,
45
+ board_id: str,
46
+ version: str = "", # v1.2.3
47
+ port: str = "",
48
+ variants: bool = False,
49
+ fw_folder: Optional[Path] = None,
50
+ trie: int = 1,
51
+ selector: Optional[Dict[str, str]] = None,
52
+ ) -> List[FWInfo]:
53
+ if selector is None:
54
+ selector = {}
55
+ fw_folder = fw_folder or config.firmware_folder
56
+ # Use the information in firmwares.jsonl to find the firmware file
57
+ log.debug(f"{trie}] Looking for firmware for {board_id} {version} ")
58
+ fw_list = downloaded_firmwares(fw_folder)
59
+ if not fw_list:
60
+ log.error("No firmware files found. Please download the firmware first.")
61
+ return []
62
+ # filter by version
63
+ version = clean_version(version)
64
+ fw_list = filter_downloaded_fwlist(fw_list, board_id, version, port, variants, selector)
65
+
66
+ if not fw_list and trie < 3:
67
+ log.info(f"Try ({trie+1}) to find a firmware for the board {board_id}")
68
+ if trie == 1:
69
+ # ESP board naming conventions have changed by adding a PORT prefix
70
+ if port.startswith("esp") and not board_id.startswith(port.upper()):
71
+ board_id = f"{port.upper()}_{board_id}"
72
+ # RP2 board naming conventions have changed by adding a _RPI prefix
73
+ if port == "rp2" and not board_id.startswith("RPI_"):
74
+ board_id = f"RPI_{board_id}"
75
+ elif trie == 2:
76
+ board_id = board_id.replace("_", "-")
77
+
78
+ fw_list = find_downloaded_firmware(
79
+ fw_folder=fw_folder,
80
+ board_id=board_id,
81
+ version=version,
82
+ port=port,
83
+ trie=trie + 1,
84
+ selector=selector,
85
+ )
86
+ # hope we have a match now for the board
87
+ # sort by filename
88
+ fw_list.sort(key=lambda x: x.filename)
89
+ return fw_list
90
+
91
+
92
+ def filter_downloaded_fwlist(
93
+ fw_list: List[FWInfo],
94
+ board_id: str,
95
+ version: str, # v1.2.3
96
+ port: str,
97
+ # preview: bool,
98
+ variants: bool,
99
+ selector: dict,
100
+ ) -> List[FWInfo]:
101
+ """Filter the downloaded firmware list based on the provided parameters"""
102
+ if "preview" in version:
103
+ # never get a preview for an older version
104
+ fw_list = [fw for fw in fw_list if fw.preview]
105
+ else:
106
+ # older FWInfo version has no v1.2.3 prefix
107
+ either = [clean_version(version, drop_v=False), clean_version(version, drop_v=True)]
108
+ fw_list = [fw for fw in fw_list if fw.version in either]
109
+ log.trace(f"Filtering firmware for {version} : {len(fw_list)} found.")
110
+ # filter by port
111
+ if port:
112
+ fw_list = [fw for fw in fw_list if fw.port == port]
113
+ log.trace(f"Filtering firmware for {port} : {len(fw_list)} found.")
114
+
115
+ if board_id:
116
+ if variants:
117
+ # any variant of this board_id
118
+ fw_list = [fw for fw in fw_list if fw.board == board_id]
119
+ else:
120
+ # the firmware variant should match exactly the board_id
121
+ fw_list = [fw for fw in fw_list if fw.variant == board_id]
122
+ log.trace(f"Filtering firmware for {board_id} : {len(fw_list)} found.")
123
+ if selector and port in selector:
124
+ fw_list = [fw for fw in fw_list if fw.filename.endswith(selector[port])]
125
+ return fw_list
126
+
127
+
128
+ # #########################################################################################################
129
+ #
mpflash/mpflash/errors.py CHANGED
@@ -1,5 +1,9 @@
1
- """Custom exceptions for the MPFlash package."""
2
-
3
-
4
- class MPFlashError(Exception):
5
- pass
1
+ """Custom exceptions for the MPFlash package."""
2
+
3
+
4
+ class MPFlashError(Exception):
5
+ """Base class for exceptions in this module."""
6
+
7
+ def __init__(self, message: str):
8
+ self.message = message
9
+ super().__init__(message)
mpflash/mpflash/flash.py CHANGED
@@ -1,69 +1,52 @@
1
- import time
2
- from pathlib import Path
3
-
4
- from loguru import logger as log
5
-
6
- from mpflash.common import PORT_FWTYPES
7
- from mpflash.mpremoteboard import MPRemoteBoard
8
-
9
- from .flash_esp import flash_esp
10
- from .flash_stm32 import flash_stm32
11
- from .flash_uf2 import flash_uf2
12
- from .worklist import WorkList
13
-
14
- # #########################################################################################################
15
-
16
-
17
- def flash_list(
18
- todo: WorkList,
19
- fw_folder: Path,
20
- erase: bool,
21
- bootloader: bool,
22
- ):
23
- """Flash a list of boards with the specified firmware."""
24
- flashed = []
25
- for mcu, fw_info in todo:
26
- fw_file = fw_folder / fw_info.filename
27
- if not fw_file.exists():
28
- log.error(f"File {fw_file} does not exist, skipping {mcu.board} on {mcu.serialport}")
29
- continue
30
- log.info(f"Updating {mcu.board} on {mcu.serialport} to {fw_info.version}")
31
- updated = None
32
- # try:
33
- if mcu.port in [port for port, exts in PORT_FWTYPES.items() if ".uf2" in exts] and fw_file.suffix == ".uf2":
34
- # any .uf2 port ["samd", "rp2", "nrf"]:
35
- if bootloader:
36
- enter_bootloader(mcu)
37
- updated = flash_uf2(mcu, fw_file=fw_file, erase=erase)
38
- elif mcu.port in ["stm32"]:
39
- if bootloader:
40
- enter_bootloader(mcu)
41
- updated = flash_stm32(mcu, fw_file, erase=erase)
42
- elif mcu.port in ["esp32", "esp8266"]:
43
- # bootloader is handled by esptool for esp32/esp8266
44
- updated = flash_esp(mcu, fw_file=fw_file, erase=erase)
45
- else:
46
- log.error(f"Don't (yet) know how to flash {mcu.port}-{mcu.board} on {mcu.serialport}")
47
-
48
- if updated:
49
- flashed.append(updated)
50
- else:
51
- log.error(f"Failed to flash {mcu.board} on {mcu.serialport}")
52
- return flashed
53
-
54
-
55
- def enter_bootloader(mcu: MPRemoteBoard, timeout: int = 10, wait_after: int = 2):
56
- """Enter the bootloader mode for the board"""
57
- log.info(f"Entering bootloader on {mcu.board} on {mcu.serialport}")
58
- mcu.run_command("bootloader", timeout=timeout)
59
- time.sleep(wait_after)
60
-
61
-
62
- # TODO:
63
- # flash from some sort of queue to allow different images to be flashed to the same board
64
- # - flash variant 1
65
- # - stub variant 1
66
- # - flash variant 2
67
- # - stub variant 2
68
- #
69
- # JIT download / download any missing firmwares based on the detected boards
1
+ from pathlib import Path
2
+
3
+ from loguru import logger as log
4
+
5
+ from mpflash.bootloader import enter_bootloader
6
+ from mpflash.common import PORT_FWTYPES, BootloaderMethod
7
+
8
+ from .flash_esp import flash_esp
9
+ from .flash_stm32 import flash_stm32
10
+ from .flash_uf2 import flash_uf2
11
+ from .worklist import WorkList
12
+
13
+ # #########################################################################################################
14
+
15
+
16
+
17
+ def flash_list(
18
+ todo: WorkList,
19
+ fw_folder: Path,
20
+ erase: bool,
21
+ bootloader: BootloaderMethod,
22
+ ):
23
+ """Flash a list of boards with the specified firmware."""
24
+ UF2_PORTS = [port for port, exts in PORT_FWTYPES.items() if ".uf2" in exts]
25
+ flashed = []
26
+ for mcu, fw_info in todo:
27
+ fw_file = fw_folder / fw_info.filename
28
+ if not fw_file.exists():
29
+ log.error(f"File {fw_file} does not exist, skipping {mcu.board} on {mcu.serialport}")
30
+ continue
31
+ log.info(f"Updating {mcu.board} on {mcu.serialport} to {fw_info.version}")
32
+ updated = None
33
+ # try:
34
+ if mcu.port in UF2_PORTS and fw_file.suffix == ".uf2":
35
+ if not enter_bootloader(mcu, bootloader):
36
+ continue
37
+ updated = flash_uf2(mcu, fw_file=fw_file, erase=erase)
38
+ elif mcu.port in ["stm32"]:
39
+ if not enter_bootloader(mcu, bootloader):
40
+ continue
41
+ updated = flash_stm32(mcu, fw_file, erase=erase)
42
+ elif mcu.port in ["esp32", "esp8266"]:
43
+ # bootloader is handled by esptool for esp32/esp8266
44
+ updated = flash_esp(mcu, fw_file=fw_file, erase=erase)
45
+ else:
46
+ log.error(f"Don't (yet) know how to flash {mcu.port}-{mcu.board} on {mcu.serialport}")
47
+
48
+ if updated:
49
+ flashed.append(updated)
50
+ else:
51
+ log.error(f"Failed to flash {mcu.board} on {mcu.serialport}")
52
+ return flashed
@@ -1,59 +1,59 @@
1
- """
2
- # #########################################################################################################
3
- # Flash ESP32 and ESP8266 via esptool
4
- # #########################################################################################################
5
- """
6
-
7
- from pathlib import Path
8
- from typing import List, Optional
9
-
10
- import esptool
11
- from loguru import logger as log
12
-
13
- from mpflash.mpboard_id import find_known_board
14
- from mpflash.mpremoteboard import MPRemoteBoard
15
-
16
-
17
- def flash_esp(mcu: MPRemoteBoard, fw_file: Path, *, erase: bool = True) -> Optional[MPRemoteBoard]:
18
- if mcu.port not in ["esp32", "esp8266"] or mcu.board in ["ARDUINO_NANO_ESP32"]:
19
- log.error(f"esptool not supported for {mcu.port} {mcu.board} on {mcu.serialport}")
20
- return None
21
-
22
- log.info(f"Flashing {fw_file} on {mcu.board} on {mcu.serialport}")
23
- if not mcu.cpu:
24
- # Lookup CPU based on the board name
25
- mcu.cpu = find_known_board(mcu.board).cpu
26
-
27
- cmds: List[List[str]] = []
28
- if erase:
29
- cmds.append(f"esptool --chip {mcu.cpu} --port {mcu.serialport} erase_flash".split())
30
-
31
- if mcu.cpu.upper().startswith("ESP32"):
32
- baud_rate = str(921_600)
33
- if mcu.cpu.upper() in ("ESP32", "ESP32S2"):
34
- start_addr = "0x1000"
35
- elif mcu.cpu.upper() in ("ESP32S3", "ESP32C3"):
36
- start_addr = "0x0"
37
- cmds.append(
38
- f"esptool --chip {mcu.cpu} --port {mcu.serialport} -b {baud_rate} write_flash --compress {start_addr}".split()
39
- + [str(fw_file)]
40
- )
41
- elif mcu.cpu.upper() == "ESP8266":
42
- baud_rate = str(460_800)
43
- start_addr = "0x0"
44
- cmds.append(
45
- f"esptool --chip {mcu.cpu} --port {mcu.serialport} -b {baud_rate} write_flash --flash_size=detect {start_addr}".split()
46
- + [str(fw_file)]
47
- )
48
- try:
49
- for cmd in cmds:
50
- log.info(f"Running {' '.join(cmd)} ")
51
- esptool.main(cmd[1:])
52
- except Exception as e:
53
- log.error(f"Failed to flash {mcu.board} on {mcu.serialport} : {e}")
54
- return None
55
-
56
- log.info("Done flashing, resetting the board and wait for it to restart")
57
- mcu.wait_for_restart()
58
- log.success(f"Flashed {mcu.serialport} to {mcu.board} {mcu.version}")
59
- return mcu
1
+ """
2
+ # #########################################################################################################
3
+ # Flash ESP32 and ESP8266 via esptool
4
+ # #########################################################################################################
5
+ """
6
+
7
+ from pathlib import Path
8
+ from typing import List, Optional
9
+
10
+ import esptool
11
+ from loguru import logger as log
12
+
13
+ from mpflash.mpboard_id import find_known_board
14
+ from mpflash.mpremoteboard import MPRemoteBoard
15
+
16
+
17
+ def flash_esp(mcu: MPRemoteBoard, fw_file: Path, *, erase: bool = True) -> Optional[MPRemoteBoard]:
18
+ if mcu.port not in ["esp32", "esp8266"] or mcu.board in ["ARDUINO_NANO_ESP32"]:
19
+ log.error(f"esptool not supported for {mcu.port} {mcu.board} on {mcu.serialport}")
20
+ return None
21
+
22
+ log.info(f"Flashing {fw_file} on {mcu.board} on {mcu.serialport}")
23
+ if not mcu.cpu:
24
+ # Lookup CPU based on the board name
25
+ mcu.cpu = find_known_board(mcu.board).cpu
26
+
27
+ cmds: List[List[str]] = []
28
+ if erase:
29
+ cmds.append(f"esptool --chip {mcu.cpu} --port {mcu.serialport} erase_flash".split())
30
+
31
+ if mcu.cpu.upper().startswith("ESP32"):
32
+ baud_rate = str(921_600)
33
+ if mcu.cpu.upper() in ("ESP32", "ESP32S2"):
34
+ start_addr = "0x1000"
35
+ elif mcu.cpu.upper() in ("ESP32S3", "ESP32C3"):
36
+ start_addr = "0x0"
37
+ cmds.append(
38
+ f"esptool --chip {mcu.cpu} --port {mcu.serialport} -b {baud_rate} write_flash --compress {start_addr}".split()
39
+ + [str(fw_file)]
40
+ )
41
+ elif mcu.cpu.upper() == "ESP8266":
42
+ baud_rate = str(460_800)
43
+ start_addr = "0x0"
44
+ cmds.append(
45
+ f"esptool --chip {mcu.cpu} --port {mcu.serialport} -b {baud_rate} write_flash --flash_size=detect {start_addr}".split()
46
+ + [str(fw_file)]
47
+ )
48
+ try:
49
+ for cmd in cmds:
50
+ log.info(f"Running {' '.join(cmd)} ")
51
+ esptool.main(cmd[1:])
52
+ except Exception as e:
53
+ log.error(f"Failed to flash {mcu.board} on {mcu.serialport} : {e}")
54
+ return None
55
+
56
+ log.info("Done flashing, resetting the board and wait for it to restart")
57
+ mcu.wait_for_restart()
58
+ log.success(f"Flashed {mcu.serialport} to {mcu.board} {mcu.version}")
59
+ return mcu
@@ -1,24 +1,24 @@
1
- """Flash STM32 boards using either STM32CubeProgrammer CLI or dfu-util"""
2
-
3
- from pathlib import Path
4
-
5
- from loguru import logger as log
6
-
7
- # from .flash_stm32_cube import flash_stm32_cubecli
8
- from .flash_stm32_dfu import dfu_init, flash_stm32_dfu
9
- from mpflash.mpremoteboard import MPRemoteBoard
10
-
11
-
12
- def flash_stm32(mcu: MPRemoteBoard, fw_file: Path, *, erase: bool, stm32_dfu: bool = True):
13
- # sourcery skip: lift-return-into-if
14
- log.info("Using dfu-util")
15
- dfu_init()
16
- updated = flash_stm32_dfu(mcu, fw_file=fw_file, erase=erase)
17
- # if stm32_dfu:
18
- # else:
19
- # log.info("Using STM32CubeProgrammer CLI")
20
- # updated = flash_stm32_cubecli(mcu, fw_file=fw_file, erase=erase)
21
-
22
- mcu.wait_for_restart()
23
- log.success(f"Flashed {mcu.version} to {mcu.board}")
24
- return updated
1
+ """Flash STM32 boards using either STM32CubeProgrammer CLI or dfu-util"""
2
+
3
+ from pathlib import Path
4
+
5
+ from loguru import logger as log
6
+
7
+ # from .flash_stm32_cube import flash_stm32_cubecli
8
+ from .flash_stm32_dfu import dfu_init, flash_stm32_dfu
9
+ from mpflash.mpremoteboard import MPRemoteBoard
10
+
11
+
12
+ def flash_stm32(mcu: MPRemoteBoard, fw_file: Path, *, erase: bool, stm32_dfu: bool = True):
13
+ # sourcery skip: lift-return-into-if
14
+ log.info("Using dfu-util")
15
+ dfu_init()
16
+ updated = flash_stm32_dfu(mcu, fw_file=fw_file, erase=erase)
17
+ # if stm32_dfu:
18
+ # else:
19
+ # log.info("Using STM32CubeProgrammer CLI")
20
+ # updated = flash_stm32_cubecli(mcu, fw_file=fw_file, erase=erase)
21
+
22
+ mcu.wait_for_restart()
23
+ log.success(f"Flashed {mcu.version} to {mcu.board}")
24
+ return updated