eric6/MicroPython/MicroPythonDevices.py

Sun, 07 Jul 2019 18:48:17 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 07 Jul 2019 18:48:17 +0200
branch
micropython
changeset 7054
fb84d8489bc1
child 7058
bdd583f96e96
permissions
-rw-r--r--

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)

eric ide

mercurial