371 "</ol>" |
371 "</ol>" |
372 ), |
372 ), |
373 "firmware": "CircuitPython", |
373 "firmware": "CircuitPython", |
374 }, |
374 }, |
375 |
375 |
376 "rp2040": { |
376 "circuitpython_rp2040": { |
377 "volumes": { |
377 "volumes": { |
378 (0x0000, 0x0000): [ |
378 (0x239A, 0x80F4): [ |
379 "RPI-RP2", # Raspberry Pi Pico does not present a TTY |
379 "RPI-RP2", # Raspberry Pi Pico loaded with CircuitPython |
380 ], |
380 ], |
381 }, |
381 }, |
382 "instructions": QCoreApplication.translate( |
382 "instructions": QCoreApplication.translate( |
383 "UF2FlashDialog", |
383 "UF2FlashDialog", |
384 "<h3>Pi Pico (RP2040) Board</h3>" |
384 "<h3>Pi Pico (RP2040) Board</h3>" |
385 "<p>In order to prepare the board for flashing follow these" |
385 "<p>In order to prepare the board for flashing follow these" |
386 " steps:</p><ol>" |
386 " steps:</p><ol>" |
|
387 "<li>Enter 'bootloader' mode (board <b>without</b> RESET button):" |
|
388 "<ul>" |
387 "<li>Plug in your board while holding the BOOTSEL button.</li>" |
389 "<li>Plug in your board while holding the BOOTSEL button.</li>" |
|
390 "</ul>" |
|
391 "Enter 'bootloader' mode (board <b>with</b> RESET button):" |
|
392 "<ul>" |
|
393 "<li>hold down RESET</li>" |
|
394 "<li>hold down BOOTSEL</li>" |
|
395 "<li>release RESET</li>" |
|
396 "<li>release BOOTSEL</li>" |
|
397 "</ul></li>" |
|
398 "<li>Wait until the device has entered 'bootloader' mode.</li>" |
|
399 "<li>Ensure the boot volume is available (this may require" |
|
400 " mounting it).</li>" |
|
401 "<li>Select the firmware file to be flashed and click the" |
|
402 " flash button.</li>" |
|
403 "</ol>" |
|
404 ), |
|
405 "firmware": "CircuitPython", |
|
406 }, |
|
407 |
|
408 "rp2040": { |
|
409 "volumes": { |
|
410 (0x0000, 0x0000): [ |
|
411 "RPI-RP2", # Raspberry Pi Pico does not present a TTY |
|
412 ], |
|
413 }, |
|
414 "instructions": QCoreApplication.translate( |
|
415 "UF2FlashDialog", |
|
416 "<h3>Pi Pico (RP2040) Board</h3>" |
|
417 "<p>In order to prepare the board for flashing follow these" |
|
418 " steps:</p><ol>" |
|
419 "<li>Enter 'bootloader' mode (board <b>without</b> RESET button):" |
|
420 "<ul>" |
|
421 "<li>Plug in your board while holding the BOOTSEL button.</li>" |
|
422 "</ul>" |
|
423 "Enter 'bootloader' mode (board <b>with</b> RESET button):" |
|
424 "<ul>" |
|
425 "<li>hold down RESET</li>" |
|
426 "<li>hold down BOOTSEL</li>" |
|
427 "<li>release RESET</li>" |
|
428 "<li>release BOOTSEL</li>" |
|
429 "</ul></li>" |
388 "<li>Wait until the device has entered 'bootloader' mode.</li>" |
430 "<li>Wait until the device has entered 'bootloader' mode.</li>" |
389 "<li>Ensure the boot volume is available (this may require" |
431 "<li>Ensure the boot volume is available (this may require" |
390 " mounting it).</li>" |
432 " mounting it).</li>" |
391 "<li>Select the firmware file to be flashed and click the" |
433 "<li>Select the firmware file to be flashed and click the" |
392 " flash button.</li>" |
434 " flash button.</li>" |
419 if vid == 0 and pid == 0: |
461 if vid == 0 and pid == 0: |
420 # no device detected at port |
462 # no device detected at port |
421 continue |
463 continue |
422 |
464 |
423 for board in SupportedUF2Boards: |
465 for board in SupportedUF2Boards: |
424 if not boardType or (board == boardType): |
466 if not boardType or (board.startswith(boardType)): |
425 if (vid, pid) in SupportedUF2Boards[board]["volumes"]: |
467 if (vid, pid) in SupportedUF2Boards[board]["volumes"]: |
426 foundDevices.append(( |
468 foundDevices.append(( |
427 board, |
469 board, |
428 port.description(), |
470 port.description(), |
429 (vid, pid), |
471 (vid, pid), |
522 self.devicesComboBox.addItem("") |
564 self.devicesComboBox.addItem("") |
523 self.devicesComboBox.addItem(self.tr("Manual Select")) |
565 self.devicesComboBox.addItem(self.tr("Manual Select")) |
524 self.devicesComboBox.setItemData(1, self.__manualType, |
566 self.devicesComboBox.setItemData(1, self.__manualType, |
525 self.DeviceTypeRole) |
567 self.DeviceTypeRole) |
526 elif len(devices) == 1: |
568 elif len(devices) == 1: |
|
569 # set the board type to the found one |
|
570 self.__boardType = devices[0][0] |
|
571 |
527 self.devicesComboBox.addItem(devices[0][1]) |
572 self.devicesComboBox.addItem(devices[0][1]) |
528 self.devicesComboBox.setItemData( |
573 self.devicesComboBox.setItemData( |
529 0, devices[0][0], self.DeviceTypeRole) |
574 0, devices[0][0], self.DeviceTypeRole) |
530 self.devicesComboBox.setItemData( |
575 self.devicesComboBox.setItemData( |
531 0, devices[0][2], self.DeviceVidPidRole) |
576 0, devices[0][2], self.DeviceVidPidRole) |
673 ) |
718 ) |
674 for boardType in SupportedUF2Boards: |
719 for boardType in SupportedUF2Boards: |
675 htmlText += "<hr/>" + SupportedUF2Boards[boardType]["instructions"] |
720 htmlText += "<hr/>" + SupportedUF2Boards[boardType]["instructions"] |
676 self.infoEdit.setHtml(htmlText) |
721 self.infoEdit.setHtml(htmlText) |
677 |
722 |
678 def __showNoVolumeInformation(self, volumes): |
723 def __showNoVolumeInformation(self, volumes, boardType): |
679 """ |
724 """ |
680 Private method to show information about the expected boot volume(s). |
725 Private method to show information about the expected boot volume(s). |
681 |
726 |
682 @param volumes list of expected volume names |
727 @param volumes list of expected volume names |
683 @type list of str |
728 @type list of str |
|
729 @param boardType type of the board to show instructions for |
|
730 @type str |
684 """ |
731 """ |
685 self.infoLabel.setText(self.tr("Boot Volume not found:")) |
732 self.infoLabel.setText(self.tr("Boot Volume not found:")) |
686 |
733 |
687 htmlText = self.tr( |
734 htmlText = self.tr( |
688 "<h4>No Boot Volume detected.</h4>" |
735 "<h4>No Boot Volume detected.</h4>" |
698 htmlText += self.tr( |
745 htmlText += self.tr( |
699 "This volume should have one of these names.</p>" |
746 "This volume should have one of these names.</p>" |
700 "<ul><li>{0}</li></ul>" |
747 "<ul><li>{0}</li></ul>" |
701 "<p>Press <b>Refresh</b> when ready.</p>" |
748 "<p>Press <b>Refresh</b> when ready.</p>" |
702 ).format("</li><li>".join(sorted(volumes))) |
749 ).format("</li><li>".join(sorted(volumes))) |
|
750 |
|
751 if boardType: |
|
752 htmlText += self.tr( |
|
753 "<h4>Reset Instructions</h4>" |
|
754 "<p>Follow the instructions below to set the board into" |
|
755 " 'bootloader' mode. Press <b>Refresh</b> when ready.</p>" |
|
756 ) |
|
757 htmlText += "<hr/>" + SupportedUF2Boards[boardType]["instructions"] |
|
758 |
703 self.infoEdit.setHtml(htmlText) |
759 self.infoEdit.setHtml(htmlText) |
704 |
760 |
705 def __showMultipleVolumesInformation(self, volumePaths): |
761 def __showMultipleVolumesInformation(self, volumePaths): |
706 """ |
762 """ |
707 Private method to show information because multiple devices of the |
763 Private method to show information because multiple devices of the |
782 foundVolumes = [] |
842 foundVolumes = [] |
783 for volume in volumes: |
843 for volume in volumes: |
784 foundVolumes += Utilities.findVolume(volume, findAll=True) |
844 foundVolumes += Utilities.findVolume(volume, findAll=True) |
785 |
845 |
786 if len(foundVolumes) == 0: |
846 if len(foundVolumes) == 0: |
787 self.__showNoVolumeInformation(volumes) |
847 self.__showNoVolumeInformation(volumes, boardType) |
788 self.bootPicker.clear() |
848 self.bootPicker.clear() |
789 elif len(foundVolumes) == 1: |
849 elif len(foundVolumes) == 1: |
790 self.bootPicker.setText(foundVolumes[0]) |
850 self.bootPicker.setText(foundVolumes[0]) |
791 else: |
851 else: |
792 self.__showMultipleVolumesInformation() |
852 self.__showMultipleVolumesInformation() |