diff -r f0a7469a2ad4 -r fb84d8489bc1 eric6/MicroPython/MicroPythonDevices.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric6/MicroPython/MicroPythonDevices.py Sun Jul 07 18:48:17 2019 +0200 @@ -0,0 +1,220 @@ +# -*- 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)