--- a/src/eric7/MicroPython/UF2FlashDialog.py Thu Mar 20 11:54:57 2025 +0100 +++ b/src/eric7/MicroPython/UF2FlashDialog.py Thu Mar 20 19:31:39 2025 +0100 @@ -12,7 +12,6 @@ import shutil from PyQt6.QtCore import QCoreApplication, QEventLoop, Qt, QThread, pyqtSlot -from PyQt6.QtSerialPort import QSerialPortInfo from PyQt6.QtWidgets import QDialog, QInputDialog from eric7.EricGui import EricPixmapCache @@ -28,7 +27,7 @@ import usb.core SupportedUF2Boards = { - "circuitpython": { + "MPy or CPy": { "volumes": { (0x03EB, 0x2402): [ ("SAMD21", "SAMD21 Board"), @@ -778,48 +777,15 @@ "</ol>", ), "show_all": True, - "firmware": "CircuitPython", - }, - "nrf52": { - "volumes": { - (0x239A, 0x0029): [ - ("FTHR840BOOT", "Feather nRF52840 Express"), - ("MDK840DONGL", "MDK nRF52840 USB Dongle"), - ], - (0x239A, 0x0063): [ - ("NANO33BOOT", "Nano 33 BLE"), - ], - (0x239A, 0x00DA): [ - ("XENONBOOT ", "Particle Xenon"), - ], - (0x2886, 0x0045): [ - ("XIAO-SENSE", "XIAO nRF52840 Sense"), - ], - }, - "instructions": QCoreApplication.translate( - "UF2FlashDialog", - "<h3>NRF52 Board</h3>" - "<p>In order to prepare the board for flashing follow these" - " steps:</p><ol>" - "<li>Switch your device to 'bootloader' mode by double-pressing" - " the reset button.</li>" - "<li>Wait until the device has entered 'bootloader' mode.</li>" - "<li>(If this does not happen, then try shorter or longer" - " pauses between presses.)</li>" - "<li>Ensure the boot volume is available (this may require" - " mounting it).</li>" - "<li>Select the firmware file to be flashed and click the" - " flash button.</li>" - "</ol>", - ), - "show_all": True, "firmware": "MicroPython / CircuitPython", }, - "rp2": { + "RP2": { "volumes": { - (0x0000, 0x0000): [ - ("RPI-RP2", "Raspberry Pi Pico"), # we don't have valid VID/PID - ("RP2350", "Raspberry Pi Pico 2"), # we don't have valid VID/PID + (0x2E8A, 0x0003): [ + ("RPI-RP2", "Raspberry Pi Pico"), + ], + (0x2E8A, 0x000F): [ + ("RP2350", "Raspberry Pi Pico 2"), ], }, "instructions": QCoreApplication.translate( @@ -893,14 +859,9 @@ foundDevices.discard((board, description, vidpid)) # step 2: determine all devices that have their UF2 volume not mounted - availablePorts = QSerialPortInfo.availablePorts() - for port in availablePorts: - vid = port.vendorIdentifier() - pid = port.productIdentifier() - - if vid == 0 and pid == 0: - # no device detected at port - continue + for device in usb.core.find(find_all=True): + vid = device.idVendor + pid = device.idProduct for board in SupportedUF2Boards: if (not boardType or (board.startswith(boardType))) and ( @@ -911,10 +872,13 @@ if (vid, pid) == device[2]: break else: + description = ", ".join( + v[1] for v in SupportedUF2Boards[board]["volumes"][(vid, pid)] + ) foundDevices.add( ( board, - port.description(), + description, (vid, pid), ) ) @@ -1211,6 +1175,21 @@ ).format("</li><li>".join(sorted(volumePaths))) self.infoEdit.setHtml(htmlText) + def __showFlashInstruction(self): + """ + Private method to show information for the actual flashing process. + """ + self.infoLabel.setText(self.tr("Flash Instructions:")) + + htmlText = self.tr( + "<h4>Flash selected device.</h4>" + "<p>Follow the instructions below to flash the selected device.</p><ol>" + "<li>Select the firmware file to be flashed.</li>" + "<li>Click the flash button.</li>" + "</ol>" + ) + self.infoEdit.setHtml(htmlText) + @pyqtSlot() def on_flashButton_clicked(self): """ @@ -1253,7 +1232,6 @@ """ self.__populate() self.__updateFlashButton() - self.on_devicesComboBox_currentIndexChanged(0) @pyqtSlot(int) def on_devicesComboBox_currentIndexChanged(self, index): @@ -1278,15 +1256,14 @@ volumes = SupportedUF2Boards[boardType]["volumes"][vidpid] foundVolumes = [] for volume, _ in volumes: - foundVolumes += FileSystemUtilities.findVolume( - volume, findAll=True, markerFile="INFO_UF2.TXT" - ) + foundVolumes += FileSystemUtilities.findVolume(volume, findAll=True) foundVolumes = list(set(foundVolumes)) # make entries unique if len(foundVolumes) == 0: self.__showNoVolumeInformation([v[0] for v in volumes], boardType) self.bootPicker.clear() elif len(foundVolumes) == 1: + self.__showFlashInstruction() self.bootPicker.setText(foundVolumes[0]) else: self.__showMultipleVolumesInformation(foundVolumes)