Sat, 20 Feb 2021 14:28:14 +0100
MicroPython
- added support for "Raspberry Pi Pico" (i.e. RP2040 based boards)
--- a/docs/changelog Sat Feb 20 14:25:06 2021 +0100 +++ b/docs/changelog Sat Feb 20 14:28:14 2021 +0100 @@ -8,14 +8,15 @@ - Debugger -- added capability to delete environment variables for the debugged script by adding a '-' to the variable name in the start dialog -- Debug Viewer: +- Debug Viewer -- changed code to show project relative paths in the breakpoint viewer - File Browser -- added capability to show/hide hidden files (i.e. those starting with '.') -- added capability to create new files/directories and delete them - Mercurial Interface -- added support for Mercurial 5.7 -- MicroPython: +- MicroPython + -- added support for "Raspberry Pi Pico" (i.e. RP2040 based boards) -- extended the list of supported (recognized) CircuitPython boards -- added capability to manually configure devices not yet known by eric6 -- added a generic dialog for flashing UF2 capable devices (with device
--- a/eric6.epj Sat Feb 20 14:25:06 2021 +0100 +++ b/eric6.epj Sat Feb 20 14:28:14 2021 +0100 @@ -250,10 +250,12 @@ "eric6/IconEditor/IconSizeDialog.py", "eric6/IconEditor/__init__.py", "eric6/IconEditor/cursors/__init__.py", + "eric6/MicroPython/AddEditDevicesDialog.py", "eric6/MicroPython/CircuitPythonDevices.py", "eric6/MicroPython/EspBackupRestoreFirmwareDialog.py", "eric6/MicroPython/EspDevices.py", "eric6/MicroPython/EspFirmwareSelectionDialog.py", + "eric6/MicroPython/GenericMicroPythonDevices.py", "eric6/MicroPython/IgnoredDevicesDialog.py", "eric6/MicroPython/MicroPythonCommandsInterface.py", "eric6/MicroPython/MicroPythonDevices.py", @@ -266,6 +268,8 @@ "eric6/MicroPython/MicroPythonWidget.py", "eric6/MicroPython/MicrobitDevices.py", "eric6/MicroPython/PyBoardDevices.py", + "eric6/MicroPython/UF2FlashDialog.py", + "eric6/MicroPython/UnknownDevicesDialog.py", "eric6/MicroPython/__init__.py", "eric6/MultiProject/AddProjectDialog.py", "eric6/MultiProject/MultiProject.py", @@ -1623,10 +1627,7 @@ "scripts/uninstall-debugclients.py", "scripts/uninstall.py", "setup.py", - "eric6/MicroPython/AddEditDevicesDialog.py", - "eric6/MicroPython/UnknownDevicesDialog.py", - "eric6/MicroPython/GenericMicroPythonDevices.py", - "eric6/MicroPython/UF2FlashDialog.py" + "eric6/MicroPython/RP2040Devices.py" ], "FORMS": [ "eric6/CondaInterface/CondaExecDialog.ui", @@ -1669,12 +1670,15 @@ "eric6/HexEdit/HexEditReplaceWidget.ui", "eric6/HexEdit/HexEditSearchWidget.ui", "eric6/IconEditor/IconSizeDialog.ui", + "eric6/MicroPython/AddEditDevicesDialog.ui", "eric6/MicroPython/EspBackupRestoreFirmwareDialog.ui", "eric6/MicroPython/EspFirmwareSelectionDialog.ui", "eric6/MicroPython/IgnoredDevicesDialog.ui", "eric6/MicroPython/MicroPythonFileManagerWidget.ui", "eric6/MicroPython/MicroPythonProgressInfoDialog.ui", "eric6/MicroPython/MicroPythonWidget.ui", + "eric6/MicroPython/UF2FlashDialog.ui", + "eric6/MicroPython/UnknownDevicesDialog.ui", "eric6/MultiProject/AddProjectDialog.ui", "eric6/MultiProject/PropertiesDialog.ui", "eric6/Network/IRC/IrcChannelEditDialog.ui", @@ -2071,10 +2075,7 @@ "eric6/WebBrowser/VirusTotal/VirusTotalWhoisDialog.ui", "eric6/WebBrowser/WebBrowserClearPrivateDataDialog.ui", "eric6/WebBrowser/WebBrowserLanguagesDialog.ui", - "eric6/WebBrowser/ZoomManager/ZoomValuesDialog.ui", - "eric6/MicroPython/AddEditDevicesDialog.ui", - "eric6/MicroPython/UnknownDevicesDialog.ui", - "eric6/MicroPython/UF2FlashDialog.ui" + "eric6/WebBrowser/ZoomManager/ZoomValuesDialog.ui" ], "RESOURCES": [], "INTERFACES": [], @@ -2287,9 +2288,9 @@ "linux/eric6_browser.desktop", "linux/eric6_browser.desktop.in", "others/default.e4k", + "others/default.ekj", "others/default_Mac.e4k", - "others/pylint.rc", - "others/default.ekj" + "others/pylint.rc" ], "TRANSLATIONS": [ "eric6/i18n/eric6_cs.qm", @@ -2387,38 +2388,22 @@ "PROJECTTYPESPECIFICDATA": {}, "CHECKERSPARMS": { "Pep8Checker": { - "EnabledCheckerCategories": "C, D, E, M, N, W", - "ExcludeFiles": "*/ThirdParty/*, */coverage/*, */Ui_*.py, */Examples/*, */*_rc.py,*/pycodestyle.py,*/pyflakes/checker.py,*/mccabe.py,*/eradicate.py", - "ExcludeMessages": "C101,E265,E266,E305,E402,M201,M301,M302,M303,M304,M305,M306,M307,M308,M311,M312,M313,M314,M315,M321,M701,M702,M811,M834,N802,N803,N807,N808,N821,W293,W504", - "IncludeMessages": "", - "RepeatMessages": true, - "FixCodes": "", - "NoFixCodes": "E501", - "FixIssues": false, - "ShowIgnored": false, - "MaxLineLength": 79, - "MaxDocLineLength": 79, + "AnnotationsChecker": { + "MaximumComplexity": 3, + "MinimumCoverage": 75 + }, "BlankLines": [ 2, 1 ], - "HangClosing": false, - "DocstringType": "eric", - "MaxCodeComplexity": 10, - "LineComplexity": 25, - "LineComplexityScore": 10, - "ValidEncodings": "latin-1, utf-8", - "CopyrightMinFileSize": 0, - "CopyrightAuthor": "", - "FutureChecker": "", "BuiltinsChecker": { - "str": [ + "bytes": [ "unicode" ], "chr": [ "unichr" ], - "bytes": [ + "str": [ "unicode" ] }, @@ -2440,11 +2425,26 @@ "- " ] }, - "AnnotationsChecker": { - "MinimumCoverage": 75, - "MaximumComplexity": 3 - }, + "CopyrightAuthor": "", + "CopyrightMinFileSize": 0, + "DocstringType": "eric", + "EnabledCheckerCategories": "C, D, E, M, N, W", + "ExcludeFiles": "*/ThirdParty/*, */coverage/*, */Ui_*.py, */Examples/*, */*_rc.py,*/pycodestyle.py,*/pyflakes/checker.py,*/mccabe.py,*/eradicate.py", + "ExcludeMessages": "C101,E265,E266,E305,E402,M201,M301,M302,M303,M304,M305,M306,M307,M308,M311,M312,M313,M314,M315,M321,M701,M702,M811,M834,N802,N803,N807,N808,N821,W293,W504", + "FixCodes": "", + "FixIssues": false, + "FutureChecker": "", + "HangClosing": false, + "IncludeMessages": "", + "LineComplexity": 25, + "LineComplexityScore": 10, + "MaxCodeComplexity": 10, + "MaxDocLineLength": 79, + "MaxLineLength": 79, + "NoFixCodes": "E501", + "RepeatMessages": true, "SecurityChecker": { + "CheckTypedException": false, "HardcodedTmpDirectories": [ "/tmp", "/var/tmp", @@ -2468,12 +2468,13 @@ ], "WeakKeySizeDsaHigh": "1024", "WeakKeySizeDsaMedium": "2048", - "WeakKeySizeRsaHigh": "1024", - "WeakKeySizeRsaMedium": "2048", "WeakKeySizeEcHigh": "160", "WeakKeySizeEcMedium": "224", - "CheckTypedException": false - } + "WeakKeySizeRsaHigh": "1024", + "WeakKeySizeRsaMedium": "2048" + }, + "ShowIgnored": false, + "ValidEncodings": "latin-1, utf-8" }, "SyntaxChecker": { "ExcludeFiles": "*/coverage/*, */ThirdParty/*, */Examples/*"
--- a/eric6/MicroPython/MicroPythonDevices.py Sat Feb 20 14:25:06 2021 +0100 +++ b/eric6/MicroPython/MicroPythonDevices.py Sat Feb 20 14:28:14 2021 +0100 @@ -137,7 +137,16 @@ "port_description": "", }, - # TODO: add RP2040 boards (VID: 0x2e8a, PID: 0x0005) + "rp2040": { + "ids": [ + (0x2E8A, 0x0005), # Raspberry Pi Pico + ], + "description": QCoreApplication.translate( + "MicroPythonDevice", "RP2040 based"), + "icon": "rp2040Device", + "port_description": "", + }, + "generic": { # only manually configured devices use this "ids": [], @@ -290,7 +299,9 @@ elif deviceType == "pyboard": from .PyBoardDevices import PyBoardDevice return PyBoardDevice(microPythonWidget, deviceType) - # TODO: add RP2040 boards (VID: 0x2e8a, PID: 0x0005) + elif deviceType == "rp2040": + from .RP2040Devices import RP2040Device + return RP2040Device(microPythonWidget, deviceType) elif deviceType == "generic": from .GenericMicroPythonDevices import GenericMicroPythonDevice return GenericMicroPythonDevice(microPythonWidget, deviceType, @@ -494,7 +505,7 @@ commands = [c.encode("utf-8)") + b'\r' for c in commandsList] commands.append(b'\r') commands.append(b'\x04') - rawOff = [b'\x02'] + rawOff = [b'\x02', b'\x02'] commandSequence = rawOn + newLine + commands + rawOff self.microPython.commandsInterface().executeAsync(commandSequence)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/MicroPython/RP2040Devices.py Sat Feb 20 14:28:14 2021 +0100 @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2021 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the device interface class for RP2040 based boards +(e.g. Raspberry Pi Pico). +""" + +from PyQt5.QtCore import pyqtSlot + +from .MicroPythonDevices import MicroPythonDevice +from .MicroPythonWidget import HAS_QTCHART + +import Preferences + + +class RP2040Device(MicroPythonDevice): + """ + Class implementing the device for RP2040 based boards. + """ + def __init__(self, microPythonWidget, deviceType, parent=None): + """ + Constructor + + @param microPythonWidget reference to the main MicroPython widget + @type MicroPythonWidget + @param deviceType device type assigned to this device interface + @type str + @param parent reference to the parent object + @type QObject + """ + super(RP2040Device, self).__init__( + microPythonWidget, deviceType, parent) + + def setButtons(self): + """ + Public method to enable the supported action buttons. + """ + super(RP2040Device, self).setButtons() + self.microPython.setActionButtons( + run=True, repl=True, files=True, chart=HAS_QTCHART) + + def forceInterrupt(self): + """ + Public method to determine the need for an interrupt when opening the + serial connection. + + @return flag indicating an interrupt is needed + @rtype bool + """ + return False + + def deviceName(self): + """ + Public method to get the name of the device. + + @return name of the device + @rtype str + """ + return self.tr("RP2040") + + def canStartRepl(self): + """ + Public method to determine, if a REPL can be started. + + @return tuple containing a flag indicating it is safe to start a REPL + and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def canStartPlotter(self): + """ + Public method to determine, if a Plotter can be started. + + @return tuple containing a flag indicating it is safe to start a + Plotter and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def canRunScript(self): + """ + Public method to determine, if a script can be executed. + + @return tuple containing a flag indicating it is safe to start a + Plotter and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def runScript(self, script): + """ + Public method to run the given Python script. + + @param script script to be executed + @type str + """ + pythonScript = script.split("\n") + self.sendCommands(pythonScript) + + def canStartFileManager(self): + """ + Public method to determine, if a File Manager can be started. + + @return tuple containing a flag indicating it is safe to start a + File Manager and a reason why it cannot. + @rtype tuple of (bool, str) + """ + return True, "" + + def addDeviceMenuEntries(self, menu): + """ + Public method to add device specific entries to the given menu. + + @param menu reference to the context menu + @type QMenu + """ + connected = self.microPython.isConnected() + + act = menu.addAction(self.tr("Activate Bootloader"), + self.__activateBootloader) + act.setEnabled(connected) + act = menu.addAction(self.tr("Flash Firmware"), self.__flashPython) + act.setEnabled(not connected) + + def hasFlashMenuEntry(self): + """ + Public method to check, if the device has its own flash menu entry. + + @return flag indicating a specific flash menu entry + @rtype bool + """ + return True + + @pyqtSlot() + def __flashPython(self): + """ + Private slot to flash a MicroPython firmware to the device. + """ + from .UF2FlashDialog import UF2FlashDialog + dlg = UF2FlashDialog(boardType="rp2040") + dlg.exec() + + def __activateBootloader(self): + """ + Private method to switch the board into 'bootloader' mode. + """ + if self.microPython.isConnected(): + self.microPython.commandsInterface().execute([ + "import machine", + "machine.bootloader()", + ]) + # simulate pressing the disconnect button + self.microPython.on_connectButton_clicked() + + def getDocumentationUrl(self): + """ + Public method to get the device documentation URL. + + @return documentation URL of the device + @rtype str + """ + return Preferences.getMicroPython("MicroPythonDocuUrl") + + def getDownloadMenuEntries(self): + """ + Public method to retrieve the entries for the downloads menu. + + @return list of tuples with menu text and URL to be opened for each + entry + @rtype list of tuple of (str, str) + """ + return [ + (self.tr("MicroPython Firmware"), + Preferences.getMicroPython("MicroPythonFirmwareUrl")), + ("<separator>", ""), + (self.tr("CircuitPython Firmware"), + Preferences.getMicroPython("CircuitPythonFirmwareUrl")), + (self.tr("CircuitPython Libraries"), + Preferences.getMicroPython("CircuitPythonLibrariesUrl")) + ]