Sat, 12 Oct 2019 15:08:28 +0200
MicroPython: added support for PyBoard.
--- a/docs/changelog Thu Oct 10 19:08:02 2019 +0200 +++ b/docs/changelog Sat Oct 12 15:08:28 2019 +0200 @@ -2,6 +2,8 @@ ---------- Version 19.11: - bug fixes +- MicroPython + -- added support for PyBoard Version 19.10: - bug fixes
--- a/eric6.e4p Thu Oct 10 19:08:02 2019 +0200 +++ b/eric6.e4p Sat Oct 12 15:08:28 2019 +0200 @@ -259,6 +259,7 @@ <Source>eric6/MicroPython/MicroPythonSerialPort.py</Source> <Source>eric6/MicroPython/MicroPythonWidget.py</Source> <Source>eric6/MicroPython/MicrobitDevices.py</Source> + <Source>eric6/MicroPython/PyBoardDevices.py</Source> <Source>eric6/MicroPython/__init__.py</Source> <Source>eric6/MultiProject/AddProjectDialog.py</Source> <Source>eric6/MultiProject/MultiProject.py</Source> @@ -2036,9 +2037,6 @@ <Other>eric6/APIs/MicroPython/circuitpython.api</Other> <Other>eric6/APIs/MicroPython/microbit.api</Other> <Other>eric6/APIs/MicroPython/micropython.api</Other> - <Other>eric6/APIs/Python/zope-2.10.7.api</Other> - <Other>eric6/APIs/Python/zope-2.11.2.api</Other> - <Other>eric6/APIs/Python/zope-3.3.1.api</Other> <Other>eric6/APIs/Python3/PyQt4.bas</Other> <Other>eric6/APIs/Python3/PyQt5.bas</Other> <Other>eric6/APIs/Python3/PyQtChart.bas</Other> @@ -2046,6 +2044,9 @@ <Other>eric6/APIs/Python3/QScintilla2.bas</Other> <Other>eric6/APIs/Python3/eric6.api</Other> <Other>eric6/APIs/Python3/eric6.bas</Other> + <Other>eric6/APIs/Python/zope-2.10.7.api</Other> + <Other>eric6/APIs/Python/zope-2.11.2.api</Other> + <Other>eric6/APIs/Python/zope-3.3.1.api</Other> <Other>eric6/APIs/QSS/qss.api</Other> <Other>eric6/APIs/Ruby/Ruby-1.8.7.api</Other> <Other>eric6/APIs/Ruby/Ruby-1.8.7.bas</Other>
--- a/eric6/MicroPython/MicroPythonDevices.py Thu Oct 10 19:08:02 2019 +0200 +++ b/eric6/MicroPython/MicroPythonDevices.py Sat Oct 12 15:08:28 2019 +0200 @@ -54,6 +54,16 @@ "description": "BBC micro:bit", "icon": "microbitDevice", }, + + "pyboard": { + "ids": [ + (0xF055, 0x9800), # Pyboard in CDC mode + (0xF055, 0x9801), # Pyboard in CDC+HID mode + (0xF055, 0x9802), # Pyboard in CDC+MSC mode + ], + "description": "PyBoard", + "icon": "micropython48", + } } @@ -144,6 +154,9 @@ elif deviceType == "bbc_microbit": from .MicrobitDevices import MicrobitDevice return MicrobitDevice(microPythonWidget) + elif deviceType == "pyboard": + from .PyBoardDevices import PyBoardDevice + return PyBoardDevice(microPythonWidget) else: # nothing specific requested return MicroPythonDevice(microPythonWidget)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/MicroPython/PyBoardDevices.py Sat Oct 12 15:08:28 2019 +0200 @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the device interface class for PyBoard boards. +""" + +from E5Gui import E5MessageBox +from E5Gui.E5Application import e5App + +from .MicroPythonDevices import MicroPythonDevice +from .MicroPythonWidget import HAS_QTCHART + +import Utilities +import Preferences + + +class PyBoardDevice(MicroPythonDevice): + """ + Class implementing the device for PyBoard boards. + """ + DeviceVolumeName = "PYBFLASH" + + FlashInstructionsURL = ( + "https://github.com/micropython/micropython/wiki/" + "Pyboard-Firmware-Update" + ) + + def __init__(self, microPythonWidget, parent=None): + """ + Constructor + + @param microPythonWidget reference to the main MicroPython widget + @type MicroPythonWidget + @param parent reference to the parent object + @type QObject + """ + super(PyBoardDevice, self).__init__(microPythonWidget, parent) + + def setButtons(self): + """ + Public method to enable the supported action buttons. + """ + super(PyBoardDevice, self).setButtons() + self.microPython.setActionButtons( + run=True, repl=True, files=True, chart=HAS_QTCHART) + + if self.__deviceVolumeMounted(): + self.microPython.setActionButtons(open=True, save=True) + + 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("PyBoard") + + 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 supportsLocalFileAccess(self): + """ + Public method to indicate file access via a local directory. + + @return flag indicating file access via local directory + @rtype bool + """ + return self.__deviceVolumeMounted() + + def __deviceVolumeMounted(self): + """ + Private method to check, if the device volume is mounted. + + @return flag indicated a mounted device + @rtype bool + """ + return self.getWorkspace(silent=True).endswith(self.DeviceVolumeName) + + def getWorkspace(self, silent=False): + """ + Public method to get the workspace directory. + + @param silent flag indicating silent operations + @type bool + @return workspace directory used for saving files + @rtype str + """ + # Attempts to find the path on the filesystem that represents the + # plugged in PyBoard board. + deviceDirectory = Utilities.findVolume(self.DeviceVolumeName) + + if deviceDirectory: + return deviceDirectory + else: + # return the default workspace and give the user a warning (unless + # silent mode is selected) + if not silent: + E5MessageBox.warning( + self.microPython, + self.tr("Workspace Directory"), + self.tr("Python files for PyBoard devices are stored" + " on the device. Therefore, to edit these files" + " you need to have the device plugged in. Until" + " you plug in a device, the standard directory" + " will be used.")) + + return super(PyBoardDevice, self).getWorkspace() + + def getDocumentationUrl(self): + """ + Public method to get the device documentation URL. + + @return documentation URL of the device + @rtype str + """ + return Preferences.getMicroPython("MicroPythonDocuUrl") + + def addDeviceMenuEntries(self, menu): + """ + Public method to add device specific entries to the given menu. + + @param menu reference to the context menu + @type QMenu + """ + menu.addAction( + self.tr("MicroPython Install Instructions"), + self.__showInstallInstructions) + + def __showInstallInstructions(self): + """ + Private slot to open the URL containing instructions for installing + MicroPython on the pyboard. + """ + e5App().getObject("UserInterface").launchHelpViewer( + PyBoardDevice.FlashInstructionsURL)