micropython-stubber 1.19.0__py3-none-any.whl → 1.20.1__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.
- {micropython_stubber-1.19.0.dist-info → micropython_stubber-1.20.1.dist-info}/METADATA +4 -4
- {micropython_stubber-1.19.0.dist-info → micropython_stubber-1.20.1.dist-info}/RECORD +37 -41
- mpflash/README.md +41 -33
- mpflash/libusb_flash.ipynb +203 -203
- mpflash/mpflash/ask_input.py +18 -3
- mpflash/mpflash/cli_download.py +16 -12
- mpflash/mpflash/cli_flash.py +16 -7
- mpflash/mpflash/cli_group.py +1 -1
- mpflash/mpflash/cli_list.py +2 -2
- mpflash/mpflash/cli_main.py +4 -3
- mpflash/mpflash/download.py +11 -8
- mpflash/mpflash/flash_uf2.py +1 -1
- mpflash/mpflash/list.py +29 -12
- mpflash/mpflash/mpboard_id/board_id.py +14 -11
- mpflash/mpflash/mpremoteboard/__init__.py +6 -5
- mpflash/mpflash/mpremoteboard/runner.py +12 -12
- mpflash/mpflash/worklist.py +1 -1
- mpflash/poetry.lock +85 -84
- mpflash/pyproject.toml +2 -2
- stubber/__init__.py +1 -1
- stubber/board/createstubs.py +4 -3
- stubber/board/createstubs_db.py +4 -4
- stubber/board/createstubs_db_min.py +825 -329
- stubber/board/createstubs_db_mpy.mpy +0 -0
- stubber/board/createstubs_mem.py +4 -4
- stubber/board/createstubs_mem_min.py +765 -304
- stubber/board/createstubs_mem_mpy.mpy +0 -0
- stubber/board/createstubs_min.py +975 -293
- stubber/board/createstubs_mpy.mpy +0 -0
- stubber/board/modulelist.txt +1 -0
- stubber/commands/{mcu_cmd.py → get_mcu_cmd.py} +20 -3
- stubber/stubber.py +1 -9
- stubber/update_fallback.py +104 -104
- stubber/utils/config.py +6 -0
- stubber/commands/get_lobo_cmd.py +0 -58
- stubber/commands/minify_cmd.py +0 -60
- stubber/commands/upd_fallback_cmd.py +0 -36
- stubber/commands/upd_module_list_cmd.py +0 -18
- {micropython_stubber-1.19.0.dist-info → micropython_stubber-1.20.1.dist-info}/LICENSE +0 -0
- {micropython_stubber-1.19.0.dist-info → micropython_stubber-1.20.1.dist-info}/WHEEL +0 -0
- {micropython_stubber-1.19.0.dist-info → micropython_stubber-1.20.1.dist-info}/entry_points.txt +0 -0
mpflash/libusb_flash.ipynb
CHANGED
@@ -1,203 +1,203 @@
|
|
1
|
-
{
|
2
|
-
"cells": [
|
3
|
-
{
|
4
|
-
"cell_type": "code",
|
5
|
-
"execution_count": 3,
|
6
|
-
"metadata": {},
|
7
|
-
"outputs": [
|
8
|
-
{
|
9
|
-
"data": {
|
10
|
-
"text/plain": [
|
11
|
-
"[<DEVICE ID 0a05:7211 on Bus 002 Address 054>,\n",
|
12
|
-
" <DEVICE ID 0a05:7211 on Bus 002 Address 032>,\n",
|
13
|
-
" <DEVICE ID 045e:0c1e on Bus 002 Address 002>,\n",
|
14
|
-
" <DEVICE ID 045e:07b2 on Bus 002 Address 028>,\n",
|
15
|
-
" <DEVICE ID 045e:0904 on Bus 002 Address 015>,\n",
|
16
|
-
" <DEVICE ID 043e:9a39 on Bus 002 Address 057>,\n",
|
17
|
-
" <DEVICE ID 045e:0901 on Bus 002 Address 006>,\n",
|
18
|
-
" <DEVICE ID 05e3:0610 on Bus 002 Address 010>,\n",
|
19
|
-
" <DEVICE ID 2109:0817 on Bus 001 Address 001>,\n",
|
20
|
-
" <DEVICE ID 045e:0902 on Bus 002 Address 008>,\n",
|
21
|
-
" <DEVICE ID 1000:2000 on Bus 002 Address 016>,\n",
|
22
|
-
" <DEVICE ID 1189:8890 on Bus 002 Address 027>,\n",
|
23
|
-
" <DEVICE ID 2109:0817 on Bus 001 Address 002>,\n",
|
24
|
-
" <DEVICE ID 2109:2812 on Bus 002 Address 025>,\n",
|
25
|
-
" <DEVICE ID 046d:085e on Bus 002 Address 017>,\n",
|
26
|
-
" <DEVICE ID 045e:07c6 on Bus 002 Address 056>,\n",
|
27
|
-
" <DEVICE ID 0bda:5401 on Bus 002 Address 009>,\n",
|
28
|
-
" <DEVICE ID 10c4:ea60 on Bus 002 Address 055>,\n",
|
29
|
-
" <DEVICE ID 2109:2817 on Bus 002 Address 004>,\n",
|
30
|
-
" <DEVICE ID 0bda:5411 on Bus 002 Address 005>,\n",
|
31
|
-
" <DEVICE ID 045e:0900 on Bus 002 Address 003>,\n",
|
32
|
-
" <DEVICE ID 04e8:61f5 on Bus 002 Address 023>,\n",
|
33
|
-
" <DEVICE ID 045e:0903 on Bus 002 Address 020>,\n",
|
34
|
-
" <DEVICE ID 2109:2812 on Bus 002 Address 026>,\n",
|
35
|
-
" <DEVICE ID 8086:a0ed on Bus 002 Address 000>,\n",
|
36
|
-
" <DEVICE ID 2109:2817 on Bus 002 Address 013>,\n",
|
37
|
-
" <DEVICE ID 8087:0029 on Bus 002 Address 001>,\n",
|
38
|
-
" <DEVICE ID 8086:9a13 on Bus 001 Address 000>]"
|
39
|
-
]
|
40
|
-
},
|
41
|
-
"execution_count": 3,
|
42
|
-
"metadata": {},
|
43
|
-
"output_type": "execute_result"
|
44
|
-
}
|
45
|
-
],
|
46
|
-
"source": [
|
47
|
-
"import usb.core\n",
|
48
|
-
"import usb.util\n",
|
49
|
-
"import usb.backend.libusb1 as libusb1\n",
|
50
|
-
"from usb.core import USBError, Device\n",
|
51
|
-
"\n",
|
52
|
-
"from pathlib import Path\n",
|
53
|
-
"import platform\n",
|
54
|
-
"\n",
|
55
|
-
"if platform.system() == \"Windows\":\n",
|
56
|
-
" # on windows you need to use the libusb1 backend\n",
|
57
|
-
" import libusb\n",
|
58
|
-
"\n",
|
59
|
-
" arch = \"x64\" if platform.architecture()[0] == \"64bit\" else \"x86\"\n",
|
60
|
-
" libusb1_dll = Path(libusb.__file__).parent / f\"_platform\\\\_windows\\\\{arch}\\\\libusb-1.0.dll\"\n",
|
61
|
-
"\n",
|
62
|
-
" backend = libusb1.get_backend(find_library=lambda x: libusb1_dll.as_posix())\n",
|
63
|
-
"usb_devices = usb.core.find(backend=backend, find_all=True)\n",
|
64
|
-
"\n",
|
65
|
-
"list(usb_devices)"
|
66
|
-
]
|
67
|
-
},
|
68
|
-
{
|
69
|
-
"cell_type": "code",
|
70
|
-
"execution_count": null,
|
71
|
-
"metadata": {},
|
72
|
-
"outputs": [],
|
73
|
-
"source": [
|
74
|
-
"for d in usb.core.find(backend=backend, find_all=True):\n",
|
75
|
-
" print(f\"Device {d.idVendor:04x}:{d.idProduct:04x}\")\n",
|
76
|
-
" print(f\"{d.iManufacturer=}\")\n",
|
77
|
-
" print(f\"{d.iProduct=}\")\n",
|
78
|
-
" print(f\"{d.bDeviceClass=}\")\n",
|
79
|
-
" print(f\"{d.bDescriptorType=}\")\n",
|
80
|
-
" print(f\"{d.bcdDevice=}\")\n",
|
81
|
-
" print(f\"{d.bcdUSB=}\")\n",
|
82
|
-
" # print(dir(d))\n",
|
83
|
-
" # print(f\" Manufacturer: {usb.util.get_string(dev, dev.iManufacturer)}\")\n",
|
84
|
-
"\n",
|
85
|
-
" print()"
|
86
|
-
]
|
87
|
-
},
|
88
|
-
{
|
89
|
-
"cell_type": "code",
|
90
|
-
"execution_count": null,
|
91
|
-
"metadata": {},
|
92
|
-
"outputs": [],
|
93
|
-
"source": [
|
94
|
-
"import serial.tools.list_ports\n",
|
95
|
-
"\n",
|
96
|
-
"ports = serial.tools.list_ports.comports()\n",
|
97
|
-
"\n",
|
98
|
-
"for port in ports:\n",
|
99
|
-
" print(f\"Port: {port.device}\")\n",
|
100
|
-
" print(f\"Description: {port.description}\")\n",
|
101
|
-
" print(f\"Hardware ID: {port.hwid}\")\n",
|
102
|
-
" print()"
|
103
|
-
]
|
104
|
-
},
|
105
|
-
{
|
106
|
-
"cell_type": "code",
|
107
|
-
"execution_count": null,
|
108
|
-
"metadata": {},
|
109
|
-
"outputs": [],
|
110
|
-
"source": [
|
111
|
-
"from mpflash.vendor import pydfu as pydfu\n",
|
112
|
-
"\n",
|
113
|
-
"try:\n",
|
114
|
-
" pydfu.list_dfu_devices()\n",
|
115
|
-
"except SystemExit:\n",
|
116
|
-
" print(\"No DFU devices found\")"
|
117
|
-
]
|
118
|
-
},
|
119
|
-
{
|
120
|
-
"cell_type": "code",
|
121
|
-
"execution_count": null,
|
122
|
-
"metadata": {},
|
123
|
-
"outputs": [],
|
124
|
-
"source": [
|
125
|
-
"pydfu.init()"
|
126
|
-
]
|
127
|
-
},
|
128
|
-
{
|
129
|
-
"cell_type": "code",
|
130
|
-
"execution_count": null,
|
131
|
-
"metadata": {},
|
132
|
-
"outputs": [],
|
133
|
-
"source": [
|
134
|
-
"dfu_file = Path(\"C:\\\\Users\\\\josverl\\\\Downloads\\\\firmware\\\\stm32\\\\PYBV11-THREAD-v1.23.0-preview.203.dfu\")\n",
|
135
|
-
"\n",
|
136
|
-
"print(\"Read DFU file...\")\n",
|
137
|
-
"elements = pydfu.read_dfu_file(dfu_file)\n",
|
138
|
-
"if not elements:\n",
|
139
|
-
" print(\"No data in dfu file\")"
|
140
|
-
]
|
141
|
-
},
|
142
|
-
{
|
143
|
-
"cell_type": "code",
|
144
|
-
"execution_count": 1,
|
145
|
-
"metadata": {},
|
146
|
-
"outputs": [
|
147
|
-
{
|
148
|
-
"name": "stdout",
|
149
|
-
"output_type": "stream",
|
150
|
-
"text": [
|
151
|
-
"Writing memory...\n"
|
152
|
-
]
|
153
|
-
},
|
154
|
-
{
|
155
|
-
"ename": "NameError",
|
156
|
-
"evalue": "name 'pydfu' is not defined",
|
157
|
-
"output_type": "error",
|
158
|
-
"traceback": [
|
159
|
-
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
160
|
-
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
|
161
|
-
"Cell \u001b[1;32mIn[1], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWriting memory...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m----> 2\u001b[0m \u001b[43mpydfu\u001b[49m\u001b[38;5;241m.\u001b[39mwrite_elements(elements, \u001b[38;5;28;01mFalse\u001b[39;00m, progress\u001b[38;5;241m=\u001b[39mpydfu\u001b[38;5;241m.\u001b[39mcli_progress)\n",
|
162
|
-
"\u001b[1;31mNameError\u001b[0m: name 'pydfu' is not defined"
|
163
|
-
]
|
164
|
-
}
|
165
|
-
],
|
166
|
-
"source": [
|
167
|
-
"print(\"Writing memory...\")\n",
|
168
|
-
"pydfu.write_elements(elements, False, progress=pydfu.cli_progress)"
|
169
|
-
]
|
170
|
-
},
|
171
|
-
{
|
172
|
-
"cell_type": "code",
|
173
|
-
"execution_count": null,
|
174
|
-
"metadata": {},
|
175
|
-
"outputs": [],
|
176
|
-
"source": [
|
177
|
-
"print(\"Exiting DFU...\")\n",
|
178
|
-
"pydfu.exit_dfu()"
|
179
|
-
]
|
180
|
-
}
|
181
|
-
],
|
182
|
-
"metadata": {
|
183
|
-
"kernelspec": {
|
184
|
-
"display_name": ".venv",
|
185
|
-
"language": "python",
|
186
|
-
"name": "python3"
|
187
|
-
},
|
188
|
-
"language_info": {
|
189
|
-
"codemirror_mode": {
|
190
|
-
"name": "ipython",
|
191
|
-
"version": 3
|
192
|
-
},
|
193
|
-
"file_extension": ".py",
|
194
|
-
"mimetype": "text/x-python",
|
195
|
-
"name": "python",
|
196
|
-
"nbconvert_exporter": "python",
|
197
|
-
"pygments_lexer": "ipython3",
|
198
|
-
"version": "3.11.7"
|
199
|
-
}
|
200
|
-
},
|
201
|
-
"nbformat": 4,
|
202
|
-
"nbformat_minor": 2
|
203
|
-
}
|
1
|
+
{
|
2
|
+
"cells": [
|
3
|
+
{
|
4
|
+
"cell_type": "code",
|
5
|
+
"execution_count": 3,
|
6
|
+
"metadata": {},
|
7
|
+
"outputs": [
|
8
|
+
{
|
9
|
+
"data": {
|
10
|
+
"text/plain": [
|
11
|
+
"[<DEVICE ID 0a05:7211 on Bus 002 Address 054>,\n",
|
12
|
+
" <DEVICE ID 0a05:7211 on Bus 002 Address 032>,\n",
|
13
|
+
" <DEVICE ID 045e:0c1e on Bus 002 Address 002>,\n",
|
14
|
+
" <DEVICE ID 045e:07b2 on Bus 002 Address 028>,\n",
|
15
|
+
" <DEVICE ID 045e:0904 on Bus 002 Address 015>,\n",
|
16
|
+
" <DEVICE ID 043e:9a39 on Bus 002 Address 057>,\n",
|
17
|
+
" <DEVICE ID 045e:0901 on Bus 002 Address 006>,\n",
|
18
|
+
" <DEVICE ID 05e3:0610 on Bus 002 Address 010>,\n",
|
19
|
+
" <DEVICE ID 2109:0817 on Bus 001 Address 001>,\n",
|
20
|
+
" <DEVICE ID 045e:0902 on Bus 002 Address 008>,\n",
|
21
|
+
" <DEVICE ID 1000:2000 on Bus 002 Address 016>,\n",
|
22
|
+
" <DEVICE ID 1189:8890 on Bus 002 Address 027>,\n",
|
23
|
+
" <DEVICE ID 2109:0817 on Bus 001 Address 002>,\n",
|
24
|
+
" <DEVICE ID 2109:2812 on Bus 002 Address 025>,\n",
|
25
|
+
" <DEVICE ID 046d:085e on Bus 002 Address 017>,\n",
|
26
|
+
" <DEVICE ID 045e:07c6 on Bus 002 Address 056>,\n",
|
27
|
+
" <DEVICE ID 0bda:5401 on Bus 002 Address 009>,\n",
|
28
|
+
" <DEVICE ID 10c4:ea60 on Bus 002 Address 055>,\n",
|
29
|
+
" <DEVICE ID 2109:2817 on Bus 002 Address 004>,\n",
|
30
|
+
" <DEVICE ID 0bda:5411 on Bus 002 Address 005>,\n",
|
31
|
+
" <DEVICE ID 045e:0900 on Bus 002 Address 003>,\n",
|
32
|
+
" <DEVICE ID 04e8:61f5 on Bus 002 Address 023>,\n",
|
33
|
+
" <DEVICE ID 045e:0903 on Bus 002 Address 020>,\n",
|
34
|
+
" <DEVICE ID 2109:2812 on Bus 002 Address 026>,\n",
|
35
|
+
" <DEVICE ID 8086:a0ed on Bus 002 Address 000>,\n",
|
36
|
+
" <DEVICE ID 2109:2817 on Bus 002 Address 013>,\n",
|
37
|
+
" <DEVICE ID 8087:0029 on Bus 002 Address 001>,\n",
|
38
|
+
" <DEVICE ID 8086:9a13 on Bus 001 Address 000>]"
|
39
|
+
]
|
40
|
+
},
|
41
|
+
"execution_count": 3,
|
42
|
+
"metadata": {},
|
43
|
+
"output_type": "execute_result"
|
44
|
+
}
|
45
|
+
],
|
46
|
+
"source": [
|
47
|
+
"import usb.core\n",
|
48
|
+
"import usb.util\n",
|
49
|
+
"import usb.backend.libusb1 as libusb1\n",
|
50
|
+
"from usb.core import USBError, Device\n",
|
51
|
+
"\n",
|
52
|
+
"from pathlib import Path\n",
|
53
|
+
"import platform\n",
|
54
|
+
"\n",
|
55
|
+
"if platform.system() == \"Windows\":\n",
|
56
|
+
" # on windows you need to use the libusb1 backend\n",
|
57
|
+
" import libusb\n",
|
58
|
+
"\n",
|
59
|
+
" arch = \"x64\" if platform.architecture()[0] == \"64bit\" else \"x86\"\n",
|
60
|
+
" libusb1_dll = Path(libusb.__file__).parent / f\"_platform\\\\_windows\\\\{arch}\\\\libusb-1.0.dll\"\n",
|
61
|
+
"\n",
|
62
|
+
" backend = libusb1.get_backend(find_library=lambda x: libusb1_dll.as_posix())\n",
|
63
|
+
"usb_devices = usb.core.find(backend=backend, find_all=True)\n",
|
64
|
+
"\n",
|
65
|
+
"list(usb_devices)"
|
66
|
+
]
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"cell_type": "code",
|
70
|
+
"execution_count": null,
|
71
|
+
"metadata": {},
|
72
|
+
"outputs": [],
|
73
|
+
"source": [
|
74
|
+
"for d in usb.core.find(backend=backend, find_all=True):\n",
|
75
|
+
" print(f\"Device {d.idVendor:04x}:{d.idProduct:04x}\")\n",
|
76
|
+
" print(f\"{d.iManufacturer=}\")\n",
|
77
|
+
" print(f\"{d.iProduct=}\")\n",
|
78
|
+
" print(f\"{d.bDeviceClass=}\")\n",
|
79
|
+
" print(f\"{d.bDescriptorType=}\")\n",
|
80
|
+
" print(f\"{d.bcdDevice=}\")\n",
|
81
|
+
" print(f\"{d.bcdUSB=}\")\n",
|
82
|
+
" # print(dir(d))\n",
|
83
|
+
" # print(f\" Manufacturer: {usb.util.get_string(dev, dev.iManufacturer)}\")\n",
|
84
|
+
"\n",
|
85
|
+
" print()"
|
86
|
+
]
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"cell_type": "code",
|
90
|
+
"execution_count": null,
|
91
|
+
"metadata": {},
|
92
|
+
"outputs": [],
|
93
|
+
"source": [
|
94
|
+
"import serial.tools.list_ports\n",
|
95
|
+
"\n",
|
96
|
+
"ports = serial.tools.list_ports.comports()\n",
|
97
|
+
"\n",
|
98
|
+
"for port in ports:\n",
|
99
|
+
" print(f\"Port: {port.device}\")\n",
|
100
|
+
" print(f\"Description: {port.description}\")\n",
|
101
|
+
" print(f\"Hardware ID: {port.hwid}\")\n",
|
102
|
+
" print()"
|
103
|
+
]
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"cell_type": "code",
|
107
|
+
"execution_count": null,
|
108
|
+
"metadata": {},
|
109
|
+
"outputs": [],
|
110
|
+
"source": [
|
111
|
+
"from mpflash.vendor import pydfu as pydfu\n",
|
112
|
+
"\n",
|
113
|
+
"try:\n",
|
114
|
+
" pydfu.list_dfu_devices()\n",
|
115
|
+
"except SystemExit:\n",
|
116
|
+
" print(\"No DFU devices found\")"
|
117
|
+
]
|
118
|
+
},
|
119
|
+
{
|
120
|
+
"cell_type": "code",
|
121
|
+
"execution_count": null,
|
122
|
+
"metadata": {},
|
123
|
+
"outputs": [],
|
124
|
+
"source": [
|
125
|
+
"pydfu.init()"
|
126
|
+
]
|
127
|
+
},
|
128
|
+
{
|
129
|
+
"cell_type": "code",
|
130
|
+
"execution_count": null,
|
131
|
+
"metadata": {},
|
132
|
+
"outputs": [],
|
133
|
+
"source": [
|
134
|
+
"dfu_file = Path(\"C:\\\\Users\\\\josverl\\\\Downloads\\\\firmware\\\\stm32\\\\PYBV11-THREAD-v1.23.0-preview.203.dfu\")\n",
|
135
|
+
"\n",
|
136
|
+
"print(\"Read DFU file...\")\n",
|
137
|
+
"elements = pydfu.read_dfu_file(dfu_file)\n",
|
138
|
+
"if not elements:\n",
|
139
|
+
" print(\"No data in dfu file\")"
|
140
|
+
]
|
141
|
+
},
|
142
|
+
{
|
143
|
+
"cell_type": "code",
|
144
|
+
"execution_count": 1,
|
145
|
+
"metadata": {},
|
146
|
+
"outputs": [
|
147
|
+
{
|
148
|
+
"name": "stdout",
|
149
|
+
"output_type": "stream",
|
150
|
+
"text": [
|
151
|
+
"Writing memory...\n"
|
152
|
+
]
|
153
|
+
},
|
154
|
+
{
|
155
|
+
"ename": "NameError",
|
156
|
+
"evalue": "name 'pydfu' is not defined",
|
157
|
+
"output_type": "error",
|
158
|
+
"traceback": [
|
159
|
+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
160
|
+
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
|
161
|
+
"Cell \u001b[1;32mIn[1], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mWriting memory...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m----> 2\u001b[0m \u001b[43mpydfu\u001b[49m\u001b[38;5;241m.\u001b[39mwrite_elements(elements, \u001b[38;5;28;01mFalse\u001b[39;00m, progress\u001b[38;5;241m=\u001b[39mpydfu\u001b[38;5;241m.\u001b[39mcli_progress)\n",
|
162
|
+
"\u001b[1;31mNameError\u001b[0m: name 'pydfu' is not defined"
|
163
|
+
]
|
164
|
+
}
|
165
|
+
],
|
166
|
+
"source": [
|
167
|
+
"print(\"Writing memory...\")\n",
|
168
|
+
"pydfu.write_elements(elements, False, progress=pydfu.cli_progress)"
|
169
|
+
]
|
170
|
+
},
|
171
|
+
{
|
172
|
+
"cell_type": "code",
|
173
|
+
"execution_count": null,
|
174
|
+
"metadata": {},
|
175
|
+
"outputs": [],
|
176
|
+
"source": [
|
177
|
+
"print(\"Exiting DFU...\")\n",
|
178
|
+
"pydfu.exit_dfu()"
|
179
|
+
]
|
180
|
+
}
|
181
|
+
],
|
182
|
+
"metadata": {
|
183
|
+
"kernelspec": {
|
184
|
+
"display_name": ".venv",
|
185
|
+
"language": "python",
|
186
|
+
"name": "python3"
|
187
|
+
},
|
188
|
+
"language_info": {
|
189
|
+
"codemirror_mode": {
|
190
|
+
"name": "ipython",
|
191
|
+
"version": 3
|
192
|
+
},
|
193
|
+
"file_extension": ".py",
|
194
|
+
"mimetype": "text/x-python",
|
195
|
+
"name": "python",
|
196
|
+
"nbconvert_exporter": "python",
|
197
|
+
"pygments_lexer": "ipython3",
|
198
|
+
"version": "3.11.7"
|
199
|
+
}
|
200
|
+
},
|
201
|
+
"nbformat": 4,
|
202
|
+
"nbformat_minor": 2
|
203
|
+
}
|
mpflash/mpflash/ask_input.py
CHANGED
@@ -12,7 +12,7 @@ from typing import Dict, List, Sequence, Tuple, Union
|
|
12
12
|
from loguru import logger as log
|
13
13
|
|
14
14
|
from mpflash.config import config
|
15
|
-
from mpflash.mpboard_id import known_stored_boards, local_mp_ports
|
15
|
+
from mpflash.mpboard_id import get_stored_boards_for_port, known_stored_boards, local_mp_ports
|
16
16
|
from mpflash.mpremoteboard import MPRemoteBoard
|
17
17
|
from mpflash.vendor.versions import micropython_versions
|
18
18
|
|
@@ -131,7 +131,7 @@ def filter_matching_boards(answers: dict) -> Sequence[Tuple[str, str]]:
|
|
131
131
|
# Get the values of the dictionary, which are the unique items from the original list
|
132
132
|
some_boards = list(unique_dict.values())
|
133
133
|
else:
|
134
|
-
some_boards = [("No boards found", "")]
|
134
|
+
some_boards = [(f"No {answers['port']} boards found for version(s) {_versions}", "")]
|
135
135
|
return some_boards
|
136
136
|
|
137
137
|
|
@@ -186,12 +186,27 @@ def ask_versions(questions: list, *, action: str):
|
|
186
186
|
"""
|
187
187
|
# import only when needed to reduce load time
|
188
188
|
import inquirer
|
189
|
+
import inquirer.errors
|
189
190
|
|
190
191
|
input_ux = inquirer.Checkbox if action == "download" else inquirer.List
|
191
192
|
mp_versions: List[str] = micropython_versions()
|
192
193
|
mp_versions = [v for v in mp_versions if "preview" not in v]
|
194
|
+
|
195
|
+
# remove the versions for which there are no known boards in the board_info.json
|
196
|
+
# todo: this may be a little slow
|
197
|
+
mp_versions = [v for v in mp_versions if get_stored_boards_for_port("stm32", [v])]
|
198
|
+
|
193
199
|
mp_versions.append("preview")
|
194
200
|
mp_versions.reverse() # newest first
|
201
|
+
|
202
|
+
def at_least_one_validation(answers, current) -> bool:
|
203
|
+
if not current:
|
204
|
+
raise inquirer.errors.ValidationError("", reason="Please select at least one version")
|
205
|
+
if isinstance(current, list):
|
206
|
+
if not any(current):
|
207
|
+
raise inquirer.errors.ValidationError("", reason="Please select at least one version")
|
208
|
+
return True
|
209
|
+
|
195
210
|
questions.append(
|
196
211
|
input_ux(
|
197
212
|
# inquirer.List(
|
@@ -201,7 +216,7 @@ def ask_versions(questions: list, *, action: str):
|
|
201
216
|
# hints=["Use space to select multiple options"],
|
202
217
|
choices=mp_versions,
|
203
218
|
autocomplete=True,
|
204
|
-
validate=
|
219
|
+
validate=at_least_one_validation,
|
205
220
|
)
|
206
221
|
)
|
207
222
|
|
mpflash/mpflash/cli_download.py
CHANGED
@@ -6,6 +6,7 @@ from typing import List, Tuple
|
|
6
6
|
import rich_click as click
|
7
7
|
from loguru import logger as log
|
8
8
|
|
9
|
+
from mpflash.errors import MPFlashError
|
9
10
|
from mpflash.mpboard_id import find_stored_board
|
10
11
|
from mpflash.vendor.versions import clean_version
|
11
12
|
|
@@ -62,9 +63,7 @@ from .download import download
|
|
62
63
|
show_default=True,
|
63
64
|
help="""Force download of firmware even if it already exists.""",
|
64
65
|
)
|
65
|
-
def cli_download(
|
66
|
-
**kwargs,
|
67
|
-
):
|
66
|
+
def cli_download(**kwargs) -> int:
|
68
67
|
params = DownloadParams(**kwargs)
|
69
68
|
params.versions = list(params.versions)
|
70
69
|
params.boards = list(params.boards)
|
@@ -77,18 +76,23 @@ def cli_download(
|
|
77
76
|
|
78
77
|
params = ask_missing_params(params, action="download")
|
79
78
|
if not params: # Cancelled by user
|
80
|
-
|
79
|
+
return 2
|
81
80
|
params.versions = [clean_version(v, drop_v=True) for v in params.versions]
|
82
81
|
assert isinstance(params, DownloadParams)
|
83
82
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
83
|
+
try:
|
84
|
+
download(
|
85
|
+
params.fw_folder,
|
86
|
+
params.ports,
|
87
|
+
params.boards,
|
88
|
+
params.versions,
|
89
|
+
params.force,
|
90
|
+
params.clean,
|
91
|
+
)
|
92
|
+
return 0
|
93
|
+
except MPFlashError as e:
|
94
|
+
log.error(f"{e}")
|
95
|
+
return 1
|
92
96
|
|
93
97
|
|
94
98
|
def connected_ports_boards() -> Tuple[List[str], List[str]]:
|
mpflash/mpflash/cli_flash.py
CHANGED
@@ -13,7 +13,7 @@ from .cli_group import cli
|
|
13
13
|
from .cli_list import show_mcus
|
14
14
|
from .config import config
|
15
15
|
from .flash import flash_list
|
16
|
-
from .worklist import WorkList, full_auto_worklist, manual_worklist, single_auto_worklist
|
16
|
+
from .worklist import MPRemoteBoard, WorkList, full_auto_worklist, manual_worklist, single_auto_worklist
|
17
17
|
|
18
18
|
# #########################################################################################################
|
19
19
|
# CLI
|
@@ -28,7 +28,7 @@ from .worklist import WorkList, full_auto_worklist, manual_worklist, single_auto
|
|
28
28
|
"--firmware",
|
29
29
|
"-f",
|
30
30
|
"fw_folder",
|
31
|
-
type=click.Path(
|
31
|
+
type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
|
32
32
|
default=config.firmware_folder,
|
33
33
|
show_default=True,
|
34
34
|
help="The folder to retrieve the firmware from.",
|
@@ -91,7 +91,7 @@ from .worklist import WorkList, full_auto_worklist, manual_worklist, single_auto
|
|
91
91
|
show_default=True,
|
92
92
|
help="""Enter micropython bootloader mode before flashing.""",
|
93
93
|
)
|
94
|
-
def cli_flash_board(**kwargs):
|
94
|
+
def cli_flash_board(**kwargs) -> int:
|
95
95
|
# version to versions, board to boards
|
96
96
|
kwargs["versions"] = [kwargs.pop("version")] if kwargs["version"] != None else []
|
97
97
|
if kwargs["board"] is None:
|
@@ -104,6 +104,11 @@ def cli_flash_board(**kwargs):
|
|
104
104
|
if not params.boards or params.boards == []:
|
105
105
|
# nothing specified - detect connected boards
|
106
106
|
params.ports, params.boards = connected_ports_boards()
|
107
|
+
if params.boards == []:
|
108
|
+
# No MicroPython boards detected, but it could be unflashed or not in bootloader mode
|
109
|
+
# Ask for serial port and board_id to flash
|
110
|
+
params.serial = "?"
|
111
|
+
params.boards = ["?"]
|
107
112
|
else:
|
108
113
|
for board_id in params.boards:
|
109
114
|
if board_id == "":
|
@@ -122,7 +127,7 @@ def cli_flash_board(**kwargs):
|
|
122
127
|
# Ask for missing input if needed
|
123
128
|
params = ask_missing_params(params, action="flash")
|
124
129
|
if not params: # Cancelled by user
|
125
|
-
|
130
|
+
return 2
|
126
131
|
# TODO: Just in time Download of firmware
|
127
132
|
|
128
133
|
assert isinstance(params, FlashParams)
|
@@ -130,9 +135,9 @@ def cli_flash_board(**kwargs):
|
|
130
135
|
if len(params.versions) > 1:
|
131
136
|
log.error(f"Only one version can be flashed at a time, not {params.versions}")
|
132
137
|
raise MPFlashError("Only one version can be flashed at a time")
|
133
|
-
if len(params.boards) > 1:
|
134
|
-
|
135
|
-
|
138
|
+
# if len(params.boards) > 1:
|
139
|
+
# log.error(f"Only one board can be flashed at a time, not {params.boards}")
|
140
|
+
# raise MPFlashError("Only one board can be flashed at a time")
|
136
141
|
|
137
142
|
params.versions = [clean_version(v) for v in params.versions]
|
138
143
|
worklist: WorkList = []
|
@@ -163,3 +168,7 @@ def cli_flash_board(**kwargs):
|
|
163
168
|
):
|
164
169
|
log.info(f"Flashed {len(flashed)} boards")
|
165
170
|
show_mcus(flashed, title="Updated boards after flashing")
|
171
|
+
return 0
|
172
|
+
else:
|
173
|
+
log.error("No boards were flashed")
|
174
|
+
return 1
|
mpflash/mpflash/cli_group.py
CHANGED
mpflash/mpflash/cli_list.py
CHANGED
@@ -26,7 +26,7 @@ from .logger import make_quiet
|
|
26
26
|
show_default=True,
|
27
27
|
help="""Show progress""",
|
28
28
|
)
|
29
|
-
def cli_list_mcus(as_json: bool, progress: bool = True):
|
29
|
+
def cli_list_mcus(as_json: bool, progress: bool = True) -> int:
|
30
30
|
"""List the connected MCU boards, and output in a nice table or json."""
|
31
31
|
if as_json:
|
32
32
|
# avoid noise in json output
|
@@ -38,4 +38,4 @@ def cli_list_mcus(as_json: bool, progress: bool = True):
|
|
38
38
|
progress = False
|
39
39
|
if progress:
|
40
40
|
show_mcus(conn_mcus, refresh=False)
|
41
|
-
return conn_mcus
|
41
|
+
return 0 if conn_mcus else 1
|
mpflash/mpflash/cli_main.py
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
# import rich_click as click
|
4
4
|
|
5
|
+
import click
|
6
|
+
|
5
7
|
from .cli_download import cli_download
|
6
8
|
from .cli_flash import cli_flash_board
|
7
9
|
from .cli_group import cli
|
8
10
|
from .cli_list import cli_list_mcus
|
9
11
|
|
10
|
-
# from loguru import logger as log
|
11
|
-
|
12
12
|
|
13
13
|
def mpflash():
|
14
14
|
cli.add_command(cli_flash_board)
|
@@ -16,7 +16,8 @@ def mpflash():
|
|
16
16
|
cli.add_command(cli_download)
|
17
17
|
# cli(auto_envvar_prefix="MPFLASH")
|
18
18
|
try:
|
19
|
-
|
19
|
+
result = cli(standalone_mode=False)
|
20
|
+
exit(result)
|
20
21
|
except AttributeError as e:
|
21
22
|
print(f"Error: {e}")
|
22
23
|
exit(-1)
|