eric6/MicroPython/EspDevices.py

branch
maintenance
changeset 7362
028bf21bb5a2
parent 7360
9190402e4505
child 7595
5db6bfeff23e
--- a/eric6/MicroPython/EspDevices.py	Sat Dec 07 14:16:25 2019 +0100
+++ b/eric6/MicroPython/EspDevices.py	Wed Jan 01 12:01:54 2020 +0100
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de>
+# Copyright (c) 2019 - 2020 Detlev Offenbach <detlev@die-offenbachs.de>
 #
 
 """
@@ -11,7 +11,7 @@
 
 import sys
 
-from PyQt5.QtCore import pyqtSlot
+from PyQt5.QtCore import pyqtSlot, QProcess
 from PyQt5.QtWidgets import QDialog
 
 from E5Gui import E5MessageBox
@@ -24,16 +24,6 @@
 import Preferences
 
 
-# TODO: add backupFlash: python ./esptool.py --port /dev/ttyUSB4 --baud 115200 read_flash 0x00000 0x400000 backup.img
-#       selection of sizes: 1MB, 2MB, 4MB, 8MB, 16M (0x100000, 0x200000, 0x400000, 0x800000, 0x1000000)
-#       ESP8266: 256KB, 512KB (0x40000, 0x80000)
-# TODO: add restoreFlash: python esptool.py --port /dev/ttyUSB4 write_flash --flash_mode qio 0x00000 backup.img
-#       alternative modes for --flash_mode: qio,qout,dio,dout
-#       optional: --flash_size 1MB, 2MB, 4MB, 8MB, 16M (ESP8266 zusätzlich 256KB, 512KB)
-# TODO: add showChipID: python esptool.py  --port /dev/ttyUSB4  --baud 115200 chip_id
-# TODO: add showFlashID: python esptool.py  --port /dev/ttyUSB4  --baud 115200 flash_id
-# TODO: add readMAC: python esptool.py  --port /dev/ttyUSB4  --baud 115200 read_mac
-
 class EspDevice(MicroPythonDevice):
     """
     Class implementing the device for ESP32 and ESP8266 based boards.
@@ -146,6 +136,23 @@
                              self.__flashAddons)
         act.setEnabled(not connected)
         menu.addSeparator()
+        act = menu.addAction(self.tr("Backup Firmware"),
+                             self.__backupFlash)
+        act.setEnabled(not connected)
+        act = menu.addAction(self.tr("Restore Firmware"),
+                             self.__restoreFlash)
+        act.setEnabled(not connected)
+        menu.addSeparator()
+        act = menu.addAction(self.tr("Show Chip ID"),
+                             self.__showChipID)
+        act.setEnabled(not connected)
+        act = menu.addAction(self.tr("Show Flash ID"),
+                             self.__showFlashID)
+        act.setEnabled(not connected)
+        act = menu.addAction(self.tr("Show MAC Address"),
+                             self.__showMACAddress)
+        act.setEnabled(not connected)
+        menu.addSeparator()
         act = menu.addAction(self.tr("Reset Device"), self.__resetDevice)
         menu.addSeparator()
         menu.addAction(self.tr("Install 'esptool.py'"), self.__installEspTool)
@@ -168,7 +175,8 @@
                 "erase_flash",
             ]
             dlg = E5ProcessDialog(self.tr("'esptool erase_flash' Output"),
-                                  self.tr("Erase Flash"))
+                                  self.tr("Erase Flash"),
+                                  showProgress=True)
             res = dlg.startProcess(sys.executable, flashArgs)
             if res:
                 dlg.exec_()
@@ -201,7 +209,8 @@
                 firmware,
             ]
             dlg = E5ProcessDialog(self.tr("'esptool write_flash' Output"),
-                                  self.tr("Flash MicroPython Firmware"))
+                                  self.tr("Flash MicroPython Firmware"),
+                                  showProgress=True)
             res = dlg.startProcess(sys.executable, flashArgs)
             if res:
                 dlg.exec_()
@@ -225,20 +234,148 @@
                 firmware,
             ]
             dlg = E5ProcessDialog(self.tr("'esptool write_flash' Output"),
-                                  self.tr("Flash Additional Firmware"))
+                                  self.tr("Flash Additional Firmware"),
+                                  showProgress=True)
+            res = dlg.startProcess(sys.executable, flashArgs)
+            if res:
+                dlg.exec_()
+    
+    @pyqtSlot()
+    def __backupFlash(self):
+        """
+        Private slot to backup the currently flashed firmware.
+        """
+        from .EspBackupRestoreFirmwareDialog import (
+            EspBackupRestoreFirmwareDialog
+        )
+        dlg = EspBackupRestoreFirmwareDialog(backupMode=True)
+        if dlg.exec_() == QDialog.Accepted:
+            chip, flashSize, flashMode, firmware = dlg.getData()
+            flashArgs = [
+                "-u",
+                "-m", "esptool",
+                "--chip", chip,
+                "--port", self.microPython.getCurrentPort(),
+                "read_flash",
+                "0x0", flashSize,
+                firmware,
+            ]
+            dlg = E5ProcessDialog(self.tr("'esptool read_flash' Output"),
+                                  self.tr("Backup Firmware"),
+                                  showProgress=True)
             res = dlg.startProcess(sys.executable, flashArgs)
             if res:
                 dlg.exec_()
     
     @pyqtSlot()
+    def __restoreFlash(self):
+        """
+        Private slot to restore a previously saved firmware.
+        """
+        from .EspBackupRestoreFirmwareDialog import (
+            EspBackupRestoreFirmwareDialog
+        )
+        dlg = EspBackupRestoreFirmwareDialog(backupMode=False)
+        if dlg.exec_() == QDialog.Accepted:
+            chip, flashSize, flashMode, firmware = dlg.getData()
+            flashArgs = [
+                "-u",
+                "-m", "esptool",
+                "--chip", chip,
+                "--port", self.microPython.getCurrentPort(),
+                "write_flash",
+                "--flash_mode", flashMode,
+            ]
+            if bool(flashSize):
+                flashArgs.extend([
+                    "--flash_size", flashSize,
+                ])
+            flashArgs.extend([
+                "0x0",
+                firmware,
+            ])
+            dlg = E5ProcessDialog(self.tr("'esptool write_flash' Output"),
+                                  self.tr("Restore Firmware"),
+                                  showProgress=True)
+            res = dlg.startProcess(sys.executable, flashArgs)
+            if res:
+                dlg.exec_()
+    
+    @pyqtSlot()
+    def __showChipID(self):
+        """
+        Private slot to show the ID of the ESP chip.
+        """
+        args = [
+            "-u",
+            "-m", "esptool",
+            "--port", self.microPython.getCurrentPort(),
+            "chip_id"
+        ]
+        dlg = E5ProcessDialog(self.tr("'esptool chip_id' Output"),
+                              self.tr("Show Chip ID"))
+        res = dlg.startProcess(sys.executable, args)
+        if res:
+            dlg.exec_()
+    
+    @pyqtSlot()
+    def __showFlashID(self):
+        """
+        Private slot to show the ID of the ESP flash chip.
+        """
+        args = [
+            "-u",
+            "-m", "esptool",
+            "--port", self.microPython.getCurrentPort(),
+            "flash_id"
+        ]
+        dlg = E5ProcessDialog(self.tr("'esptool flash_id' Output"),
+                              self.tr("Show Flash ID"))
+        res = dlg.startProcess(sys.executable, args)
+        if res:
+            dlg.exec_()
+    
+    @pyqtSlot()
+    def __showMACAddress(self):
+        """
+        Private slot to show the MAC address of the ESP chip.
+        """
+        args = [
+            "-u",
+            "-m", "esptool",
+            "--port", self.microPython.getCurrentPort(),
+            "read_mac"
+        ]
+        dlg = E5ProcessDialog(self.tr("'esptool read_mac' Output"),
+                              self.tr("Show MAC Address"))
+        res = dlg.startProcess(sys.executable, args)
+        if res:
+            dlg.exec_()
+    
+    @pyqtSlot()
     def __resetDevice(self):
         """
         Private slot to reset the connected device.
         """
-        self.microPython.commandsInterface().execute([
-            "import machine",
-            "machine.reset()",
-        ])
+        if self.microPython.isConnected():
+            self.microPython.commandsInterface().execute([
+                "import machine",
+                "machine.reset()",
+            ])
+        else:
+            # perform a reset via esptool using flash_id command ignoring
+            # the output
+            args = [
+                "-u",
+                "-m", "esptool",
+                "--port", self.microPython.getCurrentPort(),
+                "flash_id"
+            ]
+            proc = QProcess()
+            proc.start(sys.executable, args)
+            procStarted = proc.waitForStarted(10000)
+            if procStarted:
+                proc.waitForFinished(10000)
     
     @pyqtSlot()
     def __installEspTool(self):

eric ide

mercurial