Sun, 07 Jul 2019 18:48:17 +0200
Started implementing the MicroPython support.
# -*- coding: utf-8 -*- # Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing some utility functions and the MicroPythonDevice base class. """ from __future__ import unicode_literals import logging from PyQt5.QtCore import QObject import Globals import UI.PixmapCache SupportedBoards = { "esp": { "ids": [ (0x1A86, 0x7523), # HL-340 (0x10C4, 0xEA60), # CP210x (0x0403, 0x6015), # Sparkfun ESP32 VID, PID ], "description": "ESP8266, ESP32", "icon": "esp32Device", }, "adafruit": { "ids": [ (0x239A, 0x8015), # Adafruit Feather M0 CircuitPython (0x239A, 0x8023), # Adafruit Feather M0 Express CircuitPython (0x239A, 0x801B), # Adafruit Feather M0 Express CircuitPython (0x239A, 0x8014), # Adafruit Metro M0 CircuitPython (0x239A, 0x8019), # Adafruit CircuitPlayground # Express CircuitPython (0x239A, 0x801D), # Adafruit Gemma M0 (0x239A, 0x801F), # Adafruit Trinket M0 (0x239A, 0x8012), # Adafruit ItsyBitsy M0 (0x239A, 0x8021), # Adafruit Metro M4 (0x239A, 0x8025), # Adafruit Feather RadioFruit (0x239A, 0x8026), # Adafruit Feather M4 (0x239A, 0x8028), # Adafruit pIRKey M0 (0x239A, 0x802A), # Adafruit Feather 52840 (0x239A, 0x802C), # Adafruit Itsy M4 (0x239A, 0x802E), # Adafruit CRICKit M0 (0x239A, 0xD1ED), # Adafruit HalloWing M0 (0x239A, 0x8030), # Adafruit NeoTrellis M4 (0x239A, 0x8032), # Grand Central (0x2B04, 0xC00C), # Particle Argon (0x2B04, 0xC00D), # Particle Boron (0x2B04, 0xC00E), # Particle Xenon (0x239A, 0x8034), # future board (0x239A, 0x8036), # future board (0x239A, 0x8038), # future board (0x239A, 0x803A), # future board (0x239A, 0x803C), # future board (0x239A, 0x803E), # future board (0x239A, None), # Any Adafruit Boards ], "description": "Adafruit CircuitPython", "icon": "adafruitDevice", }, "bbc_microbit": { "ids": [ (0x0D28, 0x0204), # micro:bit USB VID, PID ], "description": "BBC micro:bit", "icon": "microbitDevice", }, } def getSupportedDevices(): """ Function to get a list of supported MicroPython devices. @return set of tuples with the board type and description @rtype set of tuples of (str, str) """ boards = [] for board in SupportedBoards: boards.append( (board, SupportedBoards[board]["description"])) return boards def getFoundDevices(): """ Function to check the serial ports for supported MicroPython devices. @return set of tuples with the board type, a description and the serial port it is connected at @rtype set of tuples of (str, str, str) """ from PyQt5.QtSerialPort import QSerialPortInfo foundDevices = [] availablePorts = QSerialPortInfo.availablePorts() for port in availablePorts: vid = port.vendorIdentifier() pid = port.productIdentifier() for board in SupportedBoards: if ((vid, pid) in SupportedBoards[board]["ids"] or (vid, None) in SupportedBoards[board]["ids"]): foundDevices.append( (board, SupportedBoards[board]["description"], port.portName())) break else: logging.debug("Unknown device: (0x%04x:0x%04x)", vid, pid) return foundDevices def getDeviceIcon(boardName, iconFormat=True): """ Function to get the icon for the given board. @param boardName name of the board @type str @param iconFormat flag indicating to get an icon or a pixmap @type bool @return icon for the board (iconFormat == True) or a pixmap (iconFormat == False) @rtype QIcon or QPixmap """ if boardName in SupportedBoards: iconName = SupportedBoards[boardName]["icon"] else: # return a generic MicroPython icon iconName = "micropython48" if iconFormat: return UI.PixmapCache.getIcon(iconName) else: return UI.PixmapCache.getPixmap(iconName) def getDevice(deviceType): """ Public method to instantiate a specific MicroPython device interface. @param deviceType type of the device interface @type str @return instantiated device interface @rtype MicroPythonDevice """ # TODO: not implemented yet return None class MicroPythonDevice(QObject): """ Base class for the more specific MicroPython devices. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent object @type QObject """ super(MicroPythonDevice, self).__init__(parent) def supportedActions(self): """ Public method to get the names of the supported actions. @return tuple of supported actions out of "repl", "run", "files", "chart" @rtype tuple of str """ return tuple() def findDevice(self, deviceType): """ Public method to find the first device of a specific type. @param deviceType device type @type str @return tuple containing the port the device is connected to and its serial number @rtype tuple of (str, str) """ from PyQt5.QtSerialPort import QSerialPortInfo availablePorts = QSerialPortInfo.availablePorts() for port in availablePorts: vid = port.vendorIdentifier() pid = port.productIdentifier() for board in SupportedBoards: if ((vid, pid) in SupportedBoards[board] or (vid, None) in SupportedBoards[board]): portName = port.portName() serialNumber = port.serialNumber() return (self.__portPath(portName), serialNumber) return (None, None) def __portPath(self, portName): """ Private method to get the full path of a given port. @param portName name of the port the path shall be determined for @type str @return full port path @rtype str """ if Globals.isWindowsPlatform(): # return name unchanged return portName else: # assume Posix system (Linux or macOS) return "/dev/{0}".format(portName)