mpflash 1.25.0.post1__py3-none-any.whl → 1.25.0.post3__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.
- mpflash/add_firmware.py +43 -16
- mpflash/ask_input.py +4 -4
- mpflash/basicgit.py +1 -1
- mpflash/bootloader/manual.py +1 -1
- mpflash/cli_download.py +8 -5
- mpflash/cli_flash.py +31 -35
- mpflash/cli_group.py +3 -0
- mpflash/cli_list.py +8 -3
- mpflash/cli_main.py +4 -0
- mpflash/common.py +2 -38
- mpflash/config.py +21 -0
- mpflash/db/__init__.py +2 -0
- mpflash/db/core.py +61 -0
- mpflash/db/gather_boards.py +112 -0
- mpflash/db/loader.py +122 -0
- mpflash/db/meta.py +78 -0
- mpflash/db/micropython_boards.zip +0 -0
- mpflash/db/models.py +93 -0
- mpflash/db/tools.py +27 -0
- mpflash/download/__init__.py +46 -64
- mpflash/download/from_web.py +26 -36
- mpflash/download/fwinfo.py +41 -0
- mpflash/download/jid.py +56 -0
- mpflash/downloaded.py +79 -93
- mpflash/flash/__init__.py +7 -3
- mpflash/flash/esp.py +2 -1
- mpflash/flash/stm32.py +1 -1
- mpflash/flash/uf2/windows.py +3 -1
- mpflash/flash/worklist.py +16 -28
- mpflash/list.py +3 -3
- mpflash/logger.py +43 -9
- mpflash/mpboard_id/__init__.py +3 -9
- mpflash/mpboard_id/alternate.py +56 -0
- mpflash/mpboard_id/board_id.py +11 -94
- mpflash/mpboard_id/known.py +45 -57
- mpflash/mpboard_id/resolve.py +19 -0
- mpflash/mpremoteboard/__init__.py +3 -2
- mpflash/mpremoteboard/mpy_fw_info.py +1 -0
- mpflash/mpremoteboard/runner.py +5 -2
- mpflash/vendor/pydfu.py +33 -6
- mpflash/versions.py +3 -0
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0.post3.dist-info}/METADATA +56 -12
- mpflash-1.25.0.post3.dist-info/RECORD +69 -0
- mpflash/db/boards.py +0 -63
- mpflash/db/downloads.py +0 -87
- mpflash/mpboard_id/add_boards.py +0 -260
- mpflash/mpboard_id/board.py +0 -40
- mpflash/mpboard_id/store.py +0 -47
- mpflash-1.25.0.post1.dist-info/RECORD +0 -62
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0.post3.dist-info}/LICENSE +0 -0
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0.post3.dist-info}/WHEEL +0 -0
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0.post3.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: mpflash
|
3
|
-
Version: 1.25.0.
|
3
|
+
Version: 1.25.0.post3
|
4
4
|
Summary: Flash and download tool for MicroPython firmwares
|
5
5
|
License: MIT
|
6
6
|
Keywords: MicroPython,firmware,flash,download,UF2,esptool
|
@@ -29,13 +29,13 @@ Requires-Dist: loguru (>=0.7.2,<0.8.0)
|
|
29
29
|
Requires-Dist: mpremote (>=1.22.0,<2.0.0)
|
30
30
|
Requires-Dist: packaging (>=24.2,<25.0)
|
31
31
|
Requires-Dist: platformdirs (>=4.2.0,<5.0.0)
|
32
|
-
Requires-Dist:
|
33
|
-
Requires-Dist: psutil (>=5.9.8,<8.0.0)
|
32
|
+
Requires-Dist: psutil (>=7.0.0,<8.0.0)
|
34
33
|
Requires-Dist: pygithub (>=2.1.1,<3.0.0)
|
35
34
|
Requires-Dist: pyusb (>=1.2.1,<2.0.0)
|
36
35
|
Requires-Dist: pywin32 (>=310,<311) ; sys_platform == "win32"
|
37
36
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
38
37
|
Requires-Dist: rich-click (>=1.8.1,<2.0.0)
|
38
|
+
Requires-Dist: sqlalchemy (>=2.0.41,<3.0.0)
|
39
39
|
Requires-Dist: tenacity (==9.0.0)
|
40
40
|
Project-URL: Homepage, https://github.com/Josverl/mpflash/blob/main/README.md
|
41
41
|
Project-URL: Repository, https://github.com/Josverl/mpflash
|
@@ -58,9 +58,22 @@ This tool was initially created to be used in a CI/CD pipeline to automate the p
|
|
58
58
|
- `samd`, using ` .uf2`, using filecopy
|
59
59
|
- `esp32`, using `.bin`, using esptool,
|
60
60
|
- `esp8266`, using `.bin`, using esptool
|
61
|
-
- `stm32`, using ` .dfu`, using pydfu
|
61
|
+
- `stm32`, using ` .dfu`, using pydfu (also in Windows)
|
62
62
|
|
63
63
|
Not yet implemented: `nrf`, `cc3200`, `mimxrt`, `renesas`
|
64
|
+
|
65
|
+
## Release v1.25.0(.post2)
|
66
|
+
|
67
|
+
This release includes several new features and improvements:
|
68
|
+
- **New features:**
|
69
|
+
- Added support for `--variant` option to specify a specific variant of the board when flashing.
|
70
|
+
- mpflash now uses a slqlite database to store information on all possible micropython firmwares, and the management of the downloaded firmware files.
|
71
|
+
- This allows for a better identification of boards, and matches to the correct firmware.
|
72
|
+
- Use the MicroPython v1.25.0 `sys.implementation._build` to as board_id when avaialable
|
73
|
+
- Automatically try to download firmware if not yet available locally. No lonmger need to specify the `--download` option.
|
74
|
+
- Restructured mpboard_id to use a SQLite db to be able to ID more boards and variants
|
75
|
+
- vendored and adapted `board_database.py` from mpflash, kudos @mattytrentini
|
76
|
+
|
64
77
|
|
65
78
|
## Features
|
66
79
|
1. List the connected boards including their firmware details, in a tabular or json format
|
@@ -79,15 +92,46 @@ You can use mpflash to perform various operations on your MicroPython boards. He
|
|
79
92
|
| Command | Description |
|
80
93
|
|---------|-------------|
|
81
94
|
| `mpflash list` | List the connected board(s) including their firmware details |
|
95
|
+
| `mpflash flash` | Flash the latest stable firmware to the connected board(s), downloading the firmware if needed |
|
82
96
|
| `mpflash download` | Download the MicroPython firmware(s) for the connected board(s) |
|
83
|
-
| `mpflash flash` | Flash the latest stable firmware to the connected board(s) |
|
84
97
|
|
85
|
-
|
98
|
+
**Listing connected boards:**
|
99
|
+
`mpflash list` will list all connected boards in a table , including their serial port, family, board name, CPU, version and build number.
|
100
|
+
Options are available to list the boards in a json format, or to filter the list by serial port or board type.
|
101
|
+
|
102
|
+
|
103
|
+
**Flashing boards with new firmware:**
|
104
|
+
`mpflash flash` will flash the latest stable firmware to all connected boards, downloading the firmware if needed.
|
105
|
+
It will try to determine the current micropython borad and variant, download the firmware if needed, and flash the correct firmware to each board.
|
106
|
+
|
107
|
+
Common options are:
|
108
|
+
|
109
|
+
- `--version` to specify the version of the firmware to flash, defaults to the latest stable version.
|
110
|
+
- `--serial` to specify the serial port(s) to flash, defaults to all connected boards.
|
111
|
+
- `--board` to specify which firmware to flash to a single board
|
112
|
+
- `--variant` to specify a specific variant of the board
|
113
|
+
|
114
|
+
**Downloading firmware:**
|
115
|
+
`mpflash download` will download the latest stable firmware for all connected boards, or a specific board if specified. It will download the firmware from the official MicroPython website and save it in your `Downloads/firmware` directory.
|
116
|
+
When a board is specified for which multiple variants are available, all variants will be downloaded.
|
86
117
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
118
|
+
Common options are:
|
119
|
+
|
120
|
+
- `--version` to specify the version of the firmware to download, defaults to the latest stable version. (e.g. `stable`, `preview`, `x.y.z`)
|
121
|
+
- `--serial` to specify the serial port(s) to flash, defaults to all connected boards.
|
122
|
+
- `--board` to specify which firmware to flash to a single board
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
## Selecting or ignoring specific serial ports
|
127
|
+
|
128
|
+
You can use the `--serial` option to select a specific serial port(s) to flash,
|
129
|
+
Or you can use the `--ignore` option to ignore a specific serial port(s).
|
130
|
+
|
131
|
+
Either option can be specified multiple times, can be globs (e.g. COM*) or exact port names (e.g. /dev/ttyUSB0).
|
132
|
+
To permenently ignore a port, you can set the `MPFLASH_IGNORE` environment variable to a space-separated list of serial ports or globs.
|
133
|
+
|
134
|
+
In addition there is a --bluetooth option to simplify ignoring bluetooth ports, where the default is to ignore bluetooth ports.
|
91
135
|
|
92
136
|
```
|
93
137
|
--serial,--serial-port -s SERIALPORT Serial port(s) (or globs) to list. [default: *] > > --ignore -i SERIALPORT Serial port(s) (or globs) to ignore. Defaults to MPFLASH_IGNORE. │
|
@@ -102,9 +146,9 @@ This file can contain a description of the board, which will be shown in the lis
|
|
102
146
|
description = "Blue Norwegian actuator"
|
103
147
|
```
|
104
148
|
|
105
|
-
If you want the board to be ignored by mpflash, you can add the following to the board_info.toml file:
|
149
|
+
If you want the board to be ignored by mpflash, no matter which serial port it is connected to, you can add the following to the `board_info.toml` file:
|
106
150
|
```toml
|
107
|
-
description = "Blue Norwegian
|
151
|
+
description = "Blue Norwegian actuator"
|
108
152
|
[mpflash]
|
109
153
|
ignore = true
|
110
154
|
```
|
@@ -0,0 +1,69 @@
|
|
1
|
+
mpflash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
mpflash/add_firmware.py,sha256=P1yaNUdExfzC_qnhE-P5ALZg1Uh7XT6Xf7NYccJP7Rc,4317
|
3
|
+
mpflash/ask_input.py,sha256=YUx65Xwj6dNPwWcbQiWG7U4wDW69zEdno2HcT1KwPBg,8886
|
4
|
+
mpflash/basicgit.py,sha256=Aiz6rF6PVhQir-FU-T1NhbjsW803y39Js6xnWs8-yu4,9676
|
5
|
+
mpflash/bootloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
+
mpflash/bootloader/activate.py,sha256=orQOw4XTkXVZI-rMInRb0T5Wp3qA_BlzbJUA2gyBToU,2361
|
7
|
+
mpflash/bootloader/detect.py,sha256=OagP2QVWeLLWkZt2paqEF6r4_x3QDcBGNCPOWfMy9NQ,2686
|
8
|
+
mpflash/bootloader/manual.py,sha256=WYC4x-dxrSwVUfgnKTlu34pCzckrWJKZnWsARDocycI,3169
|
9
|
+
mpflash/bootloader/micropython.py,sha256=v_kZkvg0uWZDbMrT78gmiYHbD83QLdnrctvEClI8iRg,529
|
10
|
+
mpflash/bootloader/touch1200.py,sha256=VND7_YniS9Vx6WEaAxjI72RZZ6WBOwmBTsKJkbuaAHk,1105
|
11
|
+
mpflash/cli_download.py,sha256=sMMIVTE4P9O2GpWB9jcbOiKQX-XJ0nu2bBylRbWu0X8,3872
|
12
|
+
mpflash/cli_flash.py,sha256=Is8UH1QZ33XuajrkVOIdjOubyvAb5CcZKONJgdmmZGk,7966
|
13
|
+
mpflash/cli_group.py,sha256=Uf_1ZmeeSIsaGLuuKn3KPPPVi8fJVbIacJYFZx_oPHc,2684
|
14
|
+
mpflash/cli_list.py,sha256=ZuRalXXjDGo6FhgMTv54BQD_PNss7eeopeZQ_uE1J90,2632
|
15
|
+
mpflash/cli_main.py,sha256=NMhEtMtSe7ApE-210Q4p-g7ZgewgO-4z1Q-vNKLQ47Y,1277
|
16
|
+
mpflash/common.py,sha256=iKDoc6Ut8XbZ8fYLEI2XsoU7GuG_pFG0KGcRWXPl1wE,5922
|
17
|
+
mpflash/config.py,sha256=bmwNSJzk27iHcI-r3C6hm6-TeOat2ymzbbv-Q-xuO2o,3048
|
18
|
+
mpflash/connected.py,sha256=oxZdk1o-AfNPhJsSxr3KrMH_gdYfrjqc_IpT6J8Ng9k,3496
|
19
|
+
mpflash/db/__init__.py,sha256=wnIlO4nOXsPGXMbn2OCqHRsR-hUmtJsko8VdqjH3ZUE,45
|
20
|
+
mpflash/db/core.py,sha256=hyzurZp8QMl8Q9B00Q-tOkOUp68T8XhM7tj3dm5cDHw,2283
|
21
|
+
mpflash/db/gather_boards.py,sha256=8QS7NIt3n9ROqtgVAnoqU8YMeObLGaN2pvJL7d_kULA,3905
|
22
|
+
mpflash/db/loader.py,sha256=0L4I3ySaGLFlzy9FlV7_nzbqzA6MHwi0FhgDG5FJ_9U,4848
|
23
|
+
mpflash/db/meta.py,sha256=I7JycEx37MVVYowA0VFfUYFX9IURiTTsWQ1RhFgGqes,2251
|
24
|
+
mpflash/db/micropython_boards.zip,sha256=cc4m7VSskj__rhabw3j5OZCiz1yEi6yCx7JGFn1QB0k,16647
|
25
|
+
mpflash/db/models.py,sha256=Q4yjZPcNRIGWevoACeGDS1i31QX6jq1q5TsyPjmdmz4,3448
|
26
|
+
mpflash/db/tools.py,sha256=6SEGfshNob4yRQ4h-Cj_xcWMRY28sbA8CWauNXV_uMI,814
|
27
|
+
mpflash/download/__init__.py,sha256=zidXvsSFCfR-BZCZ6TiB7uEucEuUqXnZhKSfTs60lzU,7930
|
28
|
+
mpflash/download/from_web.py,sha256=PVJDaFfYLJGXlPva5fExh4Yg2H7j3idyJEcfOiVVJBs,7608
|
29
|
+
mpflash/download/fwinfo.py,sha256=gpa92PkysT1B7mxPAFJ-b_6y03QCNgHKm-J6T_RFNMI,1852
|
30
|
+
mpflash/download/jid.py,sha256=503HW4jIB22fsb9vYphXqqO33LTMtvPdENG81wKDgMs,2334
|
31
|
+
mpflash/downloaded.py,sha256=508sqROPf0Ymz7UxMzReXtK6mG1EcoXA-ysGdzV-VM0,4040
|
32
|
+
mpflash/errors.py,sha256=IAidY3qkZsXy6Pm1rdmVFmGyg81ywHhse3itaPctA2w,247
|
33
|
+
mpflash/flash/__init__.py,sha256=jif7-ifsXMabidjNdqUQyl1CwD5_USjCAZFhU5W-Aw8,2992
|
34
|
+
mpflash/flash/esp.py,sha256=4977E1hDqJ4-EIkLzwrUtgZuc0ZTD7NvP1PQZgZ2DoU,3227
|
35
|
+
mpflash/flash/stm32.py,sha256=jNgMpJaxUwtJ-v6VU1luD1t41AQprCUeNVCVEovxQe0,595
|
36
|
+
mpflash/flash/stm32_dfu.py,sha256=W-3JsRQyf3DduoIRXDmGZ35RogqtjQgcJnk-GOtQoLE,3090
|
37
|
+
mpflash/flash/uf2/__init__.py,sha256=haL84hP2p1ZjKF6dXJJHAB_NTf7jT91MuZvmvg9SpIA,3617
|
38
|
+
mpflash/flash/uf2/boardid.py,sha256=U5wGM8VA3wEpUxQCMtuXpMZZomdVH8J_Zd5_GekUMuU,423
|
39
|
+
mpflash/flash/uf2/linux.py,sha256=uTgqyS7C7xfQ25RrTcSUkt-m2u2Ks_o7bPLzIecPoC8,4355
|
40
|
+
mpflash/flash/uf2/macos.py,sha256=JTaIpqnR_0k4oSEvzs9amhmK-PMxUJyZLnZ_wZwxa-0,1228
|
41
|
+
mpflash/flash/uf2/uf2disk.py,sha256=4_P2l-kedM7VSliA2u706LQLxvu3xWSod1-lj-xjZis,298
|
42
|
+
mpflash/flash/uf2/windows.py,sha256=OEeskObPtpIE4a5NzYIcBqg3FkM5MGPGEa4lGGOfntY,1338
|
43
|
+
mpflash/flash/worklist.py,sha256=ZqbgYChXFGEVLVlGKeS9eJJDToxBYqjrfWE2NIa7Cck,5622
|
44
|
+
mpflash/list.py,sha256=NNhKpRh3ARZMdq56GLJgJ67GeuUf9SxjTzFhQjDsi9A,4008
|
45
|
+
mpflash/logger.py,sha256=b2pNiAEXgpUDZKnMjtgBAGgMpPwTB3u030EhJiXyLZQ,2009
|
46
|
+
mpflash/mpboard_id/__init__.py,sha256=Z6gDDWTCSKPp2fsuaUz80zgrklBR9XDlSLF9y_evR9A,391
|
47
|
+
mpflash/mpboard_id/alternate.py,sha256=ZhqfdA9sLJmyOfJ6WwK9wrzzUn6JQdkAreiL0q5XEQg,1913
|
48
|
+
mpflash/mpboard_id/board_id.py,sha256=dGbYnqaGHm6Z68P6aCq5bv95pyhi9KKhQleQXmlyO8Y,2046
|
49
|
+
mpflash/mpboard_id/board_info.json,sha256=A3ZIt38KvAy2NMB5srHorSBd3Q3wOZIXufWiIs3XLrs,1019745
|
50
|
+
mpflash/mpboard_id/board_info.zip,sha256=-2bnQGRsIQuJUfz-7_-GQ8pMWJ1evhCez6yfjhXocNw,23213
|
51
|
+
mpflash/mpboard_id/known.py,sha256=GrNe4FtzVIdi9L9xuJ1gzorzXTvdfrugX1iVc_Nblb8,3325
|
52
|
+
mpflash/mpboard_id/resolve.py,sha256=5KCZ0Tcg3FYZ3HK_zux5EguwoSC2E03kCpW2fh4rN2A,779
|
53
|
+
mpflash/mpremoteboard/__init__.py,sha256=MOzb7igpawgJcZyCwolAP80GRch9Anw_uzDuaCMBSFo,12092
|
54
|
+
mpflash/mpremoteboard/mpy_fw_info.py,sha256=ZDEPJN9XJnoG_oeWcLNiLJAD5bkVX2yI_j4K7msUxWM,5196
|
55
|
+
mpflash/mpremoteboard/runner.py,sha256=auJuK7uBq_qdZOX9DgzRARyAsTyhT8c9ycP02VqhMf4,4943
|
56
|
+
mpflash/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
|
+
mpflash/vendor/board_database.py,sha256=Cb8fEhJaZ2siMkLPW5rPwV9yzBsTtKGOqWUd9TxNgFM,8763
|
58
|
+
mpflash/vendor/click_aliases.py,sha256=adLhqLxNpJEPjSCIRSTkR-QzSgavGFKT0cwRbjxpzRU,5395
|
59
|
+
mpflash/vendor/dfu.py,sha256=6rqGCBS8mTxxaLtkdzJ8O6nc74kFk8jrkmKvxw-x-u8,5693
|
60
|
+
mpflash/vendor/pico-universal-flash-nuke/LICENSE.txt,sha256=Zkc2iTNbib2NCMwtLjMEz0vFCPglgvaw6Mj7QiWldpQ,1484
|
61
|
+
mpflash/vendor/pico-universal-flash-nuke/universal_flash_nuke.uf2,sha256=QuPMppqHMVOt3vDVU0bikHRLsTiDRQYNUcGQ_OLRFGI,28160
|
62
|
+
mpflash/vendor/pydfu.py,sha256=KD1RHHuhvhWi-l1UB6GyggkxouDKtZgkG4ivRbIfwC4,21264
|
63
|
+
mpflash/vendor/readme.md,sha256=BQ7Uxf8joeYMjTUuSLLBG49ob6a9MgFPIEwuc72-Mfw,415
|
64
|
+
mpflash/versions.py,sha256=HuujLNdMKY_mQXyEqwXVHcU8nbuXeBiWP2TMA5JQhr4,4884
|
65
|
+
mpflash-1.25.0.post3.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
|
66
|
+
mpflash-1.25.0.post3.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
|
67
|
+
mpflash-1.25.0.post3.dist-info/METADATA,sha256=dbSzPHFoSdH8cECZgjgi_AXOK9y-p-V0xWwCvYDx8xY,26718
|
68
|
+
mpflash-1.25.0.post3.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
69
|
+
mpflash-1.25.0.post3.dist-info/RECORD,,
|
mpflash/db/boards.py
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
|
2
|
-
from __future__ import annotations
|
3
|
-
|
4
|
-
import sqlite3
|
5
|
-
from pathlib import Path
|
6
|
-
from typing import List
|
7
|
-
|
8
|
-
from mpflash.common import FWInfo
|
9
|
-
from mpflash.config import config
|
10
|
-
from mpflash.logger import log
|
11
|
-
|
12
|
-
|
13
|
-
def find_board_id(
|
14
|
-
db_path: Path | None = None, board_id: str = "", description: str = "", version: str = "%"
|
15
|
-
) -> List[str]:
|
16
|
-
"""Get a list of board IDs from the database based on the board ID or description"""
|
17
|
-
db_path = db_path or config.db_path
|
18
|
-
conn = sqlite3.connect(db_path)
|
19
|
-
conn.row_factory = sqlite3.Row
|
20
|
-
rows = []
|
21
|
-
with conn:
|
22
|
-
cursor = conn.cursor()
|
23
|
-
|
24
|
-
query = """
|
25
|
-
SELECT DISTINCT board_id FROM board_downloaded
|
26
|
-
where board_id like ? and version like ?
|
27
|
-
ORDER BY `version` ASC
|
28
|
-
"""
|
29
|
-
cursor.execute(query, (board_id,version))
|
30
|
-
rows = cursor.fetchall()
|
31
|
-
if len(rows) == 0:
|
32
|
-
cursor.execute(
|
33
|
-
"""
|
34
|
-
SELECT DISTINCT description FROM board_downloaded
|
35
|
-
where description like ? and version like ?
|
36
|
-
ORDER BY `description` ASC
|
37
|
-
""",
|
38
|
-
(description,version),
|
39
|
-
)
|
40
|
-
rows = cursor.fetchall()
|
41
|
-
|
42
|
-
return [row['board_id'] for row in rows]
|
43
|
-
|
44
|
-
|
45
|
-
def find_board_info(
|
46
|
-
db_path: Path | None = None, board_id: str = "", version: str = "%"
|
47
|
-
) -> List[sqlite3.Row]:
|
48
|
-
"""get a list of board rows from the database based on the board ID and version"""
|
49
|
-
db_path = db_path or config.db_path
|
50
|
-
conn = sqlite3.connect(db_path)
|
51
|
-
conn.row_factory = sqlite3.Row
|
52
|
-
rows = []
|
53
|
-
with conn:
|
54
|
-
cursor = conn.cursor()
|
55
|
-
query = """
|
56
|
-
SELECT * FROM board_downloaded
|
57
|
-
where board_id like ? and version like ?
|
58
|
-
ORDER BY board_id, version ASC
|
59
|
-
"""
|
60
|
-
cursor.execute(query, (board_id,version,))
|
61
|
-
rows = cursor.fetchall()
|
62
|
-
|
63
|
-
return rows
|
mpflash/db/downloads.py
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import sqlite3
|
4
|
-
from pathlib import Path
|
5
|
-
from typing import List
|
6
|
-
|
7
|
-
from mpflash.common import FWInfo
|
8
|
-
from mpflash.config import config
|
9
|
-
from mpflash.logger import log
|
10
|
-
|
11
|
-
|
12
|
-
def upsert_download(conn: sqlite3.Connection, board: FWInfo):
|
13
|
-
"""
|
14
|
-
Adds a row to the downloaded firmware table in the database.
|
15
|
-
- downloads.board_id <-- FWInfo.variant
|
16
|
-
- downloads.source <-- FWInfo.firmware
|
17
|
-
|
18
|
-
Args:
|
19
|
-
conn : The database connection to use.
|
20
|
-
board : The firmware information to add to the database.
|
21
|
-
|
22
|
-
"""
|
23
|
-
with conn:
|
24
|
-
conn.execute(
|
25
|
-
"""
|
26
|
-
INSERT INTO downloads
|
27
|
-
(port, board, filename, source, board_id, version, build, ext, family, custom, description)
|
28
|
-
VALUES
|
29
|
-
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
30
|
-
ON CONFLICT(filename) DO UPDATE SET
|
31
|
-
port=excluded.port,
|
32
|
-
board=excluded.board,
|
33
|
-
source=excluded.source,
|
34
|
-
board_id=excluded.board_id,
|
35
|
-
version=excluded.version,
|
36
|
-
build=excluded.build,
|
37
|
-
ext=excluded.ext,
|
38
|
-
family=excluded.family,
|
39
|
-
custom=excluded.custom,
|
40
|
-
description=excluded.description
|
41
|
-
""",
|
42
|
-
(
|
43
|
-
board.port,
|
44
|
-
board.board,
|
45
|
-
board.filename,
|
46
|
-
board.firmware,
|
47
|
-
board.variant,
|
48
|
-
board.version,
|
49
|
-
board.build,
|
50
|
-
board.ext,
|
51
|
-
board.family,
|
52
|
-
board.custom,
|
53
|
-
board.description,
|
54
|
-
),
|
55
|
-
)
|
56
|
-
conn.commit()
|
57
|
-
|
58
|
-
def downloaded(db_path: Path | None = None) -> List[FWInfo]:
|
59
|
-
"""Load a list of locally downloaded firmwares from the database"""
|
60
|
-
db_path = db_path or config.db_path
|
61
|
-
with sqlite3.connect(db_path) as conn:
|
62
|
-
firmwares: List[FWInfo] = []
|
63
|
-
try:
|
64
|
-
conn.row_factory = sqlite3.Row
|
65
|
-
cursor = conn.cursor()
|
66
|
-
cursor.execute("SELECT * FROM downloads")
|
67
|
-
rows = cursor.fetchall()
|
68
|
-
for row in rows:
|
69
|
-
fw_info = FWInfo.from_dict(
|
70
|
-
{
|
71
|
-
"filename": row["filename"],
|
72
|
-
"version": row["version"],
|
73
|
-
"board": row["board"],
|
74
|
-
"variant": row["board_id"],
|
75
|
-
"port": row["port"],
|
76
|
-
"firmware": row["source"],
|
77
|
-
"build": row["build"],
|
78
|
-
"preview": 1 if int(row["build"]) > 0 else 0,
|
79
|
-
}
|
80
|
-
)
|
81
|
-
firmwares.append(fw_info)
|
82
|
-
except sqlite3.Error as e:
|
83
|
-
log.error(f"Database error: {e}")
|
84
|
-
|
85
|
-
# sort by filename
|
86
|
-
firmwares.sort(key=lambda x: x.filename)
|
87
|
-
return firmwares
|
mpflash/mpboard_id/add_boards.py
DELETED
@@ -1,260 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Collects board name and description information from MicroPython and writes it to JSON and CSV files.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import re
|
6
|
-
from pathlib import Path
|
7
|
-
from typing import List, Optional
|
8
|
-
|
9
|
-
import inquirer
|
10
|
-
import rich
|
11
|
-
import rich.table
|
12
|
-
from rich.console import Console
|
13
|
-
from rich.progress import track
|
14
|
-
|
15
|
-
import mpflash.basicgit as git
|
16
|
-
from mpflash.logger import log
|
17
|
-
from mpflash.mpboard_id import Board
|
18
|
-
from mpflash.mpboard_id.store import write_boardinfo_json
|
19
|
-
from mpflash.versions import get_preview_mp_version, micropython_versions
|
20
|
-
|
21
|
-
# look for all mpconfigboard.h files and extract the board name
|
22
|
-
# from the #define MICROPY_HW_BOARD_NAME "PYBD_SF6"
|
23
|
-
# and the #define MICROPY_HW_MCU_NAME "STM32F767xx"
|
24
|
-
RE_H_MICROPY_HW_BOARD_NAME = re.compile(r"#define\s+MICROPY_HW_BOARD_NAME\s+\"(.+)\"")
|
25
|
-
RE_H_MICROPY_HW_MCU_NAME = re.compile(r"#define\s+MICROPY_HW_MCU_NAME\s+\"(.+)\"")
|
26
|
-
# find boards and variants in the mpconfigboard*.cmake files
|
27
|
-
RE_CMAKE_MICROPY_HW_BOARD_NAME = re.compile(r"MICROPY_HW_BOARD_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
|
28
|
-
RE_CMAKE_MICROPY_HW_MCU_NAME = re.compile(r"MICROPY_HW_MCU_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
|
29
|
-
# TODO: normal make files
|
30
|
-
|
31
|
-
|
32
|
-
def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None) -> List[Board]:
|
33
|
-
"""Collects board name and decriptions from mpconfigboard.h files.
|
34
|
-
|
35
|
-
Args:
|
36
|
-
mpy_path (Path): The path to the MicroPython repository.
|
37
|
-
version (str): The version of MicroPython.
|
38
|
-
|
39
|
-
Returns:
|
40
|
-
List[Board]: A list of Board objects containing the board information.
|
41
|
-
"""
|
42
|
-
if not mpy_path.exists() or not mpy_path.is_dir():
|
43
|
-
raise FileNotFoundError(f"MicroPython path {mpy_path} does not exist.")
|
44
|
-
family = family or "micropython"
|
45
|
-
version = version or git.get_local_tag() # type: ignore
|
46
|
-
if not version:
|
47
|
-
raise ValueError("No version provided and no local tag found.")
|
48
|
-
elif version in ["main", "master"]:
|
49
|
-
version = get_preview_mp_version()
|
50
|
-
|
51
|
-
board_list: List[Board] = []
|
52
|
-
# look in mpconfigboard.h files
|
53
|
-
board_list = boards_from_cmake(mpy_path, version, family)
|
54
|
-
|
55
|
-
# look for boards in the .cmake files
|
56
|
-
board_list.extend(boards_from_headers(mpy_path, version, family))
|
57
|
-
|
58
|
-
# TODO:? look for variants in the board.json files
|
59
|
-
|
60
|
-
return board_list
|
61
|
-
|
62
|
-
|
63
|
-
def boards_from_cmake(mpy_path: Path, version: str, family: str):
|
64
|
-
"""Get boards from the mpconfigboard.cmake files to the board_list."""
|
65
|
-
board_list = []
|
66
|
-
for path in mpy_path.glob("ports/**/mpconfigboard*.cmake"):
|
67
|
-
board = path.parent.name
|
68
|
-
port = path.parent.parent.parent.name
|
69
|
-
with open(path, "r") as f:
|
70
|
-
board_name = mcu_name = "-"
|
71
|
-
for line in f:
|
72
|
-
line = line.strip()
|
73
|
-
if match := RE_CMAKE_MICROPY_HW_BOARD_NAME.match(line):
|
74
|
-
description = match["variant"]
|
75
|
-
board_list.append(
|
76
|
-
Board(
|
77
|
-
board_id=board,
|
78
|
-
port=port,
|
79
|
-
board_name=board_name,
|
80
|
-
mcu_name=mcu_name,
|
81
|
-
description=description,
|
82
|
-
path=path.relative_to(mpy_path),
|
83
|
-
version=version,
|
84
|
-
family=family,
|
85
|
-
)
|
86
|
-
)
|
87
|
-
elif match := RE_CMAKE_MICROPY_HW_MCU_NAME.match(line):
|
88
|
-
description = match["variant"]
|
89
|
-
board_list.append(
|
90
|
-
Board(
|
91
|
-
board_id=board,
|
92
|
-
port=port,
|
93
|
-
board_name=board_name,
|
94
|
-
mcu_name=mcu_name,
|
95
|
-
description=description,
|
96
|
-
path=path.relative_to(mpy_path),
|
97
|
-
version=version,
|
98
|
-
family=family,
|
99
|
-
)
|
100
|
-
)
|
101
|
-
return board_list
|
102
|
-
|
103
|
-
|
104
|
-
def boards_from_headers(mpy_path: Path, version: str, family: str):
|
105
|
-
"""Get boards from the mpconfigboard.h files to the board_list."""
|
106
|
-
board_list = []
|
107
|
-
for path in mpy_path.glob("ports/**/mpconfigboard.h"):
|
108
|
-
board = path.parent.name
|
109
|
-
port = path.parent.parent.parent.name
|
110
|
-
with open(path, "r") as f:
|
111
|
-
board_name = mcu_name = "-"
|
112
|
-
found = 0
|
113
|
-
for line in f:
|
114
|
-
if match := RE_H_MICROPY_HW_BOARD_NAME.match(line):
|
115
|
-
board_name = match[1]
|
116
|
-
found += 1
|
117
|
-
elif match := RE_H_MICROPY_HW_MCU_NAME.match(line):
|
118
|
-
mcu_name = match[1]
|
119
|
-
found += 1
|
120
|
-
if found == 2:
|
121
|
-
description = f"{board_name} with {mcu_name}" if mcu_name != "-" else board_name
|
122
|
-
board_list.append(
|
123
|
-
Board(
|
124
|
-
board_id=board,
|
125
|
-
port=port,
|
126
|
-
board_name=board_name,
|
127
|
-
mcu_name=mcu_name,
|
128
|
-
description=description,
|
129
|
-
path=path.relative_to(mpy_path),
|
130
|
-
version=version,
|
131
|
-
family=family,
|
132
|
-
)
|
133
|
-
)
|
134
|
-
found = 0
|
135
|
-
if found == 1:
|
136
|
-
description = board_name
|
137
|
-
board_list.append(
|
138
|
-
Board(
|
139
|
-
board_id=board,
|
140
|
-
port=port,
|
141
|
-
board_name=board_name,
|
142
|
-
mcu_name=mcu_name,
|
143
|
-
description=description,
|
144
|
-
path=path.relative_to(mpy_path),
|
145
|
-
version=version,
|
146
|
-
family=family,
|
147
|
-
)
|
148
|
-
)
|
149
|
-
return board_list
|
150
|
-
|
151
|
-
|
152
|
-
def boards_for_versions(versions: List[str], mpy_path: Path):
|
153
|
-
"""Gets the list of boards for multiple versions of MicroPython.
|
154
|
-
|
155
|
-
Args:
|
156
|
-
versions (List[str]): The list of MicroPython versions.
|
157
|
-
mpy_path (Path): The path to the MicroPython repository.
|
158
|
-
|
159
|
-
Returns:
|
160
|
-
List[Board]: The list of Board objects.
|
161
|
-
"""
|
162
|
-
board_list: List[Board] = []
|
163
|
-
# first fetch all tags from the repository
|
164
|
-
git.fetch(mpy_path)
|
165
|
-
for version in track(versions, description="Searching MicroPython versions"):
|
166
|
-
if git.checkout_tag(tag=version, repo=mpy_path):
|
167
|
-
new_ones = boards_from_repo(mpy_path, version, family="micropython")
|
168
|
-
print(f"Found {len(new_ones)} board definitions for {version}.")
|
169
|
-
board_list += new_ones
|
170
|
-
else:
|
171
|
-
print(f"Could not checkout version {version}.")
|
172
|
-
|
173
|
-
# sort the board_list by description and board
|
174
|
-
print("Total number of boards found:", len(board_list))
|
175
|
-
|
176
|
-
board_list = unique_boards(board_list)
|
177
|
-
print("Unique board descriptions found:", len(board_list))
|
178
|
-
return board_list
|
179
|
-
|
180
|
-
|
181
|
-
def unique_boards(board_list: List[Board], *, key_version: bool = True):
|
182
|
-
"""Remove duplicate boards by 'BOARD_ID description' from the list."""
|
183
|
-
seen = set()
|
184
|
-
result = []
|
185
|
-
for x in board_list:
|
186
|
-
if key_version:
|
187
|
-
key = f"{x.board_id}|{x.version}|{x.description}"
|
188
|
-
else:
|
189
|
-
key = f"{x.board_id}|{x.description}"
|
190
|
-
if key not in seen:
|
191
|
-
result.append(x)
|
192
|
-
seen.add(key)
|
193
|
-
result.sort(key=lambda x: x.description.lower())
|
194
|
-
return result
|
195
|
-
|
196
|
-
|
197
|
-
def make_table(board_list: List[Board]) -> rich.table.Table:
|
198
|
-
"""Creates a rich table with board information."""
|
199
|
-
is_wide = True
|
200
|
-
|
201
|
-
table = rich.table.Table(title="MicroPython Board Information")
|
202
|
-
table.add_column("Port", justify="left", style="magenta")
|
203
|
-
table.add_column("BOARD_ID", justify="left", style="green")
|
204
|
-
table.add_column("Variant(s)", justify="left", style="blue")
|
205
|
-
table.add_column("Description", justify="left", style="cyan")
|
206
|
-
table.add_column("Board Name", justify="left", style="blue")
|
207
|
-
if is_wide:
|
208
|
-
table.add_column("MCU Name", justify="left", style="blue")
|
209
|
-
table.add_column("Detection", justify="left", style="yellow")
|
210
|
-
table.add_column("Version", justify="left", style="blue")
|
211
|
-
if is_wide:
|
212
|
-
table.add_column("Family", justify="left", style="blue")
|
213
|
-
|
214
|
-
for board in board_list:
|
215
|
-
row = [board.port, board.board_id, board.variant, board.description, board.board_name]
|
216
|
-
if is_wide:
|
217
|
-
row.append(board.mcu_name)
|
218
|
-
row.extend((str(Path(board.path).suffix), board.version))
|
219
|
-
if is_wide:
|
220
|
-
row.append(board.family)
|
221
|
-
table.add_row(*row)
|
222
|
-
|
223
|
-
return table
|
224
|
-
|
225
|
-
|
226
|
-
def ask_mpy_path():
|
227
|
-
"""Ask the user for the path to the MicroPython repository."""
|
228
|
-
questions = [
|
229
|
-
inquirer.Text(
|
230
|
-
"mpy_path",
|
231
|
-
message="Enter the path to the MicroPython repository",
|
232
|
-
default="./repos/micropython",
|
233
|
-
)
|
234
|
-
]
|
235
|
-
if answers := inquirer.prompt(questions):
|
236
|
-
return Path(answers["mpy_path"])
|
237
|
-
else:
|
238
|
-
raise ValueError("No path provided.")
|
239
|
-
|
240
|
-
|
241
|
-
def main():
|
242
|
-
"""Main function to collect and write board information."""
|
243
|
-
|
244
|
-
console = Console()
|
245
|
-
|
246
|
-
mpy_path = ask_mpy_path()
|
247
|
-
versions = micropython_versions(minver="v1.10") + ["master"]
|
248
|
-
board_list = boards_for_versions(versions, mpy_path)
|
249
|
-
|
250
|
-
here = Path(__file__).parent
|
251
|
-
log.info(write_boardinfo_json(board_list, folder=here))
|
252
|
-
# write_files(board_list, folder=CONFIG.board_path)
|
253
|
-
|
254
|
-
# table of when the board was added
|
255
|
-
table = make_table(unique_boards(board_list, key_version=False))
|
256
|
-
console.print(table)
|
257
|
-
|
258
|
-
|
259
|
-
if __name__ == "__main__":
|
260
|
-
main()
|
mpflash/mpboard_id/board.py
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
from dataclasses import dataclass, field
|
2
|
-
from pathlib import Path
|
3
|
-
from typing import Union
|
4
|
-
|
5
|
-
|
6
|
-
# - source : get_boardnames.py
|
7
|
-
@dataclass
|
8
|
-
class Board:
|
9
|
-
"""
|
10
|
-
MicroPython Board definitions, parsed from the make and header files
|
11
|
-
"""
|
12
|
-
|
13
|
-
port: str # micropython port
|
14
|
-
board_id: str # BOARD_ID (Foldername) as used in the make files
|
15
|
-
board_name: str # Short board description
|
16
|
-
description: str # Long board description
|
17
|
-
path: Union[Path, str]
|
18
|
-
version: str = field(default="") # version of MicroPython""
|
19
|
-
# versions: List[str] = field(default=[]) # version of MicroPython""
|
20
|
-
family: str = field(default="micropython")
|
21
|
-
mcu_name: str = field(default="")
|
22
|
-
cpu: str = field(default="")
|
23
|
-
variant: str = field(default="")
|
24
|
-
mcu: str = field(default="")
|
25
|
-
|
26
|
-
def __post_init__(self):
|
27
|
-
if not self.cpu:
|
28
|
-
if " with " in self.description:
|
29
|
-
self.cpu = self.description.rsplit(" with ")[-1]
|
30
|
-
else:
|
31
|
-
self.cpu = self.port
|
32
|
-
|
33
|
-
@staticmethod
|
34
|
-
def from_dict(data: dict) -> "Board":
|
35
|
-
valid_keys = {field.name for field in Board.__dataclass_fields__.values()}
|
36
|
-
filtered_data = {k: v for k, v in data.items() if k in valid_keys}
|
37
|
-
return Board(**filtered_data)
|
38
|
-
|
39
|
-
def to_dict(self) -> dict:
|
40
|
-
return self.__dict__
|