|
14 | 14 | AUxEsptoolEraseFlash
|
15 | 15 | from .mpremote_utils import MPRemoteSession
|
16 | 16 | from .au_act_rp2 import AUxRp2UploadRp2
|
17 |
| -from .au_act_teensy import AUxTeensyUploadTeensy, TeensyProgress |
| 17 | +from .au_act_teensy import AUxTeensyUploadTeensy |
18 | 18 | from .pyqt_utils import PopupListButton
|
19 | 19 | from .firmware_utils import FirmwareFile, resource_path, GithubFirmware
|
20 | 20 |
|
@@ -97,8 +97,6 @@ def __init__(self, parent: QWidget = None) -> None:
|
97 | 97 | # ---------------------------- Variables/Objects ------------------
|
98 | 98 | self.flashSize = 0
|
99 | 99 |
|
100 |
| - self.teensyProgress = TeensyProgress() # Progress tracking for Teensy uploads. Its done in a different way for ESP32 and RP2... |
101 |
| - |
102 | 100 | self.githubFirmware = GithubFirmware(_RELEASE_REPO, _BOARD_MANIFEST_FILE, _RESOURCE_DIRECTORY)
|
103 | 101 |
|
104 | 102 | if self.githubFirmware.offline:
|
@@ -144,13 +142,16 @@ def __init__(self, parent: QWidget = None) -> None:
|
144 | 142 |
|
145 | 143 | # Populate the device button with the list of devices from the latest release
|
146 | 144 | # Add an automatic device detection option to the list of devices
|
147 |
| - self.device_button.addIconItem(_AUTO_DETECT_DECORATOR, "Automatically detect the device", resource_path("auto_detect.png", _RESOURCE_DIRECTORY)) |
| 145 | + self.device_button.addIconItem(_AUTO_DETECT_DECORATOR, "If your board is already running MicroPython, automatically selects board.", resource_path("auto_detect.png", _RESOURCE_DIRECTORY)) |
148 | 146 |
|
149 |
| - for device, imagePath in self.githubFirmware.get_all_board_image_paths(): |
150 |
| - self.device_button.addIconItem(device, "", imagePath) |
| 147 | + for device, description, imagePath in self.githubFirmware.get_all_board_icon_info(): |
| 148 | + self.device_button.addIconItem(device, description, imagePath) |
151 | 149 |
|
152 | 150 | # Add the local firmware option to the list of firmware files
|
153 |
| - self.firmware_button.addIconItem(_LOCAL_DECORATOR, "Local firmware file", resource_path("fw_local.png", _RESOURCE_DIRECTORY)) |
| 151 | + self.firmware_button.addIconItem(_LOCAL_DECORATOR, |
| 152 | + "Manually select a firmware file from your local machine.", |
| 153 | + resource_path("fw_local.png",_RESOURCE_DIRECTORY) |
| 154 | + ) |
154 | 155 |
|
155 | 156 | # Attach the browse callback to the firmware button's textChanged signal
|
156 | 157 | self.firmware_button.textChanged.connect(self.on_fw_button_pressed)
|
@@ -296,13 +297,15 @@ def update_firmware_list(self) -> None:
|
296 | 297 |
|
297 | 298 | self.firmware_button.items.clear()
|
298 | 299 | # Add the local firmware option to the list of firmware files
|
299 |
| - self.firmware_button.addIconItem(_LOCAL_DECORATOR, "Local firmware file", resource_path("fw_local.png", _RESOURCE_DIRECTORY)) |
| 300 | + self.firmware_button.addIconItem(_LOCAL_DECORATOR, |
| 301 | + "Manually select a firmware file from your local machine.", |
| 302 | + resource_path("fw_local.png",_RESOURCE_DIRECTORY) |
| 303 | + ) |
300 | 304 |
|
301 | 305 | # Check the currently selected device item and update the firmware list accordingly
|
302 | 306 | self.firmware_button.setText(_FIRMWARE_CHOICE_DECORATOR)
|
303 | 307 | currentDevice = self.device_button.text()
|
304 | 308 | for fw in self.githubFirmware.deviceDict[currentDevice]:
|
305 |
| - # print("Adding firmware: ", fw.displayName, " for device: ", currentDevice) |
306 | 309 | self.firmware_button.addIconItem(fw.displayName, fw.description(), fw.fw_image_path())
|
307 | 310 |
|
308 | 311 | def show_user_message(self, message: str, windowTitle: str, warning = False) -> None:
|
@@ -369,16 +372,8 @@ def parse_progress(self, msg: str) -> None:
|
369 | 372 | """Parse the progress message."""
|
370 | 373 | if self.is_esp32_upload():
|
371 | 374 | self.parse_esp32_progress(msg)
|
372 |
| - elif self.is_teensy_upload(): |
373 |
| - progress = self.teensyProgress.parse_message(msg) |
374 |
| - # update the progress bar with the extracted percentage |
375 |
| - if progress is not None: |
376 |
| - if progress > 0 and progress < 100: |
377 |
| - # emit the progress signal to update the progress bar in the GUI |
378 |
| - self.sig_progress.emit(progress) |
379 | 375 |
|
380 |
| - # rp2 progress is handled down a few levels while the firmware is being uploaded. |
381 |
| - # this is because it is not a parsing of the output message but rather a manual tracking of the copy progress. |
| 376 | + # rp2 progress and teensy progress are handled down a few levels while the firmware is being uploaded. |
382 | 377 |
|
383 | 378 | @pyqtSlot(str)
|
384 | 379 | def appendMessage(self, msg: str) -> None:
|
@@ -432,6 +427,19 @@ def progress_bar_start(self, label) -> None:
|
432 | 427 |
|
433 | 428 | @pyqtSlot(int)
|
434 | 429 | def on_progress(self, progress: int) -> None:
|
| 430 | + if progress < 0: |
| 431 | + # This indicates an error from the worker. We can handle differently for different platforms. |
| 432 | + # For now, this will only happen when teensy times out waiting for the bootloader |
| 433 | + if self.is_teensy_upload(): |
| 434 | + # Open a popup warning the user that the upload failed. |
| 435 | + # Also end the upload and allow them to try again by re-enabling the back button (interface) |
| 436 | + error_message = "Teensy upload timed out waiting for the bootloader to be ready. Please try again." |
| 437 | + # If on MacOS, also inform user they need to check their "Input Monitoring" security permissions |
| 438 | + if platform.system() == "Darwin": |
| 439 | + error_message += "\n\nIf you are on MacOS, please also check your \"Input Monitoring\" security permissions for this application." |
| 440 | + self.show_user_message(error_message, "Teensy Upload Error", warning=True) |
| 441 | + self.end_upload_with_message(error_message) |
| 442 | + |
435 | 443 | self.progress_bar.setValue(progress)
|
436 | 444 |
|
437 | 445 | #--------------------------------------------------------------
|
@@ -465,15 +473,15 @@ def on_finished(self, status, action_type, job_id) -> None:
|
465 | 473 | self.writeMessage("Reset complete...")
|
466 | 474 | # Emit a signal to update the progress bar to 100%
|
467 | 475 | self.sig_progress.emit(100)
|
468 |
| - self.writeMessage("DONE: Firmware file copied to ESP32 device.\n") |
| 476 | + self.writeMessage("DONE: ESP32 Upload Job Complete.\n") |
469 | 477 | self.disable_interface(False)
|
470 | 478 |
|
471 | 479 | if action_type == AUxRp2UploadRp2.ACTION_ID:
|
472 |
| - self.end_upload_with_message("DONE: Firmware file copied to RP2 device.\n") |
| 480 | + self.end_upload_with_message("DONE: RP2 Upload Job Complete.\n") |
473 | 481 |
|
474 | 482 | if action_type == AUxTeensyUploadTeensy.ACTION_ID:
|
475 | 483 | self.sig_progress.emit(100)
|
476 |
| - self.end_upload_with_message("DONE: Firmware file copied to Teensy device.\n") |
| 484 | + self.end_upload_with_message("DONE: Teensy Upload Job Complete\n") |
477 | 485 |
|
478 | 486 | # --------------------------------------------------------------
|
479 | 487 | # on_port_combobox()
|
@@ -782,17 +790,10 @@ def end_upload_with_message(self, msg: str) -> None:
|
782 | 790 | """End the upload with a message."""
|
783 | 791 | self.writeMessage(msg)
|
784 | 792 | self.cleanup_temp()
|
785 |
| - # self.switch_to_page_one() |
786 | 793 | self.disable_interface(False)
|
787 |
| - # self.progress_bar.hide() |
788 |
| - # self.progress_label.hide() |
789 | 794 |
|
790 | 795 | def get_mpremote_session(self) -> MPRemoteSession:
|
791 | 796 | """Get an mpremote session for the current port."""
|
792 |
| - # portName = self.port_combobox.currentText() # This will be something like "USB Serial Device (COM3)" |
793 |
| - # portName = portName.split("(")[1].split(")")[0].strip() # This will be something like "COM3" and is what mpremote wants |
794 |
| - # print("Port: ", self.port_button.text()) |
795 |
| - |
796 | 797 | # check if we are on mac or linux and if so, we need to add the /dev/ prefix to the port name
|
797 | 798 | if platform.system() == "Darwin" or platform.system().startswith("Linux"):
|
798 | 799 | portName = "/dev/" + self.port_button.text()
|
@@ -820,10 +821,17 @@ def do_upload_rp2(self, fwFile = None) -> None:
|
820 | 821 |
|
821 | 822 | # Start an mpremote session for selected port
|
822 | 823 | mpr = self.get_mpremote_session()
|
| 824 | + |
| 825 | + mpr_base_platform = None |
| 826 | + |
| 827 | + # This means we have a valid mpremote session |
| 828 | + if mpr is not None: |
| 829 | + mpr_base_platform = mpr.get_base_platform() |
| 830 | + self.writeMessage("MPRemote session validated. Platform: " + mpr_base_platform + "\n") |
823 | 831 |
|
824 | 832 | # If we are able to use mpremote to enter bootloader mode, do so
|
825 | 833 | # Otherwise, prompt the user to press the correct button sequence to enter bootloader mode
|
826 |
| - if mpr is not None: |
| 834 | + if mpr_base_platform == "rp2": |
827 | 835 | self.writeMessage("Able to automatically enter bootloader mode...\n")
|
828 | 836 | mpr.enter_bootloader()
|
829 | 837 | self.writeMessage("Entering bootloader mode...\n")
|
@@ -905,12 +913,12 @@ def do_upload_teensy(self, fwFile = None, boardName = None) -> None:
|
905 | 913 | theJob = AxJob(AUxTeensyUploadTeensy.ACTION_ID, {"loader": resource_path("teensy_loader_cli.exe", _RESOURCE_DIRECTORY),
|
906 | 914 | "mcu":"imxrt1062",
|
907 | 915 | "board": boardName,
|
908 |
| - "file": fwFile |
| 916 | + "file": fwFile, |
| 917 | + "size": self.get_current_firmware_file_size(), |
909 | 918 | })
|
910 | 919 |
|
911 | 920 |
|
912 |
| - # Show to progress bar and set it to 0. Reset our teensy progress bar and save the file size |
913 |
| - self.teensyProgress.reset(self.get_current_firmware_file_size()) |
| 921 | + # Show progress bar and set it to 0. |
914 | 922 | self.progress_bar_start("Teensy Upload Progress:")
|
915 | 923 |
|
916 | 924 | self._worker.add_job(theJob)
|
|
0 commit comments