26 |
26 |
27 SupportedUF2Boards = { |
27 SupportedUF2Boards = { |
28 "circuitpython": { |
28 "circuitpython": { |
29 "volumes": { |
29 "volumes": { |
30 (0x03EB, 0x2402): [ |
30 (0x03EB, 0x2402): [ |
31 "SAMD21", # SAMD21 Board |
31 "SAMD21", # SAMD21 Board |
32 "SAME54", # SAME54 Board |
32 "SAME54", # SAME54 Board |
33 ], |
33 ], |
34 (0x04D8, 0xEC44): [ |
34 (0x04D8, 0xEC44): [ |
35 "PYCUBEDBOOT", # PyCubedv04 |
35 "PYCUBEDBOOT", # PyCubedv04 |
36 ], |
36 ], |
37 (0x04D8, 0xEC63): [ |
37 (0x04D8, 0xEC63): [ |
38 "BOOT", # CircuitBrains Basic |
38 "BOOT", # CircuitBrains Basic |
39 ], |
39 ], |
40 (0x04D8, 0xEC64): [ |
40 (0x04D8, 0xEC64): [ |
41 "BOOT", # CircuitBrains Deluxe |
41 "BOOT", # CircuitBrains Deluxe |
42 ], |
42 ], |
43 (0x04D8, 0xED5F): [ |
43 (0x04D8, 0xED5F): [ |
44 "UCHIPYBOOT", # uChip CircuitPython |
44 "UCHIPYBOOT", # uChip CircuitPython |
45 ], |
45 ], |
46 (0x04D8, 0xEDB3): [ |
46 (0x04D8, 0xEDB3): [ |
47 "USBHUBBOOT", # Programmable USB Hub |
47 "USBHUBBOOT", # Programmable USB Hub |
48 ], |
48 ], |
49 (0x04D8, 0xEDBE): [ |
49 (0x04D8, 0xEDBE): [ |
50 "SAM32BOOT", # SAM32 |
50 "SAM32BOOT", # SAM32 |
51 ], |
51 ], |
52 (0x04D8, 0xEF66): [ |
52 (0x04D8, 0xEF66): [ |
53 "SENSEBOX", # senseBox MCU |
53 "SENSEBOX", # senseBox MCU |
54 ], |
54 ], |
55 (0x1209, 0x2017): [ |
55 (0x1209, 0x2017): [ |
56 "MINISAMBOOT", # Mini SAM M4 |
56 "MINISAMBOOT", # Mini SAM M4 |
57 ], |
57 ], |
58 (0x1209, 0x3252): [ |
58 (0x1209, 0x3252): [ |
59 "MCBS2OMBOOT", # Module Clip w/Wroom |
59 "MCBS2OMBOOT", # Module Clip w/Wroom |
60 ], |
60 ], |
61 (0x1209, 0x3253): [ |
61 (0x1209, 0x3253): [ |
62 "MCBS2ERBOOT", # Module Clip w/Wrover |
62 "MCBS2ERBOOT", # Module Clip w/Wrover |
63 ], |
63 ], |
64 (0x1209, 0x4D44): [ |
64 (0x1209, 0x4D44): [ |
65 "ROBOM0BOOT", # Robo HAT MM1 |
65 "ROBOM0BOOT", # Robo HAT MM1 |
66 "ROBOM4BOOT", # Robo HAT MM1 M4 |
66 "ROBOM4BOOT", # Robo HAT MM1 M4 |
67 ], |
67 ], |
68 (0x1209, 0x4DDD): [ |
68 (0x1209, 0x4DDD): [ |
69 "SapBOOT", # CP Sapling |
69 "SapBOOT", # CP Sapling |
70 ], |
70 ], |
71 (0x1209, 0x7102): [ |
71 (0x1209, 0x7102): [ |
72 "MINISAMBOOT", # Mini SAM M0 |
72 "MINISAMBOOT", # Mini SAM M0 |
73 ], |
73 ], |
74 (0x1209, 0x7A01): [ |
74 (0x1209, 0x7A01): [ |
75 "MIKOTO-BOOT", # Mikoto nRF52840 |
75 "MIKOTO-BOOT", # Mikoto nRF52840 |
76 ], |
76 ], |
77 (0x1209, 0x805A): [ |
77 (0x1209, 0x805A): [ |
78 "BASTBLE", # Bast BLE |
78 "BASTBLE", # Bast BLE |
79 ], |
79 ], |
80 (0x1209, 0xE3E2): [ |
80 (0x1209, 0xE3E2): [ |
81 "StackRduino", # StackRduino M0 PRO |
81 "StackRduino", # StackRduino M0 PRO |
82 ], |
82 ], |
83 (0x1209, 0xF501): [ |
83 (0x1209, 0xF501): [ |
84 "M4SHIMBOOT", # M4-Shim |
84 "M4SHIMBOOT", # M4-Shim |
85 ], |
85 ], |
86 (0x15BA, 0x28DC): [ |
86 (0x15BA, 0x28DC): [ |
87 "OLMLIPOBOOT", # ESP32S2 DevKit Lipo |
87 "OLMLIPOBOOT", # ESP32S2 DevKit Lipo |
88 ], |
88 ], |
89 (0x16D0, 0x0CDA): [ |
89 (0x16D0, 0x0CDA): [ |
90 "AUTOMAT", # automat |
90 "AUTOMAT", # automat |
91 ], |
91 ], |
92 (0x1B4F, 0x0022): [ |
92 (0x1B4F, 0x0022): [ |
93 "SFMM852BOOT", # MicroMod nRF52840 |
93 "SFMM852BOOT", # MicroMod nRF52840 |
94 ], |
94 ], |
95 (0x1B4F, 0x002C): [ |
95 (0x1B4F, 0x002C): [ |
96 "THNG+32BOOT", # Thing Plus - STM32 |
96 "THNG+32BOOT", # Thing Plus - STM32 |
97 ], |
97 ], |
98 (0x1B4F, 0x0D22): [ |
98 (0x1B4F, 0x0D22): [ |
99 "SPARKFUN", # SAMD21 Mini Breakout |
99 "SPARKFUN", # SAMD21 Mini Breakout |
100 ], |
100 ], |
101 (0x1B4F, 0x0D23): [ |
101 (0x1B4F, 0x0D23): [ |
102 "SPARKFUN", # SAMD21 Dev Breakout |
102 "SPARKFUN", # SAMD21 Dev Breakout |
103 ], |
103 ], |
104 (0x1D50, 0x6110): [ |
104 (0x1D50, 0x6110): [ |
105 "ROBOTICS", # Robotics |
105 "ROBOTICS", # Robotics |
106 ], |
106 ], |
107 (0x1D50, 0x6112): [ |
107 (0x1D50, 0x6112): [ |
108 "RCBOOT", # Wattuino RC |
108 "RCBOOT", # Wattuino RC |
109 ], |
109 ], |
110 (0x1D50, 0x6157): [ |
110 (0x1D50, 0x6157): [ |
111 "BBOARDBOOT", # nRF52840 BBoard |
111 "BBOARDBOOT", # nRF52840 BBoard |
112 ], |
112 ], |
113 (0x1D50, 0x6160): [ |
113 (0x1D50, 0x6160): [ |
114 "BLUEMICRO", # BlueMicro |
114 "BLUEMICRO", # BlueMicro |
115 ], |
115 ], |
116 (0x1D50, 0x616F): [ |
116 (0x1D50, 0x616F): [ |
117 "BLUEMICRO", # BlueMicro |
117 "BLUEMICRO", # BlueMicro |
118 ], |
118 ], |
119 (0x1FC9, 0x0094): [ |
119 (0x1FC9, 0x0094): [ |
120 "DblM33BOOT", # Double M33 |
120 "DblM33BOOT", # Double M33 |
121 "LPC5528BOOT", # LPCXpresso 55s28 |
121 "LPC5528BOOT", # LPCXpresso 55s28 |
122 "LPC5569BOOT", # LPCXpresso 55s69 |
122 "LPC5569BOOT", # LPCXpresso 55s69 |
123 ], |
123 ], |
124 (0x1FC9, 0x0154): [ |
124 (0x1FC9, 0x0154): [ |
125 "K32L2BOOT", # FRDM-K32L2B3 |
125 "K32L2BOOT", # FRDM-K32L2B3 |
126 "K32L2BOOT", # KUIIC |
126 "K32L2BOOT", # KUIIC |
127 ], |
127 ], |
128 (0x230A, 0x00E9): [ |
128 (0x230A, 0x00E9): [ |
129 "TAU_BOOT", # Tau |
129 "TAU_BOOT", # Tau |
130 ], |
130 ], |
131 (0x2341, 0x0057): [ |
131 (0x2341, 0x0057): [ |
132 "NANOBOOT", # NANO 33 IoT |
132 "NANOBOOT", # NANO 33 IoT |
133 ], |
133 ], |
134 (0x2341, 0x8053): [ |
134 (0x2341, 0x8053): [ |
135 "MKR1300", # MKR1300 |
135 "MKR1300", # MKR1300 |
136 ], |
136 ], |
137 (0x239A, 0x000F): [ |
137 (0x239A, 0x000F): [ |
138 "ITSYBOOT", # ItsyBitsy M0 Express |
138 "ITSYBOOT", # ItsyBitsy M0 Express |
139 ], |
139 ], |
140 (0x239A, 0x0013): [ |
140 (0x239A, 0x0013): [ |
141 "METROBOOT", # Metro M0 |
141 "METROBOOT", # Metro M0 |
142 ], |
142 ], |
143 (0x239A, 0x0015): [ |
143 (0x239A, 0x0015): [ |
144 "FEATHERBOOT", # Feather M0 |
144 "FEATHERBOOT", # Feather M0 |
145 ], |
145 ], |
146 (0x239A, 0x0018): [ |
146 (0x239A, 0x0018): [ |
147 "CPLAYBOOT", # CPlay Express |
147 "CPLAYBOOT", # CPlay Express |
148 ], |
148 ], |
149 (0x239A, 0x001B): [ |
149 (0x239A, 0x001B): [ |
150 "FEATHERBOOT", # Feather M0 Express |
150 "FEATHERBOOT", # Feather M0 Express |
151 ], |
151 ], |
152 (0x239A, 0x001C): [ |
152 (0x239A, 0x001C): [ |
153 "GEMMABOOT", # Gemma M0 |
153 "GEMMABOOT", # Gemma M0 |
154 ], |
154 ], |
155 (0x239A, 0x001E): [ |
155 (0x239A, 0x001E): [ |
156 "TRINKETBOOT", # Trinket M0 |
156 "TRINKETBOOT", # Trinket M0 |
157 ], |
157 ], |
158 (0x239A, 0x0021): [ |
158 (0x239A, 0x0021): [ |
159 "METROM4BOOT", # Metro M4 Express |
159 "METROM4BOOT", # Metro M4 Express |
160 ], |
160 ], |
161 (0x239A, 0x0022): [ |
161 (0x239A, 0x0022): [ |
162 "ARCADE-D5", # Feather Arcade D51 |
162 "ARCADE-D5", # Feather Arcade D51 |
163 "FEATHERBOOT", # Feather M4 Express |
163 "FEATHERBOOT", # Feather M4 Express |
164 ], |
164 ], |
165 (0x239A, 0x0024): [ |
165 (0x239A, 0x0024): [ |
166 "RADIOBOOT", # Radiofruit M0 |
166 "RADIOBOOT", # Radiofruit M0 |
167 ], |
167 ], |
168 (0x239A, 0x0027): [ |
168 (0x239A, 0x0027): [ |
169 "PIRKEYBOOT", # pIRKey M0 |
169 "PIRKEYBOOT", # pIRKey M0 |
170 ], |
170 ], |
171 (0x239A, 0x0029): [ |
171 (0x239A, 0x0029): [ |
172 "ARGONBOOT ", # Argon |
172 "ARGONBOOT ", # Argon |
173 "BORONBOOT ", # Boron |
173 "BORONBOOT ", # Boron |
174 "FTHR840BOOT", # Feather nRF52840 Express |
174 "FTHR840BOOT", # Feather nRF52840 Express |
175 "MDK840DONGL", # MDK nRF52840 USB Dongle |
175 "MDK840DONGL", # MDK nRF52840 USB Dongle |
176 "WS52840EVK", # Waveshare nRF52840 Eval |
176 "WS52840EVK", # Waveshare nRF52840 Eval |
177 "XENONBOOT ", # Xenon |
177 "XENONBOOT ", # Xenon |
178 ], |
178 ], |
179 (0x239A, 0x002B): [ |
179 (0x239A, 0x002B): [ |
180 "ARCADE-D5", # Itsy Arcade D51 |
180 "ARCADE-D5", # Itsy Arcade D51 |
181 "ITSYM4BOOT", # ItsyBitsy M4 Express |
181 "ITSYM4BOOT", # ItsyBitsy M4 Express |
182 ], |
182 ], |
183 (0x239A, 0x002D): [ |
183 (0x239A, 0x002D): [ |
184 "CRICKITBOOT", # crickit |
184 "CRICKITBOOT", # crickit |
185 ], |
185 ], |
186 (0x239A, 0x002F): [ |
186 (0x239A, 0x002F): [ |
187 "TRELM4BOOT", # Trellis M4 Express |
187 "TRELM4BOOT", # Trellis M4 Express |
188 ], |
188 ], |
189 (0x239A, 0x0031): [ |
189 (0x239A, 0x0031): [ |
190 "GCM4BOOT", # Grand Central M4 Express |
190 "GCM4BOOT", # Grand Central M4 Express |
191 ], |
191 ], |
192 (0x239A, 0x0033): [ |
192 (0x239A, 0x0033): [ |
193 "PYBADGEBOOT", # PyBadge |
193 "PYBADGEBOOT", # PyBadge |
194 ], |
194 ], |
195 (0x239A, 0x0034): [ |
195 (0x239A, 0x0034): [ |
196 "BADGELCBOOT", # BadgeLC |
196 "BADGELCBOOT", # BadgeLC |
197 "PEWBOOT", # PewPew |
197 "PEWBOOT", # PewPew |
198 ], |
198 ], |
199 (0x239A, 0x0035): [ |
199 (0x239A, 0x0035): [ |
200 "MKRZEROBOOT", # MKRZero |
200 "MKRZEROBOOT", # MKRZero |
201 "PORTALBOOT", # PyPortal M4 Express |
201 "PORTALBOOT", # PyPortal M4 Express |
202 ], |
202 ], |
203 (0x239A, 0x0037): [ |
203 (0x239A, 0x0037): [ |
204 "METROM4BOOT", # Metro M4 AirLift |
204 "METROM4BOOT", # Metro M4 AirLift |
205 ], |
205 ], |
206 (0x239A, 0x003D): [ |
206 (0x239A, 0x003D): [ |
207 "PYGAMERBOOT", # PyGamer |
207 "PYGAMERBOOT", # PyGamer |
208 ], |
208 ], |
209 (0x239A, 0x003F): [ |
209 (0x239A, 0x003F): [ |
210 "METR840BOOT", # Metro nRF52840 Express |
210 "METR840BOOT", # Metro nRF52840 Express |
211 ], |
211 ], |
212 (0x239A, 0x0045): [ |
212 (0x239A, 0x0045): [ |
213 "CPLAYBTBOOT", # Circuit Playground nRF52840 |
213 "CPLAYBTBOOT", # Circuit Playground nRF52840 |
214 ], |
214 ], |
215 (0x239A, 0x0047): [ |
215 (0x239A, 0x0047): [ |
216 "MASKM4BOOT", # Hallowing Mask M4 |
216 "MASKM4BOOT", # Hallowing Mask M4 |
217 ], |
217 ], |
218 (0x239A, 0x0049): [ |
218 (0x239A, 0x0049): [ |
219 "HALLOM4BOOT", # HalloWing M4 |
219 "HALLOM4BOOT", # HalloWing M4 |
220 ], |
220 ], |
221 (0x239A, 0x004D): [ |
221 (0x239A, 0x004D): [ |
222 "SNEKBOOT", # snekboard |
222 "SNEKBOOT", # snekboard |
223 ], |
223 ], |
224 (0x239A, 0x0051): [ |
224 (0x239A, 0x0051): [ |
225 "ITSY840BOOT", # ItsyBitsy nRF52840 Express |
225 "ITSY840BOOT", # ItsyBitsy nRF52840 Express |
226 ], |
226 ], |
227 (0x239A, 0x0057): [ |
227 (0x239A, 0x0057): [ |
228 "SERPENTBOOT", # Serpente |
228 "SERPENTBOOT", # Serpente |
229 ], |
229 ], |
230 (0x239A, 0x0059): [ |
230 (0x239A, 0x0059): [ |
231 "FTHR405BOOT", # Feather STM32F405 Express |
231 "FTHR405BOOT", # Feather STM32F405 Express |
232 ], |
232 ], |
233 (0x239A, 0x005D): [ |
233 (0x239A, 0x005D): [ |
234 "BlackPill", # STM32F401CxUx |
234 "BlackPill", # STM32F401CxUx |
235 "STMF411BOOT", # STM32F411 Discovery |
235 "STMF411BOOT", # STM32F411 Discovery |
236 ], |
236 ], |
237 (0x239A, 0x0061): [ |
237 (0x239A, 0x0061): [ |
238 "SOLBOOT", # Sol |
238 "SOLBOOT", # Sol |
239 ], |
239 ], |
240 (0x239A, 0x0063): [ |
240 (0x239A, 0x0063): [ |
241 "NANO33BOOT", # Nano 33 BLE |
241 "NANO33BOOT", # Nano 33 BLE |
242 ], |
242 ], |
243 (0x239A, 0x0065): [ |
243 (0x239A, 0x0065): [ |
244 "ND6BOOT", # ndBit6 |
244 "ND6BOOT", # ndBit6 |
245 ], |
245 ], |
246 (0x239A, 0x0069): [ |
246 (0x239A, 0x0069): [ |
247 "STMF411BOOT", # STM32F411 BlackPill |
247 "STMF411BOOT", # STM32F411 BlackPill |
248 ], |
248 ], |
249 (0x239A, 0x006B): [ |
249 (0x239A, 0x006B): [ |
250 "shIRtty", # shIRtty |
250 "shIRtty", # shIRtty |
251 ], |
251 ], |
252 (0x239A, 0x0071): [ |
252 (0x239A, 0x0071): [ |
253 "CLUEBOOT", # CLUE nRF52840 |
253 "CLUEBOOT", # CLUE nRF52840 |
254 ], |
254 ], |
255 (0x239A, 0x0077): [ |
255 (0x239A, 0x0077): [ |
256 "RT1010BOOT", # RT1010 EVK |
256 "RT1010BOOT", # RT1010 EVK |
257 ], |
257 ], |
258 (0x239A, 0x0079): [ |
258 (0x239A, 0x0079): [ |
259 "ARAMBOOT", # ARAMCON Badge 2019 |
259 "ARAMBOOT", # ARAMCON Badge 2019 |
260 ], |
260 ], |
261 (0x239A, 0x007B): [ |
261 (0x239A, 0x007B): [ |
262 "ARAMBOOT", # ARAMCON2 Badge |
262 "ARAMBOOT", # ARAMCON2 Badge |
263 ], |
263 ], |
264 (0x239A, 0x007D): [ |
264 (0x239A, 0x007D): [ |
265 "BOOKBOOT", # The Open Book Feather |
265 "BOOKBOOT", # The Open Book Feather |
266 ], |
266 ], |
267 (0x239A, 0x007F): [ |
267 (0x239A, 0x007F): [ |
268 "BADGEBOOT", # OHS2020 Badge |
268 "BADGEBOOT", # OHS2020 Badge |
269 ], |
269 ], |
270 (0x239A, 0x0081): [ |
270 (0x239A, 0x0081): [ |
271 "RT1020BOOT", # RT1020 EVK |
271 "RT1020BOOT", # RT1020 EVK |
272 "RT1024BOOT", # RT1024 EVK |
272 "RT1024BOOT", # RT1024 EVK |
273 ], |
273 ], |
274 (0x239A, 0x0083): [ |
274 (0x239A, 0x0083): [ |
275 "RT1060BOOT", # RT1060 EVK |
275 "RT1060BOOT", # RT1060 EVK |
276 "RT1064BOOT", # RT1064 EVK |
276 "RT1064BOOT", # RT1064 EVK |
277 ], |
277 ], |
278 (0x239A, 0x0087): [ |
278 (0x239A, 0x0087): [ |
279 "FTHRSNSBOOT", # Feather nRF52840 Sense |
279 "FTHRSNSBOOT", # Feather nRF52840 Sense |
280 ], |
280 ], |
281 (0x239A, 0x0093): [ |
281 (0x239A, 0x0093): [ |
282 "ISVITABoot", # IkigaiSense Vita nRF52840 |
282 "ISVITABoot", # IkigaiSense Vita nRF52840 |
283 ], |
283 ], |
284 (0x239A, 0x0095): [ |
284 (0x239A, 0x0095): [ |
285 "UARTLOGBOOT", # UARTLogger II |
285 "UARTLOGBOOT", # UARTLogger II |
286 ], |
286 ], |
287 (0x239A, 0x009F): [ |
287 (0x239A, 0x009F): [ |
288 "ADM840BOOT", # AtelierDuMaker NRF52840 Breakout |
288 "ADM840BOOT", # AtelierDuMaker NRF52840 Breakout |
289 ], |
289 ], |
290 (0x239A, 0x00A5): [ |
290 (0x239A, 0x00A5): [ |
291 "S3DKC1BOOT", # ESP32S3 DevKitC 1 |
291 "S3DKC1BOOT", # ESP32S3 DevKitC 1 |
292 "S3DKM1BOOT", # ESP32S3 DevKitM 1 |
292 "S3DKM1BOOT", # ESP32S3 DevKitM 1 |
293 "SAOLA1RBOOT", # Saola 1R WROVER |
293 "SAOLA1RBOOT", # Saola 1R WROVER |
294 ], |
294 ], |
295 (0x239A, 0x00A7): [ |
295 (0x239A, 0x00A7): [ |
296 "SAOLA1MBOOT", # Saola 1M WROOM |
296 "SAOLA1MBOOT", # Saola 1M WROOM |
297 ], |
297 ], |
298 (0x239A, 0x00AB): [ |
298 (0x239A, 0x00AB): [ |
299 "UFTHRS2BOOT", # FeatherS2 |
299 "UFTHRS2BOOT", # FeatherS2 |
300 ], |
300 ], |
301 (0x239A, 0x00AF): [ |
301 (0x239A, 0x00AF): [ |
302 "FLUFFBOOT", # Fluff M0 |
302 "FLUFFBOOT", # Fluff M0 |
303 ], |
303 ], |
304 (0x239A, 0x00B3): [ |
304 (0x239A, 0x00B3): [ |
305 "NICENANO", # nice!nano |
305 "NICENANO", # nice!nano |
306 ], |
306 ], |
307 (0x239A, 0x00B5): [ |
307 (0x239A, 0x00B5): [ |
308 "E54XBOOT", # SAME54 Xplained |
308 "E54XBOOT", # SAME54 Xplained |
309 ], |
309 ], |
310 (0x239A, 0x00B9): [ |
310 (0x239A, 0x00B9): [ |
311 "ND7BOOT", # ndBit7 |
311 "ND7BOOT", # ndBit7 |
312 ], |
312 ], |
313 (0x239A, 0x00BB): [ |
313 (0x239A, 0x00BB): [ |
314 "MDBT50QBOOT", # Raytac MDBT50Q Demo Board 40 |
314 "MDBT50QBOOT", # Raytac MDBT50Q Demo Board 40 |
315 ], |
315 ], |
316 (0x239A, 0x00BF): [ |
316 (0x239A, 0x00BF): [ |
317 "BADGEBOOT", # BLM Badge |
317 "BADGEBOOT", # BLM Badge |
318 ], |
318 ], |
319 (0x239A, 0x00C3): [ |
319 (0x239A, 0x00C3): [ |
320 "GEMINIBOOT", # Gemini |
320 "GEMINIBOOT", # Gemini |
321 ], |
321 ], |
322 (0x239A, 0x00C5): [ |
322 (0x239A, 0x00C5): [ |
323 "MICROS2BOOT", # microS2 |
323 "MICROS2BOOT", # microS2 |
324 ], |
324 ], |
325 (0x239A, 0x00C7): [ |
325 (0x239A, 0x00C7): [ |
326 "KALUGA1BOOT", # Kaluga 1 |
326 "KALUGA1BOOT", # Kaluga 1 |
327 ], |
327 ], |
328 (0x239A, 0x00C9): [ |
328 (0x239A, 0x00C9): [ |
329 "MATRIXBOOT", # Matrix Portal M4 |
329 "MATRIXBOOT", # Matrix Portal M4 |
330 ], |
330 ], |
331 (0x239A, 0x00CB): [ |
331 (0x239A, 0x00CB): [ |
332 "QTPY_BOOT", # QT Py M0 |
332 "QTPY_BOOT", # QT Py M0 |
333 ], |
333 ], |
334 (0x239A, 0x00CD): [ |
334 (0x239A, 0x00CD): [ |
335 "FTHRCANBOOT", # Feather M4 CAN Express |
335 "FTHRCANBOOT", # Feather M4 CAN Express |
336 ], |
336 ], |
337 (0x239A, 0x00DE): [ |
337 (0x239A, 0x00DE): [ |
338 "NANOESPBOOT", # nanoESP32-S2 WROOM |
338 "NANOESPBOOT", # nanoESP32-S2 WROOM |
339 ], |
339 ], |
340 (0x239A, 0x00DF): [ |
340 (0x239A, 0x00DF): [ |
341 "METROS2BOOT", # Metro ESP32-S2 |
341 "METROS2BOOT", # Metro ESP32-S2 |
342 ], |
342 ], |
343 (0x239A, 0x00E1): [ |
343 (0x239A, 0x00E1): [ |
344 "METROM7BOOT", # Metro M7 iMX RT1011 |
344 "METROM7BOOT", # Metro M7 iMX RT1011 |
345 ], |
345 ], |
346 (0x239A, 0x00E5): [ |
346 (0x239A, 0x00E5): [ |
347 "MAGTAGBOOT", # Metro MagTag 2.9 Grayscale |
347 "MAGTAGBOOT", # Metro MagTag 2.9 Grayscale |
348 "MAGTAGBOOT", # MagTag 2.9 Grayscale |
348 "MAGTAGBOOT", # MagTag 2.9 Grayscale |
349 ], |
349 ], |
350 (0x239A, 0x00EB): [ |
350 (0x239A, 0x00EB): [ |
351 "FTHRS2BOOT", # Feather ESP32-S2 |
351 "FTHRS2BOOT", # Feather ESP32-S2 |
352 ], |
352 ], |
353 (0x239A, 0x00ED): [ |
353 (0x239A, 0x00ED): [ |
354 "FTHRS2BOOT", # Feather ESP32-S2 Reverse TFT |
354 "FTHRS2BOOT", # Feather ESP32-S2 Reverse TFT |
355 ], |
355 ], |
356 (0x239A, 0x00EF): [ |
356 (0x239A, 0x00EF): [ |
357 "TRINKEYBOOT", # NeoPixel Trinkey M0 |
357 "TRINKEYBOOT", # NeoPixel Trinkey M0 |
358 ], |
358 ], |
359 (0x239A, 0x00F5): [ |
359 (0x239A, 0x00F5): [ |
360 "STARBOOT", # Binary Star |
360 "STARBOOT", # Binary Star |
361 ], |
361 ], |
362 (0x239A, 0x00F9): [ |
362 (0x239A, 0x00F9): [ |
363 "HOUSEBOOT", # FunHouse |
363 "HOUSEBOOT", # FunHouse |
364 ], |
364 ], |
365 (0x239A, 0x00FB): [ |
365 (0x239A, 0x00FB): [ |
366 "TRINKEYBOOT", # Rotary Trinkey M0 |
366 "TRINKEYBOOT", # Rotary Trinkey M0 |
367 ], |
367 ], |
368 (0x239A, 0x00FF): [ |
368 (0x239A, 0x00FF): [ |
369 "TRINKEYBOOT", # NeoKey Trinkey M0 |
369 "TRINKEYBOOT", # NeoKey Trinkey M0 |
370 ], |
370 ], |
371 (0x239A, 0x0101): [ |
371 (0x239A, 0x0101): [ |
372 "TRINKEYBOOT", # Slide Trinkey M0 |
372 "TRINKEYBOOT", # Slide Trinkey M0 |
373 ], |
373 ], |
374 (0x239A, 0x0103): [ |
374 (0x239A, 0x0103): [ |
375 "TRINKEYBOOT", # ProxSense Trinkey M0 |
375 "TRINKEYBOOT", # ProxSense Trinkey M0 |
376 ], |
376 ], |
377 (0x239A, 0x010B): [ |
377 (0x239A, 0x010B): [ |
378 "MDBT50QBOOT", # Raytac MDBT50Q-RX |
378 "MDBT50QBOOT", # Raytac MDBT50Q-RX |
379 ], |
379 ], |
380 (0x239A, 0x010D): [ |
380 (0x239A, 0x010D): [ |
381 "GLASSESBOOT", # LED Glasses Driver nRF52840 |
381 "GLASSESBOOT", # LED Glasses Driver nRF52840 |
382 ], |
382 ], |
383 (0x239A, 0x010F): [ |
383 (0x239A, 0x010F): [ |
384 "FTHRS2BOOT", # Feather ESP32-S2 TFT |
384 "FTHRS2BOOT", # Feather ESP32-S2 TFT |
385 ], |
385 ], |
386 (0x239A, 0x0111): [ |
386 (0x239A, 0x0111): [ |
387 "QTPYS2BOOT", # QT Py ESP32-S2 |
387 "QTPYS2BOOT", # QT Py ESP32-S2 |
388 ], |
388 ], |
389 (0x239A, 0x0113): [ |
389 (0x239A, 0x0113): [ |
390 "FTHRS3BOOT", # Feather ESP32-S3 No PSRAM |
390 "FTHRS3BOOT", # Feather ESP32-S3 No PSRAM |
391 ], |
391 ], |
392 (0x239A, 0x0115): [ |
392 (0x239A, 0x0115): [ |
393 "FEATHERBOOT", # Feather M4 Adalogger |
393 "FEATHERBOOT", # Feather M4 Adalogger |
394 ], |
394 ], |
395 (0x239A, 0x0117): [ |
395 (0x239A, 0x0117): [ |
396 "CAMERABOOT", # Camera |
396 "CAMERABOOT", # Camera |
397 ], |
397 ], |
398 (0x239A, 0x0119): [ |
398 (0x239A, 0x0119): [ |
399 "QTPYS3BOOT", # QT Py ESP32-S3 |
399 "QTPYS3BOOT", # QT Py ESP32-S3 |
400 ], |
400 ], |
401 (0x239A, 0x800B): [ |
401 (0x239A, 0x800B): [ |
402 "ATMZBOOT", # ATMegaZero ESP32-S2 |
402 "ATMZBOOT", # ATMegaZero ESP32-S2 |
403 ], |
403 ], |
404 (0x239A, 0xB000): [ |
404 (0x239A, 0xB000): [ |
405 "HALLOWBOOT", # Hallowing M0 |
405 "HALLOWBOOT", # Hallowing M0 |
406 ], |
406 ], |
407 (0x239A, 0xE005): [ |
407 (0x239A, 0xE005): [ |
408 "HONKBOOT", # Big Honking Button |
408 "HONKBOOT", # Big Honking Button |
409 ], |
409 ], |
410 (0x2886, 0x000D): [ |
410 (0x2886, 0x000D): [ |
411 "Grove Zero", # Grove Zero |
411 "Grove Zero", # Grove Zero |
412 ], |
412 ], |
413 (0x2886, 0x002F): [ |
413 (0x2886, 0x002F): [ |
414 "Seeed XIAO", # Seeeduino XIAO |
414 "Seeed XIAO", # Seeeduino XIAO |
415 ], |
415 ], |
416 (0x2886, 0xF00E): [ |
416 (0x2886, 0xF00E): [ |
417 "PITAYAGO", # Pitaya Go |
417 "PITAYAGO", # Pitaya Go |
418 ], |
418 ], |
419 (0x2886, 0xF00F): [ |
419 (0x2886, 0xF00F): [ |
420 "M60KEYBOARD", # MakerDiary M60 Mechanical Keyboard |
420 "M60KEYBOARD", # MakerDiary M60 Mechanical Keyboard |
421 "nRF52840M2", # MakerDiary nRF52840 M.2 Module |
421 "nRF52840M2", # MakerDiary nRF52840 M.2 Module |
422 ], |
422 ], |
423 (0x303A, 0x7000): [ |
423 (0x303A, 0x7000): [ |
424 "ESPHMI1BOOT", # HMI 1 |
424 "ESPHMI1BOOT", # HMI 1 |
425 ], |
425 ], |
426 (0x303A, 0x8005): [ |
426 (0x303A, 0x8005): [ |
427 "TINYS2BOOT", # TinyS2 |
427 "TINYS2BOOT", # TinyS2 |
428 ], |
428 ], |
429 (0x303A, 0x8008): [ |
429 (0x303A, 0x8008): [ |
430 "TTGOS2BOOT", # TTGO_T8_S2_Display |
430 "TTGOS2BOOT", # TTGO_T8_S2_Display |
431 ], |
431 ], |
432 (0x303A, 0x800E): [ |
432 (0x303A, 0x800E): [ |
433 "CCMBRISBOOT", # CucumberRIS v1.1 |
433 "CCMBRISBOOT", # CucumberRIS v1.1 |
434 ], |
434 ], |
435 (0x303A, 0x80B0): [ |
435 (0x303A, 0x80B0): [ |
436 "RD00RBOOT", # Reference Design RD00 |
436 "RD00RBOOT", # Reference Design RD00 |
437 ], |
437 ], |
438 (0x303A, 0x80B3): [ |
438 (0x303A, 0x80B3): [ |
439 "NANOESPBOOT", # nanoESP32-S2 WROVER |
439 "NANOESPBOOT", # nanoESP32-S2 WROVER |
440 ], |
440 ], |
441 (0x303A, 0x80B5): [ |
441 (0x303A, 0x80B5): [ |
442 "FS2NEOBOOT", # FeatherS2 Neo |
442 "FS2NEOBOOT", # FeatherS2 Neo |
443 ], |
443 ], |
444 (0x303A, 0x80B6): [ |
444 (0x303A, 0x80B6): [ |
445 "MORPHBOOT", # MORPHESP-240 |
445 "MORPHBOOT", # MORPHESP-240 |
446 ], |
446 ], |
447 (0x303A, 0x80C4): [ |
447 (0x303A, 0x80C4): [ |
448 "S2MINIBOOT", # S2 Mini |
448 "S2MINIBOOT", # S2 Mini |
449 ], |
449 ], |
450 (0x303A, 0x80C7): [ |
450 (0x303A, 0x80C7): [ |
451 "S2PICOBOOT", # S2 Pico |
451 "S2PICOBOOT", # S2 Pico |
452 ], |
452 ], |
453 (0x303A, 0x80D2): [ |
453 (0x303A, 0x80D2): [ |
454 "TINYS3BOOT", # TinyS3 |
454 "TINYS3BOOT", # TinyS3 |
455 ], |
455 ], |
456 (0x303A, 0x80D5): [ |
456 (0x303A, 0x80D5): [ |
457 "PROS3BOOT", # ProS3 |
457 "PROS3BOOT", # ProS3 |
458 ], |
458 ], |
459 (0x303A, 0x80D8): [ |
459 (0x303A, 0x80D8): [ |
460 "UFTHRS3BOOT", # FeatherS3 |
460 "UFTHRS3BOOT", # FeatherS3 |
461 ], |
461 ], |
462 (0x303A, 0x80DA): [ |
462 (0x303A, 0x80DA): [ |
463 "HEXKYBOOT", # HexKy-S2 |
463 "HEXKYBOOT", # HexKy-S2 |
464 ], |
464 ], |
465 (0x303A, 0x80DE): [ |
465 (0x303A, 0x80DE): [ |
466 "LEAFS3BOOT", # BPI-Leaf-S3 |
466 "LEAFS3BOOT", # BPI-Leaf-S3 |
467 ], |
467 ], |
468 (0x303A, 0x80E1): [ |
468 (0x303A, 0x80E1): [ |
469 "LEAFS2BOOT", # BPI-Leaf-S2 |
469 "LEAFS2BOOT", # BPI-Leaf-S2 |
470 ], |
470 ], |
471 (0x303A, 0x80E4): [ |
471 (0x303A, 0x80E4): [ |
472 "BITS2BOOT", # BPI-BIT-S2 |
472 "BITS2BOOT", # BPI-BIT-S2 |
473 ], |
473 ], |
474 (0x303A, 0x80EB): [ |
474 (0x303A, 0x80EB): [ |
475 "TTGOS2BOOT", # TTGO_T8_S2_WROOM |
475 "TTGOS2BOOT", # TTGO_T8_S2_WROOM |
476 ], |
476 ], |
477 (0x303A, 0x80EE): [ |
477 (0x303A, 0x80EE): [ |
478 "TTGOS2BOOT", # TTGO_T8_S2 |
478 "TTGOS2BOOT", # TTGO_T8_S2 |
479 ], |
479 ], |
480 (0x3171, 0x0100): [ |
480 (0x3171, 0x0100): [ |
481 "CMDBOOT", # COMMANDER |
481 "CMDBOOT", # COMMANDER |
482 ], |
482 ], |
483 (0x80E7, 0x8111): [ |
483 (0x80E7, 0x8111): [ |
484 "IOTS2BOOT", # HiiBot IoTs2 |
484 "IOTS2BOOT", # HiiBot IoTs2 |
485 ], |
485 ], |
486 (0xCAFE, 0xFFFF): [ |
486 (0xCAFE, 0xFFFF): [ |
487 "F303BOOT", # STM32F303 Discovery |
487 "F303BOOT", # STM32F303 Discovery |
488 ], |
488 ], |
489 }, |
489 }, |
490 "instructions": QCoreApplication.translate( |
490 "instructions": QCoreApplication.translate( |
491 "UF2FlashDialog", |
491 "UF2FlashDialog", |
492 "<h3>CircuitPython Board</h3>" |
492 "<h3>CircuitPython Board</h3>" |
565 "<li>Wait until the device has entered 'bootloader' mode.</li>" |
563 "<li>Wait until the device has entered 'bootloader' mode.</li>" |
566 "<li>Ensure the boot volume is available (this may require" |
564 "<li>Ensure the boot volume is available (this may require" |
567 " mounting it).</li>" |
565 " mounting it).</li>" |
568 "<li>Select the firmware file to be flashed and click the" |
566 "<li>Select the firmware file to be flashed and click the" |
569 " flash button.</li>" |
567 " flash button.</li>" |
570 "</ol>" |
568 "</ol>", |
571 ), |
569 ), |
572 "show_all": True, |
570 "show_all": True, |
573 "firmware": "MicroPython / CircuitPython", |
571 "firmware": "MicroPython / CircuitPython", |
574 }, |
572 }, |
575 } |
573 } |
576 |
574 |
577 |
575 |
578 def getFoundDevices(boardType=""): |
576 def getFoundDevices(boardType=""): |
579 """ |
577 """ |
580 Function to get the list of known serial devices supporting UF2. |
578 Function to get the list of known serial devices supporting UF2. |
581 |
579 |
582 @param boardType specific board type to search for |
580 @param boardType specific board type to search for |
583 @type str |
581 @type str |
584 @return list of tuples with the board type, the port description, the |
582 @return list of tuples with the board type, the port description, the |
585 VID and PID |
583 VID and PID |
586 @rtype list of tuple of (str, str, int, int) |
584 @rtype list of tuple of (str, str, int, int) |
587 """ |
585 """ |
588 from PyQt6.QtSerialPort import QSerialPortInfo |
586 from PyQt6.QtSerialPort import QSerialPortInfo |
589 |
587 |
590 foundDevices = [] |
588 foundDevices = [] |
591 |
589 |
592 availablePorts = QSerialPortInfo.availablePorts() |
590 availablePorts = QSerialPortInfo.availablePorts() |
593 for port in availablePorts: |
591 for port in availablePorts: |
594 vid = port.vendorIdentifier() |
592 vid = port.vendorIdentifier() |
595 pid = port.productIdentifier() |
593 pid = port.productIdentifier() |
596 |
594 |
597 if vid == 0 and pid == 0: |
595 if vid == 0 and pid == 0: |
598 # no device detected at port |
596 # no device detected at port |
599 continue |
597 continue |
600 |
598 |
601 for board in SupportedUF2Boards: |
599 for board in SupportedUF2Boards: |
602 if ( |
600 if (not boardType or (board.startswith(boardType))) and ( |
603 (not boardType or (board.startswith(boardType))) and |
601 vid, |
604 (vid, pid) in SupportedUF2Boards[board]["volumes"] |
602 pid, |
605 ): |
603 ) in SupportedUF2Boards[board]["volumes"]: |
606 foundDevices.append(( |
604 foundDevices.append( |
607 board, |
605 ( |
608 port.description(), |
606 board, |
609 (vid, pid), |
607 port.description(), |
610 )) |
608 (vid, pid), |
611 |
609 ) |
|
610 ) |
|
611 |
612 # second run for boards needing special treatment (e.g. RP2040) |
612 # second run for boards needing special treatment (e.g. RP2040) |
613 for board in SupportedUF2Boards: |
613 for board in SupportedUF2Boards: |
614 if not boardType or (board == boardType): |
614 if not boardType or (board == boardType): |
615 with contextlib.suppress(KeyError): |
615 with contextlib.suppress(KeyError): |
616 # find mounted volume |
616 # find mounted volume |
617 volumes = SupportedUF2Boards[board]["volumes"][(0, 0)] |
617 volumes = SupportedUF2Boards[board]["volumes"][(0, 0)] |
618 foundVolumes = [] |
618 foundVolumes = [] |
619 for volume in volumes: |
619 for volume in volumes: |
620 foundVolumes += Utilities.findVolume(volume, findAll=True) |
620 foundVolumes += Utilities.findVolume(volume, findAll=True) |
621 if foundVolumes: |
621 if foundVolumes: |
622 foundDevices.append(( |
622 foundDevices.append( |
623 board, |
623 ( |
624 QCoreApplication.translate( |
624 board, |
625 "UF2FlashDialog", "'{0}' Board").format(board), |
625 QCoreApplication.translate( |
626 (0, 0), # VID/PID of (0, 0) is special |
626 "UF2FlashDialog", "'{0}' Board" |
627 )) |
627 ).format(board), |
628 |
628 (0, 0), # VID/PID of (0, 0) is special |
|
629 ) |
|
630 ) |
|
631 |
629 return foundDevices |
632 return foundDevices |
630 |
633 |
631 |
634 |
632 class UF2FlashDialog(QDialog, Ui_UF2FlashDialog): |
635 class UF2FlashDialog(QDialog, Ui_UF2FlashDialog): |
633 """ |
636 """ |
634 Class implementing a dialog to flash any UF2 capable device. |
637 Class implementing a dialog to flash any UF2 capable device. |
635 """ |
638 """ |
|
639 |
636 DeviceTypeRole = Qt.ItemDataRole.UserRole |
640 DeviceTypeRole = Qt.ItemDataRole.UserRole |
637 DeviceVidPidRole = Qt.ItemDataRole.UserRole + 1 |
641 DeviceVidPidRole = Qt.ItemDataRole.UserRole + 1 |
638 |
642 |
639 def __init__(self, boardType="", parent=None): |
643 def __init__(self, boardType="", parent=None): |
640 """ |
644 """ |
641 Constructor |
645 Constructor |
642 |
646 |
643 @param boardType specific board type to show the dialog for |
647 @param boardType specific board type to show the dialog for |
644 @type str |
648 @type str |
645 @param parent reference to the parent widget (defaults to None) |
649 @param parent reference to the parent widget (defaults to None) |
646 @type QWidget (optional) |
650 @type QWidget (optional) |
647 """ |
651 """ |
648 super().__init__(parent) |
652 super().__init__(parent) |
649 self.setupUi(self) |
653 self.setupUi(self) |
650 |
654 |
651 self.refreshButton.setIcon(UI.PixmapCache.getIcon("rescan")) |
655 self.refreshButton.setIcon(UI.PixmapCache.getIcon("rescan")) |
652 |
656 |
653 self.firmwarePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
657 self.firmwarePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
654 self.firmwarePicker.setFilters( |
658 self.firmwarePicker.setFilters( |
655 self.tr("MicroPython/CircuitPython Files (*.uf2);;" |
659 self.tr("MicroPython/CircuitPython Files (*.uf2);;" "All Files (*)") |
656 "All Files (*)")) |
660 ) |
657 |
661 |
658 self.bootPicker.setMode(EricPathPickerModes.DIRECTORY_SHOW_FILES_MODE) |
662 self.bootPicker.setMode(EricPathPickerModes.DIRECTORY_SHOW_FILES_MODE) |
659 self.bootPicker.setEnabled(False) |
663 self.bootPicker.setEnabled(False) |
660 |
664 |
661 self.__mandatoryStyleSheet = ( |
665 self.__mandatoryStyleSheet = ( |
662 "QLineEdit {border: 2px solid; border-color: #dd8888}" |
666 "QLineEdit {border: 2px solid; border-color: #dd8888}" |
663 if ericApp().usesDarkPalette() else |
667 if ericApp().usesDarkPalette() |
664 "QLineEdit {border: 2px solid; border-color: #800000}" |
668 else "QLineEdit {border: 2px solid; border-color: #800000}" |
665 ) |
669 ) |
666 self.__manualType = "<manual>" |
670 self.__manualType = "<manual>" |
667 |
671 |
668 self.__boardType = boardType |
672 self.__boardType = boardType |
669 |
673 |
670 self.__populate() |
674 self.__populate() |
671 |
675 |
672 self.__updateFlashButton() |
676 self.__updateFlashButton() |
673 |
677 |
674 def __populate(self): |
678 def __populate(self): |
675 """ |
679 """ |
676 Private method to (re-)populate the dialog. |
680 Private method to (re-)populate the dialog. |
677 """ |
681 """ |
678 # save the currently selected device |
682 # save the currently selected device |
679 currentDevice = self.devicesComboBox.currentText() |
683 currentDevice = self.devicesComboBox.currentText() |
680 firmwareFile = self.firmwarePicker.text() |
684 firmwareFile = self.firmwarePicker.text() |
681 |
685 |
682 # clear the entries first |
686 # clear the entries first |
683 self.devicesComboBox.clear() |
687 self.devicesComboBox.clear() |
684 self.firmwarePicker.clear() |
688 self.firmwarePicker.clear() |
685 self.bootPicker.clear() |
689 self.bootPicker.clear() |
686 self.infoLabel.clear() |
690 self.infoLabel.clear() |
687 self.infoEdit.clear() |
691 self.infoEdit.clear() |
688 |
692 |
689 # now populate the entries with data |
693 # now populate the entries with data |
690 devices = getFoundDevices(boardType=self.__boardType) |
694 devices = getFoundDevices(boardType=self.__boardType) |
691 if len(devices) == 0: |
695 if len(devices) == 0: |
692 # no device detected |
696 # no device detected |
693 devices = list(filter( |
697 devices = list( |
694 lambda x: x[0] in SupportedUF2Boards, |
698 filter( |
695 MicroPythonDevices.getFoundDevices()[0] |
699 lambda x: x[0] in SupportedUF2Boards, |
696 )) |
700 MicroPythonDevices.getFoundDevices()[0], |
|
701 ) |
|
702 ) |
697 if devices: |
703 if devices: |
698 self.__showSpecificInstructions(list(devices)) |
704 self.__showSpecificInstructions(list(devices)) |
699 else: |
705 else: |
700 self.__showAllInstructions() |
706 self.__showAllInstructions() |
701 self.devicesComboBox.addItem("") |
707 self.devicesComboBox.addItem("") |
702 self.devicesComboBox.addItem(self.tr("Manual Select")) |
708 self.devicesComboBox.addItem(self.tr("Manual Select")) |
703 self.devicesComboBox.setItemData(1, self.__manualType, |
709 self.devicesComboBox.setItemData(1, self.__manualType, self.DeviceTypeRole) |
704 self.DeviceTypeRole) |
|
705 elif len(devices) == 1: |
710 elif len(devices) == 1: |
706 # set the board type to the found one |
711 # set the board type to the found one |
707 self.__boardType = devices[0][0] |
712 self.__boardType = devices[0][0] |
708 |
713 |
709 self.devicesComboBox.addItem(devices[0][1]) |
714 self.devicesComboBox.addItem(devices[0][1]) |
710 self.devicesComboBox.setItemData( |
715 self.devicesComboBox.setItemData(0, devices[0][0], self.DeviceTypeRole) |
711 0, devices[0][0], self.DeviceTypeRole) |
716 self.devicesComboBox.setItemData(0, devices[0][2], self.DeviceVidPidRole) |
712 self.devicesComboBox.setItemData( |
|
713 0, devices[0][2], self.DeviceVidPidRole) |
|
714 self.devicesComboBox.addItem(self.tr("Manual Select")) |
717 self.devicesComboBox.addItem(self.tr("Manual Select")) |
715 self.devicesComboBox.setItemData(1, self.__manualType, |
718 self.devicesComboBox.setItemData(1, self.__manualType, self.DeviceTypeRole) |
716 self.DeviceTypeRole) |
|
717 self.on_devicesComboBox_currentIndexChanged(0) |
719 self.on_devicesComboBox_currentIndexChanged(0) |
718 else: |
720 else: |
719 self.devicesComboBox.addItem("") |
721 self.devicesComboBox.addItem("") |
720 for index, (boardType, description, |
722 for index, (boardType, description, vidpid) in enumerate( |
721 vidpid) in enumerate(sorted(devices), 1): |
723 sorted(devices), 1 |
|
724 ): |
722 self.devicesComboBox.addItem(description) |
725 self.devicesComboBox.addItem(description) |
723 self.devicesComboBox.setItemData( |
726 self.devicesComboBox.setItemData(index, boardType, self.DeviceTypeRole) |
724 index, boardType, self.DeviceTypeRole) |
727 self.devicesComboBox.setItemData(index, vidpid, self.DeviceVidPidRole) |
725 self.devicesComboBox.setItemData( |
|
726 index, vidpid, self.DeviceVidPidRole) |
|
727 self.devicesComboBox.addItem(self.tr("Manual Select")) |
728 self.devicesComboBox.addItem(self.tr("Manual Select")) |
728 self.devicesComboBox.setItemData(index + 1, self.__manualType, |
729 self.devicesComboBox.setItemData( |
729 self.DeviceTypeRole) |
730 index + 1, self.__manualType, self.DeviceTypeRole |
730 |
731 ) |
|
732 |
731 # reselect the remembered device, if it is still there |
733 # reselect the remembered device, if it is still there |
732 if currentDevice: |
734 if currentDevice: |
733 self.devicesComboBox.setCurrentText(currentDevice) |
735 self.devicesComboBox.setCurrentText(currentDevice) |
734 self.firmwarePicker.setText(firmwareFile) |
736 self.firmwarePicker.setText(firmwareFile) |
735 else: |
737 else: |
736 self.devicesComboBox.setCurrentIndex(0) |
738 self.devicesComboBox.setCurrentIndex(0) |
737 |
739 |
738 def __updateFlashButton(self): |
740 def __updateFlashButton(self): |
739 """ |
741 """ |
740 Private method to update the state of the Flash button and the retest |
742 Private method to update the state of the Flash button and the retest |
741 button. |
743 button. |
742 """ |
744 """ |
929 firmwarePath = self.firmwarePicker.text() |
924 firmwarePath = self.firmwarePicker.text() |
930 volumePath = self.bootPicker.text() |
925 volumePath = self.bootPicker.text() |
931 if os.path.exists(firmwarePath) and os.path.exists(volumePath): |
926 if os.path.exists(firmwarePath) and os.path.exists(volumePath): |
932 if boardType == self.__manualType: |
927 if boardType == self.__manualType: |
933 self.infoLabel.setText(self.tr("Flashing Firmware")) |
928 self.infoLabel.setText(self.tr("Flashing Firmware")) |
934 self.infoEdit.setHtml(self.tr( |
929 self.infoEdit.setHtml( |
935 "<p>Flashing the selected firmware to the device. Please" |
930 self.tr( |
936 " wait until the device resets automatically.</p>") |
931 "<p>Flashing the selected firmware to the device. Please" |
|
932 " wait until the device resets automatically.</p>" |
|
933 ) |
937 ) |
934 ) |
938 else: |
935 else: |
939 firmwareType = SupportedUF2Boards[boardType]["firmware"] |
936 firmwareType = SupportedUF2Boards[boardType]["firmware"] |
940 self.infoLabel.setText( |
937 self.infoLabel.setText(self.tr("Flashing {0}").format(firmwareType)) |
941 self.tr("Flashing {0}").format(firmwareType)) |
938 self.infoEdit.setHtml( |
942 self.infoEdit.setHtml(self.tr( |
939 self.tr( |
943 "<p>Flashing the {0} firmware to the device. Please wait" |
940 "<p>Flashing the {0} firmware to the device. Please wait" |
944 " until the device resets automatically.</p>" |
941 " until the device resets automatically.</p>" |
945 ).format(firmwareType)) |
942 ).format(firmwareType) |
|
943 ) |
946 QCoreApplication.processEvents( |
944 QCoreApplication.processEvents( |
947 QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents) |
945 QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents |
|
946 ) |
948 shutil.copy2(firmwarePath, volumePath) |
947 shutil.copy2(firmwarePath, volumePath) |
949 QThread.sleep(1) |
948 QThread.sleep(1) |
950 self.on_refreshButton_clicked() |
949 self.on_refreshButton_clicked() |
951 |
950 |
952 @pyqtSlot() |
951 @pyqtSlot() |
953 def on_refreshButton_clicked(self): |
952 def on_refreshButton_clicked(self): |
954 """ |
953 """ |
955 Private slot to refresh the dialog. |
954 Private slot to refresh the dialog. |
956 """ |
955 """ |
957 # special treatment for RPi Pico |
956 # special treatment for RPi Pico |
958 if self.__boardType == "circuitpython_rp2040": |
957 if self.__boardType == "circuitpython_rp2040": |
959 self.__boardType = "rp2040" |
958 self.__boardType = "rp2040" |
960 |
959 |
961 self.__populate() |
960 self.__populate() |
962 |
961 |
963 @pyqtSlot(int) |
962 @pyqtSlot(int) |
964 def on_devicesComboBox_currentIndexChanged(self, index): |
963 def on_devicesComboBox_currentIndexChanged(self, index): |
965 """ |
964 """ |
966 Private slot to handle the selection of a board. |
965 Private slot to handle the selection of a board. |
967 |
966 |
968 @param index selected index |
967 @param index selected index |
969 @type int |
968 @type int |
970 """ |
969 """ |
971 vidpid = self.devicesComboBox.itemData(index, self.DeviceVidPidRole) |
970 vidpid = self.devicesComboBox.itemData(index, self.DeviceVidPidRole) |
972 boardType = self.devicesComboBox.itemData(index, self.DeviceTypeRole) |
971 boardType = self.devicesComboBox.itemData(index, self.DeviceTypeRole) |
973 |
972 |
974 self.bootPicker.setEnabled(boardType == self.__manualType) |
973 self.bootPicker.setEnabled(boardType == self.__manualType) |
975 if boardType == self.__manualType: |
974 if boardType == self.__manualType: |
976 self.__showManualInstructions() |
975 self.__showManualInstructions() |
977 |
976 |
978 if vidpid is None: |
977 if vidpid is None: |
979 if boardType is None: |
978 if boardType is None: |
980 self.bootPicker.clear() |
979 self.bootPicker.clear() |
981 else: |
980 else: |
982 volumes = SupportedUF2Boards[boardType]["volumes"][vidpid] |
981 volumes = SupportedUF2Boards[boardType]["volumes"][vidpid] |
983 foundVolumes = [] |
982 foundVolumes = [] |
984 for volume in volumes: |
983 for volume in volumes: |
985 foundVolumes += Utilities.findVolume(volume, findAll=True) |
984 foundVolumes += Utilities.findVolume(volume, findAll=True) |
986 |
985 |
987 if len(foundVolumes) == 0: |
986 if len(foundVolumes) == 0: |
988 self.__showNoVolumeInformation(volumes, boardType) |
987 self.__showNoVolumeInformation(volumes, boardType) |
989 self.bootPicker.clear() |
988 self.bootPicker.clear() |
990 elif len(foundVolumes) == 1: |
989 elif len(foundVolumes) == 1: |
991 self.bootPicker.setText(foundVolumes[0]) |
990 self.bootPicker.setText(foundVolumes[0]) |
992 else: |
991 else: |
993 self.__showMultipleVolumesInformation() |
992 self.__showMultipleVolumesInformation() |
994 self.bootPicker.clear() |
993 self.bootPicker.clear() |
995 |
994 |
996 self.__updateFlashButton() |
995 self.__updateFlashButton() |
997 |
996 |
998 @pyqtSlot(str) |
997 @pyqtSlot(str) |
999 def on_firmwarePicker_textChanged(self, text): |
998 def on_firmwarePicker_textChanged(self, text): |
1000 """ |
999 """ |
1001 Private slot handling a change of the firmware file. |
1000 Private slot handling a change of the firmware file. |
1002 |
1001 |
1003 @param text current text of the firmware edit |
1002 @param text current text of the firmware edit |
1004 @type str |
1003 @type str |
1005 """ |
1004 """ |
1006 self.__updateFlashButton() |
1005 self.__updateFlashButton() |
1007 |
1006 |
1008 @pyqtSlot(str) |
1007 @pyqtSlot(str) |
1009 def on_bootPicker_textChanged(self, text): |
1008 def on_bootPicker_textChanged(self, text): |
1010 """ |
1009 """ |
1011 Private slot handling a change of the boot volume. |
1010 Private slot handling a change of the boot volume. |
1012 |
1011 |
1013 @param text current text of the boot volume edit |
1012 @param text current text of the boot volume edit |
1014 @type str |
1013 @type str |
1015 """ |
1014 """ |
1016 self.__updateFlashButton() |
1015 self.__updateFlashButton() |