src/eric7/MicroPython/Devices/__init__.py

branch
eric7
changeset 9756
9854647c8c5c
child 9765
6378da868bb0
equal deleted inserted replaced
9755:1a09700229e7 9756:9854647c8c5c
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Package containing the device interface modules and device specific dialogs.
8 """
9
10 import contextlib
11 import importlib
12 import logging
13
14 from PyQt6.QtCore import QCoreApplication
15 from PyQt6.QtSerialPort import QSerialPortInfo
16
17 from eric7 import Preferences
18 from eric7.EricGui import EricPixmapCache
19
20 from .DeviceBase import BaseDevice
21
22 SupportedBoards = {
23 "bbc_microbit": {
24 "ids": [
25 (0x0D28, 0x0204), # micro:bit
26 ],
27 "description": "BBC micro:bit",
28 "icon": "microbitDevice",
29 "port_description": "BBC micro:bit CMSIS-DAP",
30 "module": ".MicrobitDevices",
31 },
32 "calliope": {
33 "ids": [
34 (0x0D28, 0x0204), # Calliope mini
35 ],
36 "description": "Calliope mini",
37 "icon": "calliope_mini",
38 "port_description": "DAPLink CMSIS-DAP",
39 "module": ".MicrobitDevices",
40 },
41 "circuitpython": {
42 "ids": [
43 (0x0483, 0x572A), # STMicroelectronics NUCLEO-F446RE - CPy
44 (0x04D8, 0xE799), # Cytron Maker Zero SAMD21
45 (0x04D8, 0xEA2A), # BHDynamics DynaLoRa_USB
46 (0x04D8, 0xEAD1), # BH Dynamics DynOSSAT-EDU-EPS-v1.0
47 (0x04D8, 0xEAD2), # BH Dynamics DynOSSAT-EDU-OBC-v1.0
48 (0x04D8, 0xEC44), # maholli PyCubed
49 (0x04D8, 0xEC63), # Kevin Neubauer CircuitBrains Basic
50 (0x04D8, 0xEC64), # Kevin Neubauer CircuitBrains Deluxe
51 (0x04D8, 0xEC72), # XinaBox CC03
52 (0x04D8, 0xEC75), # XinaBox CS11
53 (0x04D8, 0xED5F), # Itaca Innovation uChip CircuitPython
54 (0x04D8, 0xED94), # maholli kicksat-sprite
55 (0x04D8, 0xEDB3), # Capable Robot Programmable USB Hub
56 (0x04D8, 0xEDBE), # maholli SAM32
57 (0x04D8, 0xEE8C), # J&J Studios LLC datum-Distance
58 (0x04D8, 0xEE8D), # J&J Studios LLC datum-IMU
59 (0x04D8, 0xEE8E), # J&J Studios LLC datum-Light
60 (0x04D8, 0xEE8F), # J&J Studios LLC datum-Weather
61 (0x04D8, 0xEF67), # senseBox MCU
62 (0x054C, 0x0BC2), # Sony Spresense
63 (0x1209, 0x2017), # Benjamin Shockley Mini SAM M4
64 (0x1209, 0x3141), # CrumpSpace CrumpS2
65 (0x1209, 0x3252), # Targett Module Clip w/Wroom
66 (0x1209, 0x3253), # Targett Module Clip w/Wrover
67 (0x1209, 0x4203), # 42. Keebs Frood
68 (0x1209, 0x4D43), # Robotics Masters Robo HAT MM1 M4
69 (0x1209, 0x4DDD), # ODT CP Sapling
70 (0x1209, 0x4DDE), # ODT CP Sapling M0 w/ SPI Flash
71 (0x1209, 0x4DDF), # ODT CP Sapling Rev B
72 (0x1209, 0x4DF0), # Oak Dev Tech Pixelwing ESP32S2
73 (0x1209, 0x4DF1), # Oak Dev Tech BREAD2040
74 (0x1209, 0x4DF2), # Oak Dev Tech CAST AWAY RP2040
75 (0x1209, 0x5A52), # ZRichard RP2.65-F
76 (0x1209, 0x5BF0), # Foosn Fomu
77 (0x1209, 0x7150), # Electronic Cats Hunter Cat NFC
78 (0x1209, 0x7382), # Invector Labs AB iLabs Challenger 840
79 (0x1209, 0x805A), # Electronic Cats BastBLE
80 (0x1209, 0x8CAE), # takayoshiotake Octave RP2040
81 (0x1209, 0xA182), # Solder Party RP2040 Stamp
82 (0x1209, 0xB182), # Solder Party BBQ20 Keyboard
83 (0x1209, 0xBAB0), # Electronic Cats Bast WiFi
84 (0x1209, 0xBAB1), # Electronic Cats Meow Meow
85 (0x1209, 0xBAB2), # Electronic Cats CatWAN USBStick
86 (0x1209, 0xBAB3), # Electronic Cats Bast Pro Mini M0
87 (0x1209, 0xBAB6), # Electronic Cats Escornabot Makech
88 (0x1209, 0xBAB8), # Electronic Cats NFC Copy Cat
89 (0x1209, 0xC051), # Betrusted Simmel
90 (0x1209, 0xCB74), # 0xCB Helios
91 (0x1209, 0xD10D), # Diodes Delight Piunora
92 (0x1209, 0xD1B5), # Radomir Dopieralski PewPew LCD
93 (0x1209, 0xE3E3), # StackRduino M0 PRO
94 (0x1209, 0xEF00), # 2231puppy E-Fidget
95 (0x1209, 0xF123), # Electrolama minik
96 (0x1209, 0xF500), # Silicognition LLC M4-Shim
97 (0x1209, 0xF502), # Silicognition LLC RP2040-Shim
98 (0x16D0, 0x08C6), # Pimoroni Keybow 2040
99 (0x16D0, 0x08C7), # Pimoroni Tiny 2040 (8MB)
100 (0x16D0, 0x08C8), # Pimoroni PicoSystem
101 (0x16D0, 0x10ED), # Mechwild PillBug
102 (0x1915, 0xB001), # Makerdiary Pitaya Go
103 (0x192F, 0xB1B2), # WarmBit BluePixel nRF52840
104 (0x1B4F, 0x0015), # SparkFun RedBoard Turbo Board
105 (0x1B4F, 0x0016), # SparkFun SAMD51 Thing+
106 (0x1B4F, 0x0017), # SparkFun LUMIDrive Board
107 (0x1B4F, 0x0020), # SparkFun MicroMod SAMD51 Processor
108 (0x1B4F, 0x0021), # SparkFun MicroMod nRF52840 Processor
109 (0x1B4F, 0x0024), # SparkFun MicroMod RP2040 Processor
110 (0x1B4F, 0x0025), # SparkFun Thing Plus RP2040
111 (0x1B4F, 0x0026), # SparkFun Pro Micro RP2040
112 (0x1B4F, 0x0027), # SparkFun STM32 MicroMod Processor
113 (0x1B4F, 0x0028), # SparkFun Thing Plus - STM32
114 (0x1B4F, 0x002E), # PJRC/Sparkfun Teensy MicroMod
115 (0x1B4F, 0x5289), # SparkFun SFE_nRF52840_Mini
116 (0x1B4F, 0x8D22), # SparkFun SAMD21 Mini Breakout
117 (0x1B4F, 0x8D23), # SparkFun SAMD21 Dev Breakout
118 (0x1B4F, 0x8D24), # SparkFun Qwiic Micro
119 (0x1D50, 0x60E8), # Radomir Dopieralski PewPew M4
120 (0x1D50, 0x6152), # nrf52.jpconstantineau.com BlueMicro833
121 (0x1D50, 0x6153), # JPConstantineau PyKey18
122 (0x1D50, 0x6153), # JPConstantineau PyKey44
123 (0x1D50, 0x6153), # JPConstantineau PyKey60
124 (0x1D50, 0x6153), # JPConstantineau PyKey87
125 (0x1D50, 0x6154), # JPConstantineau EncoderPad RP2040
126 (0x1D50, 0x6161), # nrf52.jpconstantineau.com BlueMicro840
127 (0x2019, 0x7103), # Benjamin Shockley Fig Pi
128 (0x2341, 0x8053), # Arduino MKR1300
129 (0x2341, 0x8057), # Arduino Nano 33 IoT
130 (0x2341, 0x805A), # Arduino Arduino_Nano_33_BLE
131 (0x2341, 0x824D), # Arduino Zero
132 (0x2786, 0x9207), # Switch Sc. BLE-SS dev board Multi Sensor
133 (0x2786, 0x920D), # Switch Sc. SSCI ISP1807 Dev Board
134 (0x2786, 0x920F), # Switch Sc. SSCI ISP1807 Micro Board
135 (0x2886, 0x002F), # Seeed Seeeduino XIAO
136 (0x2886, 0x0042), # Seeed Seeeduino XIAO RP2040
137 (0x2886, 0x0045), # Seeed XIAO nRF52840 Sense
138 (0x2886, 0x802D), # Seeed Seeeduino Wio Terminal
139 (0x2886, 0x802F), # Seeed Seeeduino XIAO KB
140 (0x2886, 0xF001), # Makerdiary nRF52840 M.2 Developer Kit
141 (0x2886, 0xF002), # Makerdiary M60 Keyboard
142 (0x2B04, 0xC00C), # Particle Argon
143 (0x2B04, 0xC00D), # Particle Boron
144 (0x2B04, 0xC00E), # Particle Xenon
145 (0x2E8A, 0x1000), # Cytron Maker Pi RP2040
146 (0x2E8A, 0x1002), # Pimoroni Pico LiPo (4MB)
147 (0x2E8A, 0x1003), # Pimoroni Pico LiPo (16MB)
148 (0x2E8A, 0x1005), # Melopero Shake RP2040
149 (0x2E8A, 0x1006), # Invector Labs Challenger RP2040 WiFi
150 (0x2E8A, 0x1008), # Pimoroni PGA2040
151 (0x2E8A, 0x1009), # Pimoroni Interstate 75
152 (0x2E8A, 0x100A), # Pimoroni Plasma 2040
153 (0x2E8A, 0x100B), # Invector Labs Challenger RP2040 LTE
154 (0x2E8A, 0x100D), # Invector Labs Challenger NB RP2040 WiFi
155 (0x2E8A, 0x100E), # Raspberry Pi Zero
156 (0x2E8A, 0x100F), # Cytron Maker Nano RP2040
157 (0x2E8A, 0x1012), # Raspberry Pi Compute Module 4 IO Board
158 (0x2E8A, 0x1013), # Raspberry Pi 4B
159 (0x2E8A, 0x1014), # Raspberry Pi Compute Module 4
160 (0x2E8A, 0x1015), # Raspberry Pi Zero 2W
161 (0x2E8A, 0x1016), # Pimoroni Tiny 2040 (2MB)
162 (0x2E8A, 0x1019), # Pimoroni Motor 2040
163 (0x2E8A, 0x101A), # Pimoroni Servo 2040
164 (0x2E8A, 0x101B), # Pimoroni Badger 2040
165 (0x2E8A, 0x101E), # Raspberry Pi Zero W
166 (0x2E8A, 0x101F), # Waveshare Electronics RP2040-Zero
167 (0x2E8A, 0x1023), # Invector Labs Challenger RP2040 LoRa
168 (0x2E8A, 0x1026), # ELECFREAKS Pico:ed
169 (0x2E8A, 0x1027), # WIZnet W5100S-EVB-Pico
170 (0x2E8A, 0x1029), # WIZnet W5500-EVB-Pico
171 (0x2E8A, 0x102C), # Invector Labs Challenger RP2040 WiFi/BLE
172 (0x2E8A, 0x102D), # Invector Labs Challenger RP2040 SD/RTC
173 (0x2E8A, 0x102E), # VCC-GND Studio YD-RP2040
174 (0x2E8A, 0x1032), # Invector Labs Challenger RP2040 SubGHz
175 (0x2E8A, 0x1039), # Waveshare Electronics Waveshare RP2040-LCD-1.28
176 (0x2E8A, 0x1048), # nullbits Bit-C PRO
177 (0x303A, 0x7001), # Espressif ESP32-S2-HMI-DevKit-1
178 (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1
179 (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N32R8
180 (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N8
181 (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N8R2
182 (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-N8R8
183 (0x303A, 0x7003), # Espressif ESP32-S3-DevKitC-1-nopsram
184 (0x303A, 0x7005), # Espressif ESP32-S3-Box-2.5
185 (0x303A, 0x7007), # Espressif ESP32-S3-DevKitM-1-N8
186 (0x303A, 0x7009), # Espressif ESP32-S2-DevKitC-1-N4
187 (0x303A, 0x7009), # Espressif ESP32-S2-DevKitC-1-N4R2
188 (0x303A, 0x7009), # Espressif ESP32-S2-DevKitC-1-N8R2
189 (0x303A, 0x700B), # Espressif ESP32-S3-USB-OTG-N8
190 (0x303A, 0x700D), # Espressif ESP32-S3-Box-Lite
191 (0x303A, 0x700F), # Espressif ESP32-S3-EYE
192 (0x303A, 0x8002), # UnexpectedMaker TinyS2
193 (0x303A, 0x8007), # LILYGO TTGO T8 ESP32-S2
194 (0x303A, 0x800D), # Gravitech Cucumber RS
195 (0x303A, 0x80A1), # Gravitech Cucumber R
196 (0x303A, 0x80A4), # Gravitech Cucumber M
197 (0x303A, 0x80A7), # Gravitech Cucumber MS
198 (0x303A, 0x80AA), # Espressif Franzininho WIFI w/Wroom
199 (0x303A, 0x80AD), # Espressif Franzininho WIFI w/Wrover
200 (0x303A, 0x80AF), # Artisense Reference Design RD00
201 (0x303A, 0x80B2), # Muselab nanoESP32-S2 w/Wrover
202 (0x303A, 0x80B5), # UnexpectedMaker FeatherS2 Neo
203 (0x303A, 0x80B7), # MORPHEANS MORPHESP-240
204 (0x303A, 0x80C3), # Lolin S2 Mini
205 (0x303A, 0x80C6), # Lolin S2 Pico
206 (0x303A, 0x80D1), # UnexpectedMaker TinyS3
207 (0x303A, 0x80D4), # UnexpectedMaker ProS3
208 (0x303A, 0x80D7), # UnexpectedMaker FeatherS3
209 (0x303A, 0x80D9), # FutureKeys HexKy_S2
210 (0x303A, 0x80E0), # BananaPi BPI-Leaf-S3
211 (0x303A, 0x80E6), # BananaPi BPI-Bit-S2
212 (0x303A, 0x80E8), # HiiBot IoTs2
213 (0x303A, 0x80EA), # LILYGO TTGO T8 ESP32-S2-WROOM
214 (0x303A, 0x80ED), # LILYGO TTGO T8 ESP32-S2
215 (0x303A, 0x80F9), # Cytron Maker Feather AIoT S3
216 (0x303A, 0x80FC), # Espressif MixGo CE
217 (0x303A, 0x80FD), # Espressif MixGo CE
218 (0x303A, 0x810A), # Waveshare Electronics ESP32-S2-Pico
219 (0x303A, 0x810C), # Waveshare Electronics ESP32-S2-Pico-LCD
220 (0x303A, 0x8111), # Smart Bee Designs Bee-S3
221 (0x303A, 0x8114), # Smart Bee Designs Bee-Motion-S3
222 (0x303A, 0x8117), # WEMOS LOLIN S3 16MB Flash 8MB PSRAM
223 (0x303A, 0x812C), # BananaPi BPI-PicoW-S3
224 (0x30A4, 0x0002), # Blues Inc. Swan R5
225 (0x3171, 0x0101), # 8086.net Commander
226 (0x31E2, 0x2001), # BDMICRO LLC VINA-D21
227 (0x31E2, 0x2011), # BDMICRO LLC VINA-D51
228 (0x31E2, 0x2021), # BDMICRO LLC VINA-D51
229 (0x32BD, 0x3001), # Alorium Tech. AloriumTech Evo M51
230 (0x4097, 0x0001), # TG-Boards Datalore IP M4
231 (0x612B, 0x80A7), # Ai-Thinker ESP 12k NodeMCU
232 (0x239A, None), # Any Adafruit Boards
233 ],
234 "description": "CircuitPython",
235 "icon": "circuitPythonDevice",
236 "port_description": "",
237 "module": ".CircuitPythonDevices",
238 },
239 "esp": {
240 "ids": [
241 (0x0403, 0x6001), # M5Stack ESP32 device"),
242 (0x0403, 0x6001), # FT232/FT245 (XinaBox CW01, CW02)
243 (0x0403, 0x6010), # FT2232C/D/L/HL/Q (ESP-WROVER-KIT)
244 (0x0403, 0x6011), # FT4232
245 (0x0403, 0x6014), # FT232H
246 (0x0403, 0x6015), # Sparkfun ESP32
247 (0x0403, 0x601C), # FT4222H
248 (0x10C4, 0xEA60), # CP210x
249 (0x1A86, 0x55D4), # CH343
250 (0x1A86, 0x7523), # HL-340, CH340
251 ],
252 "description": "ESP32, ESP8266",
253 "icon": "esp32Device",
254 "port_description": "",
255 "module": ".EspDevices",
256 },
257 "generic": {
258 # only manually configured devices use this
259 "ids": [],
260 "description": QCoreApplication.translate("MicroPythonDevice", "Generic Board"),
261 "icon": "micropython48",
262 "port_description": "",
263 "module": ".GenericMicroPythonDevices",
264 },
265 "pyboard": {
266 "ids": [
267 (0xF055, 0x9800), # Pyboard in CDC mode
268 (0xF055, 0x9801), # Pyboard in CDC+HID mode
269 (0xF055, 0x9802), # Pyboard in CDC+MSC mode
270 ],
271 "description": "PyBoard",
272 "icon": "micropython48",
273 "port_description": "Pyboard",
274 "module": ".PyBoardDevices",
275 },
276 "rp2040": {
277 "ids": [
278 (0x2E8A, 0x0005), # Raspberry Pi Pico
279 ],
280 "description": QCoreApplication.translate("MicroPythonDevice", "RP2040 based"),
281 "icon": "rp2040Device",
282 "port_description": "",
283 "module": ".RP2040Devices",
284 },
285 "teensy": {
286 "ids": [
287 (0xF055, 0x9802), # Pyboard in CDC+MSC mode
288 ],
289 "description": "Teensy",
290 "icon": "micropython48",
291 "port_description": "Teensy",
292 "module": ".TeensyDevices",
293 },
294 }
295
296 IgnoredBoards = (
297 (0x8086, 0x9C3D),
298 (0x8086, None),
299 )
300
301 FirmwareGithubUrls = {
302 "micropython": "https://github.com/micropython/micropython/releases/latest",
303 "circuitpython": "https://github.com/adafruit/circuitpython/releases/latest",
304 "pimoroni_pico": "https://github.com/pimoroni/pimoroni-pico/releases/latest",
305 "microbit_v1": "https://github.com/bbcmicrobit/micropython/releases/latest",
306 "microbit_v2": (
307 "https://github.com/microbit-foundation/micropython-microbit-v2/releases/latest"
308 ),
309 }
310
311
312 def getSupportedDevices():
313 """
314 Function to get a list of supported MicroPython devices.
315
316 @return set of tuples with the board type and description
317 @rtype set of tuples of (str, str)
318 """
319 boards = []
320 for board in SupportedBoards:
321 boards.append((board, SupportedBoards[board]["description"]))
322 return boards
323
324
325 def getFoundDevices():
326 """
327 Function to check the serial ports for supported MicroPython devices.
328
329 @return tuple containing a list of tuples with the board type, the port
330 description, a description, the serial port it is connected at, the
331 VID and PID for known device types, a list of tuples with VID, PID
332 and description for unknown devices and a list of tuples with VID,
333 PID, description and port name for ports with missing VID or PID
334 @rtype tuple of (list of tuples of (str, str, str, str, int, int),
335 list of tuples of (int, int, str),
336 list of tuples of (int, int, str, str)
337 """
338 foundDevices = []
339 unknownDevices = []
340 unknownPorts = []
341
342 manualDevices = {}
343 for deviceDict in Preferences.getMicroPython("ManualDevices"):
344 manualDevices[(deviceDict["vid"], deviceDict["pid"])] = deviceDict
345
346 availablePorts = QSerialPortInfo.availablePorts()
347 for port in availablePorts:
348 if port.hasVendorIdentifier() and port.hasProductIdentifier():
349 supported = False
350 vid = port.vendorIdentifier()
351 pid = port.productIdentifier()
352
353 for board in SupportedBoards:
354 if (vid, pid) in SupportedBoards[board]["ids"] or (
355 vid,
356 None,
357 ) in SupportedBoards[board]["ids"]:
358 if board in ("bbc_microbit", "calliope") and (
359 port.description().strip()
360 != SupportedBoards[board]["port_description"]
361 ):
362 # both boards have the same VID and PID
363 # try to differentiate based on port description
364 continue
365 elif board in ("pyboard", "teensy") and (
366 not port.description().startswith(
367 SupportedBoards[board]["port_description"]
368 )
369 ):
370 # both boards have the same VID and PID
371 # try to differentiate based on port description
372 continue
373 foundDevices.append(
374 (
375 board,
376 port.description(),
377 SupportedBoards[board]["description"],
378 port.portName(),
379 vid,
380 pid,
381 port.serialNumber(),
382 )
383 )
384 supported = True
385 if not supported and (vid, pid) in manualDevices:
386 # check the locally added ones next
387 board = manualDevices[(vid, pid)]["type"]
388 foundDevices.append(
389 (
390 board,
391 port.description(),
392 SupportedBoards[board]["description"],
393 port.portName(),
394 vid,
395 pid,
396 port.serialNumber(),
397 )
398 )
399 supported = True
400 if not supported:
401 if vid and pid:
402 if (vid, pid) not in IgnoredBoards and (
403 vid,
404 None,
405 ) not in IgnoredBoards:
406 unknownDevices.append((vid, pid, port.description()))
407 logging.debug(
408 "Unknown device: (0x%04x:0x%04x %s)",
409 vid,
410 pid,
411 port.description(),
412 )
413 else:
414 # either VID or PID or both not detected
415 desc = port.description()
416 if not desc:
417 desc = QCoreApplication.translate(
418 "MicroPythonDevice", "Unknown Device"
419 )
420 unknownPorts.append((vid, pid, desc, port.portName()))
421
422 elif bool(port.portName()) and Preferences.getMicroPython(
423 "EnableManualDeviceSelection"
424 ):
425 # no VID and/or PID available (e.g. in Linux container of ChromeOS)
426 desc = port.description()
427 if not desc:
428 desc = QCoreApplication.translate("MicroPythonDevice", "Unknown Device")
429 unknownPorts.append((0, 0, desc, port.portName()))
430
431 return foundDevices, unknownDevices, unknownPorts
432
433
434 def getDeviceIcon(boardName, iconFormat=True):
435 """
436 Function to get the icon for the given board.
437
438 @param boardName name of the board
439 @type str
440 @param iconFormat flag indicating to get an icon or a pixmap
441 @type bool
442 @return icon for the board (iconFormat == True) or
443 a pixmap (iconFormat == False)
444 @rtype QIcon or QPixmap
445 """
446 iconName = (
447 SupportedBoards[boardName]["icon"]
448 if boardName in SupportedBoards
449 else
450 # return a generic MicroPython icon
451 "micropython48"
452 )
453
454 if iconFormat:
455 return EricPixmapCache.getIcon(iconName)
456 else:
457 return EricPixmapCache.getPixmap(iconName)
458
459
460 def getDevice(deviceType, microPythonWidget, vid, pid, boardName="", serialNumber=""):
461 """
462 Public method to instantiate a specific MicroPython device interface.
463
464 @param deviceType type of the device interface
465 @type str
466 @param microPythonWidget reference to the main MicroPython widget
467 @type MicroPythonWidget
468 @param vid vendor ID (only used for deviceType 'generic')
469 @type int
470 @param pid product ID (only used for deviceType 'generic')
471 @type int
472 @param boardName name of the board (defaults to "")
473 @type str (optional)
474 @param serialNumber serial number of the board (defaults to "")
475 @type str (optional)
476 @return instantiated device interface
477 @rtype BaseDevice
478 """
479
480 with contextlib.suppress(KeyError):
481 mod = importlib.import_module(
482 SupportedBoards[deviceType]["module"], __package__
483 )
484 if mod:
485 return mod.createDevice(
486 microPythonWidget, deviceType, vid, pid, boardName, serialNumber
487 )
488
489 # nothing specific requested or specific one failed or is not supported yet
490 return BaseDevice(microPythonWidget, deviceType)

eric ide

mercurial