mpflash 1.24.6__tar.gz → 1.25.0.post1__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 (68) hide show
  1. {mpflash-1.24.6 → mpflash-1.25.0.post1}/PKG-INFO +71 -13
  2. {mpflash-1.24.6 → mpflash-1.25.0.post1}/README.md +64 -5
  3. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/ask_input.py +7 -7
  4. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/basicgit.py +26 -59
  5. mpflash-1.25.0.post1/mpflash/bootloader/__init__.py +0 -0
  6. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/bootloader/activate.py +1 -1
  7. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/bootloader/detect.py +1 -2
  8. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/bootloader/manual.py +0 -1
  9. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/bootloader/touch1200.py +2 -2
  10. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/cli_flash.py +28 -5
  11. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/cli_group.py +1 -0
  12. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/cli_list.py +7 -8
  13. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/cli_main.py +2 -2
  14. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/common.py +6 -14
  15. mpflash-1.25.0.post1/mpflash/config.py +68 -0
  16. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/connected.py +6 -14
  17. mpflash-1.25.0.post1/mpflash/db/boards.py +63 -0
  18. mpflash-1.25.0.post1/mpflash/db/downloads.py +87 -0
  19. mpflash-1.25.0.post1/mpflash/download/__init__.py +221 -0
  20. mpflash-1.25.0.post1/mpflash/download/from_web.py +204 -0
  21. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/downloaded.py +9 -34
  22. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/__init__.py +33 -18
  23. mpflash-1.25.0.post1/mpflash/flash/esp.py +90 -0
  24. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/uf2/__init__.py +18 -2
  25. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/uf2/linux.py +4 -9
  26. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/uf2/macos.py +1 -1
  27. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/uf2/windows.py +1 -1
  28. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/worklist.py +10 -5
  29. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/list.py +17 -6
  30. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/logger.py +1 -3
  31. mpflash-1.25.0.post1/mpflash/mpboard_id/__init__.py +17 -0
  32. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/mpboard_id/add_boards.py +6 -8
  33. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/mpboard_id/board.py +5 -2
  34. mpflash-1.25.0.post1/mpflash/mpboard_id/board_id.py +152 -0
  35. mpflash-1.25.0.post1/mpflash/mpboard_id/board_info.json +30974 -0
  36. mpflash-1.25.0.post1/mpflash/mpboard_id/board_info.zip +0 -0
  37. mpflash-1.24.6/mpflash/mpboard_id/__init__.py → mpflash-1.25.0.post1/mpflash/mpboard_id/known.py +23 -29
  38. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/mpboard_id/store.py +2 -3
  39. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/mpremoteboard/__init__.py +85 -17
  40. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/mpremoteboard/mpy_fw_info.py +23 -22
  41. mpflash-1.25.0.post1/mpflash/py.typed +0 -0
  42. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/vendor/board_database.py +86 -1
  43. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/vendor/click_aliases.py +64 -0
  44. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/vendor/dfu.py +2 -8
  45. mpflash-1.25.0.post1/mpflash/vendor/pico-universal-flash-nuke/LICENSE.txt +21 -0
  46. mpflash-1.25.0.post1/mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2 +0 -0
  47. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/vendor/pydfu.py +3 -14
  48. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/vendor/readme.md +2 -0
  49. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/versions.py +16 -6
  50. mpflash-1.25.0.post1/pyproject.toml +156 -0
  51. mpflash-1.24.6/mpflash/bootloader/__init__.py +0 -2
  52. mpflash-1.24.6/mpflash/config.py +0 -44
  53. mpflash-1.24.6/mpflash/download.py +0 -364
  54. mpflash-1.24.6/mpflash/flash/esp.py +0 -59
  55. mpflash-1.24.6/mpflash/mpboard_id/board_id.py +0 -90
  56. mpflash-1.24.6/mpflash/mpboard_id/board_info.zip +0 -0
  57. mpflash-1.24.6/pyproject.toml +0 -66
  58. {mpflash-1.24.6 → mpflash-1.25.0.post1}/LICENSE +0 -0
  59. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/__init__.py +0 -0
  60. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/add_firmware.py +0 -0
  61. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/bootloader/micropython.py +0 -0
  62. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/cli_download.py +0 -0
  63. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/errors.py +0 -0
  64. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/stm32.py +0 -0
  65. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/stm32_dfu.py +0 -0
  66. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/uf2/boardid.py +0 -0
  67. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/flash/uf2/uf2disk.py +0 -0
  68. {mpflash-1.24.6 → mpflash-1.25.0.post1}/mpflash/mpremoteboard/runner.py +0 -0
@@ -1,17 +1,15 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mpflash
3
- Version: 1.24.6
3
+ Version: 1.25.0.post1
4
4
  Summary: Flash and download tool for MicroPython firmwares
5
5
  License: MIT
6
6
  Keywords: MicroPython,firmware,flash,download,UF2,esptool
7
7
  Author: Jos Verlinde
8
8
  Author-email: jos_verlinde@hotmail.com
9
- Requires-Python: >=3.9,<4.0
9
+ Requires-Python: >=3.9, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*
10
10
  Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
- Classifier: Programming Language :: Python :: 3.11
15
13
  Classifier: Programming Language :: Python :: 3.12
16
14
  Classifier: Programming Language :: Python :: 3.13
17
15
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -32,14 +30,15 @@ Requires-Dist: mpremote (>=1.22.0,<2.0.0)
32
30
  Requires-Dist: packaging (>=24.2,<25.0)
33
31
  Requires-Dist: platformdirs (>=4.2.0,<5.0.0)
34
32
  Requires-Dist: poetry (>=2.0.1,<3.0.0)
35
- Requires-Dist: psutil (>=5.9.8,<6.0.0)
33
+ Requires-Dist: psutil (>=5.9.8,<8.0.0)
36
34
  Requires-Dist: pygithub (>=2.1.1,<3.0.0)
37
35
  Requires-Dist: pyusb (>=1.2.1,<2.0.0)
36
+ Requires-Dist: pywin32 (>=310,<311) ; sys_platform == "win32"
38
37
  Requires-Dist: requests (>=2.31.0,<3.0.0)
39
38
  Requires-Dist: rich-click (>=1.8.1,<2.0.0)
40
- Requires-Dist: tenacity (==8.2.3)
41
- Project-URL: Homepage, https://github.com/Josverl/micropython-stubber/blob/main/src/mpflash/README.md
42
- Project-URL: Repository, https://github.com/Josverl/micropython-stubber
39
+ Requires-Dist: tenacity (==9.0.0)
40
+ Project-URL: Homepage, https://github.com/Josverl/mpflash/blob/main/README.md
41
+ Project-URL: Repository, https://github.com/Josverl/mpflash
43
42
  Description-Content-Type: text/markdown
44
43
 
45
44
  # MPFLASH
@@ -48,7 +47,7 @@ Description-Content-Type: text/markdown
48
47
  [![Downloads](https://static.pepy.tech/badge/mpflash)](https://pepy.tech/project/mpflash)
49
48
 
50
49
 
51
- `mpflash` is a command-line tool for working with MicroPython firmware. It provides features to help you flash and update Micropython on one or more .
50
+ `mpflash` is a command-line tool for working with MicroPython firmware. It provides features to help you flash and update Micropython on one or more attached microcontrollers.
52
51
 
53
52
  This tool was initially created to be used in a CI/CD pipeline to automate the process of downloading and flashing MicroPython firmware to multiple boards, but it has been extend with a TUI to be used for manual downloadig, flashing and development.
54
53
 
@@ -69,7 +68,10 @@ Not yet implemented: `nrf`, `cc3200`, `mimxrt`, `renesas`
69
68
  3. Flash one or all connected MicroPython boards with a specific firmware or version.
70
69
 
71
70
  ## Installation
72
- To install mpflash, you can use: `pipx install mpflash` or `pip install mpflash`
71
+ To install mpflash, you can use either of the following commands:
72
+ - `uv tool install mpflash`
73
+ - `pipx install mpflash`
74
+ - `pip install mpflash`
73
75
 
74
76
  ## Basic usage
75
77
  You can use mpflash to perform various operations on your MicroPython boards. Here is an example of basic usage:
@@ -102,6 +104,7 @@ description = "Blue Norwegian actuator"
102
104
 
103
105
  If you want the board to be ignored by mpflash, you can add the following to the board_info.toml file:
104
106
  ```toml
107
+ description = "Blue Norwegian feeder"
105
108
  [mpflash]
106
109
  ignore = true
107
110
  ```
@@ -110,8 +113,13 @@ ignore = true
110
113
  ## Linux permissions to access usb devices
111
114
  In order to flash the firmware to the board, you need to have the correct permissions to access the USB devices.
112
115
  On Windows this will not be an issue, but on Linux you can use udev rules to give non-root users access to the USB devices.
113
- [See the stm32_permissions documentation](./stm32_udev_rules.md) for more information.
116
+ [See the stm32_permissions documentation](docs/stm32_udev_rules.md) for more information.
114
117
 
118
+ ## Use MPFlash in your own project
119
+
120
+ MPFlash can be used as a library in your own project. mpflash is used in [micropython-stubber]() to download and flash the firmware to the connected boards.
121
+
122
+ The interface is not well documented other than the code itself, but you can use the following example to get started: - docs/mpflash_api_example.ipynb
115
123
 
116
124
  ## Detailed usage
117
125
  You can list the connected boards using the following command:
@@ -257,9 +265,59 @@ Note that if no matching firmware can be found for a board, it will be skipped.
257
265
  (For example, the PYBV11 and ESP32_GENERIC_S3 boards in the example above.)
258
266
 
259
267
  ## Issues and bug reports
260
- mpflash is currently co-located in the [micropython-stubber](https://github.com/Josverl/micropython-stubber) repository.
261
- Please report any issues or bugs in the [issue tracker](https://github.com/Josverl/micropython-stubber/issues) using the MPflash feedback template.
268
+ Please report any issues or bugs in the [issue tracker](https://github.com/Josverl/mpflash/issues).
262
269
 
263
270
  ## License
264
271
  mpflash is licensed under the MIT license. See the LICENSE file for more details.
265
272
 
273
+ # Contributions
274
+ <!-- spell-checker: disable -->
275
+ <!--
276
+ To add via the cli run the following command:
277
+ npx all-contributors-cli add user things
278
+
279
+ - bug
280
+ - tool
281
+ - stubs
282
+ - test
283
+ - doc
284
+ - code
285
+ - research
286
+ - ideas
287
+ - content
288
+ - mpflash
289
+ -->
290
+
291
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
292
+ <!-- prettier-ignore-start -->
293
+ <!-- markdownlint-disable -->
294
+ <table>
295
+ <tbody>
296
+ <tr>
297
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Josverl"><img src="https://avatars2.githubusercontent.com/u/981654?v=4?s=100" width="100px;" alt="Jos Verlinde"/><br /><sub><b>Jos Verlinde</b></sub></a><br /><a href="https://github.com/Josverl/mpflash/commits?author=josverl" title="Code">💻</a> <a href="#research-josverl" title="Research">🔬</a> <a href="#ideas-josverl" title="Ideas, Planning, & Feedback">🤔</a> <a href="#content-josverl" title="Content">🖋</a> <a href="#test-josverl" title="Test">✅</a> <a href="#mpflash-josverl" title="mpflash">💥</a></td>
298
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/shariltumin"><img src="https://avatars.githubusercontent.com/u/186120?v=4?s=100" width="100px;" alt="shariltumin"/><br /><sub><b>shariltumin</b></sub></a><br /><a href="#mpflash-shariltumin" title="mpflash">💥</a> <a href="#test-shariltumin" title="Test">✅</a></td>
299
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/mattytrentini"><img src="https://avatars.githubusercontent.com/u/194201?v=4?s=100" width="100px;" alt="Matt Trentini"/><br /><sub><b>Matt Trentini</b></sub></a><br /><a href="#mpflash-mattytrentini" title="mpflash">💥</a> <a href="#test-mattytrentini" title="Test">✅</a></td>
300
+ <td align="center" valign="top" width="14.28%"><a href="http://scruss.com/blog/"><img src="https://avatars.githubusercontent.com/u/425706?v=4?s=100" width="100px;" alt="Stewart Russell"/><br /><sub><b>Stewart Russell</b></sub></a><br /><a href="#mpflash-scruss" title="mpflash">💥</a> <a href="#test-scruss" title="Test">✅</a></td>
301
+ <td align="center" valign="top" width="14.28%"><a href="https://www.gitlab.com/alelec"><img src="https://avatars.githubusercontent.com/u/3318786?v=4?s=100" width="100px;" alt="Andrew Leech"/><br /><sub><b>Andrew Leech</b></sub></a><br /><a href="#mpflash-andrewleech" title="mpflash">💥</a> <a href="#test-andrewleech" title="Test">✅</a></td>
302
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/wovo"><img src="https://avatars.githubusercontent.com/u/9039468?v=4?s=100" width="100px;" alt="Wouter van Ooijen"/><br /><sub><b>Wouter van Ooijen</b></sub></a><br /><a href="#mpflash-wovo" title="mpflash">💥</a> <a href="#test-wovo" title="Test">✅</a></td>
303
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/shaneapowell"><img src="https://avatars.githubusercontent.com/u/12113620?v=4?s=100" width="100px;" alt="Shane Powell"/><br /><sub><b>Shane Powell</b></sub></a><br /><a href="#mpflash-shaneapowell" title="mpflash">💥</a> <a href="#test-shaneapowell" title="Test">✅</a></td>
304
+ </tr>
305
+ <tr>
306
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/robert-hh"><img src="https://avatars.githubusercontent.com/u/12476868?v=4?s=100" width="100px;" alt="Robert Hammelrath"/><br /><sub><b>Robert Hammelrath</b></sub></a><br /><a href="#mpflash-robert-hh" title="mpflash">💥</a> <a href="#test-robert-hh" title="Test">✅</a></td>
307
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/beetlegigg"><img src="https://avatars.githubusercontent.com/u/34552737?v=4?s=100" width="100px;" alt="Bg"/><br /><sub><b>Bg</b></sub></a><br /><a href="#mpflash-beetlegigg" title="mpflash">💥</a> <a href="#test-beetlegigg" title="Test">✅</a></td>
308
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/rkompass"><img src="https://avatars.githubusercontent.com/u/90282516?v=4?s=100" width="100px;" alt="Raul Kompaß"/><br /><sub><b>Raul Kompaß</b></sub></a><br /><a href="#mpflash-rkompass" title="mpflash">💥</a> <a href="#test-rkompass" title="Test">✅</a></td>
309
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/garryp4"><img src="https://avatars.githubusercontent.com/u/96994876?v=4?s=100" width="100px;" alt="garryp4"/><br /><sub><b>garryp4</b></sub></a><br /><a href="#mpflash-garryp4" title="mpflash">💥</a> <a href="#test-garryp4" title="Test">✅</a></td>
310
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/shanepowell-ast"><img src="https://avatars.githubusercontent.com/u/102747617?v=4?s=100" width="100px;" alt="Shane Powell"/><br /><sub><b>Shane Powell</b></sub></a><br /><a href="#mpflash-shanepowell-ast" title="mpflash">💥</a> <a href="#test-shanepowell-ast" title="Test">✅</a></td>
311
+ <td align="center" valign="top" width="14.28%"><a href="https://andypiper.org/"><img src="https://avatars.githubusercontent.com/u/552452?v=4?s=100" width="100px;" alt="Andy Piper"/><br /><sub><b>Andy Piper</b></sub></a><br /><a href="#mpflash-andypiper" title="mpflash">💥</a> <a href="#test-andypiper" title="Test">✅</a></td>
312
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/DavesCodeMusings"><img src="https://avatars.githubusercontent.com/u/61114342?v=4?s=100" width="100px;" alt="David Horton"/><br /><sub><b>David Horton</b></sub></a><br /><a href="#mpflash-DavesCodeMusings" title="mpflash">💥</a> <a href="#test-DavesCodeMusings" title="Test">✅</a></td>
313
+ </tr>
314
+ </tbody>
315
+ </table>
316
+
317
+ <!-- markdownlint-restore -->
318
+ <!-- prettier-ignore-end -->
319
+
320
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
321
+
322
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
323
+
@@ -4,7 +4,7 @@
4
4
  [![Downloads](https://static.pepy.tech/badge/mpflash)](https://pepy.tech/project/mpflash)
5
5
 
6
6
 
7
- `mpflash` is a command-line tool for working with MicroPython firmware. It provides features to help you flash and update Micropython on one or more .
7
+ `mpflash` is a command-line tool for working with MicroPython firmware. It provides features to help you flash and update Micropython on one or more attached microcontrollers.
8
8
 
9
9
  This tool was initially created to be used in a CI/CD pipeline to automate the process of downloading and flashing MicroPython firmware to multiple boards, but it has been extend with a TUI to be used for manual downloadig, flashing and development.
10
10
 
@@ -25,7 +25,10 @@ Not yet implemented: `nrf`, `cc3200`, `mimxrt`, `renesas`
25
25
  3. Flash one or all connected MicroPython boards with a specific firmware or version.
26
26
 
27
27
  ## Installation
28
- To install mpflash, you can use: `pipx install mpflash` or `pip install mpflash`
28
+ To install mpflash, you can use either of the following commands:
29
+ - `uv tool install mpflash`
30
+ - `pipx install mpflash`
31
+ - `pip install mpflash`
29
32
 
30
33
  ## Basic usage
31
34
  You can use mpflash to perform various operations on your MicroPython boards. Here is an example of basic usage:
@@ -58,6 +61,7 @@ description = "Blue Norwegian actuator"
58
61
 
59
62
  If you want the board to be ignored by mpflash, you can add the following to the board_info.toml file:
60
63
  ```toml
64
+ description = "Blue Norwegian feeder"
61
65
  [mpflash]
62
66
  ignore = true
63
67
  ```
@@ -66,8 +70,13 @@ ignore = true
66
70
  ## Linux permissions to access usb devices
67
71
  In order to flash the firmware to the board, you need to have the correct permissions to access the USB devices.
68
72
  On Windows this will not be an issue, but on Linux you can use udev rules to give non-root users access to the USB devices.
69
- [See the stm32_permissions documentation](./stm32_udev_rules.md) for more information.
73
+ [See the stm32_permissions documentation](docs/stm32_udev_rules.md) for more information.
70
74
 
75
+ ## Use MPFlash in your own project
76
+
77
+ MPFlash can be used as a library in your own project. mpflash is used in [micropython-stubber]() to download and flash the firmware to the connected boards.
78
+
79
+ The interface is not well documented other than the code itself, but you can use the following example to get started: - docs/mpflash_api_example.ipynb
71
80
 
72
81
  ## Detailed usage
73
82
  You can list the connected boards using the following command:
@@ -213,8 +222,58 @@ Note that if no matching firmware can be found for a board, it will be skipped.
213
222
  (For example, the PYBV11 and ESP32_GENERIC_S3 boards in the example above.)
214
223
 
215
224
  ## Issues and bug reports
216
- mpflash is currently co-located in the [micropython-stubber](https://github.com/Josverl/micropython-stubber) repository.
217
- Please report any issues or bugs in the [issue tracker](https://github.com/Josverl/micropython-stubber/issues) using the MPflash feedback template.
225
+ Please report any issues or bugs in the [issue tracker](https://github.com/Josverl/mpflash/issues).
218
226
 
219
227
  ## License
220
228
  mpflash is licensed under the MIT license. See the LICENSE file for more details.
229
+
230
+ # Contributions
231
+ <!-- spell-checker: disable -->
232
+ <!--
233
+ To add via the cli run the following command:
234
+ npx all-contributors-cli add user things
235
+
236
+ - bug
237
+ - tool
238
+ - stubs
239
+ - test
240
+ - doc
241
+ - code
242
+ - research
243
+ - ideas
244
+ - content
245
+ - mpflash
246
+ -->
247
+
248
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
249
+ <!-- prettier-ignore-start -->
250
+ <!-- markdownlint-disable -->
251
+ <table>
252
+ <tbody>
253
+ <tr>
254
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Josverl"><img src="https://avatars2.githubusercontent.com/u/981654?v=4?s=100" width="100px;" alt="Jos Verlinde"/><br /><sub><b>Jos Verlinde</b></sub></a><br /><a href="https://github.com/Josverl/mpflash/commits?author=josverl" title="Code">💻</a> <a href="#research-josverl" title="Research">🔬</a> <a href="#ideas-josverl" title="Ideas, Planning, & Feedback">🤔</a> <a href="#content-josverl" title="Content">🖋</a> <a href="#test-josverl" title="Test">✅</a> <a href="#mpflash-josverl" title="mpflash">💥</a></td>
255
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/shariltumin"><img src="https://avatars.githubusercontent.com/u/186120?v=4?s=100" width="100px;" alt="shariltumin"/><br /><sub><b>shariltumin</b></sub></a><br /><a href="#mpflash-shariltumin" title="mpflash">💥</a> <a href="#test-shariltumin" title="Test">✅</a></td>
256
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/mattytrentini"><img src="https://avatars.githubusercontent.com/u/194201?v=4?s=100" width="100px;" alt="Matt Trentini"/><br /><sub><b>Matt Trentini</b></sub></a><br /><a href="#mpflash-mattytrentini" title="mpflash">💥</a> <a href="#test-mattytrentini" title="Test">✅</a></td>
257
+ <td align="center" valign="top" width="14.28%"><a href="http://scruss.com/blog/"><img src="https://avatars.githubusercontent.com/u/425706?v=4?s=100" width="100px;" alt="Stewart Russell"/><br /><sub><b>Stewart Russell</b></sub></a><br /><a href="#mpflash-scruss" title="mpflash">💥</a> <a href="#test-scruss" title="Test">✅</a></td>
258
+ <td align="center" valign="top" width="14.28%"><a href="https://www.gitlab.com/alelec"><img src="https://avatars.githubusercontent.com/u/3318786?v=4?s=100" width="100px;" alt="Andrew Leech"/><br /><sub><b>Andrew Leech</b></sub></a><br /><a href="#mpflash-andrewleech" title="mpflash">💥</a> <a href="#test-andrewleech" title="Test">✅</a></td>
259
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/wovo"><img src="https://avatars.githubusercontent.com/u/9039468?v=4?s=100" width="100px;" alt="Wouter van Ooijen"/><br /><sub><b>Wouter van Ooijen</b></sub></a><br /><a href="#mpflash-wovo" title="mpflash">💥</a> <a href="#test-wovo" title="Test">✅</a></td>
260
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/shaneapowell"><img src="https://avatars.githubusercontent.com/u/12113620?v=4?s=100" width="100px;" alt="Shane Powell"/><br /><sub><b>Shane Powell</b></sub></a><br /><a href="#mpflash-shaneapowell" title="mpflash">💥</a> <a href="#test-shaneapowell" title="Test">✅</a></td>
261
+ </tr>
262
+ <tr>
263
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/robert-hh"><img src="https://avatars.githubusercontent.com/u/12476868?v=4?s=100" width="100px;" alt="Robert Hammelrath"/><br /><sub><b>Robert Hammelrath</b></sub></a><br /><a href="#mpflash-robert-hh" title="mpflash">💥</a> <a href="#test-robert-hh" title="Test">✅</a></td>
264
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/beetlegigg"><img src="https://avatars.githubusercontent.com/u/34552737?v=4?s=100" width="100px;" alt="Bg"/><br /><sub><b>Bg</b></sub></a><br /><a href="#mpflash-beetlegigg" title="mpflash">💥</a> <a href="#test-beetlegigg" title="Test">✅</a></td>
265
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/rkompass"><img src="https://avatars.githubusercontent.com/u/90282516?v=4?s=100" width="100px;" alt="Raul Kompaß"/><br /><sub><b>Raul Kompaß</b></sub></a><br /><a href="#mpflash-rkompass" title="mpflash">💥</a> <a href="#test-rkompass" title="Test">✅</a></td>
266
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/garryp4"><img src="https://avatars.githubusercontent.com/u/96994876?v=4?s=100" width="100px;" alt="garryp4"/><br /><sub><b>garryp4</b></sub></a><br /><a href="#mpflash-garryp4" title="mpflash">💥</a> <a href="#test-garryp4" title="Test">✅</a></td>
267
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/shanepowell-ast"><img src="https://avatars.githubusercontent.com/u/102747617?v=4?s=100" width="100px;" alt="Shane Powell"/><br /><sub><b>Shane Powell</b></sub></a><br /><a href="#mpflash-shanepowell-ast" title="mpflash">💥</a> <a href="#test-shanepowell-ast" title="Test">✅</a></td>
268
+ <td align="center" valign="top" width="14.28%"><a href="https://andypiper.org/"><img src="https://avatars.githubusercontent.com/u/552452?v=4?s=100" width="100px;" alt="Andy Piper"/><br /><sub><b>Andy Piper</b></sub></a><br /><a href="#mpflash-andypiper" title="mpflash">💥</a> <a href="#test-andypiper" title="Test">✅</a></td>
269
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/DavesCodeMusings"><img src="https://avatars.githubusercontent.com/u/61114342?v=4?s=100" width="100px;" alt="David Horton"/><br /><sub><b>David Horton</b></sub></a><br /><a href="#mpflash-DavesCodeMusings" title="mpflash">💥</a> <a href="#test-DavesCodeMusings" title="Test">✅</a></td>
270
+ </tr>
271
+ </tbody>
272
+ </table>
273
+
274
+ <!-- markdownlint-restore -->
275
+ <!-- prettier-ignore-end -->
276
+
277
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
278
+
279
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
@@ -11,8 +11,7 @@ from loguru import logger as log
11
11
 
12
12
  from .common import DownloadParams, FlashParams, ParamType
13
13
  from .config import config
14
- from .mpboard_id import (get_known_boards_for_port, get_known_ports,
15
- known_stored_boards)
14
+ from .mpboard_id import get_known_boards_for_port, get_known_ports, known_stored_boards
16
15
  from .mpremoteboard import MPRemoteBoard
17
16
  from .versions import micropython_versions
18
17
 
@@ -73,11 +72,11 @@ def ask_missing_params(
73
72
  # params.ports = [p for p in params.ports if p != "?"] # remove the "?" if present
74
73
  if isinstance(answers["port"], str):
75
74
  params.ports.append(answers["port"])
76
- elif isinstance(answers["port"], list): # type: ignore
75
+ elif isinstance(answers["port"], list): # type: ignore
77
76
  params.ports.extend(answers["port"])
78
77
  else:
79
78
  raise ValueError(f"Unexpected type for answers['port']: {type(answers['port'])}")
80
-
79
+
81
80
  if "boards" in answers:
82
81
  params.boards = [b for b in params.boards if b != "?"] # remove the "?" if present
83
82
  params.boards.extend(answers["boards"] if isinstance(answers["boards"], list) else [answers["boards"]])
@@ -157,23 +156,24 @@ def ask_port_board(*, multi_select: bool, action: str):
157
156
  ),
158
157
  inquirer_ux(
159
158
  "boards",
160
- message=(
161
- "Which {port} board firmware do you want to {action} " + "to {serial} ?" if action == "flash" else "?"
162
- ),
159
+ message=("Which {port} board firmware do you want to {action} " + "to {serial} ?" if action == "flash" else "?"),
163
160
  choices=filter_matching_boards,
164
161
  validate=at_least_one_validation, # type: ignore
165
162
  # validate=lambda _, x: True if x else "Please select at least one board", # type: ignore
166
163
  ),
167
164
  ]
168
165
 
166
+
169
167
  def at_least_one_validation(answers, current) -> bool:
170
168
  import inquirer.errors
169
+
171
170
  if not current:
172
171
  raise inquirer.errors.ValidationError("", reason="Please select at least one item.")
173
172
  if isinstance(current, list) and not any(current):
174
173
  raise inquirer.errors.ValidationError("", reason="Please select at least one item.")
175
174
  return True
176
175
 
176
+
177
177
  def ask_mp_version(multi_select: bool, action: str):
178
178
  """
179
179
  Asks the user for the version selection.
@@ -4,28 +4,25 @@ Simple Git module, where needed via powershell
4
4
  Some of the functions are based on the PyGithub module
5
5
  """
6
6
 
7
- import os
8
7
  import subprocess
9
8
  from pathlib import Path
10
9
  from typing import List, Optional, Union
11
10
 
12
11
  import cachetools.func
13
- from github import Auth, BadCredentialsException, Github
14
12
  from loguru import logger as log
15
- from packaging.version import parse
16
13
 
17
- # from mpflash.versions import SET_PREVIEW
14
+ from mpflash.config import config
18
15
 
19
- # Token with no permissions to avoid throttling
20
- # https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#getting-a-higher-rate-limit
21
- PAT_NO_ACCESS = (
22
- "github_pat_"
23
- + "11AAHPVFQ0G4NTaQ73Bw5J"
24
- + "_fAp7K9sZ1qL8VFnI9g78eUlCdmOXHB3WzSdj2jtEYb4XF3N7PDJBl32qIxq"
25
- )
26
- PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
27
- GH_CLIENT = Github(auth=Auth.Token(PAT))
16
+ # from github import Auth, BadCredentialsException, Github
28
17
 
18
+ # # Token with no permissions to avoid throttling
19
+ # # https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#getting-a-higher-rate-limit
20
+ # PAT_NO_ACCESS = "github_pat_" + "11AAHPVFQ0G4NTaQ73Bw5J" + "_fAp7K9sZ1qL8VFnI9g78eUlCdmOXHB3WzSdj2jtEYb4XF3N7PDJBl32qIxq"
21
+ # PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
22
+
23
+ # # GH_CLIENT = Github(auth=Auth.Token(PAT))
24
+
25
+ # GH_CLIENT = None
29
26
 
30
27
  def _run_local_git(
31
28
  cmd: List[str],
@@ -47,14 +44,14 @@ def _run_local_git(
47
44
  encoding="utf-8",
48
45
  )
49
46
  else:
50
- result = subprocess.run(
51
- cmd, capture_output=capture_output, check=True, encoding="utf-8"
52
- )
47
+ result = subprocess.run(cmd, capture_output=capture_output, check=True, encoding="utf-8")
53
48
  except (NotADirectoryError, FileNotFoundError) as e: # pragma: no cover
49
+ log.error(f"Not a directory: {e}")
54
50
  return None
55
51
  except subprocess.CalledProcessError as e: # pragma: no cover
56
52
  # add some logging for github actions
57
- log.error(f"{str(e)} : { e.stderr}")
53
+ log.info(f"Command: {cmd}")
54
+ log.error(f"{str(e)} : {e.returncode}\n{e.stdout}\n{e.stderr}")
58
55
  return None
59
56
  if result.stderr and result.stderr != b"":
60
57
  stderr = result.stderr
@@ -88,9 +85,7 @@ def clone(remote_repo: str, path: Path, shallow: bool = False, tag: Optional[str
88
85
  return False
89
86
 
90
87
 
91
- def get_local_tag(
92
- repo: Optional[Union[str, Path]] = None, abbreviate: bool = True
93
- ) -> Union[str, None]:
88
+ def get_local_tag(repo: Optional[Union[str, Path]] = None, abbreviate: bool = True) -> Union[str, None]:
94
89
  """
95
90
  get the most recent git version tag of a local repo
96
91
  repo Path should be in the form of : repo = "./repo/micropython"
@@ -123,6 +118,9 @@ def get_local_tags(repo: Optional[Path] = None, minver: Optional[str] = None) ->
123
118
  """
124
119
  get list of all tags of a local repo
125
120
  """
121
+ # Just in time import
122
+ from packaging.version import parse
123
+
126
124
  if not repo:
127
125
  repo = Path(".")
128
126
 
@@ -136,19 +134,22 @@ def get_local_tags(repo: Optional[Path] = None, minver: Optional[str] = None) ->
136
134
  return sorted(tags)
137
135
 
138
136
 
139
- from github.GithubException import BadCredentialsException
140
-
141
-
142
137
  @cachetools.func.ttl_cache(maxsize=16, ttl=60) # 60 seconds
143
138
  def get_tags(repo: str, minver: Optional[str] = None) -> List[str]:
144
139
  """
145
140
  Get list of tag of a repote github repo.
146
141
  only the last -preview tag is kept
147
142
  """
143
+ # Just in time import
144
+ from github import BadCredentialsException
145
+ from packaging.version import parse
146
+
148
147
  if not repo or not isinstance(repo, str) or "/" not in repo: # type: ignore
149
148
  return []
149
+
150
+ gh_client = config.gh_client
150
151
  try:
151
- gh_repo = GH_CLIENT.get_repo(repo)
152
+ gh_repo = gh_client.get_repo(repo)
152
153
  except BadCredentialsException as e:
153
154
  log.error(f"Github authentication error - {e}")
154
155
  return []
@@ -179,40 +180,6 @@ def checkout_tag(tag: str, repo: Optional[Union[str, Path]] = None) -> bool:
179
180
  return True
180
181
 
181
182
 
182
- def sync_submodules(repo: Union[Path, str]) -> bool:
183
- """
184
- make sure any submodules are in sync
185
- """
186
- cmds = [
187
- ["git", "submodule", "sync", "--quiet"],
188
- # ["git", "submodule", "update", "--quiet"],
189
- ["git", "submodule", "update", "--init", "lib/micropython-lib"],
190
- ]
191
- for cmd in cmds:
192
- if result := _run_local_git(cmd, repo=repo, expect_stderr=True):
193
- # actually a good result
194
- log.debug(result.stderr)
195
- else:
196
- return False
197
- checkout_arduino_lib(Path(repo))
198
- return True
199
-
200
-
201
- def checkout_arduino_lib(mpy_path: Path):
202
- """
203
- Checkout the arduino-lib submodule repo if it exists
204
-
205
- This is needed as some of the arduino boards freeze modules originationg from the arduino-lib
206
- """
207
- # arduino_lib_path = mpy_path / "lib/arduino-lib"
208
- if (mpy_path / "lib/arduino-lib").exists():
209
- cmd = ["git", "submodule", "update", "--init", "lib/arduino-lib"]
210
- try:
211
- result = subprocess.run(cmd, cwd=mpy_path, check=True)
212
- log.info(f"checkout arduino-lib: {result.returncode}")
213
- except subprocess.CalledProcessError as e:
214
- log.warning("Could not check out arduino-lib, error: ", e)
215
-
216
183
 
217
184
  def checkout_commit(commit_hash: str, repo: Optional[Union[Path, str]] = None) -> bool:
218
185
  """
@@ -300,7 +267,7 @@ def pull(repo: Union[Path, str], branch: str = "main") -> bool:
300
267
  return result.returncode == 0
301
268
 
302
269
 
303
- def get_git_describe(folder: Optional[str] = None):
270
+ def get_git_describe(folder: Optional[Union[Path, str]] = None):
304
271
  """
305
272
  Based on MicroPython makeversionhdr.py
306
273
  returns : current git tag, commits ,commit hash : "v1.19.1-841-g3446"
File without changes
@@ -12,7 +12,7 @@ from .touch1200 import enter_bootloader_touch_1200bps
12
12
 
13
13
  BL_OPTIONS = {
14
14
  "stm32": [BootloaderMethod.TOUCH_1200, BootloaderMethod.MPY, BootloaderMethod.MANUAL],
15
- "rp2": [BootloaderMethod.TOUCH_1200, BootloaderMethod.MPY, BootloaderMethod.MANUAL],
15
+ "rp2": [BootloaderMethod.MPY, BootloaderMethod.TOUCH_1200, BootloaderMethod.MANUAL],
16
16
  "samd": [BootloaderMethod.TOUCH_1200, BootloaderMethod.MPY, BootloaderMethod.MANUAL],
17
17
  "esp32": [BootloaderMethod.NONE],
18
18
  "esp8266": [BootloaderMethod.NONE],
@@ -1,5 +1,4 @@
1
- """ Detect if a board is in bootloader mode
2
- """
1
+ """Detect if a board is in bootloader mode"""
3
2
 
4
3
  import os
5
4
 
@@ -52,7 +52,6 @@ mcu_theme = Theme(
52
52
 
53
53
 
54
54
  def enter_bootloader_manual(mcu: MPRemoteBoard, timeout: int = 10):
55
-
56
55
  message: str
57
56
  if mcu.port == "rp2":
58
57
  message = f"""\
@@ -27,10 +27,10 @@ def enter_bootloader_touch_1200bps(mcu: MPRemoteBoard, timeout: int = 10):
27
27
 
28
28
  except serial.SerialException as e:
29
29
  log.exception(e)
30
- raise MPFlashError("pySerial error: " + str(e) + "\n") from e
30
+ raise MPFlashError(f"pySerial error: {str(e)}") from e
31
31
  except Exception as e:
32
32
  log.exception(e)
33
- raise MPFlashError("Error: " + str(e) + "\n") from e
33
+ raise MPFlashError(f"Error: {str(e)}") from e
34
34
 
35
35
  # be optimistic
36
36
  return True
@@ -92,6 +92,14 @@ from mpflash.versions import clean_version
92
92
  help="The MicroPython board ID to flash. If not specified will try to read the BOARD_ID from the connected MCU.",
93
93
  metavar="BOARD_ID or ?",
94
94
  )
95
+ @click.option(
96
+ "--variant",
97
+ "-var",
98
+ "variant", # single board
99
+ multiple=False,
100
+ help="The board VARIANT to flash or '-'. If not specified will try to read the variant from the connected MCU.",
101
+ metavar="VARIANT",
102
+ )
95
103
  @click.option(
96
104
  "--cpu",
97
105
  "--chip",
@@ -102,9 +110,9 @@ from mpflash.versions import clean_version
102
110
  )
103
111
  @click.option(
104
112
  "--erase/--no-erase",
105
- default=True,
113
+ default=False,
106
114
  show_default=True,
107
- help="""Erase flash before writing new firmware. (Not supported on UF2 boards)""",
115
+ help="""Erase flash before writing new firmware.""",
108
116
  )
109
117
  @click.option(
110
118
  "--bootloader",
@@ -115,14 +123,21 @@ from mpflash.versions import clean_version
115
123
  show_default=True,
116
124
  help="""How to enter the (MicroPython) bootloader before flashing.""",
117
125
  )
126
+ @click.option(
127
+ "--flash_mode", "-fm",
128
+ type=click.Choice(["keep", "qio", "qout", "dio", "dout"]),
129
+ default="keep",
130
+ show_default=True,
131
+ help="""Flash mode for ESP boards. (default: keep)""",
132
+ )
118
133
  def cli_flash_board(**kwargs) -> int:
119
134
  # version to versions, board to boards
120
- kwargs["versions"] = [kwargs.pop("version")] if kwargs["version"] != None else []
135
+ kwargs["versions"] = [kwargs.pop("version")] if kwargs["version"] is not None else []
121
136
  if kwargs["board"] is None:
122
137
  kwargs["boards"] = []
123
138
  kwargs.pop("board")
124
139
  else:
125
- kwargs["boards"] = [kwargs.pop("board")]
140
+ kwargs["boards"] = [kwargs.pop("board")]
126
141
 
127
142
  params = FlashParams(**kwargs)
128
143
  params.versions = list(params.versions)
@@ -141,7 +156,9 @@ def cli_flash_board(**kwargs) -> int:
141
156
  all_boards: List[MPRemoteBoard] = []
142
157
  if not params.boards:
143
158
  # nothing specified - detect connected boards
144
- params.ports, params.boards, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore, bluetooth=params.bluetooth)
159
+ params.ports, params.boards, all_boards = connected_ports_boards(
160
+ include=params.ports, ignore=params.ignore, bluetooth=params.bluetooth
161
+ )
145
162
  if params.boards == []:
146
163
  # No MicroPython boards detected, but it could be unflashed or in bootloader mode
147
164
  # Ask for serial port and board_id to flash
@@ -171,6 +188,11 @@ def cli_flash_board(**kwargs) -> int:
171
188
  if not all_boards:
172
189
  log.trace("No boards detected yet, scanning for connected boards")
173
190
  _, _, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore)
191
+ # if variant id provided on the cmdline, treat is as an override
192
+ if params.variant:
193
+ for b in all_boards:
194
+ b.variant = params.variant if (params.variant.lower() not in {"-","none"}) else ""
195
+
174
196
  worklist = full_auto_worklist(
175
197
  all_boards=all_boards,
176
198
  version=params.versions[0],
@@ -199,6 +221,7 @@ def cli_flash_board(**kwargs) -> int:
199
221
  params.fw_folder,
200
222
  params.erase,
201
223
  params.bootloader,
224
+ flash_mode = params.flash_mode,
202
225
  ):
203
226
  log.info(f"Flashed {len(flashed)} boards")
204
227
  show_mcus(flashed, title="Updated boards after flashing")
@@ -39,6 +39,7 @@ def cb_test(ctx, param, value):
39
39
  config.tests = value
40
40
  return value
41
41
 
42
+
42
43
  def cb_usb(ctx, param, value: bool):
43
44
  config.usb = bool(value)
44
45
  return value
@@ -73,15 +73,14 @@ def cli_list_mcus(serial: List[str], ignore: List[str], bluetooth: bool, as_json
73
73
  # TODO? Ask user to select a serialport if [?] is given ?
74
74
 
75
75
  conn_mcus = list_mcus(ignore=ignore, include=serial, bluetooth=bluetooth)
76
- # ignore boards that have the [micropython-stubber] ignore flag set
77
- conn_mcus = [item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))]
76
+ # ignore boards that have the [mpflash] ignore flag set
77
+ conn_mcus = [item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))]
78
78
  if as_json:
79
- # remove the path and firmware attibutes from the json output as they are always empty
80
- for mcu in conn_mcus:
81
- del mcu.path
82
- del mcu.firmware
83
- print(json.dumps([mcu.__dict__ for mcu in conn_mcus], indent=4))
84
- progress = False
79
+ print(json.dumps([mcu.to_dict() for mcu in conn_mcus], indent=4))
80
+
85
81
  if progress:
86
82
  show_mcus(conn_mcus, refresh=False)
83
+ for mcu in conn_mcus:
84
+ # reset the board so it can continue to whatever it was running before
85
+ mcu.run_command("reset")
87
86
  return 0 if conn_mcus else 1