src/eric7/MicroPython/MicrobitDevices.py

branch
eric7
changeset 9751
606ac0e26533
parent 9750
4958dd72c937
child 9752
2b9546c0cbd9
--- a/src/eric7/MicroPython/MicrobitDevices.py	Thu Feb 09 09:55:57 2023 +0100
+++ b/src/eric7/MicroPython/MicrobitDevices.py	Sat Feb 11 16:59:50 2023 +0100
@@ -8,6 +8,7 @@
 Calliope mini boards.
 """
 
+import contextlib
 import os
 import shutil
 
@@ -29,7 +30,7 @@
     Class implementing the device for BBC micro:bit and Calliope mini boards.
     """
 
-    def __init__(self, microPythonWidget, deviceType, parent=None):
+    def __init__(self, microPythonWidget, deviceType, serialNumber, parent=None):
         """
         Constructor
 
@@ -37,11 +38,18 @@
         @type MicroPythonWidget
         @param deviceType type of the device
         @type str
+        @param serialNumber serial number of the board
+        @type str
         @param parent reference to the parent object
         @type QObject
         """
         super().__init__(microPythonWidget, deviceType, parent)
 
+        self.__boardId = 0  # illegal ID
+        if serialNumber:
+            with contextlib.suppress(ValueError):
+                self.__boardId = int(serialNumber[:4], 16)
+
     def setButtons(self):
         """
         Public method to enable the supported action buttons.
@@ -134,8 +142,42 @@
         @return flag indicating support for time commands
         @rtype bool
         """
+        if (
+            self.microPython.isConnected()
+            and self.checkDeviceData()
+            and self._deviceData["mpy_name"] == "circuitpython"
+        ):
+            return True
+
         return False
 
+    def __isMicroBitV1(self):
+        """
+        Private method to check, if the device is a BBC micro:bit v1.
+
+        @return falg indicating a BBC micro:bit v1
+        @rtype bool
+        """
+        return self.__boardId in (0x9900, 0x9901)
+
+    def __isMicroBitV2(self):
+        """
+        Private method to check, if the device is a BBC micro:bit v2.
+
+        @return falg indicating a BBC micro:bit v2
+        @rtype bool
+        """
+        return self.__boardId in (0x9903, 0x9904, 0x9905, 0x9906)
+
+    def __isCalliope(self):
+        """
+        Private method to check, if the device is a Calliope mini.
+
+        @return flag indicating a Calliope mini
+        @rtype bool
+        """
+        return self.__boardId in (0x12A0,)
+
     def addDeviceMenuEntries(self, menu):
         """
         Public method to add device specific entries to the given menu.
@@ -300,27 +342,23 @@
         Private slot to show the firmware version of the connected device and the
         available firmware version.
         """
-        if self.microPython.isConnected():
-            interface = self.microPython.commandsInterface()
-            if interface is not None:
-                impInfo = interface.getImplementation()
-                versionInfo = interface.version()
-                if impInfo["name"] != "micropython":
-                    EricMessageBox.critical(
-                        None,
-                        self.tr("Show MicroPython Versions"),
-                        self.tr(
-                            """The firmware of the connected device cannot be"""
-                            """ determined or the board does not run MicroPython."""
-                            """ Aborting..."""
-                        ),
-                    )
-                else:
-                    impInfo["version"] = versionInfo["release"]
-                    if self.getDeviceType() == "bbc_microbit":
-                        if "nRF51" in versionInfo["machine"]:
+        if self.microPython.isConnected() and self.checkDeviceData():
+            if self._deviceData["mpy_name"] not in ("micropython", "circuitpython"):
+                EricMessageBox.critical(
+                    None,
+                    self.tr("Show MicroPython Versions"),
+                    self.tr(
+                        """The firmware of the connected device cannot be"""
+                        """ determined or the board does not run MicroPython"""
+                        """ or CircuitPython. Aborting..."""
+                    ),
+                )
+            else:
+                if self.getDeviceType() == "bbc_microbit":
+                    if self._deviceData["mpy_name"] == "micropython":
+                        if self.__isMicroBitV1():
                             url = QUrl(FirmwareGithubUrls["microbit_v1"])
-                        elif "nRF52" in versionInfo["machine"]:
+                        elif self.__isMicroBitV2():
                             url = QUrl(FirmwareGithubUrls["microbit_v2"])
                         else:
                             EricMessageBox.critical(
@@ -332,33 +370,30 @@
                                 ),
                             )
                             return
-                    else:
-                        EricMessageBox.critical(
-                            None,
-                            self.tr("Show MicroPython Versions"),
-                            self.tr(
-                                """<p>The firmware URL for the device type <b>{0}</b>"""
-                                """ is not known. Aborting...</p>"""
-                            ).format(self.getDeviceType()),
-                        )
-                        return
+                    elif self._deviceData["mpy_name"] == "circuitpython":
+                        url = QUrl(FirmwareGithubUrls["circuitpython"])
+                else:
+                    EricMessageBox.critical(
+                        None,
+                        self.tr("Show MicroPython Versions"),
+                        self.tr(
+                            """<p>The firmware URL for the device type <b>{0}</b>"""
+                            """ is not known. Aborting...</p>"""
+                        ).format(self.getDeviceType()),
+                    )
+                    return
 
-                    ui = ericApp().getObject("UserInterface")
-                    request = QNetworkRequest(url)
-                    reply = ui.networkAccessManager().head(request)
-                    reply.finished.connect(
-                        lambda: self.__firmwareVersionResponse(reply, impInfo)
-                    )
+                ui = ericApp().getObject("UserInterface")
+                request = QNetworkRequest(url)
+                reply = ui.networkAccessManager().head(request)
+                reply.finished.connect(lambda: self.__firmwareVersionResponse(reply))
 
-    def __firmwareVersionResponse(self, reply, implementation):
+    def __firmwareVersionResponse(self, reply):
         """
         Private method handling the response of the latest version request.
 
         @param reply reference to the reply object
         @type QNetworkReply
-        @param implementation dictionary containing the implementation data of the
-            connected device
-        @type dict
         """
         latestUrl = reply.url().toString()
         tag = latestUrl.rsplit("/", 1)[-1]
@@ -367,27 +402,40 @@
             tag = tag[1:]
         latestVersion = Globals.versionToTuple(tag)
 
-        if implementation["version"] == "unknown":
+        if self._deviceData["release"] == "unknown":
             currentVersionStr = self.tr("unknown")
             currentVersion = (0, 0, 0)
         else:
-            currentVersionStr = implementation["version"]
+            currentVersionStr = self._deviceData["release"]
             currentVersion = Globals.versionToTuple(currentVersionStr)
 
+        if self._deviceData["mpy_name"] == "circuitpython":
+            kind = "CircuitPython"
+            microbitVersion = "2"  # only v2 device can run CircuitPython
+        elif self._deviceData["mpy_name"] == "micropython":
+            kind = "MicroPython"
+            if self.__isMicroBitV1():
+                microbitVersion = "1"
+            elif self.__isMicroBitV2():
+                microbitVersion = "2"
+        else:
+            kind = self.tr("Firmware")
+            microbitVersion = "?"
+
         msg = self.tr(
-            "<h4>MicroPython Version Information<br/>"
-            "(BBC micro:bit v{2})</h4>"
+            "<h4>{0} Version Information<br/>"
+            "(BBC micro:bit v{1})</h4>"
             "<table>"
-            "<tr><td>Installed:</td><td>{0}</td></tr>"
-            "<tr><td>Available:</td><td>{1}</td></tr>"
+            "<tr><td>Installed:</td><td>{2}</td></tr>"
+            "<tr><td>Available:</td><td>{3}</td></tr>"
             "</table>"
-        ).format(currentVersionStr, tag, currentVersionStr[0])
+        ).format(kind, microbitVersion, currentVersionStr, tag)
         if currentVersion < latestVersion:
             msg += self.tr("<p><b>Update available!</b></p>")
 
         EricMessageBox.information(
             None,
-            self.tr("MicroPython Version"),
+            self.tr("{0} Version").format(kind),
             msg,
         )
 
@@ -503,7 +551,10 @@
         """
         if self.getDeviceType() == "bbc_microbit":
             # BBC micro:bit
-            return Preferences.getMicroPython("MicrobitDocuUrl")
+            if self._deviceData and self._deviceData["mpy_name"] == "circuitpython":
+                return Preferences.getMicroPython("CircuitPythonDocuUrl")
+            else:
+                return Preferences.getMicroPython("MicrobitDocuUrl")
         else:
             # Calliope mini
             return Preferences.getMicroPython("CalliopeDocuUrl")
@@ -517,20 +568,34 @@
         @rtype list of tuple of (str, str)
         """
         if self.getDeviceType() == "bbc_microbit":
-            return [
-                (
-                    self.tr("MicroPython Firmware for BBC micro:bit V1"),
-                    Preferences.getMicroPython("MicrobitMicroPythonUrl"),
-                ),
-                (
-                    self.tr("MicroPython Firmware for BBC micro:bit V2"),
-                    Preferences.getMicroPython("MicrobitV2MicroPythonUrl"),
-                ),
-                (
-                    self.tr("DAPLink Firmware"),
-                    Preferences.getMicroPython("MicrobitFirmwareUrl"),
-                ),
-            ]
+            if self.__isMicroBitV1():
+                return [
+                    (
+                        self.tr("MicroPython Firmware for BBC micro:bit V1"),
+                        Preferences.getMicroPython("MicrobitMicroPythonUrl"),
+                    ),
+                    (
+                        self.tr("DAPLink Firmware"),
+                        Preferences.getMicroPython("MicrobitFirmwareUrl"),
+                    ),
+                ]
+            elif self.__isMicroBitV2():
+                return [
+                    (
+                        self.tr("MicroPython Firmware for BBC micro:bit V2"),
+                        Preferences.getMicroPython("MicrobitV2MicroPythonUrl"),
+                    ),
+                    (
+                        self.tr("CircuitPython Firmware for BBC micro:bit V2"),
+                        "https://circuitpython.org/board/microbit_v2/",
+                    ),
+                    (
+                        self.tr("DAPLink Firmware"),
+                        Preferences.getMicroPython("MicrobitFirmwareUrl"),
+                    ),
+                ]
+            else:
+                return []
         else:
             return [
                 (
@@ -544,7 +609,7 @@
             ]
 
 
-def createDevice(microPythonWidget, deviceType, vid, pid, boardName):
+def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber):
     """
     Function to instantiate a MicroPython device object.
 
@@ -558,7 +623,9 @@
     @type int
     @param boardName name of the board
     @type str
+    @param serialNumber serial number of the board
+    @type str
     @return reference to the instantiated device object
     @rtype MicrobitDevice
     """
-    return MicrobitDevice(microPythonWidget, deviceType)
+    return MicrobitDevice(microPythonWidget, deviceType, serialNumber)

eric ide

mercurial